summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rtl8723as/core
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rtl8723as/core')
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_ap.c5875
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_bt_mp.c3469
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_cmd.c376
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_debug.c152
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_ieee80211.c181
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_io.c26
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_ioctl_set.c171
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_led.c4844
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_mlme.c311
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_mlme_ext.c1048
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_mp.c46
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_mp_ioctl.c4
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_odm.c217
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_p2p.c911
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_pwrctrl.c272
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_recv.c277
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_security.c325
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_sreset.c706
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_sta_mgt.c11
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_tdls.c5882
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_wapi.c2652
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_wapi_sms4.c1846
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_wlan_util.c145
-rwxr-xr-xdrivers/net/wireless/rtl8723as/core/rtw_xmit.c386
24 files changed, 16428 insertions, 13705 deletions
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_ap.c b/drivers/net/wireless/rtl8723as/core/rtw_ap.c
index 4213f3bdf1b4..adebe11f32c7 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_ap.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_ap.c
@@ -1,2936 +1,2939 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#define _RTW_AP_C_
-
-#include <drv_conf.h>
-#include <osdep_service.h>
-#include <drv_types.h>
-#include <wifi.h>
-
-
-#ifdef CONFIG_AP_MODE
-
-extern unsigned char RTW_WPA_OUI[];
-extern unsigned char WMM_OUI[];
-extern unsigned char WPS_OUI[];
-extern unsigned char P2P_OUI[];
-extern unsigned char WFD_OUI[];
-
-void init_mlme_ap_info(_adapter *padapter)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
-
-
- _rtw_spinlock_init(&pmlmepriv->bcn_update_lock);
-
- //for ACL
- _rtw_init_queue(&pacl_list->acl_node_q);
-
- //pmlmeext->bstart_bss = _FALSE;
-
- start_ap_mode(padapter);
-}
-
-void free_mlme_ap_info(_adapter *padapter)
-{
- _irqL irqL;
- struct sta_info *psta=NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
-
- //stop_ap_mode(padapter);
-
- pmlmepriv->update_bcn = _FALSE;
- pmlmeext->bstart_bss = _FALSE;
-
- rtw_sta_flush(padapter);
-
- pmlmeinfo->state = _HW_STATE_NOLINK_;
-
- //free_assoc_sta_resources
- rtw_free_all_stainfo(padapter);
-
- //free bc/mc sta_info
- psta = rtw_get_bcmc_stainfo(padapter);
- _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
- rtw_free_stainfo(padapter, psta);
- _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
-
-
- _rtw_spinlock_free(&pmlmepriv->bcn_update_lock);
-
-}
-
-static void update_BCNTIM(_adapter *padapter)
-{
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
- unsigned char *pie = pnetwork_mlmeext->IEs;
-
- //DBG_871X("%s\n", __FUNCTION__);
-
- //update TIM IE
- //if(pstapriv->tim_bitmap)
- if(_TRUE)
- {
- u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
- u16 tim_bitmap_le;
- uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
-
- tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);
-
- p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
- if (p != NULL && tim_ielen>0)
- {
- tim_ielen += 2;
-
- premainder_ie = p+tim_ielen;
-
- tim_ie_offset = (sint)(p -pie);
-
- remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;
-
- //append TIM IE from dst_ie offset
- dst_ie = p;
- }
- else
- {
- tim_ielen = 0;
-
- //calucate head_len
- offset = _FIXED_IE_LENGTH_;
-
- /* get ssid_ie len */
- p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SSID_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
- if (p != NULL)
- offset += tmp_len+2;
-
- // get supported rates len
- p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
- if (p != NULL)
- {
- offset += tmp_len+2;
- }
-
- //DS Parameter Set IE, len=3
- offset += 3;
-
- premainder_ie = pie + offset;
-
- remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;
-
- //append TIM IE from offset
- dst_ie = pie + offset;
-
- }
-
-
- if(remainder_ielen>0)
- {
- pbackup_remainder_ie = rtw_malloc(remainder_ielen);
- if(pbackup_remainder_ie && premainder_ie)
- _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
- }
-
- *dst_ie++=_TIM_IE_;
-
- if((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fc))
- tim_ielen = 5;
- else
- tim_ielen = 4;
-
- *dst_ie++= tim_ielen;
-
- *dst_ie++=0;//DTIM count
- *dst_ie++=1;//DTIM peroid
-
- if(pstapriv->tim_bitmap&BIT(0))//for bc/mc frames
- *dst_ie++ = BIT(0);//bitmap ctrl
- else
- *dst_ie++ = 0;
-
- if(tim_ielen==4)
- {
- *dst_ie++ = *(u8*)&tim_bitmap_le;
- }
- else if(tim_ielen==5)
- {
- _rtw_memcpy(dst_ie, &tim_bitmap_le, 2);
- dst_ie+=2;
- }
-
- //copy remainder IE
- if(pbackup_remainder_ie)
- {
- _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
-
- rtw_mfree(pbackup_remainder_ie, remainder_ielen);
- }
-
- offset = (uint)(dst_ie - pie);
- pnetwork_mlmeext->IELength = offset + remainder_ielen;
-
- }
-
-#ifndef CONFIG_INTERRUPT_BASED_TXBCN
-#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
- set_tx_beacon_cmd(padapter);
-#endif
-#endif //!CONFIG_INTERRUPT_BASED_TXBCN
-
-
-}
-
-void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len)
-{
- PNDIS_802_11_VARIABLE_IEs pIE;
- u8 bmatch = _FALSE;
- u8 *pie = pnetwork->IEs;
- u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
- u32 i, offset, ielen, ie_offset, remainder_ielen = 0;
-
- for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;)
- {
- pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
-
- if (pIE->ElementID > index)
- {
- break;
- }
- else if(pIE->ElementID == index) // already exist the same IE
- {
- p = (u8 *)pIE;
- ielen = pIE->Length;
- bmatch = _TRUE;
- break;
- }
-
- p = (u8 *)pIE;
- ielen = pIE->Length;
- i += (pIE->Length + 2);
- }
-
- if (p != NULL && ielen>0)
- {
- ielen += 2;
-
- premainder_ie = p+ielen;
-
- ie_offset = (sint)(p -pie);
-
- remainder_ielen = pnetwork->IELength - ie_offset - ielen;
-
- if(bmatch)
- dst_ie = p;
- else
- dst_ie = (p+ielen);
- }
-
- if(remainder_ielen>0)
- {
- pbackup_remainder_ie = rtw_malloc(remainder_ielen);
- if(pbackup_remainder_ie && premainder_ie)
- _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
- }
-
- *dst_ie++=index;
- *dst_ie++=len;
-
- _rtw_memcpy(dst_ie, data, len);
- dst_ie+=len;
-
- //copy remainder IE
- if(pbackup_remainder_ie)
- {
- _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
-
- rtw_mfree(pbackup_remainder_ie, remainder_ielen);
- }
-
- offset = (uint)(dst_ie - pie);
- pnetwork->IELength = offset + remainder_ielen;
-}
-
-void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index)
-{
- u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
- uint offset, ielen, ie_offset, remainder_ielen = 0;
- u8 *pie = pnetwork->IEs;
-
- p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen, pnetwork->IELength - _FIXED_IE_LENGTH_);
- if (p != NULL && ielen>0)
- {
- ielen += 2;
-
- premainder_ie = p+ielen;
-
- ie_offset = (sint)(p -pie);
-
- remainder_ielen = pnetwork->IELength - ie_offset - ielen;
-
- dst_ie = p;
- }
-
- if(remainder_ielen>0)
- {
- pbackup_remainder_ie = rtw_malloc(remainder_ielen);
- if(pbackup_remainder_ie && premainder_ie)
- _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
- }
-
- //copy remainder IE
- if(pbackup_remainder_ie)
- {
- _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
-
- rtw_mfree(pbackup_remainder_ie, remainder_ielen);
- }
-
- offset = (uint)(dst_ie - pie);
- pnetwork->IELength = offset + remainder_ielen;
-}
-
-
-u8 chk_sta_is_alive(struct sta_info *psta);
-u8 chk_sta_is_alive(struct sta_info *psta)
-{
- u8 ret = _FALSE;
- #ifdef DBG_EXPIRATION_CHK
- DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", expire_to:%u, %s%ssq_len:%u\n"
- , MAC_ARG(psta->hwaddr)
- , psta->rssi_stat.UndecoratedSmoothedPWDB
- //, STA_RX_PKTS_ARG(psta)
- , STA_RX_PKTS_DIFF_ARG(psta)
- , psta->expire_to
- , psta->state&WIFI_SLEEP_STATE?"PS, ":""
- , psta->state&WIFI_STA_ALIVE_CHK_STATE?"SAC, ":""
- , psta->sleepq_len
- );
- #endif
-
- //if(sta_last_rx_pkts(psta) == sta_rx_pkts(psta))
- if((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) == (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts))
- {
- #if 0
- if(psta->state&WIFI_SLEEP_STATE)
- ret = _TRUE;
- #endif
- }
- else
- {
- ret = _TRUE;
- }
-
- sta_update_last_rx_pkts(psta);
-
- return ret;
-}
-
-void expire_timeout_chk(_adapter *padapter)
-{
- _irqL irqL;
- _list *phead, *plist;
- u8 updated;
- struct sta_info *psta=NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- u8 chk_alive_num = 0;
- char chk_alive_list[NUM_STA];
- int i;
-
- _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
-
- phead = &pstapriv->auth_list;
- plist = get_next(phead);
-
- //check auth_queue
- #ifdef DBG_EXPIRATION_CHK
- if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
- DBG_871X(FUNC_NDEV_FMT" auth_list, cnt:%u\n"
- , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->auth_list_cnt);
- }
- #endif
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
- {
- psta = LIST_CONTAINOR(plist, struct sta_info, auth_list);
- plist = get_next(plist);
-
- if(psta->expire_to>0)
- {
- psta->expire_to--;
- if (psta->expire_to == 0)
- {
- rtw_list_delete(&psta->auth_list);
- pstapriv->auth_list_cnt--;
-
- DBG_871X("auth expire %02X%02X%02X%02X%02X%02X\n",
- psta->hwaddr[0],psta->hwaddr[1],psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5]);
-
- _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
-
- _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
- rtw_free_stainfo(padapter, psta);
- _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
-
- _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
- }
- }
-
- }
-
- _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
-
- psta = NULL;
-
-
- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
-
- phead = &pstapriv->asoc_list;
- plist = get_next(phead);
-
- //check asoc_queue
- #ifdef DBG_EXPIRATION_CHK
- if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
- DBG_871X(FUNC_NDEV_FMT" asoc_list, cnt:%u\n"
- , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->asoc_list_cnt);
- }
- #endif
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
- {
- psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
- plist = get_next(plist);
-
- if (chk_sta_is_alive(psta) || !psta->expire_to) {
- psta->expire_to = pstapriv->expire_to;
- psta->keep_alive_trycnt = 0;
- #ifdef CONFIG_TX_MCAST2UNI
- psta->under_exist_checking = 0;
- #endif // CONFIG_TX_MCAST2UNI
- } else {
- psta->expire_to--;
- }
-
-#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
-#ifdef CONFIG_TX_MCAST2UNI
-#ifdef CONFIG_80211N_HT
- if ( (psta->flags & WLAN_STA_HT) && (psta->htpriv.agg_enable_bitmap || psta->under_exist_checking) ) {
- // check sta by delba(addba) for 11n STA
- // ToDo: use CCX report to check for all STAs
- //DBG_871X("asoc check by DELBA/ADDBA! (pstapriv->expire_to=%d s)(psta->expire_to=%d s), [%02x, %d]\n", pstapriv->expire_to*2, psta->expire_to*2, psta->htpriv.agg_enable_bitmap, psta->under_exist_checking);
-
- if ( psta->expire_to <= (pstapriv->expire_to - 50 ) ) {
- DBG_871X("asoc expire by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);
- psta->under_exist_checking = 0;
- psta->expire_to = 0;
- } else if ( psta->expire_to <= (pstapriv->expire_to - 3) && (psta->under_exist_checking==0)) {
- DBG_871X("asoc check by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);
- psta->under_exist_checking = 1;
- //tear down TX AMPDU
- send_delba(padapter, 1, psta->hwaddr);// // originator
- psta->htpriv.agg_enable_bitmap = 0x0;//reset
- psta->htpriv.candidate_tid_bitmap = 0x0;//reset
- }
- }
-#endif //CONFIG_80211N_HT
-#endif // CONFIG_TX_MCAST2UNI
-#endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK
-
- if (psta->expire_to <= 0)
- {
- #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
-
- if (padapter->registrypriv.wifi_spec == 1)
- {
- psta->expire_to = pstapriv->expire_to;
- continue;
- }
-
- if (psta->state & WIFI_SLEEP_STATE) {
- if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
- //to check if alive by another methods if staion is at ps mode.
- psta->expire_to = pstapriv->expire_to;
- psta->state |= WIFI_STA_ALIVE_CHK_STATE;
-
- //DBG_871X("alive chk, sta:" MAC_FMT " is at ps mode!\n", MAC_ARG(psta->hwaddr));
-
- //to update bcn with tim_bitmap for this station
- pstapriv->tim_bitmap |= BIT(psta->aid);
- update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
-
- if(!pmlmeext->active_keep_alive_check)
- continue;
- }
- }
-
- if (pmlmeext->active_keep_alive_check) {
- int stainfo_offset;
-
- stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
- if (stainfo_offset_valid(stainfo_offset)) {
- chk_alive_list[chk_alive_num++] = stainfo_offset;
- }
-
- continue;
- }
- #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
-
- rtw_list_delete(&psta->asoc_list);
- pstapriv->asoc_list_cnt--;
-
- DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
- updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);
- }
- else
- {
- /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
- if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt)
- && padapter->xmitpriv.free_xmitframe_cnt < ((NR_XMITFRAME/pstapriv->asoc_list_cnt)/2)
- ){
- DBG_871X("%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__
- , MAC_ARG(psta->hwaddr)
- , psta->sleepq_len, padapter->xmitpriv.free_xmitframe_cnt, pstapriv->asoc_list_cnt);
- wakeup_sta_to_xmit(padapter, psta);
- }
- }
- }
-
- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
-
-#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
-if (chk_alive_num) {
-
- u8 backup_oper_channel=0;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- /* switch to correct channel of current network before issue keep-alive frames */
- if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
- backup_oper_channel = rtw_get_oper_ch(padapter);
- SelectChannel(padapter, pmlmeext->cur_channel);
- }
-
- /* issue null data to check sta alive*/
- for (i = 0; i < chk_alive_num; i++) {
-
- int ret = _FAIL;
-
- psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
- if(!(psta->state &_FW_LINKED))
- continue;
-
- if (psta->state & WIFI_SLEEP_STATE)
- ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50);
- else
- ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50);
-
- psta->keep_alive_trycnt++;
- if (ret == _SUCCESS)
- {
- DBG_871X("asoc check, sta(" MAC_FMT ") is alive\n", MAC_ARG(psta->hwaddr));
- psta->expire_to = pstapriv->expire_to;
- psta->keep_alive_trycnt = 0;
- continue;
- }
- else if (psta->keep_alive_trycnt <= 3)
- {
- DBG_871X("ack check for asoc expire, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt);
- psta->expire_to = 1;
- continue;
- }
-
- psta->keep_alive_trycnt = 0;
-
- DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
- if (rtw_is_list_empty(&psta->asoc_list)==_FALSE) {
- rtw_list_delete(&psta->asoc_list);
- pstapriv->asoc_list_cnt--;
- updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);
- }
- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
-
- }
-
- if (backup_oper_channel>0) /* back to the original operation channel */
- SelectChannel(padapter, backup_oper_channel);
-}
-#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
-
- associated_clients_update(padapter, updated);
-}
-
-void add_RATid(_adapter *padapter, struct sta_info *psta, u8 rssi_level)
-{
- int i;
- u8 rf_type;
- u32 init_rate=0;
- unsigned char sta_band = 0, raid, shortGIrate = _FALSE;
- unsigned char limit;
- unsigned int tx_ra_bitmap=0;
- struct ht_priv *psta_ht = NULL;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
-
-#ifdef CONFIG_80211N_HT
- if(psta)
- psta_ht = &psta->htpriv;
- else
- return;
-#endif //CONFIG_80211N_HT
-
- if(!(psta->state & _FW_LINKED))
- return;
-
- //b/g mode ra_bitmap
- for (i=0; i<sizeof(psta->bssrateset); i++)
- {
- if (psta->bssrateset[i])
- tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
- }
-#ifdef CONFIG_80211N_HT
- //n mode ra_bitmap
- if(psta_ht->ht_option)
- {
- rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
- if(rf_type == RF_2T2R)
- limit=16;// 2R
- else
- limit=8;// 1R
-
- for (i=0; i<limit; i++) {
- if (psta_ht->ht_cap.supp_mcs_set[i/8] & BIT(i%8))
- tx_ra_bitmap |= BIT(i+12);
- }
-
- //max short GI rate
- shortGIrate = psta_ht->sgi;
- }
-#endif //CONFIG_80211N_HT
-
-#if 0//gtest
- if(get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)
- {
- //is this a 2r STA?
- if((pstat->tx_ra_bitmap & 0x0ff00000) != 0 && !(priv->pshare->has_2r_sta & BIT(pstat->aid)))
- {
- priv->pshare->has_2r_sta |= BIT(pstat->aid);
- if(rtw_read16(padapter, 0x102501f6) != 0xffff)
- {
- rtw_write16(padapter, 0x102501f6, 0xffff);
- reset_1r_sta_RA(priv, 0xffff);
- Switch_1SS_Antenna(priv, 3);
- }
- }
- else// bg or 1R STA?
- {
- if((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len && priv->pshare->has_2r_sta == 0)
- {
- if(rtw_read16(padapter, 0x102501f6) != 0x7777)
- { // MCS7 SGI
- rtw_write16(padapter, 0x102501f6,0x7777);
- reset_1r_sta_RA(priv, 0x7777);
- Switch_1SS_Antenna(priv, 2);
- }
- }
- }
-
- }
-
- if ((pstat->rssi_level < 1) || (pstat->rssi_level > 3))
- {
- if (pstat->rssi >= priv->pshare->rf_ft_var.raGoDownUpper)
- pstat->rssi_level = 1;
- else if ((pstat->rssi >= priv->pshare->rf_ft_var.raGoDown20MLower) ||
- ((priv->pshare->is_40m_bw) && (pstat->ht_cap_len) &&
- (pstat->rssi >= priv->pshare->rf_ft_var.raGoDown40MLower) &&
- (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SUPPORT_CH_WDTH_))))
- pstat->rssi_level = 2;
- else
- pstat->rssi_level = 3;
- }
-
- // rate adaptive by rssi
- if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len)
- {
- if ((get_rf_mimo_mode(priv) == MIMO_1T2R) || (get_rf_mimo_mode(priv) == MIMO_1T1R))
- {
- switch (pstat->rssi_level) {
- case 1:
- pstat->tx_ra_bitmap &= 0x100f0000;
- break;
- case 2:
- pstat->tx_ra_bitmap &= 0x100ff000;
- break;
- case 3:
- if (priv->pshare->is_40m_bw)
- pstat->tx_ra_bitmap &= 0x100ff005;
- else
- pstat->tx_ra_bitmap &= 0x100ff001;
-
- break;
- }
- }
- else
- {
- switch (pstat->rssi_level) {
- case 1:
- pstat->tx_ra_bitmap &= 0x1f0f0000;
- break;
- case 2:
- pstat->tx_ra_bitmap &= 0x1f0ff000;
- break;
- case 3:
- if (priv->pshare->is_40m_bw)
- pstat->tx_ra_bitmap &= 0x000ff005;
- else
- pstat->tx_ra_bitmap &= 0x000ff001;
-
- break;
- }
-
- // Don't need to mask high rates due to new rate adaptive parameters
- //if (pstat->is_broadcom_sta) // use MCS12 as the highest rate vs. Broadcom sta
- // pstat->tx_ra_bitmap &= 0x81ffffff;
-
- // NIC driver will report not supporting MCS15 and MCS14 in asoc req
- //if (pstat->is_rtl8190_sta && !pstat->is_2t_mimo_sta)
- // pstat->tx_ra_bitmap &= 0x83ffffff; // if Realtek 1x2 sta, don't use MCS15 and MCS14
- }
- }
- else if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) && isErpSta(pstat))
- {
- switch (pstat->rssi_level) {
- case 1:
- pstat->tx_ra_bitmap &= 0x00000f00;
- break;
- case 2:
- pstat->tx_ra_bitmap &= 0x00000ff0;
- break;
- case 3:
- pstat->tx_ra_bitmap &= 0x00000ff5;
- break;
- }
- }
- else
- {
- pstat->tx_ra_bitmap &= 0x0000000d;
- }
-
- // disable tx short GI when station cannot rx MCS15(AP is 2T2R)
- // disable tx short GI when station cannot rx MCS7 (AP is 1T2R or 1T1R)
- // if there is only 1r STA and we are 2T2R, DO NOT mask SGI rate
- if ((!(pstat->tx_ra_bitmap & 0x8000000) && (priv->pshare->has_2r_sta > 0) && (get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)) ||
- (!(pstat->tx_ra_bitmap & 0x80000) && (get_rf_mimo_mode(padapter) != RTL8712_RF_2T2R)))
- {
- pstat->tx_ra_bitmap &= ~BIT(28);
- }
-#endif
-
- if ( pcur_network->Configuration.DSConfig > 14 ) {
- // 5G band
- if (tx_ra_bitmap & 0xffff000)
- sta_band |= WIRELESS_11_5N | WIRELESS_11A;
- else
- sta_band |= WIRELESS_11A;
- } else {
- if (tx_ra_bitmap & 0xffff000)
- sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
- else if (tx_ra_bitmap & 0xff0)
- sta_band |= WIRELESS_11G |WIRELESS_11B;
- else
- sta_band |= WIRELESS_11B;
- }
-
- psta->wireless_mode = sta_band;
-
- raid = networktype_to_raid(sta_band);
- init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
-
- if (psta->aid < NUM_STA)
- {
- u8 arg = 0;
-
- arg = psta->mac_id&0x1f;
-
- arg |= BIT(7);//support entry 2~31
-
- if (shortGIrate==_TRUE)
- arg |= BIT(5);
-
- tx_ra_bitmap |= ((raid<<28)&0xf0000000);
-
- DBG_871X("%s=> mac_id:%d , raid:%d , bitmap=0x%x, arg=0x%x\n",
- __FUNCTION__ , psta->mac_id, raid ,tx_ra_bitmap, arg);
-
- //bitmap[0:27] = tx_rate_bitmap
- //bitmap[28:31]= Rate Adaptive id
- //arg[0:4] = macid
- //arg[5] = Short GI
- rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level);
-
-
- if (shortGIrate==_TRUE)
- init_rate |= BIT(6);
-
- //set ra_id, init_rate
- psta->raid = raid;
- psta->init_rate = init_rate;
-
- }
- else
- {
- DBG_871X("station aid %d exceed the max number\n", psta->aid);
- }
-
-}
-
-static void update_bmc_sta(_adapter *padapter)
-{
- _irqL irqL;
- u32 init_rate=0;
- unsigned char network_type, raid;
- int i, supportRateNum = 0;
- unsigned int tx_ra_bitmap=0;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
- struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
-
- if(psta)
- {
- psta->aid = 0;//default set to 0
- //psta->mac_id = psta->aid+4;
- psta->mac_id = psta->aid + 1;
-
- psta->qos_option = 0;
-#ifdef CONFIG_80211N_HT
- psta->htpriv.ht_option = _FALSE;
-#endif //CONFIG_80211N_HT
-
- psta->ieee8021x_blocked = 0;
-
- _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
-
- //psta->dot118021XPrivacy = _NO_PRIVACY_;//!!! remove it, because it has been set before this.
-
-
-
- //prepare for add_RATid
- supportRateNum = rtw_get_rateset_len((u8*)&pcur_network->SupportedRates);
- network_type = rtw_check_network_type((u8*)&pcur_network->SupportedRates, supportRateNum, 1);
-
- _rtw_memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
- psta->bssratelen = supportRateNum;
-
- //b/g mode ra_bitmap
- for (i=0; i<supportRateNum; i++)
- {
- if (psta->bssrateset[i])
- tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
- }
-
- if ( pcur_network->Configuration.DSConfig > 14 ) {
- //force to A mode. 5G doesn't support CCK rates
- network_type = WIRELESS_11A;
- tx_ra_bitmap = 0x150; // 6, 12, 24 Mbps
- } else {
- //force to b mode
- network_type = WIRELESS_11B;
- tx_ra_bitmap = 0xf;
- }
-
- //tx_ra_bitmap = update_basic_rate(pcur_network->SupportedRates, supportRateNum);
-
- raid = networktype_to_raid(network_type);
- init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
-
- //DBG_871X("Add id %d val %08x to ratr for bmc sta\n", psta->aid, tx_ra_bitmap);
- //ap mode
- rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
-
- //if(pHalData->fw_ractrl == _TRUE)
- {
- u8 arg = 0;
-
- arg = psta->mac_id&0x1f;
-
- arg |= BIT(7);
-
- //if (shortGIrate==_TRUE)
- // arg |= BIT(5);
-
- tx_ra_bitmap |= ((raid<<28)&0xf0000000);
-
- DBG_871X("update_bmc_sta, mask=0x%x, arg=0x%x\n", tx_ra_bitmap, arg);
-
- //bitmap[0:27] = tx_rate_bitmap
- //bitmap[28:31]= Rate Adaptive id
- //arg[0:4] = macid
- //arg[5] = Short GI
- rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0);
-
- }
-
- //set ra_id, init_rate
- psta->raid = raid;
- psta->init_rate = init_rate;
-
- rtw_stassoc_hw_rpt(padapter, psta);
-
- _enter_critical_bh(&psta->lock, &irqL);
- psta->state = _FW_LINKED;
- _exit_critical_bh(&psta->lock, &irqL);
-
- }
- else
- {
- DBG_871X("add_RATid_bmc_sta error!\n");
- }
-
-}
-
-//notes:
-//AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode
-//MAC_ID = AID+1 for sta in ap/adhoc mode
-//MAC_ID = 1 for bc/mc for sta/ap/adhoc
-//MAC_ID = 0 for bssid for sta/ap/adhoc
-//CAM_ID = //0~3 for default key, cmd_id=macid + 3, macid=aid+1;
-
-void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta)
-{
- _irqL irqL;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
-#ifdef CONFIG_80211N_HT
- struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
- struct ht_priv *phtpriv_sta = &psta->htpriv;
-#endif //CONFIG_80211N_HT
- //set intf_tag to if1
- //psta->intf_tag = 0;
-
- //psta->mac_id = psta->aid+4;
- psta->mac_id = psta->aid+1;
- DBG_871X("%s\n",__FUNCTION__);
-
- //ap mode
- rtw_hal_set_odm_var(padapter,HAL_ODM_STA_INFO,psta,_TRUE);
-
- if(psecuritypriv->dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)
- psta->ieee8021x_blocked = _TRUE;
- else
- psta->ieee8021x_blocked = _FALSE;
-
-
- //update sta's cap
-
- //ERP
- VCS_update(padapter, psta);
-#ifdef CONFIG_80211N_HT
- //HT related cap
- if(phtpriv_sta->ht_option)
- {
- //check if sta supports rx ampdu
- phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
-
- //check if sta support s Short GI
- if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40))
- {
- phtpriv_sta->sgi = _TRUE;
- }
-
- // bwmode
- if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
- {
- //phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_40;
- phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
- phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
-
- }
-
- psta->qos_option = _TRUE;
-
- }
- else
- {
- phtpriv_sta->ampdu_enable = _FALSE;
-
- phtpriv_sta->sgi = _FALSE;
- phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
- phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- }
-
- //Rx AMPDU
- send_delba(padapter, 0, psta->hwaddr);// recipient
-
- //TX AMPDU
- send_delba(padapter, 1, psta->hwaddr);// // originator
- phtpriv_sta->agg_enable_bitmap = 0x0;//reset
- phtpriv_sta->candidate_tid_bitmap = 0x0;//reset
-#endif //CONFIG_80211N_HT
-
- //todo: init other variables
-
- _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
-
-
- //add ratid
- //add_RATid(padapter, psta);//move to ap_sta_info_defer_update()
-
-
- _enter_critical_bh(&psta->lock, &irqL);
- psta->state |= _FW_LINKED;
- _exit_critical_bh(&psta->lock, &irqL);
-
-
-}
-
-static void update_hw_ht_param(_adapter *padapter)
-{
- unsigned char max_AMPDU_len;
- unsigned char min_MPDU_spacing;
- struct registry_priv *pregpriv = &padapter->registrypriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
-
- DBG_871X("%s\n", __FUNCTION__);
-
-
- //handle A-MPDU parameter field
- /*
- AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
- AMPDU_para [4:2]:Min MPDU Start Spacing
- */
- max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
-
- min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
-
- rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
-
- rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
-
- //
- // Config SM Power Save setting
- //
- pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
- if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
- {
- /*u8 i;
- //update the MCS rates
- for (i = 0; i < 16; i++)
- {
- pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
- }*/
- DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__);
- }
-
- //
- // Config current HT Protection mode.
- //
- //pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
-
-}
-
-static void start_bss_network(_adapter *padapter, u8 *pbuf)
-{
- u8 *p;
- u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
- u16 bcn_interval;
- u32 acparm;
- int ie_len;
- struct registry_priv *pregpriv = &padapter->registrypriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct security_priv* psecuritypriv=&(padapter->securitypriv);
- WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
- struct HT_info_element *pht_info=NULL;
-#ifdef CONFIG_P2P
- struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
-#endif //CONFIG_P2P
-
- //DBG_871X("%s\n", __FUNCTION__);
-
- bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
- cur_channel = pnetwork->Configuration.DSConfig;
- cur_bwmode = HT_CHANNEL_WIDTH_20;;
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
-
- //check if there is wps ie,
- //if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd,
- //and at first time the security ie ( RSN/WPA IE) will not include in beacon.
- if(NULL == rtw_get_wps_ie(pnetwork->IEs+_FIXED_IE_LENGTH_, pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL))
- {
- pmlmeext->bstart_bss = _TRUE;
- }
-
- //todo: update wmm, ht cap
- //pmlmeinfo->WMM_enable;
- //pmlmeinfo->HT_enable;
- if(pmlmepriv->qospriv.qos_option)
- pmlmeinfo->WMM_enable = _TRUE;
-#ifdef CONFIG_80211N_HT
- if(pmlmepriv->htpriv.ht_option)
- {
- pmlmeinfo->WMM_enable = _TRUE;
- pmlmeinfo->HT_enable = _TRUE;
- //pmlmeinfo->HT_info_enable = _TRUE;
- //pmlmeinfo->HT_caps_enable = _TRUE;
-
- update_hw_ht_param(padapter);
- }
-#endif //#CONFIG_80211N_HT
-
-
- if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at first time
- {
- //WEP Key will be set before this function, do not clear CAM.
- if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_))
- flush_all_cam_entry(padapter); //clear CAM
- }
-
- //set MSR to AP_Mode
- Set_MSR(padapter, _HW_STATE_AP_);
-
- //Set BSSID REG
- rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress);
-
- //Set EDCA param reg
-#ifdef CONFIG_CONCURRENT_MODE
- acparm = 0x005ea42b;
-#else
- acparm = 0x002F3217; // VO
-#endif
- rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
- acparm = 0x005E4317; // VI
- rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
- //acparm = 0x00105320; // BE
- acparm = 0x005ea42b;
- rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
- acparm = 0x0000A444; // BK
- rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
-
- //Set Security
- val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
- rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
-
- //Beacon Control related register
- rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));
-
-
- UpdateBrateTbl(padapter, pnetwork->SupportedRates);
- rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
-
- if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at first time
- {
- //u32 initialgain;
-
- //initialgain = 0x1e;
-
-
- //disable dynamic functions, such as high power, DIG
- //Save_DM_Func_Flag(padapter);
- //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
-
-#ifdef CONFIG_CONCURRENT_MODE
- if(padapter->adapter_type > PRIMARY_ADAPTER)
- {
- if(rtw_buddy_adapter_up(padapter))
- {
- _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
-
- //turn on all dynamic functions on PRIMARY_ADAPTER, dynamic functions only runs at PRIMARY_ADAPTER
- Switch_DM_Func(pbuddy_adapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
-
- //rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
- }
- }
- else
-#endif
- {
- //turn on all dynamic functions
- Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
-
- //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
- }
-
- }
-#ifdef CONFIG_80211N_HT
- //set channel, bwmode
- p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
- if( p && ie_len)
- {
- pht_info = (struct HT_info_element *)(p+2);
-
- if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2)))
- {
- //switch to the 40M Hz mode
- //pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
- cur_bwmode = HT_CHANNEL_WIDTH_40;
- switch (pht_info->infos[0] & 0x3)
- {
- case 1:
- //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
- break;
-
- case 3:
- //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
- break;
-
- default:
- //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
- break;
- }
-
- }
-
- }
-#endif //CONFIG_80211N_HT
-#ifdef CONFIG_DUALMAC_CONCURRENT
- dc_set_ap_channel_bandwidth(padapter, cur_channel, cur_ch_offset, cur_bwmode);
-#else
- //TODO: need to judge the phy parameters on concurrent mode for single phy
- //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-#ifdef CONFIG_CONCURRENT_MODE
- if(!check_buddy_fwstate(padapter, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY))
- {
- set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
- }
- else if(check_buddy_fwstate(padapter, _FW_LINKED)==_TRUE)//only second adapter can enter AP Mode
- {
- _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
- struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
-
- //To sync cur_channel/cur_bwmode/cur_ch_offset with primary adapter
- DBG_871X("primary iface is at linked state, sync cur_channel/cur_bwmode/cur_ch_offset\n");
- DBG_871X("primary adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
- DBG_871X("second adapter, CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
-
- cur_channel = pbuddy_mlmeext->cur_channel;
- if(cur_bwmode == HT_CHANNEL_WIDTH_40)
- {
- if(pht_info)
- pht_info->infos[0] &= ~(BIT(0)|BIT(1));
-
- if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
- {
- cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
-
- //to update cur_ch_offset value in beacon
- if(pht_info)
- {
- switch(cur_ch_offset)
- {
- case HAL_PRIME_CHNL_OFFSET_LOWER:
- pht_info->infos[0] |= 0x1;
- break;
- case HAL_PRIME_CHNL_OFFSET_UPPER:
- pht_info->infos[0] |= 0x3;
- break;
- case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
- default:
- break;
- }
- }
-
- }
- else if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20)
- {
- cur_bwmode = HT_CHANNEL_WIDTH_20;
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
-
- if(cur_channel>0 && cur_channel<5)
- {
- if(pht_info)
- pht_info->infos[0] |= 0x1;
-
- cur_bwmode = HT_CHANNEL_WIDTH_40;
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
- }
-
- if(cur_channel>7 && cur_channel<(14+1))
- {
- if(pht_info)
- pht_info->infos[0] |= 0x3;
-
- cur_bwmode = HT_CHANNEL_WIDTH_40;
- cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
- }
-
- set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
- }
-
- }
-
- // to update channel value in beacon
- pnetwork->Configuration.DSConfig = cur_channel;
- p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
- if(p && ie_len>0)
- *(p + 2) = cur_channel;
-
- if(pht_info)
- pht_info->primary_channel = cur_channel;
- }
-#else
- set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
-#endif //CONFIG_CONCURRENT_MODE
-
- DBG_871X("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
-
- //
- pmlmeext->cur_channel = cur_channel;
- pmlmeext->cur_bwmode = cur_bwmode;
- pmlmeext->cur_ch_offset = cur_ch_offset;
-#endif //CONFIG_DUALMAC_CONCURRENT
- pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;
-
- //update cur_wireless_mode
- update_wireless_mode(padapter);
-
- //udpate capability after cur_wireless_mode updated
- update_capinfo(padapter, rtw_get_capability((WLAN_BSSID_EX *)pnetwork));
-
- //let pnetwork_mlmeext == pnetwork_mlme.
- _rtw_memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
-
-#ifdef CONFIG_P2P
- _rtw_memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.Ssid, pnetwork->Ssid.SsidLength);
- pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.SsidLength;
-#endif //CONFIG_P2P
-
- if(_TRUE == pmlmeext->bstart_bss)
- {
- update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
-
-#ifndef CONFIG_INTERRUPT_BASED_TXBCN //other case will tx beacon when bcn interrupt coming in.
-#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
- //issue beacon frame
- if(send_beacon(padapter)==_FAIL)
- {
- DBG_871X("issue_beacon, fail!\n");
- }
-#endif
-#endif //!CONFIG_INTERRUPT_BASED_TXBCN
-
- }
-
-
- //update bc/mc sta_info
- update_bmc_sta(padapter);
-
- //pmlmeext->bstart_bss = _TRUE;
-
-}
-
-int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len)
-{
- int ret=_SUCCESS;
- u8 *p;
- u8 *pHT_caps_ie=NULL;
- u8 *pHT_info_ie=NULL;
- struct sta_info *psta = NULL;
- u16 cap, ht_cap=_FALSE;
- uint ie_len = 0;
- int group_cipher, pairwise_cipher;
- u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
- int supportRateNum = 0;
- u8 OUI1[] = {0x00, 0x50, 0xf2,0x01};
- u8 wps_oui[4]={0x0,0x50,0xf2,0x04};
- u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- WLAN_BSSID_EX *pbss_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
- struct sta_priv *pstapriv = &padapter->stapriv;
- u8 *ie = pbss_network->IEs;
-
-
- /* SSID */
- /* Supported rates */
- /* DS Params */
- /* WLAN_EID_COUNTRY */
- /* ERP Information element */
- /* Extended supported rates */
- /* WPA/WPA2 */
- /* Wi-Fi Wireless Multimedia Extensions */
- /* ht_capab, ht_oper */
- /* WPS IE */
-
- DBG_871X("%s, len=%d\n", __FUNCTION__, len);
-
- if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
- return _FAIL;
-
-
- if(len>MAX_IE_SZ)
- return _FAIL;
-
- pbss_network->IELength = len;
-
- _rtw_memset(ie, 0, MAX_IE_SZ);
-
- _rtw_memcpy(ie, pbuf, pbss_network->IELength);
-
-
- if(pbss_network->InfrastructureMode!=Ndis802_11APMode)
- return _FAIL;
-
- pbss_network->Rssi = 0;
-
- _rtw_memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- //beacon interval
- p = rtw_get_beacon_interval_from_ie(ie);//ie + 8; // 8: TimeStamp, 2: Beacon Interval 2:Capability
- //pbss_network->Configuration.BeaconPeriod = le16_to_cpu(*(unsigned short*)p);
- pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p);
-
- //capability
- //cap = *(unsigned short *)rtw_get_capability_from_ie(ie);
- //cap = le16_to_cpu(cap);
- cap = RTW_GET_LE16(ie);
-
- //SSID
- p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength -_BEACON_IE_OFFSET_));
- if(p && ie_len>0)
- {
- _rtw_memset(&pbss_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
- _rtw_memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);
- pbss_network->Ssid.SsidLength = ie_len;
- }
-
- //chnnel
- channel = 0;
- pbss_network->Configuration.Length = 0;
- p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
- if(p && ie_len>0)
- channel = *(p + 2);
-
- pbss_network->Configuration.DSConfig = channel;
-
-
- _rtw_memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
- // get supported rates
- p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
- if (p != NULL)
- {
- _rtw_memcpy(supportRate, p+2, ie_len);
- supportRateNum = ie_len;
- }
-
- //get ext_supported rates
- p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_);
- if (p != NULL)
- {
- _rtw_memcpy(supportRate+supportRateNum, p+2, ie_len);
- supportRateNum += ie_len;
-
- }
-
- network_type = rtw_check_network_type(supportRate, supportRateNum, channel);
-
- rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
-
-
- //parsing ERP_IE
- p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
- if(p && ie_len>0)
- {
- ERP_IE_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)p);
- }
-
- //update privacy/security
- if (cap & BIT(4))
- pbss_network->Privacy = 1;
- else
- pbss_network->Privacy = 0;
-
- psecuritypriv->wpa_psk = 0;
-
- //wpa2
- group_cipher = 0; pairwise_cipher = 0;
- psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
- psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
- p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
- if(p && ie_len>0)
- {
- if(rtw_parse_wpa2_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
- {
- psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
-
- psecuritypriv->dot8021xalg = 1;//psk, todo:802.1x
- psecuritypriv->wpa_psk |= BIT(1);
-
- psecuritypriv->wpa2_group_cipher = group_cipher;
- psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
-#if 0
- switch(group_cipher)
- {
- case WPA_CIPHER_NONE:
- psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
- break;
- case WPA_CIPHER_WEP40:
- psecuritypriv->wpa2_group_cipher = _WEP40_;
- break;
- case WPA_CIPHER_TKIP:
- psecuritypriv->wpa2_group_cipher = _TKIP_;
- break;
- case WPA_CIPHER_CCMP:
- psecuritypriv->wpa2_group_cipher = _AES_;
- break;
- case WPA_CIPHER_WEP104:
- psecuritypriv->wpa2_group_cipher = _WEP104_;
- break;
- }
-
- switch(pairwise_cipher)
- {
- case WPA_CIPHER_NONE:
- psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
- break;
- case WPA_CIPHER_WEP40:
- psecuritypriv->wpa2_pairwise_cipher = _WEP40_;
- break;
- case WPA_CIPHER_TKIP:
- psecuritypriv->wpa2_pairwise_cipher = _TKIP_;
- break;
- case WPA_CIPHER_CCMP:
- psecuritypriv->wpa2_pairwise_cipher = _AES_;
- break;
- case WPA_CIPHER_WEP104:
- psecuritypriv->wpa2_pairwise_cipher = _WEP104_;
- break;
- }
-#endif
- }
-
- }
-
- //wpa
- ie_len = 0;
- group_cipher = 0; pairwise_cipher = 0;
- psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
- psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
- for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))
- {
- p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
- if ((p) && (_rtw_memcmp(p+2, OUI1, 4)))
- {
- if(rtw_parse_wpa_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
- {
- psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
-
- psecuritypriv->dot8021xalg = 1;//psk, todo:802.1x
-
- psecuritypriv->wpa_psk |= BIT(0);
-
- psecuritypriv->wpa_group_cipher = group_cipher;
- psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
-
-#if 0
- switch(group_cipher)
- {
- case WPA_CIPHER_NONE:
- psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
- break;
- case WPA_CIPHER_WEP40:
- psecuritypriv->wpa_group_cipher = _WEP40_;
- break;
- case WPA_CIPHER_TKIP:
- psecuritypriv->wpa_group_cipher = _TKIP_;
- break;
- case WPA_CIPHER_CCMP:
- psecuritypriv->wpa_group_cipher = _AES_;
- break;
- case WPA_CIPHER_WEP104:
- psecuritypriv->wpa_group_cipher = _WEP104_;
- break;
- }
-
- switch(pairwise_cipher)
- {
- case WPA_CIPHER_NONE:
- psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
- break;
- case WPA_CIPHER_WEP40:
- psecuritypriv->wpa_pairwise_cipher = _WEP40_;
- break;
- case WPA_CIPHER_TKIP:
- psecuritypriv->wpa_pairwise_cipher = _TKIP_;
- break;
- case WPA_CIPHER_CCMP:
- psecuritypriv->wpa_pairwise_cipher = _AES_;
- break;
- case WPA_CIPHER_WEP104:
- psecuritypriv->wpa_pairwise_cipher = _WEP104_;
- break;
- }
-#endif
- }
-
- break;
-
- }
-
- if ((p == NULL) || (ie_len == 0))
- {
- break;
- }
-
- }
-
- //wmm
- ie_len = 0;
- pmlmepriv->qospriv.qos_option = 0;
- if(pregistrypriv->wmm_enable)
- {
- for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))
- {
- p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
- if((p) && _rtw_memcmp(p+2, WMM_PARA_IE, 6))
- {
- pmlmepriv->qospriv.qos_option = 1;
-
- *(p+8) |= BIT(7);//QoS Info, support U-APSD
-
- /* disable all ACM bits since the WMM admission control is not supported */
- *(p + 10) &= ~BIT(4); /* BE */
- *(p + 14) &= ~BIT(4); /* BK */
- *(p + 18) &= ~BIT(4); /* VI */
- *(p + 22) &= ~BIT(4); /* VO */
-
- break;
- }
-
- if ((p == NULL) || (ie_len == 0))
- {
- break;
- }
- }
- }
-#ifdef CONFIG_80211N_HT
- //parsing HT_CAP_IE
- p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
- if(p && ie_len>0)
- {
- u8 rf_type;
-
- struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2);
-
- pHT_caps_ie=p;
-
-
- ht_cap = _TRUE;
- network_type |= WIRELESS_11_24N;
-
-
- rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
-
- if((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
- (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
- {
- pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
- }
- else
- {
- pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
- }
-
- pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03); //set Max Rx AMPDU size to 64K
-
- if(rf_type == RF_1T1R)
- {
- pht_cap->supp_mcs_set[0] = 0xff;
- pht_cap->supp_mcs_set[1] = 0x0;
- }
-
- _rtw_memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);
-
- }
-
- //parsing HT_INFO_IE
- p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
- if(p && ie_len>0)
- {
- pHT_info_ie=p;
- }
-#endif //CONFIG_80211N_HT
- switch(network_type)
- {
- case WIRELESS_11B:
- pbss_network->NetworkTypeInUse = Ndis802_11DS;
- break;
- case WIRELESS_11G:
- case WIRELESS_11BG:
- case WIRELESS_11G_24N:
- case WIRELESS_11BG_24N:
- pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
- break;
- case WIRELESS_11A:
- pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
- break;
- default :
- pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
- break;
- }
-
- pmlmepriv->cur_network.network_type = network_type;
-
-#ifdef CONFIG_80211N_HT
- pmlmepriv->htpriv.ht_option = _FALSE;
-
- if( (psecuritypriv->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
- (psecuritypriv->wpa_pairwise_cipher&WPA_CIPHER_TKIP))
- {
- //todo:
- //ht_cap = _FALSE;
- }
-
- //ht_cap
- if(pregistrypriv->ht_enable && ht_cap==_TRUE)
- {
- pmlmepriv->htpriv.ht_option = _TRUE;
- pmlmepriv->qospriv.qos_option = 1;
-
- if(pregistrypriv->ampdu_enable==1)
- {
- pmlmepriv->htpriv.ampdu_enable = _TRUE;
- }
-
- HT_caps_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_caps_ie);
-
- HT_info_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_info_ie);
- }
-#endif
-
-
- pbss_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pbss_network);
-
- //issue beacon to start bss network
- start_bss_network(padapter, (u8*)pbss_network);
-
-
- //alloc sta_info for ap itself
- psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
- if(!psta)
- {
- psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
- if (psta == NULL)
- {
- return _FAIL;
- }
- }
- psta->state |= WIFI_AP_STATE; //Aries, add,fix bug of flush_cam_entry at STOP AP mode , 0724
- rtw_indicate_connect( padapter);
-
- pmlmepriv->cur_network.join_res = _TRUE;//for check if already set beacon
-
- //update bc/mc sta_info
- //update_bmc_sta(padapter);
-
- return ret;
-
-}
-
-void rtw_set_macaddr_acl(_adapter *padapter, int mode)
-{
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
-
- DBG_871X("%s, mode=%d\n", __func__, mode);
-
- pacl_list->mode = mode;
-}
-
-int rtw_acl_add_sta(_adapter *padapter, u8 *addr)
-{
- _irqL irqL;
- _list *plist, *phead;
- u8 added = _FALSE;
- int i, ret=0;
- struct rtw_wlan_acl_node *paclnode;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
- _queue *pacl_node_q =&pacl_list->acl_node_q;
-
- DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));
-
- if((NUM_ACL-1) < pacl_list->num)
- return (-1);
-
-
- _enter_critical_bh(&(pacl_node_q->lock), &irqL);
-
- phead = get_list_head(pacl_node_q);
- plist = get_next(phead);
-
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
- {
- paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
- plist = get_next(plist);
-
- if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN))
- {
- if(paclnode->valid == _TRUE)
- {
- added = _TRUE;
- DBG_871X("%s, sta has been added\n", __func__);
- break;
- }
- }
- }
-
- _exit_critical_bh(&(pacl_node_q->lock), &irqL);
-
-
- if(added == _TRUE)
- return ret;
-
-
- _enter_critical_bh(&(pacl_node_q->lock), &irqL);
-
- for(i=0; i< NUM_ACL; i++)
- {
- paclnode = &pacl_list->aclnode[i];
-
- if(paclnode->valid == _FALSE)
- {
- _rtw_init_listhead(&paclnode->list);
-
- _rtw_memcpy(paclnode->addr, addr, ETH_ALEN);
-
- paclnode->valid = _TRUE;
-
- rtw_list_insert_tail(&paclnode->list, get_list_head(pacl_node_q));
-
- pacl_list->num++;
-
- break;
- }
- }
-
- DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num);
-
- _exit_critical_bh(&(pacl_node_q->lock), &irqL);
-
- return ret;
-}
-
-int rtw_acl_remove_sta(_adapter *padapter, u8 *addr)
-{
- _irqL irqL;
- _list *plist, *phead;
- int i, ret=0;
- struct rtw_wlan_acl_node *paclnode;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
- _queue *pacl_node_q =&pacl_list->acl_node_q;
-
- DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));
-
- _enter_critical_bh(&(pacl_node_q->lock), &irqL);
-
- phead = get_list_head(pacl_node_q);
- plist = get_next(phead);
-
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
- {
- paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
- plist = get_next(plist);
-
- if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN))
- {
- if(paclnode->valid == _TRUE)
- {
- paclnode->valid = _FALSE;
-
- rtw_list_delete(&paclnode->list);
-
- pacl_list->num--;
- }
- }
- }
-
- _exit_critical_bh(&(pacl_node_q->lock), &irqL);
-
- DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num);
-
- return ret;
-
-}
-
-#ifdef CONFIG_NATIVEAP_MLME
-
-static void update_bcn_fixed_ie(_adapter *padapter)
-{
- DBG_871X("%s\n", __FUNCTION__);
-
-}
-
-static void update_bcn_erpinfo_ie(_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
- unsigned char *p, *ie = pnetwork->IEs;
- u32 len = 0;
-
- DBG_871X("%s, ERP_enable=%d\n", __FUNCTION__, pmlmeinfo->ERP_enable);
-
- if(!pmlmeinfo->ERP_enable)
- return;
-
- //parsing ERP_IE
- p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
- if(p && len>0)
- {
- PNDIS_802_11_VARIABLE_IEs pIE = (PNDIS_802_11_VARIABLE_IEs)p;
-
- if (pmlmepriv->num_sta_non_erp == 1)
- pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION;
- else
- pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION);
-
- if(pmlmepriv->num_sta_no_short_preamble > 0)
- pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
- else
- pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
-
- ERP_IE_handler(padapter, pIE);
- }
-
-}
-
-static void update_bcn_htcap_ie(_adapter *padapter)
-{
- DBG_871X("%s\n", __FUNCTION__);
-
-}
-
-static void update_bcn_htinfo_ie(_adapter *padapter)
-{
- DBG_871X("%s\n", __FUNCTION__);
-
-}
-
-static void update_bcn_rsn_ie(_adapter *padapter)
-{
- DBG_871X("%s\n", __FUNCTION__);
-
-}
-
-static void update_bcn_wpa_ie(_adapter *padapter)
-{
- DBG_871X("%s\n", __FUNCTION__);
-
-}
-
-static void update_bcn_wmm_ie(_adapter *padapter)
-{
- DBG_871X("%s\n", __FUNCTION__);
-
-}
-
-static void update_bcn_wps_ie(_adapter *padapter)
-{
- u8 *pwps_ie=NULL, *pwps_ie_src, *premainder_ie, *pbackup_remainder_ie=NULL;
- uint wps_ielen=0, wps_offset, remainder_ielen;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
- unsigned char *ie = pnetwork->IEs;
- u32 ielen = pnetwork->IELength;
-
-
- DBG_871X("%s\n", __FUNCTION__);
-
- pwps_ie = rtw_get_wps_ie(ie+_FIXED_IE_LENGTH_, ielen-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
-
- if(pwps_ie==NULL || wps_ielen==0)
- return;
-
- wps_offset = (uint)(pwps_ie-ie);
-
- premainder_ie = pwps_ie + wps_ielen;
-
- remainder_ielen = ielen - wps_offset - wps_ielen;
-
- if(remainder_ielen>0)
- {
- pbackup_remainder_ie = rtw_malloc(remainder_ielen);
- if(pbackup_remainder_ie)
- _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
- }
-
-
- pwps_ie_src = pmlmepriv->wps_beacon_ie;
- if(pwps_ie_src == NULL)
- return;
-
-
- wps_ielen = (uint)pwps_ie_src[1];//to get ie data len
- if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
- {
- _rtw_memcpy(pwps_ie, pwps_ie_src, wps_ielen+2);
- pwps_ie += (wps_ielen+2);
-
- if(pbackup_remainder_ie)
- _rtw_memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
-
- //update IELength
- pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen;
- }
-
- if(pbackup_remainder_ie)
- rtw_mfree(pbackup_remainder_ie, remainder_ielen);
-
-}
-
-static void update_bcn_p2p_ie(_adapter *padapter)
-{
-
-}
-
-static void update_bcn_vendor_spec_ie(_adapter *padapter, u8*oui)
-{
- DBG_871X("%s\n", __FUNCTION__);
-
- if(_rtw_memcmp(RTW_WPA_OUI, oui, 4))
- {
- update_bcn_wpa_ie(padapter);
- }
- else if(_rtw_memcmp(WMM_OUI, oui, 4))
- {
- update_bcn_wmm_ie(padapter);
- }
- else if(_rtw_memcmp(WPS_OUI, oui, 4))
- {
- update_bcn_wps_ie(padapter);
- }
- else if(_rtw_memcmp(P2P_OUI, oui, 4))
- {
- update_bcn_p2p_ie(padapter);
- }
- else
- {
- DBG_871X("unknown OUI type!\n");
- }
-
-
-}
-
-void update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
-{
- _irqL irqL;
- struct mlme_priv *pmlmepriv;
- struct mlme_ext_priv *pmlmeext;
- //struct mlme_ext_info *pmlmeinfo;
-
- //DBG_871X("%s\n", __FUNCTION__);
-
- if(!padapter)
- return;
-
- pmlmepriv = &(padapter->mlmepriv);
- pmlmeext = &(padapter->mlmeextpriv);
- //pmlmeinfo = &(pmlmeext->mlmext_info);
-
- if(_FALSE == pmlmeext->bstart_bss)
- return;
-
- _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
-
- switch(ie_id)
- {
- case 0xFF:
-
- update_bcn_fixed_ie(padapter);//8: TimeStamp, 2: Beacon Interval 2:Capability
-
- break;
-
- case _TIM_IE_:
-
- update_BCNTIM(padapter);
-
- break;
-
- case _ERPINFO_IE_:
-
- update_bcn_erpinfo_ie(padapter);
-
- break;
-
- case _HT_CAPABILITY_IE_:
-
- update_bcn_htcap_ie(padapter);
-
- break;
-
- case _RSN_IE_2_:
-
- update_bcn_rsn_ie(padapter);
-
- break;
-
- case _HT_ADD_INFO_IE_:
-
- update_bcn_htinfo_ie(padapter);
-
- break;
-
- case _VENDOR_SPECIFIC_IE_:
-
- update_bcn_vendor_spec_ie(padapter, oui);
-
- break;
-
- default:
- break;
- }
-
- pmlmepriv->update_bcn = _TRUE;
-
- _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
-
-#ifndef CONFIG_INTERRUPT_BASED_TXBCN
-#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
- if(tx)
- {
- //send_beacon(padapter);//send_beacon must execute on TSR level
- set_tx_beacon_cmd(padapter);
- }
-#else
- {
- //PCI will issue beacon when BCN interrupt occurs.
- }
-#endif
-#endif //!CONFIG_INTERRUPT_BASED_TXBCN
-
-}
-
-#ifdef CONFIG_80211N_HT
-
-/*
-op_mode
-Set to 0 (HT pure) under the followign conditions
- - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
- - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
-Set to 1 (HT non-member protection) if there may be non-HT STAs
- in both the primary and the secondary channel
-Set to 2 if only HT STAs are associated in BSS,
- however and at least one 20 MHz HT STA is associated
-Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
- (currently non-GF HT station is considered as non-HT STA also)
-*/
-static int rtw_ht_operation_update(_adapter *padapter)
-{
- u16 cur_op_mode, new_op_mode;
- int op_mode_changes = 0;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
-
- if(pmlmepriv->htpriv.ht_option == _TRUE)
- return 0;
-
- //if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)
- // return 0;
-
- DBG_871X("%s current operation mode=0x%X\n",
- __FUNCTION__, pmlmepriv->ht_op_mode);
-
- if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
- && pmlmepriv->num_sta_ht_no_gf) {
- pmlmepriv->ht_op_mode |=
- HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
- op_mode_changes++;
- } else if ((pmlmepriv->ht_op_mode &
- HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
- pmlmepriv->num_sta_ht_no_gf == 0) {
- pmlmepriv->ht_op_mode &=
- ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
- op_mode_changes++;
- }
-
- if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
- (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
- pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
- op_mode_changes++;
- } else if ((pmlmepriv->ht_op_mode &
- HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
- (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
- pmlmepriv->ht_op_mode &=
- ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
- op_mode_changes++;
- }
-
- /* Note: currently we switch to the MIXED op mode if HT non-greenfield
- * station is associated. Probably it's a theoretical case, since
- * it looks like all known HT STAs support greenfield.
- */
- new_op_mode = 0;
- if (pmlmepriv->num_sta_no_ht ||
- (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
- new_op_mode = OP_MODE_MIXED;
- else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH)
- && pmlmepriv->num_sta_ht_20mhz)
- new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
- else if (pmlmepriv->olbc_ht)
- new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
- else
- new_op_mode = OP_MODE_PURE;
-
- cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
- if (cur_op_mode != new_op_mode) {
- pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
- pmlmepriv->ht_op_mode |= new_op_mode;
- op_mode_changes++;
- }
-
- DBG_871X("%s new operation mode=0x%X changes=%d\n",
- __FUNCTION__, pmlmepriv->ht_op_mode, op_mode_changes);
-
- return op_mode_changes;
-
-}
-
-#endif /* CONFIG_80211N_HT */
-
-void associated_clients_update(_adapter *padapter, u8 updated)
-{
- //update associcated stations cap.
- if(updated == _TRUE)
- {
- _irqL irqL;
- _list *phead, *plist;
- struct sta_info *psta=NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
-
- phead = &pstapriv->asoc_list;
- plist = get_next(phead);
-
- //check asoc_queue
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
- {
- psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
-
- plist = get_next(plist);
-
- VCS_update(padapter, psta);
- }
-
- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
-
- }
-
-}
-
-/* called > TSR LEVEL for USB or SDIO Interface*/
-void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta)
-{
- u8 beacon_updated = _FALSE;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
-
-
-#if 0
- if (!(psta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
- !psta->no_short_preamble_set) {
- psta->no_short_preamble_set = 1;
- pmlmepriv->num_sta_no_short_preamble++;
- if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
- (pmlmepriv->num_sta_no_short_preamble == 1))
- ieee802_11_set_beacons(hapd->iface);
- }
-#endif
-
-
- if(!(psta->flags & WLAN_STA_SHORT_PREAMBLE))
- {
- if(!psta->no_short_preamble_set)
- {
- psta->no_short_preamble_set = 1;
-
- pmlmepriv->num_sta_no_short_preamble++;
-
- if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
- (pmlmepriv->num_sta_no_short_preamble == 1))
- {
- beacon_updated = _TRUE;
- update_beacon(padapter, 0xFF, NULL, _TRUE);
- }
-
- }
- }
- else
- {
- if(psta->no_short_preamble_set)
- {
- psta->no_short_preamble_set = 0;
-
- pmlmepriv->num_sta_no_short_preamble--;
-
- if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
- (pmlmepriv->num_sta_no_short_preamble == 0))
- {
- beacon_updated = _TRUE;
- update_beacon(padapter, 0xFF, NULL, _TRUE);
- }
-
- }
- }
-
-#if 0
- if (psta->flags & WLAN_STA_NONERP && !psta->nonerp_set) {
- psta->nonerp_set = 1;
- pmlmepriv->num_sta_non_erp++;
- if (pmlmepriv->num_sta_non_erp == 1)
- ieee802_11_set_beacons(hapd->iface);
- }
-#endif
-
- if(psta->flags & WLAN_STA_NONERP)
- {
- if(!psta->nonerp_set)
- {
- psta->nonerp_set = 1;
-
- pmlmepriv->num_sta_non_erp++;
-
- if (pmlmepriv->num_sta_non_erp == 1)
- {
- beacon_updated = _TRUE;
- update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
- }
- }
-
- }
- else
- {
- if(psta->nonerp_set)
- {
- psta->nonerp_set = 0;
-
- pmlmepriv->num_sta_non_erp--;
-
- if (pmlmepriv->num_sta_non_erp == 0)
- {
- beacon_updated = _TRUE;
- update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
- }
- }
-
- }
-
-
-#if 0
- if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT) &&
- !psta->no_short_slot_time_set) {
- psta->no_short_slot_time_set = 1;
- pmlmepriv->num_sta_no_short_slot_time++;
- if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
- (pmlmepriv->num_sta_no_short_slot_time == 1))
- ieee802_11_set_beacons(hapd->iface);
- }
-#endif
-
- if(!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT))
- {
- if(!psta->no_short_slot_time_set)
- {
- psta->no_short_slot_time_set = 1;
-
- pmlmepriv->num_sta_no_short_slot_time++;
-
- if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
- (pmlmepriv->num_sta_no_short_slot_time == 1))
- {
- beacon_updated = _TRUE;
- update_beacon(padapter, 0xFF, NULL, _TRUE);
- }
-
- }
- }
- else
- {
- if(psta->no_short_slot_time_set)
- {
- psta->no_short_slot_time_set = 0;
-
- pmlmepriv->num_sta_no_short_slot_time--;
-
- if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
- (pmlmepriv->num_sta_no_short_slot_time == 0))
- {
- beacon_updated = _TRUE;
- update_beacon(padapter, 0xFF, NULL, _TRUE);
- }
- }
- }
-
-#ifdef CONFIG_80211N_HT
-
- if (psta->flags & WLAN_STA_HT)
- {
- u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
-
- DBG_871X("HT: STA " MAC_FMT " HT Capabilities "
- "Info: 0x%04x\n", MAC_ARG(psta->hwaddr), ht_capab);
-
- if (psta->no_ht_set) {
- psta->no_ht_set = 0;
- pmlmepriv->num_sta_no_ht--;
- }
-
- if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
- if (!psta->no_ht_gf_set) {
- psta->no_ht_gf_set = 1;
- pmlmepriv->num_sta_ht_no_gf++;
- }
- DBG_871X("%s STA " MAC_FMT " - no "
- "greenfield, num of non-gf stations %d\n",
- __FUNCTION__, MAC_ARG(psta->hwaddr),
- pmlmepriv->num_sta_ht_no_gf);
- }
-
- if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {
- if (!psta->ht_20mhz_set) {
- psta->ht_20mhz_set = 1;
- pmlmepriv->num_sta_ht_20mhz++;
- }
- DBG_871X("%s STA " MAC_FMT " - 20 MHz HT, "
- "num of 20MHz HT STAs %d\n",
- __FUNCTION__, MAC_ARG(psta->hwaddr),
- pmlmepriv->num_sta_ht_20mhz);
- }
-
- }
- else
- {
- if (!psta->no_ht_set) {
- psta->no_ht_set = 1;
- pmlmepriv->num_sta_no_ht++;
- }
- if(pmlmepriv->htpriv.ht_option == _TRUE) {
- DBG_871X("%s STA " MAC_FMT
- " - no HT, num of non-HT stations %d\n",
- __FUNCTION__, MAC_ARG(psta->hwaddr),
- pmlmepriv->num_sta_no_ht);
- }
- }
-
- if (rtw_ht_operation_update(padapter) > 0)
- {
- update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);
- update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);
- }
-
-#endif /* CONFIG_80211N_HT */
-
- //update associcated stations cap.
- associated_clients_update(padapter, beacon_updated);
-
- DBG_871X("%s, updated=%d\n", __func__, beacon_updated);
-
-}
-
-u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta)
-{
- u8 beacon_updated = _FALSE;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
-
- if(!psta)
- return beacon_updated;
-
- if (psta->no_short_preamble_set) {
- psta->no_short_preamble_set = 0;
- pmlmepriv->num_sta_no_short_preamble--;
- if (pmlmeext->cur_wireless_mode > WIRELESS_11B
- && pmlmepriv->num_sta_no_short_preamble == 0)
- {
- beacon_updated = _TRUE;
- update_beacon(padapter, 0xFF, NULL, _TRUE);
- }
- }
-
- if (psta->nonerp_set) {
- psta->nonerp_set = 0;
- pmlmepriv->num_sta_non_erp--;
- if (pmlmepriv->num_sta_non_erp == 0)
- {
- beacon_updated = _TRUE;
- update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
- }
- }
-
- if (psta->no_short_slot_time_set) {
- psta->no_short_slot_time_set = 0;
- pmlmepriv->num_sta_no_short_slot_time--;
- if (pmlmeext->cur_wireless_mode > WIRELESS_11B
- && pmlmepriv->num_sta_no_short_slot_time == 0)
- {
- beacon_updated = _TRUE;
- update_beacon(padapter, 0xFF, NULL, _TRUE);
- }
- }
-
-#ifdef CONFIG_80211N_HT
-
- if (psta->no_ht_gf_set) {
- psta->no_ht_gf_set = 0;
- pmlmepriv->num_sta_ht_no_gf--;
- }
-
- if (psta->no_ht_set) {
- psta->no_ht_set = 0;
- pmlmepriv->num_sta_no_ht--;
- }
-
- if (psta->ht_20mhz_set) {
- psta->ht_20mhz_set = 0;
- pmlmepriv->num_sta_ht_20mhz--;
- }
-
- if (rtw_ht_operation_update(padapter) > 0)
- {
- update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);
- update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);
- }
-
-#endif /* CONFIG_80211N_HT */
-
- //update associcated stations cap.
- //associated_clients_update(padapter, beacon_updated); //move it to avoid deadlock
-
- DBG_871X("%s, updated=%d\n", __func__, beacon_updated);
-
- return beacon_updated;
-
-}
-
-u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason)
-{
- _irqL irqL;
- u8 beacon_updated = _FALSE;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- if(!psta)
- return beacon_updated;
-
- if (active == _TRUE)
- {
-#ifdef CONFIG_80211N_HT
- //tear down Rx AMPDU
- send_delba(padapter, 0, psta->hwaddr);// recipient
-
- //tear down TX AMPDU
- send_delba(padapter, 1, psta->hwaddr);// // originator
-
-#endif //CONFIG_80211N_HT
-
- issue_deauth(padapter, psta->hwaddr, reason);
- }
-
- psta->htpriv.agg_enable_bitmap = 0x0;//reset
- psta->htpriv.candidate_tid_bitmap = 0x0;//reset
-
-
- //report_del_sta_event(padapter, psta->hwaddr, reason);
-
- //clear cam entry / key
- //clear_cam_entry(padapter, (psta->mac_id + 3));
- rtw_clearstakey_cmd(padapter, (u8*)psta, (u8)(psta->mac_id + 3), _TRUE);
-
-
- _enter_critical_bh(&psta->lock, &irqL);
- psta->state &= ~_FW_LINKED;
- _exit_critical_bh(&psta->lock, &irqL);
-
- #ifdef CONFIG_IOCTL_CFG80211
- if (1) {
- #ifdef COMPAT_KERNEL_RELEASE
- rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
- #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
- rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
- #else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
- /* will call rtw_cfg80211_indicate_sta_disassoc() in cmd_thread for old API context */
- #endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
- } else
- #endif //CONFIG_IOCTL_CFG80211
- {
- rtw_indicate_sta_disassoc_event(padapter, psta);
- }
-
- report_del_sta_event(padapter, psta->hwaddr, reason);
-
- beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
-
- _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
- rtw_free_stainfo(padapter, psta);
- _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
-
-
- return beacon_updated;
-
-}
-
-int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset)
-{
- _irqL irqL;
- _list *phead, *plist;
- int ret=0;
- struct sta_info *psta = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
-
- if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
- return ret;
-
- DBG_871X(FUNC_NDEV_FMT" with ch:%u, offset:%u\n",
- FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset);
-
- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
- phead = &pstapriv->asoc_list;
- plist = get_next(phead);
-
- /* for each sta in asoc_queue */
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
- {
- psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
- plist = get_next(plist);
-
- issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset);
- psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2);
- }
- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
-
- issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset);
-
- return ret;
-}
-
-int rtw_sta_flush(_adapter *padapter)
-{
- _irqL irqL;
- _list *phead, *plist;
- int ret=0;
- struct sta_info *psta = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
- u8 chk_alive_num = 0;
- char chk_alive_list[NUM_STA];
- int i;
-
- DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
-
- if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
- return ret;
-
- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
- phead = &pstapriv->asoc_list;
- plist = get_next(phead);
-
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
- int stainfo_offset;
-
- psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
- plist = get_next(plist);
-
- /* Remove sta from asoc_list */
- rtw_list_delete(&psta->asoc_list);
- pstapriv->asoc_list_cnt--;
-
- /* Keep sta for ap_free_sta() beyond this asoc_list loop */
- stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
- if (stainfo_offset_valid(stainfo_offset)) {
- chk_alive_list[chk_alive_num++] = stainfo_offset;
- }
- }
- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
-
-
- /* For each sta in chk_alive_list, call ap_free_sta */
- for (i = 0; i < chk_alive_num; i++) {
- psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
- ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
- }
-
- issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
-
- associated_clients_update(padapter, _TRUE);
-
- return ret;
-
-}
-
-/* called > TSR LEVEL for USB or SDIO Interface*/
-void sta_info_update(_adapter *padapter, struct sta_info *psta)
-{
- int flags = psta->flags;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
-
-
- //update wmm cap.
- if(WLAN_STA_WME&flags)
- psta->qos_option = 1;
- else
- psta->qos_option = 0;
-
- if(pmlmepriv->qospriv.qos_option == 0)
- psta->qos_option = 0;
-
-
-#ifdef CONFIG_80211N_HT
- //update 802.11n ht cap.
- if(WLAN_STA_HT&flags)
- {
- psta->htpriv.ht_option = _TRUE;
- psta->qos_option = 1;
- }
- else
- {
- psta->htpriv.ht_option = _FALSE;
- }
-
- if(pmlmepriv->htpriv.ht_option == _FALSE)
- psta->htpriv.ht_option = _FALSE;
-#endif
-
-
- update_sta_info_apmode(padapter, psta);
-
-
-}
-
-/* called >= TSR LEVEL for USB or SDIO Interface*/
-void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta)
-{
- if(psta->state & _FW_LINKED)
- {
- //add ratid
- add_RATid(padapter, psta, 0);//DM_RATR_STA_INIT
- }
-}
-
-/* restore hw setting from sw data structures */
-void rtw_ap_restore_network(_adapter *padapter)
-{
- struct mlme_priv *mlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct sta_priv * pstapriv = &padapter->stapriv;
- struct sta_info *psta;
- struct security_priv* psecuritypriv=&(padapter->securitypriv);
- _irqL irqL;
- _list *phead, *plist;
- u8 chk_alive_num = 0;
- char chk_alive_list[NUM_STA];
- int i;
-
- rtw_setopmode_cmd(padapter, Ndis802_11APMode);
-
- set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
- start_bss_network(padapter, (u8*)&mlmepriv->cur_network.network);
-
- if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
- (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))
- {
- /* restore group key, WEP keys is restored in ips_leave() */
- rtw_set_key(padapter, psecuritypriv, psecuritypriv->dot118021XGrpKeyid, 0);
- }
-
- /* per sta pairwise key and settings */
- if((padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_) &&
- (padapter->securitypriv.dot11PrivacyAlgrthm != _AES_)) {
- return;
- }
-
- _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
-
- phead = &pstapriv->asoc_list;
- plist = get_next(phead);
-
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
- int stainfo_offset;
-
- psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
- plist = get_next(plist);
-
- stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
- if (stainfo_offset_valid(stainfo_offset)) {
- chk_alive_list[chk_alive_num++] = stainfo_offset;
- }
- }
-
- _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
-
- for (i = 0; i < chk_alive_num; i++) {
- psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
-
- if (psta == NULL) {
- DBG_871X(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter));
- }
- else if(psta->state &_FW_LINKED)
- {
- Update_RA_Entry(padapter, psta);
- //pairwise key
- rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE);
- }
- }
-
-}
-
-void start_ap_mode(_adapter *padapter)
-{
- int i;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
-
- pmlmepriv->update_bcn = _FALSE;
-
- //init_mlme_ap_info(padapter);
- pmlmeext->bstart_bss = _FALSE;
-
- pmlmepriv->num_sta_non_erp = 0;
-
- pmlmepriv->num_sta_no_short_slot_time = 0;
-
- pmlmepriv->num_sta_no_short_preamble = 0;
-
- pmlmepriv->num_sta_ht_no_gf = 0;
-#ifdef CONFIG_80211N_HT
- pmlmepriv->num_sta_no_ht = 0;
-#endif //CONFIG_80211N_HT
- pmlmepriv->num_sta_ht_20mhz = 0;
-
- pmlmepriv->olbc = _FALSE;
-
- pmlmepriv->olbc_ht = _FALSE;
-
-#ifdef CONFIG_80211N_HT
- pmlmepriv->ht_op_mode = 0;
-#endif
-
- for(i=0; i<NUM_STA; i++)
- pstapriv->sta_aid[i] = NULL;
-
- pmlmepriv->wps_beacon_ie = NULL;
- pmlmepriv->wps_probe_resp_ie = NULL;
- pmlmepriv->wps_assoc_resp_ie = NULL;
-
- pmlmepriv->p2p_beacon_ie = NULL;
- pmlmepriv->p2p_probe_resp_ie = NULL;
-
-
- //for ACL
- _rtw_init_listhead(&(pacl_list->acl_node_q.queue));
- pacl_list->num = 0;
- pacl_list->mode = 0;
- for(i = 0; i < NUM_ACL; i++)
- {
- _rtw_init_listhead(&pacl_list->aclnode[i].list);
- pacl_list->aclnode[i].valid = _FALSE;
- }
-
-}
-
-void stop_ap_mode(_adapter *padapter)
-{
- _irqL irqL;
- _list *phead, *plist;
- struct rtw_wlan_acl_node *paclnode;
- struct sta_info *psta=NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
- _queue *pacl_node_q =&pacl_list->acl_node_q;
-
- pmlmepriv->update_bcn = _FALSE;
- pmlmeext->bstart_bss = _FALSE;
- //_rtw_spinlock_free(&pmlmepriv->bcn_update_lock);
-
- //reset and init security priv , this can refine with rtw_reset_securitypriv
- _rtw_memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv));
- padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
- padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
-
- //for ACL
- _enter_critical_bh(&(pacl_node_q->lock), &irqL);
- phead = get_list_head(pacl_node_q);
- plist = get_next(phead);
- while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
- {
- paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
- plist = get_next(plist);
-
- if(paclnode->valid == _TRUE)
- {
- paclnode->valid = _FALSE;
-
- rtw_list_delete(&paclnode->list);
-
- pacl_list->num--;
- }
- }
- _exit_critical_bh(&(pacl_node_q->lock), &irqL);
-
- DBG_871X("%s, free acl_node_queue, num=%d\n", __func__, pacl_list->num);
-
- rtw_sta_flush(padapter);
-
- //free_assoc_sta_resources
- rtw_free_all_stainfo(padapter);
-
- psta = rtw_get_bcmc_stainfo(padapter);
- _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
- rtw_free_stainfo(padapter, psta);
- _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
-
- rtw_init_bcmc_stainfo(padapter);
-
- rtw_free_mlme_priv_ie_data(pmlmepriv);
-
-}
-
-#endif //CONFIG_NATIVEAP_MLME
-#endif //CONFIG_AP_MODE
-
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ *
+ ******************************************************************************/
+#define _RTW_AP_C_
+
+#include <drv_conf.h>
+#include <osdep_service.h>
+#include <drv_types.h>
+#include <wifi.h>
+
+
+#ifdef CONFIG_AP_MODE
+
+extern unsigned char RTW_WPA_OUI[];
+extern unsigned char WMM_OUI[];
+extern unsigned char WPS_OUI[];
+extern unsigned char P2P_OUI[];
+extern unsigned char WFD_OUI[];
+
+void init_mlme_ap_info(_adapter *padapter)
+{
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
+
+
+ _rtw_spinlock_init(&pmlmepriv->bcn_update_lock);
+
+ //for ACL
+ _rtw_init_queue(&pacl_list->acl_node_q);
+
+ //pmlmeext->bstart_bss = _FALSE;
+
+ start_ap_mode(padapter);
+}
+
+void free_mlme_ap_info(_adapter *padapter)
+{
+ _irqL irqL;
+ struct sta_info *psta=NULL;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ //stop_ap_mode(padapter);
+
+ pmlmepriv->update_bcn = _FALSE;
+ pmlmeext->bstart_bss = _FALSE;
+
+ rtw_sta_flush(padapter);
+
+ pmlmeinfo->state = _HW_STATE_NOLINK_;
+
+ //free_assoc_sta_resources
+ rtw_free_all_stainfo(padapter);
+
+ //free bc/mc sta_info
+ psta = rtw_get_bcmc_stainfo(padapter);
+ _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+ rtw_free_stainfo(padapter, psta);
+ _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+ _rtw_spinlock_free(&pmlmepriv->bcn_update_lock);
+
+}
+
+static void update_BCNTIM(_adapter *padapter)
+{
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
+ unsigned char *pie = pnetwork_mlmeext->IEs;
+
+ //DBG_871X("%s\n", __FUNCTION__);
+
+ //update TIM IE
+ //if(pstapriv->tim_bitmap)
+ if(_TRUE)
+ {
+ u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
+ u16 tim_bitmap_le;
+ uint offset, tmp_len, tim_ielen, tim_ie_offset, remainder_ielen;
+
+ tim_bitmap_le = cpu_to_le16(pstapriv->tim_bitmap);
+
+ p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, _TIM_IE_, &tim_ielen, pnetwork_mlmeext->IELength - _FIXED_IE_LENGTH_);
+ if (p != NULL && tim_ielen>0)
+ {
+ tim_ielen += 2;
+
+ premainder_ie = p+tim_ielen;
+
+ tim_ie_offset = (sint)(p -pie);
+
+ remainder_ielen = pnetwork_mlmeext->IELength - tim_ie_offset - tim_ielen;
+
+ //append TIM IE from dst_ie offset
+ dst_ie = p;
+ }
+ else
+ {
+ tim_ielen = 0;
+
+ //calucate head_len
+ offset = _FIXED_IE_LENGTH_;
+
+ /* get ssid_ie len */
+ p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SSID_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
+ if (p != NULL)
+ offset += tmp_len+2;
+
+ // get supported rates len
+ p = rtw_get_ie(pie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &tmp_len, (pnetwork_mlmeext->IELength - _BEACON_IE_OFFSET_));
+ if (p != NULL)
+ {
+ offset += tmp_len+2;
+ }
+
+ //DS Parameter Set IE, len=3
+ offset += 3;
+
+ premainder_ie = pie + offset;
+
+ remainder_ielen = pnetwork_mlmeext->IELength - offset - tim_ielen;
+
+ //append TIM IE from offset
+ dst_ie = pie + offset;
+
+ }
+
+
+ if(remainder_ielen>0)
+ {
+ pbackup_remainder_ie = rtw_malloc(remainder_ielen);
+ if(pbackup_remainder_ie && premainder_ie)
+ _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
+ }
+
+ *dst_ie++=_TIM_IE_;
+
+ if((pstapriv->tim_bitmap&0xff00) && (pstapriv->tim_bitmap&0x00fc))
+ tim_ielen = 5;
+ else
+ tim_ielen = 4;
+
+ *dst_ie++= tim_ielen;
+
+ *dst_ie++=0;//DTIM count
+ *dst_ie++=1;//DTIM peroid
+
+ if(pstapriv->tim_bitmap&BIT(0))//for bc/mc frames
+ *dst_ie++ = BIT(0);//bitmap ctrl
+ else
+ *dst_ie++ = 0;
+
+ if(tim_ielen==4)
+ {
+ *dst_ie++ = *(u8*)&tim_bitmap_le;
+ }
+ else if(tim_ielen==5)
+ {
+ _rtw_memcpy(dst_ie, &tim_bitmap_le, 2);
+ dst_ie+=2;
+ }
+
+ //copy remainder IE
+ if(pbackup_remainder_ie)
+ {
+ _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
+
+ rtw_mfree(pbackup_remainder_ie, remainder_ielen);
+ }
+
+ offset = (uint)(dst_ie - pie);
+ pnetwork_mlmeext->IELength = offset + remainder_ielen;
+
+ }
+
+#ifndef CONFIG_INTERRUPT_BASED_TXBCN
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+ set_tx_beacon_cmd(padapter);
+#endif
+#endif //!CONFIG_INTERRUPT_BASED_TXBCN
+
+
+}
+
+void rtw_add_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index, u8 *data, u8 len)
+{
+ PNDIS_802_11_VARIABLE_IEs pIE;
+ u8 bmatch = _FALSE;
+ u8 *pie = pnetwork->IEs;
+ u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
+ u32 i, offset, ielen, ie_offset, remainder_ielen = 0;
+
+ for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;)
+ {
+ pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
+
+ if (pIE->ElementID > index)
+ {
+ break;
+ }
+ else if(pIE->ElementID == index) // already exist the same IE
+ {
+ p = (u8 *)pIE;
+ ielen = pIE->Length;
+ bmatch = _TRUE;
+ break;
+ }
+
+ p = (u8 *)pIE;
+ ielen = pIE->Length;
+ i += (pIE->Length + 2);
+ }
+
+ if (p != NULL && ielen>0)
+ {
+ ielen += 2;
+
+ premainder_ie = p+ielen;
+
+ ie_offset = (sint)(p -pie);
+
+ remainder_ielen = pnetwork->IELength - ie_offset - ielen;
+
+ if(bmatch)
+ dst_ie = p;
+ else
+ dst_ie = (p+ielen);
+ }
+
+ if(remainder_ielen>0)
+ {
+ pbackup_remainder_ie = rtw_malloc(remainder_ielen);
+ if(pbackup_remainder_ie && premainder_ie)
+ _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
+ }
+
+ *dst_ie++=index;
+ *dst_ie++=len;
+
+ _rtw_memcpy(dst_ie, data, len);
+ dst_ie+=len;
+
+ //copy remainder IE
+ if(pbackup_remainder_ie)
+ {
+ _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
+
+ rtw_mfree(pbackup_remainder_ie, remainder_ielen);
+ }
+
+ offset = (uint)(dst_ie - pie);
+ pnetwork->IELength = offset + remainder_ielen;
+}
+
+void rtw_remove_bcn_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 index)
+{
+ u8 *p, *dst_ie, *premainder_ie=NULL, *pbackup_remainder_ie=NULL;
+ uint offset, ielen, ie_offset, remainder_ielen = 0;
+ u8 *pie = pnetwork->IEs;
+
+ p = rtw_get_ie(pie + _FIXED_IE_LENGTH_, index, &ielen, pnetwork->IELength - _FIXED_IE_LENGTH_);
+ if (p != NULL && ielen>0)
+ {
+ ielen += 2;
+
+ premainder_ie = p+ielen;
+
+ ie_offset = (sint)(p -pie);
+
+ remainder_ielen = pnetwork->IELength - ie_offset - ielen;
+
+ dst_ie = p;
+ }
+ else {
+ return;
+ }
+
+ if(remainder_ielen>0)
+ {
+ pbackup_remainder_ie = rtw_malloc(remainder_ielen);
+ if(pbackup_remainder_ie && premainder_ie)
+ _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
+ }
+
+ //copy remainder IE
+ if(pbackup_remainder_ie)
+ {
+ _rtw_memcpy(dst_ie, pbackup_remainder_ie, remainder_ielen);
+
+ rtw_mfree(pbackup_remainder_ie, remainder_ielen);
+ }
+
+ offset = (uint)(dst_ie - pie);
+ pnetwork->IELength = offset + remainder_ielen;
+}
+
+
+u8 chk_sta_is_alive(struct sta_info *psta);
+u8 chk_sta_is_alive(struct sta_info *psta)
+{
+ u8 ret = _FALSE;
+ #ifdef DBG_EXPIRATION_CHK
+ DBG_871X("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", expire_to:%u, %s%ssq_len:%u\n"
+ , MAC_ARG(psta->hwaddr)
+ , psta->rssi_stat.UndecoratedSmoothedPWDB
+ //, STA_RX_PKTS_ARG(psta)
+ , STA_RX_PKTS_DIFF_ARG(psta)
+ , psta->expire_to
+ , psta->state&WIFI_SLEEP_STATE?"PS, ":""
+ , psta->state&WIFI_STA_ALIVE_CHK_STATE?"SAC, ":""
+ , psta->sleepq_len
+ );
+ #endif
+
+ //if(sta_last_rx_pkts(psta) == sta_rx_pkts(psta))
+ if((psta->sta_stats.last_rx_data_pkts + psta->sta_stats.last_rx_ctrl_pkts) == (psta->sta_stats.rx_data_pkts + psta->sta_stats.rx_ctrl_pkts))
+ {
+ #if 0
+ if(psta->state&WIFI_SLEEP_STATE)
+ ret = _TRUE;
+ #endif
+ }
+ else
+ {
+ ret = _TRUE;
+ }
+
+ sta_update_last_rx_pkts(psta);
+
+ return ret;
+}
+
+void expire_timeout_chk(_adapter *padapter)
+{
+ _irqL irqL;
+ _list *phead, *plist;
+ u8 updated;
+ struct sta_info *psta=NULL;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ u8 chk_alive_num = 0;
+ char chk_alive_list[NUM_STA];
+ int i;
+
+ _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
+
+ phead = &pstapriv->auth_list;
+ plist = get_next(phead);
+
+ //check auth_queue
+ #ifdef DBG_EXPIRATION_CHK
+ if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
+ DBG_871X(FUNC_NDEV_FMT" auth_list, cnt:%u\n"
+ , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->auth_list_cnt);
+ }
+ #endif
+ while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
+ {
+ psta = LIST_CONTAINOR(plist, struct sta_info, auth_list);
+ plist = get_next(plist);
+
+ if(psta->expire_to>0)
+ {
+ psta->expire_to--;
+ if (psta->expire_to == 0)
+ {
+ rtw_list_delete(&psta->auth_list);
+ pstapriv->auth_list_cnt--;
+
+ DBG_871X("auth expire %02X%02X%02X%02X%02X%02X\n",
+ psta->hwaddr[0],psta->hwaddr[1],psta->hwaddr[2],psta->hwaddr[3],psta->hwaddr[4],psta->hwaddr[5]);
+
+ _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
+
+ _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+ rtw_free_stainfo(padapter, psta);
+ _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+
+ _enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
+ }
+ }
+
+ }
+
+ _exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
+
+ psta = NULL;
+
+
+ _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+
+ phead = &pstapriv->asoc_list;
+ plist = get_next(phead);
+
+ //check asoc_queue
+ #ifdef DBG_EXPIRATION_CHK
+ if (rtw_end_of_queue_search(phead, plist) == _FALSE) {
+ DBG_871X(FUNC_NDEV_FMT" asoc_list, cnt:%u\n"
+ , FUNC_NDEV_ARG(padapter->pnetdev), pstapriv->asoc_list_cnt);
+ }
+ #endif
+ while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
+ {
+ psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
+ plist = get_next(plist);
+
+ if (chk_sta_is_alive(psta) || !psta->expire_to) {
+ psta->expire_to = pstapriv->expire_to;
+ psta->keep_alive_trycnt = 0;
+ #ifdef CONFIG_TX_MCAST2UNI
+ psta->under_exist_checking = 0;
+ #endif // CONFIG_TX_MCAST2UNI
+ } else {
+ psta->expire_to--;
+ }
+
+#ifndef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
+#ifdef CONFIG_TX_MCAST2UNI
+#ifdef CONFIG_80211N_HT
+ if ( (psta->flags & WLAN_STA_HT) && (psta->htpriv.agg_enable_bitmap || psta->under_exist_checking) ) {
+ // check sta by delba(addba) for 11n STA
+ // ToDo: use CCX report to check for all STAs
+ //DBG_871X("asoc check by DELBA/ADDBA! (pstapriv->expire_to=%d s)(psta->expire_to=%d s), [%02x, %d]\n", pstapriv->expire_to*2, psta->expire_to*2, psta->htpriv.agg_enable_bitmap, psta->under_exist_checking);
+
+ if ( psta->expire_to <= (pstapriv->expire_to - 50 ) ) {
+ DBG_871X("asoc expire by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);
+ psta->under_exist_checking = 0;
+ psta->expire_to = 0;
+ } else if ( psta->expire_to <= (pstapriv->expire_to - 3) && (psta->under_exist_checking==0)) {
+ DBG_871X("asoc check by DELBA/ADDBA! (%d s)\n", (pstapriv->expire_to-psta->expire_to)*2);
+ psta->under_exist_checking = 1;
+ //tear down TX AMPDU
+ send_delba(padapter, 1, psta->hwaddr);// // originator
+ psta->htpriv.agg_enable_bitmap = 0x0;//reset
+ psta->htpriv.candidate_tid_bitmap = 0x0;//reset
+ }
+ }
+#endif //CONFIG_80211N_HT
+#endif // CONFIG_TX_MCAST2UNI
+#endif //CONFIG_ACTIVE_KEEP_ALIVE_CHECK
+
+ if (psta->expire_to <= 0)
+ {
+ #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+
+ if (padapter->registrypriv.wifi_spec == 1)
+ {
+ psta->expire_to = pstapriv->expire_to;
+ continue;
+ }
+
+ if (psta->state & WIFI_SLEEP_STATE) {
+ if (!(psta->state & WIFI_STA_ALIVE_CHK_STATE)) {
+ //to check if alive by another methods if staion is at ps mode.
+ psta->expire_to = pstapriv->expire_to;
+ psta->state |= WIFI_STA_ALIVE_CHK_STATE;
+
+ //DBG_871X("alive chk, sta:" MAC_FMT " is at ps mode!\n", MAC_ARG(psta->hwaddr));
+
+ //to update bcn with tim_bitmap for this station
+ pstapriv->tim_bitmap |= BIT(psta->aid);
+ update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
+
+ if(!pmlmeext->active_keep_alive_check)
+ continue;
+ }
+ }
+
+ if (pmlmeext->active_keep_alive_check) {
+ int stainfo_offset;
+
+ stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
+ if (stainfo_offset_valid(stainfo_offset)) {
+ chk_alive_list[chk_alive_num++] = stainfo_offset;
+ }
+
+ continue;
+ }
+ #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
+
+ rtw_list_delete(&psta->asoc_list);
+ pstapriv->asoc_list_cnt--;
+
+ DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
+ updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);
+ }
+ else
+ {
+ /* TODO: Aging mechanism to digest frames in sleep_q to avoid running out of xmitframe */
+ if (psta->sleepq_len > (NR_XMITFRAME/pstapriv->asoc_list_cnt)
+ && padapter->xmitpriv.free_xmitframe_cnt < ((NR_XMITFRAME/pstapriv->asoc_list_cnt)/2)
+ ){
+ DBG_871X("%s sta:"MAC_FMT", sleepq_len:%u, free_xmitframe_cnt:%u, asoc_list_cnt:%u, clear sleep_q\n", __func__
+ , MAC_ARG(psta->hwaddr)
+ , psta->sleepq_len, padapter->xmitpriv.free_xmitframe_cnt, pstapriv->asoc_list_cnt);
+ wakeup_sta_to_xmit(padapter, psta);
+ }
+ }
+ }
+
+ _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+
+#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
+if (chk_alive_num) {
+
+ u8 backup_oper_channel=0;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ /* switch to correct channel of current network before issue keep-alive frames */
+ if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
+ backup_oper_channel = rtw_get_oper_ch(padapter);
+ SelectChannel(padapter, pmlmeext->cur_channel);
+ }
+
+ /* issue null data to check sta alive*/
+ for (i = 0; i < chk_alive_num; i++) {
+
+ int ret = _FAIL;
+
+ psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
+ if(!(psta->state &_FW_LINKED))
+ continue;
+
+ if (psta->state & WIFI_SLEEP_STATE)
+ ret = issue_nulldata(padapter, psta->hwaddr, 0, 1, 50);
+ else
+ ret = issue_nulldata(padapter, psta->hwaddr, 0, 3, 50);
+
+ psta->keep_alive_trycnt++;
+ if (ret == _SUCCESS)
+ {
+ DBG_871X("asoc check, sta(" MAC_FMT ") is alive\n", MAC_ARG(psta->hwaddr));
+ psta->expire_to = pstapriv->expire_to;
+ psta->keep_alive_trycnt = 0;
+ continue;
+ }
+ else if (psta->keep_alive_trycnt <= 3)
+ {
+ DBG_871X("ack check for asoc expire, keep_alive_trycnt=%d\n", psta->keep_alive_trycnt);
+ psta->expire_to = 1;
+ continue;
+ }
+
+ psta->keep_alive_trycnt = 0;
+
+ DBG_871X("asoc expire "MAC_FMT", state=0x%x\n", MAC_ARG(psta->hwaddr), psta->state);
+ _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+ if (rtw_is_list_empty(&psta->asoc_list)==_FALSE) {
+ rtw_list_delete(&psta->asoc_list);
+ pstapriv->asoc_list_cnt--;
+ updated = ap_free_sta(padapter, psta, _FALSE, WLAN_REASON_DEAUTH_LEAVING);
+ }
+ _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+
+ }
+
+ if (backup_oper_channel>0) /* back to the original operation channel */
+ SelectChannel(padapter, backup_oper_channel);
+}
+#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
+
+ associated_clients_update(padapter, updated);
+}
+
+void add_RATid(_adapter *padapter, struct sta_info *psta, u8 rssi_level)
+{
+ int i;
+ u8 rf_type;
+ u32 init_rate=0;
+ unsigned char sta_band = 0, raid, shortGIrate = _FALSE;
+ unsigned char limit;
+ unsigned int tx_ra_bitmap=0;
+ struct ht_priv *psta_ht = NULL;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
+
+#ifdef CONFIG_80211N_HT
+ if(psta)
+ psta_ht = &psta->htpriv;
+ else
+ return;
+#endif //CONFIG_80211N_HT
+
+ if(!(psta->state & _FW_LINKED))
+ return;
+
+ //b/g mode ra_bitmap
+ for (i=0; i<sizeof(psta->bssrateset); i++)
+ {
+ if (psta->bssrateset[i])
+ tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
+ }
+#ifdef CONFIG_80211N_HT
+ //n mode ra_bitmap
+ if(psta_ht->ht_option)
+ {
+ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+ if(rf_type == RF_2T2R)
+ limit=16;// 2R
+ else
+ limit=8;// 1R
+
+ for (i=0; i<limit; i++) {
+ if (psta_ht->ht_cap.supp_mcs_set[i/8] & BIT(i%8))
+ tx_ra_bitmap |= BIT(i+12);
+ }
+
+ //max short GI rate
+ shortGIrate = psta_ht->sgi;
+ }
+#endif //CONFIG_80211N_HT
+
+#if 0//gtest
+ if(get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)
+ {
+ //is this a 2r STA?
+ if((pstat->tx_ra_bitmap & 0x0ff00000) != 0 && !(priv->pshare->has_2r_sta & BIT(pstat->aid)))
+ {
+ priv->pshare->has_2r_sta |= BIT(pstat->aid);
+ if(rtw_read16(padapter, 0x102501f6) != 0xffff)
+ {
+ rtw_write16(padapter, 0x102501f6, 0xffff);
+ reset_1r_sta_RA(priv, 0xffff);
+ Switch_1SS_Antenna(priv, 3);
+ }
+ }
+ else// bg or 1R STA?
+ {
+ if((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len && priv->pshare->has_2r_sta == 0)
+ {
+ if(rtw_read16(padapter, 0x102501f6) != 0x7777)
+ { // MCS7 SGI
+ rtw_write16(padapter, 0x102501f6,0x7777);
+ reset_1r_sta_RA(priv, 0x7777);
+ Switch_1SS_Antenna(priv, 2);
+ }
+ }
+ }
+
+ }
+
+ if ((pstat->rssi_level < 1) || (pstat->rssi_level > 3))
+ {
+ if (pstat->rssi >= priv->pshare->rf_ft_var.raGoDownUpper)
+ pstat->rssi_level = 1;
+ else if ((pstat->rssi >= priv->pshare->rf_ft_var.raGoDown20MLower) ||
+ ((priv->pshare->is_40m_bw) && (pstat->ht_cap_len) &&
+ (pstat->rssi >= priv->pshare->rf_ft_var.raGoDown40MLower) &&
+ (pstat->ht_cap_buf.ht_cap_info & cpu_to_le16(_HTCAP_SUPPORT_CH_WDTH_))))
+ pstat->rssi_level = 2;
+ else
+ pstat->rssi_level = 3;
+ }
+
+ // rate adaptive by rssi
+ if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11N) && pstat->ht_cap_len)
+ {
+ if ((get_rf_mimo_mode(priv) == MIMO_1T2R) || (get_rf_mimo_mode(priv) == MIMO_1T1R))
+ {
+ switch (pstat->rssi_level) {
+ case 1:
+ pstat->tx_ra_bitmap &= 0x100f0000;
+ break;
+ case 2:
+ pstat->tx_ra_bitmap &= 0x100ff000;
+ break;
+ case 3:
+ if (priv->pshare->is_40m_bw)
+ pstat->tx_ra_bitmap &= 0x100ff005;
+ else
+ pstat->tx_ra_bitmap &= 0x100ff001;
+
+ break;
+ }
+ }
+ else
+ {
+ switch (pstat->rssi_level) {
+ case 1:
+ pstat->tx_ra_bitmap &= 0x1f0f0000;
+ break;
+ case 2:
+ pstat->tx_ra_bitmap &= 0x1f0ff000;
+ break;
+ case 3:
+ if (priv->pshare->is_40m_bw)
+ pstat->tx_ra_bitmap &= 0x000ff005;
+ else
+ pstat->tx_ra_bitmap &= 0x000ff001;
+
+ break;
+ }
+
+ // Don't need to mask high rates due to new rate adaptive parameters
+ //if (pstat->is_broadcom_sta) // use MCS12 as the highest rate vs. Broadcom sta
+ // pstat->tx_ra_bitmap &= 0x81ffffff;
+
+ // NIC driver will report not supporting MCS15 and MCS14 in asoc req
+ //if (pstat->is_rtl8190_sta && !pstat->is_2t_mimo_sta)
+ // pstat->tx_ra_bitmap &= 0x83ffffff; // if Realtek 1x2 sta, don't use MCS15 and MCS14
+ }
+ }
+ else if ((priv->pmib->dot11BssType.net_work_type & WIRELESS_11G) && isErpSta(pstat))
+ {
+ switch (pstat->rssi_level) {
+ case 1:
+ pstat->tx_ra_bitmap &= 0x00000f00;
+ break;
+ case 2:
+ pstat->tx_ra_bitmap &= 0x00000ff0;
+ break;
+ case 3:
+ pstat->tx_ra_bitmap &= 0x00000ff5;
+ break;
+ }
+ }
+ else
+ {
+ pstat->tx_ra_bitmap &= 0x0000000d;
+ }
+
+ // disable tx short GI when station cannot rx MCS15(AP is 2T2R)
+ // disable tx short GI when station cannot rx MCS7 (AP is 1T2R or 1T1R)
+ // if there is only 1r STA and we are 2T2R, DO NOT mask SGI rate
+ if ((!(pstat->tx_ra_bitmap & 0x8000000) && (priv->pshare->has_2r_sta > 0) && (get_rf_mimo_mode(padapter) == RTL8712_RF_2T2R)) ||
+ (!(pstat->tx_ra_bitmap & 0x80000) && (get_rf_mimo_mode(padapter) != RTL8712_RF_2T2R)))
+ {
+ pstat->tx_ra_bitmap &= ~BIT(28);
+ }
+#endif
+
+ if ( pcur_network->Configuration.DSConfig > 14 ) {
+ // 5G band
+ if (tx_ra_bitmap & 0xffff000)
+ sta_band |= WIRELESS_11_5N ;
+
+ if (tx_ra_bitmap & 0xff0)
+ sta_band |= WIRELESS_11A;
+
+ } else {
+ if (tx_ra_bitmap & 0xffff000)
+ sta_band |= WIRELESS_11_24N;
+
+ if (tx_ra_bitmap & 0xff0)
+ sta_band |= WIRELESS_11G;
+
+ if (tx_ra_bitmap & 0x0f)
+ sta_band |= WIRELESS_11B;
+ }
+
+ psta->wireless_mode = sta_band;
+
+ raid = networktype_to_raid(sta_band);
+ init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
+
+ if (psta->aid < NUM_STA)
+ {
+ u8 arg = 0;
+
+ arg = psta->mac_id&0x1f;
+
+ arg |= BIT(7);//support entry 2~31
+
+ if (shortGIrate==_TRUE)
+ arg |= BIT(5);
+
+ tx_ra_bitmap |= ((raid<<28)&0xf0000000);
+
+ DBG_871X("%s=> mac_id:%d , raid:%d , bitmap=0x%x, arg=0x%x\n",
+ __FUNCTION__ , psta->mac_id, raid ,tx_ra_bitmap, arg);
+
+ //bitmap[0:27] = tx_rate_bitmap
+ //bitmap[28:31]= Rate Adaptive id
+ //arg[0:4] = macid
+ //arg[5] = Short GI
+ rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level);
+
+
+ if (shortGIrate==_TRUE)
+ init_rate |= BIT(6);
+
+ //set ra_id, init_rate
+ psta->raid = raid;
+ psta->init_rate = init_rate;
+
+ }
+ else
+ {
+ DBG_871X("station aid %d exceed the max number\n", psta->aid);
+ }
+
+}
+
+void update_bmc_sta(_adapter *padapter)
+{
+ _irqL irqL;
+ u32 init_rate=0;
+ unsigned char network_type, raid;
+ int i, supportRateNum = 0;
+ unsigned int tx_ra_bitmap=0;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
+ struct sta_info *psta = rtw_get_bcmc_stainfo(padapter);
+
+ if(psta)
+ {
+ psta->aid = 0;//default set to 0
+ //psta->mac_id = psta->aid+4;
+ psta->mac_id = psta->aid + 1;
+
+ psta->qos_option = 0;
+#ifdef CONFIG_80211N_HT
+ psta->htpriv.ht_option = _FALSE;
+#endif //CONFIG_80211N_HT
+
+ psta->ieee8021x_blocked = 0;
+
+ _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
+
+ //psta->dot118021XPrivacy = _NO_PRIVACY_;//!!! remove it, because it has been set before this.
+
+
+
+ //prepare for add_RATid
+ supportRateNum = rtw_get_rateset_len((u8*)&pcur_network->SupportedRates);
+ network_type = rtw_check_network_type((u8*)&pcur_network->SupportedRates, supportRateNum, 1);
+
+ _rtw_memcpy(psta->bssrateset, &pcur_network->SupportedRates, supportRateNum);
+ psta->bssratelen = supportRateNum;
+
+ //b/g mode ra_bitmap
+ for (i=0; i<supportRateNum; i++)
+ {
+ if (psta->bssrateset[i])
+ tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
+ }
+
+ if ( pcur_network->Configuration.DSConfig > 14 ) {
+ //force to A mode. 5G doesn't support CCK rates
+ network_type = WIRELESS_11A;
+ tx_ra_bitmap = 0x150; // 6, 12, 24 Mbps
+ } else {
+ //force to b mode
+ network_type = WIRELESS_11B;
+ tx_ra_bitmap = 0xf;
+ }
+
+ //tx_ra_bitmap = update_basic_rate(pcur_network->SupportedRates, supportRateNum);
+
+ raid = networktype_to_raid(network_type);
+ init_rate = get_highest_rate_idx(tx_ra_bitmap&0x0fffffff)&0x3f;
+
+ //DBG_871X("Add id %d val %08x to ratr for bmc sta\n", psta->aid, tx_ra_bitmap);
+ //ap mode
+ rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
+
+ //if(pHalData->fw_ractrl == _TRUE)
+ {
+ u8 arg = 0;
+
+ arg = psta->mac_id&0x1f;
+
+ arg |= BIT(7);
+
+ //if (shortGIrate==_TRUE)
+ // arg |= BIT(5);
+
+ tx_ra_bitmap |= ((raid<<28)&0xf0000000);
+
+ DBG_871X("update_bmc_sta, mask=0x%x, arg=0x%x\n", tx_ra_bitmap, arg);
+
+ //bitmap[0:27] = tx_rate_bitmap
+ //bitmap[28:31]= Rate Adaptive id
+ //arg[0:4] = macid
+ //arg[5] = Short GI
+ rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, 0);
+
+ }
+
+ //set ra_id, init_rate
+ psta->raid = raid;
+ psta->init_rate = init_rate;
+
+ rtw_sta_media_status_rpt(padapter, psta, 1);
+
+ _enter_critical_bh(&psta->lock, &irqL);
+ psta->state = _FW_LINKED;
+ _exit_critical_bh(&psta->lock, &irqL);
+
+ }
+ else
+ {
+ DBG_871X("add_RATid_bmc_sta error!\n");
+ }
+
+}
+
+//notes:
+//AID: 1~MAX for sta and 0 for bc/mc in ap/adhoc mode
+//MAC_ID = AID+1 for sta in ap/adhoc mode
+//MAC_ID = 1 for bc/mc for sta/ap/adhoc
+//MAC_ID = 0 for bssid for sta/ap/adhoc
+//CAM_ID = //0~3 for default key, cmd_id=macid + 3, macid=aid+1;
+
+void update_sta_info_apmode(_adapter *padapter, struct sta_info *psta)
+{
+ _irqL irqL;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+#ifdef CONFIG_80211N_HT
+ struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
+ struct ht_priv *phtpriv_sta = &psta->htpriv;
+#endif //CONFIG_80211N_HT
+ //set intf_tag to if1
+ //psta->intf_tag = 0;
+
+ //psta->mac_id = psta->aid+4;
+ psta->mac_id = psta->aid+1;
+ DBG_871X("%s\n",__FUNCTION__);
+
+ //ap mode
+ rtw_hal_set_odm_var(padapter,HAL_ODM_STA_INFO,psta,_TRUE);
+
+ if(psecuritypriv->dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)
+ psta->ieee8021x_blocked = _TRUE;
+ else
+ psta->ieee8021x_blocked = _FALSE;
+
+
+ //update sta's cap
+
+ //ERP
+ VCS_update(padapter, psta);
+#ifdef CONFIG_80211N_HT
+ //HT related cap
+ if(phtpriv_sta->ht_option)
+ {
+ //check if sta supports rx ampdu
+ phtpriv_sta->ampdu_enable = phtpriv_ap->ampdu_enable;
+
+ //check if sta support s Short GI
+ if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40))
+ {
+ phtpriv_sta->sgi = _TRUE;
+ }
+
+ // bwmode
+ if((phtpriv_sta->ht_cap.cap_info & phtpriv_ap->ht_cap.cap_info) & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
+ {
+ //phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_40;
+ phtpriv_sta->bwmode = pmlmeext->cur_bwmode;
+ phtpriv_sta->ch_offset = pmlmeext->cur_ch_offset;
+
+ }
+
+ psta->qos_option = _TRUE;
+
+ }
+ else
+ {
+ phtpriv_sta->ampdu_enable = _FALSE;
+
+ phtpriv_sta->sgi = _FALSE;
+ phtpriv_sta->bwmode = HT_CHANNEL_WIDTH_20;
+ phtpriv_sta->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+ }
+
+ //Rx AMPDU
+ send_delba(padapter, 0, psta->hwaddr);// recipient
+
+ //TX AMPDU
+ send_delba(padapter, 1, psta->hwaddr);// // originator
+ phtpriv_sta->agg_enable_bitmap = 0x0;//reset
+ phtpriv_sta->candidate_tid_bitmap = 0x0;//reset
+#endif //CONFIG_80211N_HT
+
+ //todo: init other variables
+
+ _rtw_memset((void*)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
+
+
+ //add ratid
+ //add_RATid(padapter, psta);//move to ap_sta_info_defer_update()
+
+
+ _enter_critical_bh(&psta->lock, &irqL);
+ psta->state |= _FW_LINKED;
+ _exit_critical_bh(&psta->lock, &irqL);
+
+
+}
+
+static void update_hw_ht_param(_adapter *padapter)
+{
+ unsigned char max_AMPDU_len;
+ unsigned char min_MPDU_spacing;
+ struct registry_priv *pregpriv = &padapter->registrypriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ DBG_871X("%s\n", __FUNCTION__);
+
+
+ //handle A-MPDU parameter field
+ /*
+ AMPDU_para [1:0]:Max AMPDU Len => 0:8k , 1:16k, 2:32k, 3:64k
+ AMPDU_para [4:2]:Min MPDU Start Spacing
+ */
+ max_AMPDU_len = pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x03;
+
+ min_MPDU_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & 0x1c) >> 2;
+
+ rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_MIN_SPACE, (u8 *)(&min_MPDU_spacing));
+
+ rtw_hal_set_hwreg(padapter, HW_VAR_AMPDU_FACTOR, (u8 *)(&max_AMPDU_len));
+
+ //
+ // Config SM Power Save setting
+ //
+ pmlmeinfo->SM_PS = (pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info & 0x0C) >> 2;
+ if(pmlmeinfo->SM_PS == WLAN_HT_CAP_SM_PS_STATIC)
+ {
+ /*u8 i;
+ //update the MCS rates
+ for (i = 0; i < 16; i++)
+ {
+ pmlmeinfo->HT_caps.HT_cap_element.MCS_rate[i] &= MCS_rate_1R[i];
+ }*/
+ DBG_871X("%s(): WLAN_HT_CAP_SM_PS_STATIC\n",__FUNCTION__);
+ }
+
+ //
+ // Config current HT Protection mode.
+ //
+ //pmlmeinfo->HT_protection = pmlmeinfo->HT_info.infos[1] & 0x3;
+
+}
+
+static void start_bss_network(_adapter *padapter, u8 *pbuf)
+{
+ u8 *p;
+ u8 val8, cur_channel, cur_bwmode, cur_ch_offset;
+ u16 bcn_interval;
+ u32 acparm;
+ int ie_len;
+ struct registry_priv *pregpriv = &padapter->registrypriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct security_priv* psecuritypriv=&(padapter->securitypriv);
+ WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ WLAN_BSSID_EX *pnetwork_mlmeext = &(pmlmeinfo->network);
+ struct HT_info_element *pht_info=NULL;
+#ifdef CONFIG_P2P
+ struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
+#endif //CONFIG_P2P
+
+ //DBG_871X("%s\n", __FUNCTION__);
+
+ bcn_interval = (u16)pnetwork->Configuration.BeaconPeriod;
+ cur_channel = pnetwork->Configuration.DSConfig;
+ cur_bwmode = HT_CHANNEL_WIDTH_20;;
+ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+
+
+ //check if there is wps ie,
+ //if there is wpsie in beacon, the hostapd will update beacon twice when stating hostapd,
+ //and at first time the security ie ( RSN/WPA IE) will not include in beacon.
+ if(NULL == rtw_get_wps_ie(pnetwork->IEs+_FIXED_IE_LENGTH_, pnetwork->IELength-_FIXED_IE_LENGTH_, NULL, NULL))
+ {
+ pmlmeext->bstart_bss = _TRUE;
+ }
+
+ //todo: update wmm, ht cap
+ //pmlmeinfo->WMM_enable;
+ //pmlmeinfo->HT_enable;
+ if(pmlmepriv->qospriv.qos_option)
+ pmlmeinfo->WMM_enable = _TRUE;
+#ifdef CONFIG_80211N_HT
+ if(pmlmepriv->htpriv.ht_option)
+ {
+ pmlmeinfo->WMM_enable = _TRUE;
+ pmlmeinfo->HT_enable = _TRUE;
+ //pmlmeinfo->HT_info_enable = _TRUE;
+ //pmlmeinfo->HT_caps_enable = _TRUE;
+
+ update_hw_ht_param(padapter);
+ }
+#endif //#CONFIG_80211N_HT
+
+
+ if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at first time
+ {
+ //WEP Key will be set before this function, do not clear CAM.
+ if ((psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) && (psecuritypriv->dot11PrivacyAlgrthm != _WEP104_))
+ flush_all_cam_entry(padapter); //clear CAM
+ }
+
+ //set MSR to AP_Mode
+ Set_MSR(padapter, _HW_STATE_AP_);
+
+ //Set BSSID REG
+ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->MacAddress);
+
+ //Set EDCA param reg
+#ifdef CONFIG_CONCURRENT_MODE
+ acparm = 0x005ea42b;
+#else
+ acparm = 0x002F3217; // VO
+#endif
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
+ acparm = 0x005E4317; // VI
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
+ //acparm = 0x00105320; // BE
+ acparm = 0x005ea42b;
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
+ acparm = 0x0000A444; // BK
+ rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
+
+ //Set Security
+ val8 = (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
+ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
+
+ //Beacon Control related register
+ rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&bcn_interval));
+
+
+ UpdateBrateTbl(padapter, pnetwork->SupportedRates);
+ rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
+
+ if(pmlmepriv->cur_network.join_res != _TRUE) //setting only at first time
+ {
+ //u32 initialgain;
+
+ //initialgain = 0x1e;
+
+
+ //disable dynamic functions, such as high power, DIG
+ //Save_DM_Func_Flag(padapter);
+ //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
+
+#ifdef CONFIG_CONCURRENT_MODE
+ if(padapter->adapter_type > PRIMARY_ADAPTER)
+ {
+ if(rtw_buddy_adapter_up(padapter))
+ {
+ _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
+
+ //turn on all dynamic functions on PRIMARY_ADAPTER, dynamic functions only runs at PRIMARY_ADAPTER
+ Switch_DM_Func(pbuddy_adapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
+
+ //rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
+ }
+ }
+ else
+#endif
+ {
+ //turn on all dynamic functions
+ Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
+
+ //rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
+ }
+
+ }
+#ifdef CONFIG_80211N_HT
+ //set channel, bwmode
+ p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
+ if( p && ie_len)
+ {
+ pht_info = (struct HT_info_element *)(p+2);
+
+ if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2)))
+ {
+ //switch to the 40M Hz mode
+ //pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
+ cur_bwmode = HT_CHANNEL_WIDTH_40;
+ switch (pht_info->infos[0] & 0x3)
+ {
+ case 1:
+ //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
+ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
+ break;
+
+ case 3:
+ //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
+ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
+ break;
+
+ default:
+ //pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+ break;
+ }
+
+ }
+
+ }
+#endif //CONFIG_80211N_HT
+#ifdef CONFIG_DUALMAC_CONCURRENT
+ dc_set_ap_channel_bandwidth(padapter, cur_channel, cur_ch_offset, cur_bwmode);
+#else
+ //TODO: need to judge the phy parameters on concurrent mode for single phy
+ //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
+#ifdef CONFIG_CONCURRENT_MODE
+ if(!check_buddy_fwstate(padapter, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY))
+ {
+ set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
+ }
+ else if(check_buddy_fwstate(padapter, _FW_LINKED)==_TRUE)//only second adapter can enter AP Mode
+ {
+ _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
+ struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
+
+ //To sync cur_channel/cur_bwmode/cur_ch_offset with primary adapter
+ DBG_871X("primary iface is at linked state, sync cur_channel/cur_bwmode/cur_ch_offset\n");
+ DBG_871X("primary adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
+ DBG_871X("second adapter, CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
+
+ cur_channel = pbuddy_mlmeext->cur_channel;
+ if(cur_bwmode == HT_CHANNEL_WIDTH_40)
+ {
+ if(pht_info)
+ pht_info->infos[0] &= ~(BIT(0)|BIT(1));
+
+ if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
+ {
+ cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
+
+ //to update cur_ch_offset value in beacon
+ if(pht_info)
+ {
+ switch(cur_ch_offset)
+ {
+ case HAL_PRIME_CHNL_OFFSET_LOWER:
+ pht_info->infos[0] |= 0x1;
+ break;
+ case HAL_PRIME_CHNL_OFFSET_UPPER:
+ pht_info->infos[0] |= 0x3;
+ break;
+ case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
+ default:
+ break;
+ }
+ }
+
+ }
+ else if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20)
+ {
+ cur_bwmode = HT_CHANNEL_WIDTH_20;
+ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+
+ if(cur_channel>0 && cur_channel<5)
+ {
+ if(pht_info)
+ pht_info->infos[0] |= 0x1;
+
+ cur_bwmode = HT_CHANNEL_WIDTH_40;
+ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
+ }
+
+ if(cur_channel>7 && cur_channel<(14+1))
+ {
+ if(pht_info)
+ pht_info->infos[0] |= 0x3;
+
+ cur_bwmode = HT_CHANNEL_WIDTH_40;
+ cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
+ }
+
+ set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
+ }
+
+ }
+
+ // to update channel value in beacon
+ pnetwork->Configuration.DSConfig = cur_channel;
+ p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
+ if(p && ie_len>0)
+ *(p + 2) = cur_channel;
+
+ if(pht_info)
+ pht_info->primary_channel = cur_channel;
+ }
+#else
+ set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
+#endif //CONFIG_CONCURRENT_MODE
+
+ DBG_871X("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
+
+ //
+ pmlmeext->cur_channel = cur_channel;
+ pmlmeext->cur_bwmode = cur_bwmode;
+ pmlmeext->cur_ch_offset = cur_ch_offset;
+#endif //CONFIG_DUALMAC_CONCURRENT
+ pmlmeext->cur_wireless_mode = pmlmepriv->cur_network.network_type;
+
+ //update cur_wireless_mode
+ update_wireless_mode(padapter);
+
+ //udpate capability after cur_wireless_mode updated
+ update_capinfo(padapter, rtw_get_capability((WLAN_BSSID_EX *)pnetwork));
+
+ //let pnetwork_mlmeext == pnetwork_mlme.
+ _rtw_memcpy(pnetwork_mlmeext, pnetwork, pnetwork->Length);
+
+#ifdef CONFIG_P2P
+ _rtw_memcpy(pwdinfo->p2p_group_ssid, pnetwork->Ssid.Ssid, pnetwork->Ssid.SsidLength);
+ pwdinfo->p2p_group_ssid_len = pnetwork->Ssid.SsidLength;
+#endif //CONFIG_P2P
+
+ if(_TRUE == pmlmeext->bstart_bss)
+ {
+ update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
+
+#ifndef CONFIG_INTERRUPT_BASED_TXBCN //other case will tx beacon when bcn interrupt coming in.
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+ //issue beacon frame
+ if(send_beacon(padapter)==_FAIL)
+ {
+ DBG_871X("issue_beacon, fail!\n");
+ }
+#endif
+#endif //!CONFIG_INTERRUPT_BASED_TXBCN
+
+ }
+
+
+ //update bc/mc sta_info
+ update_bmc_sta(padapter);
+
+ //pmlmeext->bstart_bss = _TRUE;
+
+}
+
+int rtw_check_beacon_data(_adapter *padapter, u8 *pbuf, int len)
+{
+ int ret=_SUCCESS;
+ u8 *p;
+ u8 *pHT_caps_ie=NULL;
+ u8 *pHT_info_ie=NULL;
+ struct sta_info *psta = NULL;
+ u16 cap, ht_cap=_FALSE;
+ uint ie_len = 0;
+ int group_cipher, pairwise_cipher;
+ u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX];
+ int supportRateNum = 0;
+ u8 OUI1[] = {0x00, 0x50, 0xf2,0x01};
+ u8 wps_oui[4]={0x0,0x50,0xf2,0x04};
+ u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ WLAN_BSSID_EX *pbss_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ u8 *ie = pbss_network->IEs;
+
+
+ /* SSID */
+ /* Supported rates */
+ /* DS Params */
+ /* WLAN_EID_COUNTRY */
+ /* ERP Information element */
+ /* Extended supported rates */
+ /* WPA/WPA2 */
+ /* Wi-Fi Wireless Multimedia Extensions */
+ /* ht_capab, ht_oper */
+ /* WPS IE */
+
+ DBG_871X("%s, len=%d\n", __FUNCTION__, len);
+
+ if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
+ return _FAIL;
+
+
+ if(len>MAX_IE_SZ)
+ return _FAIL;
+
+ pbss_network->IELength = len;
+
+ _rtw_memset(ie, 0, MAX_IE_SZ);
+
+ _rtw_memcpy(ie, pbuf, pbss_network->IELength);
+
+
+ if(pbss_network->InfrastructureMode!=Ndis802_11APMode)
+ return _FAIL;
+
+ pbss_network->Rssi = 0;
+
+ _rtw_memcpy(pbss_network->MacAddress, myid(&(padapter->eeprompriv)), ETH_ALEN);
+
+ //beacon interval
+ p = rtw_get_beacon_interval_from_ie(ie);//ie + 8; // 8: TimeStamp, 2: Beacon Interval 2:Capability
+ //pbss_network->Configuration.BeaconPeriod = le16_to_cpu(*(unsigned short*)p);
+ pbss_network->Configuration.BeaconPeriod = RTW_GET_LE16(p);
+
+ //capability
+ //cap = *(unsigned short *)rtw_get_capability_from_ie(ie);
+ //cap = le16_to_cpu(cap);
+ cap = RTW_GET_LE16(ie);
+
+ //SSID
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SSID_IE_, &ie_len, (pbss_network->IELength -_BEACON_IE_OFFSET_));
+ if(p && ie_len>0)
+ {
+ _rtw_memset(&pbss_network->Ssid, 0, sizeof(NDIS_802_11_SSID));
+ _rtw_memcpy(pbss_network->Ssid.Ssid, (p + 2), ie_len);
+ pbss_network->Ssid.SsidLength = ie_len;
+ }
+
+ //chnnel
+ channel = 0;
+ pbss_network->Configuration.Length = 0;
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _DSSET_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ if(p && ie_len>0)
+ channel = *(p + 2);
+
+ pbss_network->Configuration.DSConfig = channel;
+
+
+ _rtw_memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX);
+ // get supported rates
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _SUPPORTEDRATES_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ if (p != NULL)
+ {
+ _rtw_memcpy(supportRate, p+2, ie_len);
+ supportRateNum = ie_len;
+ }
+
+ //get ext_supported rates
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ie_len, pbss_network->IELength - _BEACON_IE_OFFSET_);
+ if (p != NULL)
+ {
+ _rtw_memcpy(supportRate+supportRateNum, p+2, ie_len);
+ supportRateNum += ie_len;
+
+ }
+
+ network_type = rtw_check_network_type(supportRate, supportRateNum, channel);
+
+ rtw_set_supported_rate(pbss_network->SupportedRates, network_type);
+
+
+ //parsing ERP_IE
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ if(p && ie_len>0)
+ {
+ ERP_IE_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)p);
+ }
+
+ //update privacy/security
+ if (cap & BIT(4))
+ pbss_network->Privacy = 1;
+ else
+ pbss_network->Privacy = 0;
+
+ psecuritypriv->wpa_psk = 0;
+
+ //wpa2
+ group_cipher = 0; pairwise_cipher = 0;
+ psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
+ psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ if(p && ie_len>0)
+ {
+ if(rtw_parse_wpa2_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
+ {
+ psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
+
+ psecuritypriv->dot8021xalg = 1;//psk, todo:802.1x
+ psecuritypriv->wpa_psk |= BIT(1);
+
+ psecuritypriv->wpa2_group_cipher = group_cipher;
+ psecuritypriv->wpa2_pairwise_cipher = pairwise_cipher;
+#if 0
+ switch(group_cipher)
+ {
+ case WPA_CIPHER_NONE:
+ psecuritypriv->wpa2_group_cipher = _NO_PRIVACY_;
+ break;
+ case WPA_CIPHER_WEP40:
+ psecuritypriv->wpa2_group_cipher = _WEP40_;
+ break;
+ case WPA_CIPHER_TKIP:
+ psecuritypriv->wpa2_group_cipher = _TKIP_;
+ break;
+ case WPA_CIPHER_CCMP:
+ psecuritypriv->wpa2_group_cipher = _AES_;
+ break;
+ case WPA_CIPHER_WEP104:
+ psecuritypriv->wpa2_group_cipher = _WEP104_;
+ break;
+ }
+
+ switch(pairwise_cipher)
+ {
+ case WPA_CIPHER_NONE:
+ psecuritypriv->wpa2_pairwise_cipher = _NO_PRIVACY_;
+ break;
+ case WPA_CIPHER_WEP40:
+ psecuritypriv->wpa2_pairwise_cipher = _WEP40_;
+ break;
+ case WPA_CIPHER_TKIP:
+ psecuritypriv->wpa2_pairwise_cipher = _TKIP_;
+ break;
+ case WPA_CIPHER_CCMP:
+ psecuritypriv->wpa2_pairwise_cipher = _AES_;
+ break;
+ case WPA_CIPHER_WEP104:
+ psecuritypriv->wpa2_pairwise_cipher = _WEP104_;
+ break;
+ }
+#endif
+ }
+
+ }
+
+ //wpa
+ ie_len = 0;
+ group_cipher = 0; pairwise_cipher = 0;
+ psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
+ psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
+ for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))
+ {
+ p = rtw_get_ie(p, _SSN_IE_1_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
+ if ((p) && (_rtw_memcmp(p+2, OUI1, 4)))
+ {
+ if(rtw_parse_wpa_ie(p, ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
+ {
+ psecuritypriv->dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
+
+ psecuritypriv->dot8021xalg = 1;//psk, todo:802.1x
+
+ psecuritypriv->wpa_psk |= BIT(0);
+
+ psecuritypriv->wpa_group_cipher = group_cipher;
+ psecuritypriv->wpa_pairwise_cipher = pairwise_cipher;
+
+#if 0
+ switch(group_cipher)
+ {
+ case WPA_CIPHER_NONE:
+ psecuritypriv->wpa_group_cipher = _NO_PRIVACY_;
+ break;
+ case WPA_CIPHER_WEP40:
+ psecuritypriv->wpa_group_cipher = _WEP40_;
+ break;
+ case WPA_CIPHER_TKIP:
+ psecuritypriv->wpa_group_cipher = _TKIP_;
+ break;
+ case WPA_CIPHER_CCMP:
+ psecuritypriv->wpa_group_cipher = _AES_;
+ break;
+ case WPA_CIPHER_WEP104:
+ psecuritypriv->wpa_group_cipher = _WEP104_;
+ break;
+ }
+
+ switch(pairwise_cipher)
+ {
+ case WPA_CIPHER_NONE:
+ psecuritypriv->wpa_pairwise_cipher = _NO_PRIVACY_;
+ break;
+ case WPA_CIPHER_WEP40:
+ psecuritypriv->wpa_pairwise_cipher = _WEP40_;
+ break;
+ case WPA_CIPHER_TKIP:
+ psecuritypriv->wpa_pairwise_cipher = _TKIP_;
+ break;
+ case WPA_CIPHER_CCMP:
+ psecuritypriv->wpa_pairwise_cipher = _AES_;
+ break;
+ case WPA_CIPHER_WEP104:
+ psecuritypriv->wpa_pairwise_cipher = _WEP104_;
+ break;
+ }
+#endif
+ }
+
+ break;
+
+ }
+
+ if ((p == NULL) || (ie_len == 0))
+ {
+ break;
+ }
+
+ }
+
+ //wmm
+ ie_len = 0;
+ pmlmepriv->qospriv.qos_option = 0;
+ if(pregistrypriv->wmm_enable)
+ {
+ for (p = ie + _BEACON_IE_OFFSET_; ;p += (ie_len + 2))
+ {
+ p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
+ if((p) && _rtw_memcmp(p+2, WMM_PARA_IE, 6))
+ {
+ pmlmepriv->qospriv.qos_option = 1;
+
+ *(p+8) |= BIT(7);//QoS Info, support U-APSD
+
+ /* disable all ACM bits since the WMM admission control is not supported */
+ *(p + 10) &= ~BIT(4); /* BE */
+ *(p + 14) &= ~BIT(4); /* BK */
+ *(p + 18) &= ~BIT(4); /* VI */
+ *(p + 22) &= ~BIT(4); /* VO */
+
+ break;
+ }
+
+ if ((p == NULL) || (ie_len == 0))
+ {
+ break;
+ }
+ }
+ }
+#ifdef CONFIG_80211N_HT
+ //parsing HT_CAP_IE
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ if(p && ie_len>0)
+ {
+ u8 rf_type;
+
+ struct rtw_ieee80211_ht_cap *pht_cap = (struct rtw_ieee80211_ht_cap *)(p+2);
+
+ pHT_caps_ie=p;
+
+
+ ht_cap = _TRUE;
+ network_type |= WIRELESS_11_24N;
+
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+
+ if((psecuritypriv->wpa_pairwise_cipher & WPA_CIPHER_CCMP) ||
+ (psecuritypriv->wpa2_pairwise_cipher & WPA_CIPHER_CCMP))
+ {
+ pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2));
+ }
+ else
+ {
+ pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00);
+ }
+
+ pht_cap->ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_FACTOR & 0x03); //set Max Rx AMPDU size to 64K
+
+ if(rf_type == RF_1T1R)
+ {
+ pht_cap->supp_mcs_set[0] = 0xff;
+ pht_cap->supp_mcs_set[1] = 0x0;
+ }
+
+ _rtw_memcpy(&pmlmepriv->htpriv.ht_cap, p+2, ie_len);
+
+ }
+
+ //parsing HT_INFO_IE
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pbss_network->IELength - _BEACON_IE_OFFSET_));
+ if(p && ie_len>0)
+ {
+ pHT_info_ie=p;
+ }
+#endif //CONFIG_80211N_HT
+ switch(network_type)
+ {
+ case WIRELESS_11B:
+ pbss_network->NetworkTypeInUse = Ndis802_11DS;
+ break;
+ case WIRELESS_11G:
+ case WIRELESS_11BG:
+ case WIRELESS_11G_24N:
+ case WIRELESS_11BG_24N:
+ pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
+ break;
+ case WIRELESS_11A:
+ pbss_network->NetworkTypeInUse = Ndis802_11OFDM5;
+ break;
+ default :
+ pbss_network->NetworkTypeInUse = Ndis802_11OFDM24;
+ break;
+ }
+
+ pmlmepriv->cur_network.network_type = network_type;
+
+#ifdef CONFIG_80211N_HT
+ pmlmepriv->htpriv.ht_option = _FALSE;
+
+ if( (psecuritypriv->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
+ (psecuritypriv->wpa_pairwise_cipher&WPA_CIPHER_TKIP))
+ {
+ //todo:
+ //ht_cap = _FALSE;
+ }
+
+ //ht_cap
+ if(pregistrypriv->ht_enable && ht_cap==_TRUE)
+ {
+ pmlmepriv->htpriv.ht_option = _TRUE;
+ pmlmepriv->qospriv.qos_option = 1;
+
+ if(pregistrypriv->ampdu_enable==1)
+ {
+ pmlmepriv->htpriv.ampdu_enable = _TRUE;
+ }
+
+ HT_caps_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_caps_ie);
+
+ HT_info_handler(padapter, (PNDIS_802_11_VARIABLE_IEs)pHT_info_ie);
+ }
+#endif
+
+
+ pbss_network->Length = get_WLAN_BSSID_EX_sz((WLAN_BSSID_EX *)pbss_network);
+
+ //issue beacon to start bss network
+ start_bss_network(padapter, (u8*)pbss_network);
+
+
+ //alloc sta_info for ap itself
+ psta = rtw_get_stainfo(&padapter->stapriv, pbss_network->MacAddress);
+ if(!psta)
+ {
+ psta = rtw_alloc_stainfo(&padapter->stapriv, pbss_network->MacAddress);
+ if (psta == NULL)
+ {
+ return _FAIL;
+ }
+ }
+ psta->state |= WIFI_AP_STATE; //Aries, add,fix bug of flush_cam_entry at STOP AP mode , 0724
+ rtw_indicate_connect( padapter);
+
+ pmlmepriv->cur_network.join_res = _TRUE;//for check if already set beacon
+
+ //update bc/mc sta_info
+ //update_bmc_sta(padapter);
+
+ return ret;
+
+}
+
+void rtw_set_macaddr_acl(_adapter *padapter, int mode)
+{
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
+
+ DBG_871X("%s, mode=%d\n", __func__, mode);
+
+ pacl_list->mode = mode;
+}
+
+int rtw_acl_add_sta(_adapter *padapter, u8 *addr)
+{
+ _irqL irqL;
+ _list *plist, *phead;
+ u8 added = _FALSE;
+ int i, ret=0;
+ struct rtw_wlan_acl_node *paclnode;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
+ _queue *pacl_node_q =&pacl_list->acl_node_q;
+
+ DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));
+
+ if((NUM_ACL-1) < pacl_list->num)
+ return (-1);
+
+
+ _enter_critical_bh(&(pacl_node_q->lock), &irqL);
+
+ phead = get_list_head(pacl_node_q);
+ plist = get_next(phead);
+
+ while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
+ {
+ paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
+ plist = get_next(plist);
+
+ if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN))
+ {
+ if(paclnode->valid == _TRUE)
+ {
+ added = _TRUE;
+ DBG_871X("%s, sta has been added\n", __func__);
+ break;
+ }
+ }
+ }
+
+ _exit_critical_bh(&(pacl_node_q->lock), &irqL);
+
+
+ if(added == _TRUE)
+ return ret;
+
+
+ _enter_critical_bh(&(pacl_node_q->lock), &irqL);
+
+ for(i=0; i< NUM_ACL; i++)
+ {
+ paclnode = &pacl_list->aclnode[i];
+
+ if(paclnode->valid == _FALSE)
+ {
+ _rtw_init_listhead(&paclnode->list);
+
+ _rtw_memcpy(paclnode->addr, addr, ETH_ALEN);
+
+ paclnode->valid = _TRUE;
+
+ rtw_list_insert_tail(&paclnode->list, get_list_head(pacl_node_q));
+
+ pacl_list->num++;
+
+ break;
+ }
+ }
+
+ DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num);
+
+ _exit_critical_bh(&(pacl_node_q->lock), &irqL);
+
+ return ret;
+}
+
+int rtw_acl_remove_sta(_adapter *padapter, u8 *addr)
+{
+ _irqL irqL;
+ _list *plist, *phead;
+ int i, ret=0;
+ struct rtw_wlan_acl_node *paclnode;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
+ _queue *pacl_node_q =&pacl_list->acl_node_q;
+
+ DBG_871X("%s(acl_num=%d)=" MAC_FMT "\n", __func__, pacl_list->num, MAC_ARG(addr));
+
+ _enter_critical_bh(&(pacl_node_q->lock), &irqL);
+
+ phead = get_list_head(pacl_node_q);
+ plist = get_next(phead);
+
+ while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
+ {
+ paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
+ plist = get_next(plist);
+
+ if(_rtw_memcmp(paclnode->addr, addr, ETH_ALEN))
+ {
+ if(paclnode->valid == _TRUE)
+ {
+ paclnode->valid = _FALSE;
+
+ rtw_list_delete(&paclnode->list);
+
+ pacl_list->num--;
+ }
+ }
+ }
+
+ _exit_critical_bh(&(pacl_node_q->lock), &irqL);
+
+ DBG_871X("%s, acl_num=%d\n", __func__, pacl_list->num);
+
+ return ret;
+
+}
+
+#ifdef CONFIG_NATIVEAP_MLME
+
+static void update_bcn_fixed_ie(_adapter *padapter)
+{
+ DBG_871X("%s\n", __FUNCTION__);
+
+}
+
+static void update_bcn_erpinfo_ie(_adapter *padapter)
+{
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
+ unsigned char *p, *ie = pnetwork->IEs;
+ u32 len = 0;
+
+ DBG_871X("%s, ERP_enable=%d\n", __FUNCTION__, pmlmeinfo->ERP_enable);
+
+ if(!pmlmeinfo->ERP_enable)
+ return;
+
+ //parsing ERP_IE
+ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _ERPINFO_IE_, &len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
+ if(p && len>0)
+ {
+ PNDIS_802_11_VARIABLE_IEs pIE = (PNDIS_802_11_VARIABLE_IEs)p;
+
+ if (pmlmepriv->num_sta_non_erp == 1)
+ pIE->data[0] |= RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION;
+ else
+ pIE->data[0] &= ~(RTW_ERP_INFO_NON_ERP_PRESENT|RTW_ERP_INFO_USE_PROTECTION);
+
+ if(pmlmepriv->num_sta_no_short_preamble > 0)
+ pIE->data[0] |= RTW_ERP_INFO_BARKER_PREAMBLE_MODE;
+ else
+ pIE->data[0] &= ~(RTW_ERP_INFO_BARKER_PREAMBLE_MODE);
+
+ ERP_IE_handler(padapter, pIE);
+ }
+
+}
+
+static void update_bcn_htcap_ie(_adapter *padapter)
+{
+ DBG_871X("%s\n", __FUNCTION__);
+
+}
+
+static void update_bcn_htinfo_ie(_adapter *padapter)
+{
+ DBG_871X("%s\n", __FUNCTION__);
+
+}
+
+static void update_bcn_rsn_ie(_adapter *padapter)
+{
+ DBG_871X("%s\n", __FUNCTION__);
+
+}
+
+static void update_bcn_wpa_ie(_adapter *padapter)
+{
+ DBG_871X("%s\n", __FUNCTION__);
+
+}
+
+static void update_bcn_wmm_ie(_adapter *padapter)
+{
+ DBG_871X("%s\n", __FUNCTION__);
+
+}
+
+static void update_bcn_wps_ie(_adapter *padapter)
+{
+ u8 *pwps_ie=NULL, *pwps_ie_src, *premainder_ie, *pbackup_remainder_ie=NULL;
+ uint wps_ielen=0, wps_offset, remainder_ielen;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
+ unsigned char *ie = pnetwork->IEs;
+ u32 ielen = pnetwork->IELength;
+
+
+ DBG_871X("%s\n", __FUNCTION__);
+
+ pwps_ie = rtw_get_wps_ie(ie+_FIXED_IE_LENGTH_, ielen-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
+
+ if(pwps_ie==NULL || wps_ielen==0)
+ return;
+
+ wps_offset = (uint)(pwps_ie-ie);
+
+ premainder_ie = pwps_ie + wps_ielen;
+
+ remainder_ielen = ielen - wps_offset - wps_ielen;
+
+ if(remainder_ielen>0)
+ {
+ pbackup_remainder_ie = rtw_malloc(remainder_ielen);
+ if(pbackup_remainder_ie)
+ _rtw_memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen);
+ }
+
+
+ pwps_ie_src = pmlmepriv->wps_beacon_ie;
+ if(pwps_ie_src == NULL)
+ return;
+
+
+ wps_ielen = (uint)pwps_ie_src[1];//to get ie data len
+ if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
+ {
+ _rtw_memcpy(pwps_ie, pwps_ie_src, wps_ielen+2);
+ pwps_ie += (wps_ielen+2);
+
+ if(pbackup_remainder_ie)
+ _rtw_memcpy(pwps_ie, pbackup_remainder_ie, remainder_ielen);
+
+ //update IELength
+ pnetwork->IELength = wps_offset + (wps_ielen+2) + remainder_ielen;
+ }
+
+ if(pbackup_remainder_ie)
+ rtw_mfree(pbackup_remainder_ie, remainder_ielen);
+
+}
+
+static void update_bcn_p2p_ie(_adapter *padapter)
+{
+
+}
+
+static void update_bcn_vendor_spec_ie(_adapter *padapter, u8*oui)
+{
+ DBG_871X("%s\n", __FUNCTION__);
+
+ if(_rtw_memcmp(RTW_WPA_OUI, oui, 4))
+ {
+ update_bcn_wpa_ie(padapter);
+ }
+ else if(_rtw_memcmp(WMM_OUI, oui, 4))
+ {
+ update_bcn_wmm_ie(padapter);
+ }
+ else if(_rtw_memcmp(WPS_OUI, oui, 4))
+ {
+ update_bcn_wps_ie(padapter);
+ }
+ else if(_rtw_memcmp(P2P_OUI, oui, 4))
+ {
+ update_bcn_p2p_ie(padapter);
+ }
+ else
+ {
+ DBG_871X("unknown OUI type!\n");
+ }
+
+
+}
+
+void update_beacon(_adapter *padapter, u8 ie_id, u8 *oui, u8 tx)
+{
+ _irqL irqL;
+ struct mlme_priv *pmlmepriv;
+ struct mlme_ext_priv *pmlmeext;
+ //struct mlme_ext_info *pmlmeinfo;
+
+ //DBG_871X("%s\n", __FUNCTION__);
+
+ if(!padapter)
+ return;
+
+ pmlmepriv = &(padapter->mlmepriv);
+ pmlmeext = &(padapter->mlmeextpriv);
+ //pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ if(_FALSE == pmlmeext->bstart_bss)
+ return;
+
+ _enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
+
+ switch(ie_id)
+ {
+ case 0xFF:
+
+ update_bcn_fixed_ie(padapter);//8: TimeStamp, 2: Beacon Interval 2:Capability
+
+ break;
+
+ case _TIM_IE_:
+
+ update_BCNTIM(padapter);
+
+ break;
+
+ case _ERPINFO_IE_:
+
+ update_bcn_erpinfo_ie(padapter);
+
+ break;
+
+ case _HT_CAPABILITY_IE_:
+
+ update_bcn_htcap_ie(padapter);
+
+ break;
+
+ case _RSN_IE_2_:
+
+ update_bcn_rsn_ie(padapter);
+
+ break;
+
+ case _HT_ADD_INFO_IE_:
+
+ update_bcn_htinfo_ie(padapter);
+
+ break;
+
+ case _VENDOR_SPECIFIC_IE_:
+
+ update_bcn_vendor_spec_ie(padapter, oui);
+
+ break;
+
+ default:
+ break;
+ }
+
+ pmlmepriv->update_bcn = _TRUE;
+
+ _exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
+
+#ifndef CONFIG_INTERRUPT_BASED_TXBCN
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+ if(tx)
+ {
+ //send_beacon(padapter);//send_beacon must execute on TSR level
+ set_tx_beacon_cmd(padapter);
+ }
+#else
+ {
+ //PCI will issue beacon when BCN interrupt occurs.
+ }
+#endif
+#endif //!CONFIG_INTERRUPT_BASED_TXBCN
+
+}
+
+#ifdef CONFIG_80211N_HT
+
+/*
+op_mode
+Set to 0 (HT pure) under the followign conditions
+ - all STAs in the BSS are 20/40 MHz HT in 20/40 MHz BSS or
+ - all STAs in the BSS are 20 MHz HT in 20 MHz BSS
+Set to 1 (HT non-member protection) if there may be non-HT STAs
+ in both the primary and the secondary channel
+Set to 2 if only HT STAs are associated in BSS,
+ however and at least one 20 MHz HT STA is associated
+Set to 3 (HT mixed mode) when one or more non-HT STAs are associated
+ (currently non-GF HT station is considered as non-HT STA also)
+*/
+static int rtw_ht_operation_update(_adapter *padapter)
+{
+ u16 cur_op_mode, new_op_mode;
+ int op_mode_changes = 0;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct ht_priv *phtpriv_ap = &pmlmepriv->htpriv;
+
+ if(pmlmepriv->htpriv.ht_option == _TRUE)
+ return 0;
+
+ //if (!iface->conf->ieee80211n || iface->conf->ht_op_mode_fixed)
+ // return 0;
+
+ DBG_871X("%s current operation mode=0x%X\n",
+ __FUNCTION__, pmlmepriv->ht_op_mode);
+
+ if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT)
+ && pmlmepriv->num_sta_ht_no_gf) {
+ pmlmepriv->ht_op_mode |=
+ HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
+ op_mode_changes++;
+ } else if ((pmlmepriv->ht_op_mode &
+ HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT) &&
+ pmlmepriv->num_sta_ht_no_gf == 0) {
+ pmlmepriv->ht_op_mode &=
+ ~HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT;
+ op_mode_changes++;
+ }
+
+ if (!(pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
+ (pmlmepriv->num_sta_no_ht || pmlmepriv->olbc_ht)) {
+ pmlmepriv->ht_op_mode |= HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
+ op_mode_changes++;
+ } else if ((pmlmepriv->ht_op_mode &
+ HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT) &&
+ (pmlmepriv->num_sta_no_ht == 0 && !pmlmepriv->olbc_ht)) {
+ pmlmepriv->ht_op_mode &=
+ ~HT_INFO_OPERATION_MODE_NON_HT_STA_PRESENT;
+ op_mode_changes++;
+ }
+
+ /* Note: currently we switch to the MIXED op mode if HT non-greenfield
+ * station is associated. Probably it's a theoretical case, since
+ * it looks like all known HT STAs support greenfield.
+ */
+ new_op_mode = 0;
+ if (pmlmepriv->num_sta_no_ht ||
+ (pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_NON_GF_DEVS_PRESENT))
+ new_op_mode = OP_MODE_MIXED;
+ else if ((phtpriv_ap->ht_cap.cap_info & IEEE80211_HT_CAP_SUP_WIDTH)
+ && pmlmepriv->num_sta_ht_20mhz)
+ new_op_mode = OP_MODE_20MHZ_HT_STA_ASSOCED;
+ else if (pmlmepriv->olbc_ht)
+ new_op_mode = OP_MODE_MAY_BE_LEGACY_STAS;
+ else
+ new_op_mode = OP_MODE_PURE;
+
+ cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
+ if (cur_op_mode != new_op_mode) {
+ pmlmepriv->ht_op_mode &= ~HT_INFO_OPERATION_MODE_OP_MODE_MASK;
+ pmlmepriv->ht_op_mode |= new_op_mode;
+ op_mode_changes++;
+ }
+
+ DBG_871X("%s new operation mode=0x%X changes=%d\n",
+ __FUNCTION__, pmlmepriv->ht_op_mode, op_mode_changes);
+
+ return op_mode_changes;
+
+}
+
+#endif /* CONFIG_80211N_HT */
+
+void associated_clients_update(_adapter *padapter, u8 updated)
+{
+ //update associcated stations cap.
+ if(updated == _TRUE)
+ {
+ _irqL irqL;
+ _list *phead, *plist;
+ struct sta_info *psta=NULL;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+
+ phead = &pstapriv->asoc_list;
+ plist = get_next(phead);
+
+ //check asoc_queue
+ while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
+ {
+ psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
+
+ plist = get_next(plist);
+
+ VCS_update(padapter, psta);
+ }
+
+ _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+
+ }
+
+}
+
+/* called > TSR LEVEL for USB or SDIO Interface*/
+void bss_cap_update_on_sta_join(_adapter *padapter, struct sta_info *psta)
+{
+ u8 beacon_updated = _FALSE;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+
+
+#if 0
+ if (!(psta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
+ !psta->no_short_preamble_set) {
+ psta->no_short_preamble_set = 1;
+ pmlmepriv->num_sta_no_short_preamble++;
+ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
+ (pmlmepriv->num_sta_no_short_preamble == 1))
+ ieee802_11_set_beacons(hapd->iface);
+ }
+#endif
+
+
+ if(!(psta->flags & WLAN_STA_SHORT_PREAMBLE))
+ {
+ if(!psta->no_short_preamble_set)
+ {
+ psta->no_short_preamble_set = 1;
+
+ pmlmepriv->num_sta_no_short_preamble++;
+
+ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
+ (pmlmepriv->num_sta_no_short_preamble == 1))
+ {
+ beacon_updated = _TRUE;
+ update_beacon(padapter, 0xFF, NULL, _TRUE);
+ }
+
+ }
+ }
+ else
+ {
+ if(psta->no_short_preamble_set)
+ {
+ psta->no_short_preamble_set = 0;
+
+ pmlmepriv->num_sta_no_short_preamble--;
+
+ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
+ (pmlmepriv->num_sta_no_short_preamble == 0))
+ {
+ beacon_updated = _TRUE;
+ update_beacon(padapter, 0xFF, NULL, _TRUE);
+ }
+
+ }
+ }
+
+#if 0
+ if (psta->flags & WLAN_STA_NONERP && !psta->nonerp_set) {
+ psta->nonerp_set = 1;
+ pmlmepriv->num_sta_non_erp++;
+ if (pmlmepriv->num_sta_non_erp == 1)
+ ieee802_11_set_beacons(hapd->iface);
+ }
+#endif
+
+ if(psta->flags & WLAN_STA_NONERP)
+ {
+ if(!psta->nonerp_set)
+ {
+ psta->nonerp_set = 1;
+
+ pmlmepriv->num_sta_non_erp++;
+
+ if (pmlmepriv->num_sta_non_erp == 1)
+ {
+ beacon_updated = _TRUE;
+ update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
+ }
+ }
+
+ }
+ else
+ {
+ if(psta->nonerp_set)
+ {
+ psta->nonerp_set = 0;
+
+ pmlmepriv->num_sta_non_erp--;
+
+ if (pmlmepriv->num_sta_non_erp == 0)
+ {
+ beacon_updated = _TRUE;
+ update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
+ }
+ }
+
+ }
+
+
+#if 0
+ if (!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT) &&
+ !psta->no_short_slot_time_set) {
+ psta->no_short_slot_time_set = 1;
+ pmlmepriv->num_sta_no_short_slot_time++;
+ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
+ (pmlmepriv->num_sta_no_short_slot_time == 1))
+ ieee802_11_set_beacons(hapd->iface);
+ }
+#endif
+
+ if(!(psta->capability & WLAN_CAPABILITY_SHORT_SLOT))
+ {
+ if(!psta->no_short_slot_time_set)
+ {
+ psta->no_short_slot_time_set = 1;
+
+ pmlmepriv->num_sta_no_short_slot_time++;
+
+ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
+ (pmlmepriv->num_sta_no_short_slot_time == 1))
+ {
+ beacon_updated = _TRUE;
+ update_beacon(padapter, 0xFF, NULL, _TRUE);
+ }
+
+ }
+ }
+ else
+ {
+ if(psta->no_short_slot_time_set)
+ {
+ psta->no_short_slot_time_set = 0;
+
+ pmlmepriv->num_sta_no_short_slot_time--;
+
+ if ((pmlmeext->cur_wireless_mode > WIRELESS_11B) &&
+ (pmlmepriv->num_sta_no_short_slot_time == 0))
+ {
+ beacon_updated = _TRUE;
+ update_beacon(padapter, 0xFF, NULL, _TRUE);
+ }
+ }
+ }
+
+#ifdef CONFIG_80211N_HT
+
+ if (psta->flags & WLAN_STA_HT)
+ {
+ u16 ht_capab = le16_to_cpu(psta->htpriv.ht_cap.cap_info);
+
+ DBG_871X("HT: STA " MAC_FMT " HT Capabilities "
+ "Info: 0x%04x\n", MAC_ARG(psta->hwaddr), ht_capab);
+
+ if (psta->no_ht_set) {
+ psta->no_ht_set = 0;
+ pmlmepriv->num_sta_no_ht--;
+ }
+
+ if ((ht_capab & IEEE80211_HT_CAP_GRN_FLD) == 0) {
+ if (!psta->no_ht_gf_set) {
+ psta->no_ht_gf_set = 1;
+ pmlmepriv->num_sta_ht_no_gf++;
+ }
+ DBG_871X("%s STA " MAC_FMT " - no "
+ "greenfield, num of non-gf stations %d\n",
+ __FUNCTION__, MAC_ARG(psta->hwaddr),
+ pmlmepriv->num_sta_ht_no_gf);
+ }
+
+ if ((ht_capab & IEEE80211_HT_CAP_SUP_WIDTH) == 0) {
+ if (!psta->ht_20mhz_set) {
+ psta->ht_20mhz_set = 1;
+ pmlmepriv->num_sta_ht_20mhz++;
+ }
+ DBG_871X("%s STA " MAC_FMT " - 20 MHz HT, "
+ "num of 20MHz HT STAs %d\n",
+ __FUNCTION__, MAC_ARG(psta->hwaddr),
+ pmlmepriv->num_sta_ht_20mhz);
+ }
+
+ }
+ else
+ {
+ if (!psta->no_ht_set) {
+ psta->no_ht_set = 1;
+ pmlmepriv->num_sta_no_ht++;
+ }
+ if(pmlmepriv->htpriv.ht_option == _TRUE) {
+ DBG_871X("%s STA " MAC_FMT
+ " - no HT, num of non-HT stations %d\n",
+ __FUNCTION__, MAC_ARG(psta->hwaddr),
+ pmlmepriv->num_sta_no_ht);
+ }
+ }
+
+ if (rtw_ht_operation_update(padapter) > 0)
+ {
+ update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);
+ update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);
+ }
+
+#endif /* CONFIG_80211N_HT */
+
+ //update associcated stations cap.
+ associated_clients_update(padapter, beacon_updated);
+
+ DBG_871X("%s, updated=%d\n", __func__, beacon_updated);
+
+}
+
+u8 bss_cap_update_on_sta_leave(_adapter *padapter, struct sta_info *psta)
+{
+ u8 beacon_updated = _FALSE;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+
+ if(!psta)
+ return beacon_updated;
+
+ if (psta->no_short_preamble_set) {
+ psta->no_short_preamble_set = 0;
+ pmlmepriv->num_sta_no_short_preamble--;
+ if (pmlmeext->cur_wireless_mode > WIRELESS_11B
+ && pmlmepriv->num_sta_no_short_preamble == 0)
+ {
+ beacon_updated = _TRUE;
+ update_beacon(padapter, 0xFF, NULL, _TRUE);
+ }
+ }
+
+ if (psta->nonerp_set) {
+ psta->nonerp_set = 0;
+ pmlmepriv->num_sta_non_erp--;
+ if (pmlmepriv->num_sta_non_erp == 0)
+ {
+ beacon_updated = _TRUE;
+ update_beacon(padapter, _ERPINFO_IE_, NULL, _TRUE);
+ }
+ }
+
+ if (psta->no_short_slot_time_set) {
+ psta->no_short_slot_time_set = 0;
+ pmlmepriv->num_sta_no_short_slot_time--;
+ if (pmlmeext->cur_wireless_mode > WIRELESS_11B
+ && pmlmepriv->num_sta_no_short_slot_time == 0)
+ {
+ beacon_updated = _TRUE;
+ update_beacon(padapter, 0xFF, NULL, _TRUE);
+ }
+ }
+
+#ifdef CONFIG_80211N_HT
+
+ if (psta->no_ht_gf_set) {
+ psta->no_ht_gf_set = 0;
+ pmlmepriv->num_sta_ht_no_gf--;
+ }
+
+ if (psta->no_ht_set) {
+ psta->no_ht_set = 0;
+ pmlmepriv->num_sta_no_ht--;
+ }
+
+ if (psta->ht_20mhz_set) {
+ psta->ht_20mhz_set = 0;
+ pmlmepriv->num_sta_ht_20mhz--;
+ }
+
+ if (rtw_ht_operation_update(padapter) > 0)
+ {
+ update_beacon(padapter, _HT_CAPABILITY_IE_, NULL, _FALSE);
+ update_beacon(padapter, _HT_ADD_INFO_IE_, NULL, _TRUE);
+ }
+
+#endif /* CONFIG_80211N_HT */
+
+ //update associcated stations cap.
+ //associated_clients_update(padapter, beacon_updated); //move it to avoid deadlock
+
+ DBG_871X("%s, updated=%d\n", __func__, beacon_updated);
+
+ return beacon_updated;
+
+}
+
+u8 ap_free_sta(_adapter *padapter, struct sta_info *psta, bool active, u16 reason)
+{
+ _irqL irqL;
+ u8 beacon_updated = _FALSE;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ if(!psta)
+ return beacon_updated;
+
+ if (active == _TRUE)
+ {
+#ifdef CONFIG_80211N_HT
+ //tear down Rx AMPDU
+ send_delba(padapter, 0, psta->hwaddr);// recipient
+
+ //tear down TX AMPDU
+ send_delba(padapter, 1, psta->hwaddr);// // originator
+
+#endif //CONFIG_80211N_HT
+
+ issue_deauth(padapter, psta->hwaddr, reason);
+ }
+
+ psta->htpriv.agg_enable_bitmap = 0x0;//reset
+ psta->htpriv.candidate_tid_bitmap = 0x0;//reset
+
+
+ //report_del_sta_event(padapter, psta->hwaddr, reason);
+
+ //clear cam entry / key
+ //clear_cam_entry(padapter, (psta->mac_id + 3));
+ rtw_clearstakey_cmd(padapter, (u8*)psta, (u8)(psta->mac_id + 3), _TRUE);
+
+
+ _enter_critical_bh(&psta->lock, &irqL);
+ psta->state &= ~_FW_LINKED;
+ _exit_critical_bh(&psta->lock, &irqL);
+
+ #ifdef CONFIG_IOCTL_CFG80211
+ if (1) {
+ #ifdef COMPAT_KERNEL_RELEASE
+ rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
+ #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
+ rtw_cfg80211_indicate_sta_disassoc(padapter, psta->hwaddr, reason);
+ #else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
+ /* will call rtw_cfg80211_indicate_sta_disassoc() in cmd_thread for old API context */
+ #endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
+ } else
+ #endif //CONFIG_IOCTL_CFG80211
+ {
+ rtw_indicate_sta_disassoc_event(padapter, psta);
+ }
+
+ report_del_sta_event(padapter, psta->hwaddr, reason);
+
+ beacon_updated = bss_cap_update_on_sta_leave(padapter, psta);
+
+ _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+ rtw_free_stainfo(padapter, psta);
+ _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+
+
+ return beacon_updated;
+
+}
+
+int rtw_ap_inform_ch_switch(_adapter *padapter, u8 new_ch, u8 ch_offset)
+{
+ _irqL irqL;
+ _list *phead, *plist;
+ int ret=0;
+ struct sta_info *psta = NULL;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+
+ if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
+ return ret;
+
+ DBG_871X(FUNC_NDEV_FMT" with ch:%u, offset:%u\n",
+ FUNC_NDEV_ARG(padapter->pnetdev), new_ch, ch_offset);
+
+ _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+ phead = &pstapriv->asoc_list;
+ plist = get_next(phead);
+
+ /* for each sta in asoc_queue */
+ while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
+ {
+ psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
+ plist = get_next(plist);
+
+ issue_action_spct_ch_switch(padapter, psta->hwaddr, new_ch, ch_offset);
+ psta->expire_to = ((pstapriv->expire_to * 2) > 5) ? 5 : (pstapriv->expire_to * 2);
+ }
+ _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+
+ issue_action_spct_ch_switch(padapter, bc_addr, new_ch, ch_offset);
+
+ return ret;
+}
+
+int rtw_sta_flush(_adapter *padapter)
+{
+ _irqL irqL;
+ _list *phead, *plist;
+ int ret=0;
+ struct sta_info *psta = NULL;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+ u8 chk_alive_num = 0;
+ char chk_alive_list[NUM_STA];
+ int i;
+
+ DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
+
+ if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
+ return ret;
+
+ _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+ phead = &pstapriv->asoc_list;
+ plist = get_next(phead);
+
+ while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
+ int stainfo_offset;
+
+ psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
+ plist = get_next(plist);
+
+ /* Remove sta from asoc_list */
+ rtw_list_delete(&psta->asoc_list);
+ pstapriv->asoc_list_cnt--;
+
+ /* Keep sta for ap_free_sta() beyond this asoc_list loop */
+ stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
+ if (stainfo_offset_valid(stainfo_offset)) {
+ chk_alive_list[chk_alive_num++] = stainfo_offset;
+ }
+ }
+ _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+
+
+ /* For each sta in chk_alive_list, call ap_free_sta */
+ for (i = 0; i < chk_alive_num; i++) {
+ psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
+ ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
+ }
+
+ issue_deauth(padapter, bc_addr, WLAN_REASON_DEAUTH_LEAVING);
+
+ associated_clients_update(padapter, _TRUE);
+
+ return ret;
+
+}
+
+/* called > TSR LEVEL for USB or SDIO Interface*/
+void sta_info_update(_adapter *padapter, struct sta_info *psta)
+{
+ int flags = psta->flags;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+
+ //update wmm cap.
+ if(WLAN_STA_WME&flags)
+ psta->qos_option = 1;
+ else
+ psta->qos_option = 0;
+
+ if(pmlmepriv->qospriv.qos_option == 0)
+ psta->qos_option = 0;
+
+
+#ifdef CONFIG_80211N_HT
+ //update 802.11n ht cap.
+ if(WLAN_STA_HT&flags)
+ {
+ psta->htpriv.ht_option = _TRUE;
+ psta->qos_option = 1;
+ }
+ else
+ {
+ psta->htpriv.ht_option = _FALSE;
+ }
+
+ if(pmlmepriv->htpriv.ht_option == _FALSE)
+ psta->htpriv.ht_option = _FALSE;
+#endif
+
+
+ update_sta_info_apmode(padapter, psta);
+
+
+}
+
+/* called >= TSR LEVEL for USB or SDIO Interface*/
+void ap_sta_info_defer_update(_adapter *padapter, struct sta_info *psta)
+{
+ if(psta->state & _FW_LINKED)
+ {
+ //add ratid
+ add_RATid(padapter, psta, 0);//DM_RATR_STA_INIT
+ }
+}
+/* restore hw setting from sw data structures */
+void rtw_ap_restore_network(_adapter *padapter)
+{
+ struct mlme_priv *mlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct sta_priv * pstapriv = &padapter->stapriv;
+ struct sta_info *psta;
+ struct security_priv* psecuritypriv=&(padapter->securitypriv);
+ _irqL irqL;
+ _list *phead, *plist;
+ u8 chk_alive_num = 0;
+ char chk_alive_list[NUM_STA];
+ int i;
+
+ rtw_setopmode_cmd(padapter, Ndis802_11APMode,_FALSE);
+
+ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
+
+ start_bss_network(padapter, (u8*)&mlmepriv->cur_network.network);
+
+ if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
+ (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))
+ {
+ /* restore group key, WEP keys is restored in ips_leave() */
+ rtw_set_key(padapter, psecuritypriv, psecuritypriv->dot118021XGrpKeyid, 0,_FALSE);
+ }
+
+ _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+
+ phead = &pstapriv->asoc_list;
+ plist = get_next(phead);
+
+ while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
+ int stainfo_offset;
+
+ psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
+ plist = get_next(plist);
+
+ stainfo_offset = rtw_stainfo_offset(pstapriv, psta);
+ if (stainfo_offset_valid(stainfo_offset)) {
+ chk_alive_list[chk_alive_num++] = stainfo_offset;
+ }
+ }
+
+ _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
+
+ for (i = 0; i < chk_alive_num; i++) {
+ psta = rtw_get_stainfo_by_offset(pstapriv, chk_alive_list[i]);
+
+ if (psta == NULL) {
+ DBG_871X(FUNC_ADPT_FMT" sta_info is null\n", FUNC_ADPT_ARG(padapter));
+ }
+ else if(psta->state &_FW_LINKED)
+ {
+ Update_RA_Entry(padapter, psta);
+ //pairwise key
+ /* per sta pairwise key and settings */
+ if( (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
+ (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))
+ {
+ rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE,_FALSE);
+ }
+ }
+ }
+
+}
+
+void start_ap_mode(_adapter *padapter)
+{
+ int i;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
+
+ pmlmepriv->update_bcn = _FALSE;
+
+ //init_mlme_ap_info(padapter);
+ pmlmeext->bstart_bss = _FALSE;
+
+ pmlmepriv->num_sta_non_erp = 0;
+
+ pmlmepriv->num_sta_no_short_slot_time = 0;
+
+ pmlmepriv->num_sta_no_short_preamble = 0;
+
+ pmlmepriv->num_sta_ht_no_gf = 0;
+#ifdef CONFIG_80211N_HT
+ pmlmepriv->num_sta_no_ht = 0;
+#endif //CONFIG_80211N_HT
+ pmlmepriv->num_sta_ht_20mhz = 0;
+
+ pmlmepriv->olbc = _FALSE;
+
+ pmlmepriv->olbc_ht = _FALSE;
+
+#ifdef CONFIG_80211N_HT
+ pmlmepriv->ht_op_mode = 0;
+#endif
+
+ for(i=0; i<NUM_STA; i++)
+ pstapriv->sta_aid[i] = NULL;
+
+ pmlmepriv->wps_beacon_ie = NULL;
+ pmlmepriv->wps_probe_resp_ie = NULL;
+ pmlmepriv->wps_assoc_resp_ie = NULL;
+
+ pmlmepriv->p2p_beacon_ie = NULL;
+ pmlmepriv->p2p_probe_resp_ie = NULL;
+
+
+ //for ACL
+ _rtw_init_listhead(&(pacl_list->acl_node_q.queue));
+ pacl_list->num = 0;
+ pacl_list->mode = 0;
+ for(i = 0; i < NUM_ACL; i++)
+ {
+ _rtw_init_listhead(&pacl_list->aclnode[i].list);
+ pacl_list->aclnode[i].valid = _FALSE;
+ }
+
+}
+
+void stop_ap_mode(_adapter *padapter)
+{
+ _irqL irqL;
+ _list *phead, *plist;
+ struct rtw_wlan_acl_node *paclnode;
+ struct sta_info *psta=NULL;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct wlan_acl_pool *pacl_list = &pstapriv->acl_list;
+ _queue *pacl_node_q =&pacl_list->acl_node_q;
+
+ pmlmepriv->update_bcn = _FALSE;
+ pmlmeext->bstart_bss = _FALSE;
+ //_rtw_spinlock_free(&pmlmepriv->bcn_update_lock);
+
+ //reset and init security priv , this can refine with rtw_reset_securitypriv
+ _rtw_memset((unsigned char *)&padapter->securitypriv, 0, sizeof (struct security_priv));
+ padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
+ padapter->securitypriv.ndisencryptstatus = Ndis802_11WEPDisabled;
+
+ //for ACL
+ _enter_critical_bh(&(pacl_node_q->lock), &irqL);
+ phead = get_list_head(pacl_node_q);
+ plist = get_next(phead);
+ while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
+ {
+ paclnode = LIST_CONTAINOR(plist, struct rtw_wlan_acl_node, list);
+ plist = get_next(plist);
+
+ if(paclnode->valid == _TRUE)
+ {
+ paclnode->valid = _FALSE;
+
+ rtw_list_delete(&paclnode->list);
+
+ pacl_list->num--;
+ }
+ }
+ _exit_critical_bh(&(pacl_node_q->lock), &irqL);
+
+ DBG_871X("%s, free acl_node_queue, num=%d\n", __func__, pacl_list->num);
+
+ rtw_sta_flush(padapter);
+
+ //free_assoc_sta_resources
+ rtw_free_all_stainfo(padapter);
+
+ psta = rtw_get_bcmc_stainfo(padapter);
+ _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+ rtw_free_stainfo(padapter, psta);
+ _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+
+ rtw_init_bcmc_stainfo(padapter);
+
+ rtw_free_mlme_priv_ie_data(pmlmepriv);
+
+}
+
+#endif //CONFIG_NATIVEAP_MLME
+#endif //CONFIG_AP_MODE
+
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_bt_mp.c b/drivers/net/wireless/rtl8723as/core/rtw_bt_mp.c
index 8b2afecc7b62..e3e0f3d95fec 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_bt_mp.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_bt_mp.c
@@ -1,1734 +1,1735 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-
-
-#include "rtw_bt_mp.h"
-#include <drv_types.h>
-#include <rtl8723a_hal.h>
-
-#ifdef CONFIG_RTL8723A
-
-void MPh2c_timeout_handle(void *FunctionContext)
-{
- _adapter *pAdapter = (_adapter *)FunctionContext;
- PMPT_CONTEXT pMptCtx=&pAdapter->mppriv.MptCtx;
-
- DBG_8192C("[MPT], MPh2c_timeout_handle \n");
-
- pMptCtx->bMPh2c_timeout=_TRUE;
-
- _rtw_up_sema(&pMptCtx->MPh2c_Sema);
-
- //_cancel_timer_ex( &pMptCtx->MPh2c_timeout_timer);
-
- return;
-}
-u32 WaitC2Hevent( PADAPTER pAdapter,BOOLEAN *C2H_event ,u32 delay_time)
-{
- PMPT_CONTEXT pMptCtx=&(pAdapter->mppriv.MptCtx);
- pMptCtx->bMPh2c_timeout=_FALSE;
-
- _set_timer( &pMptCtx->MPh2c_timeout_timer, delay_time );
-
- _rtw_down_sema(&pMptCtx->MPh2c_Sema);
-
- if( pMptCtx->bMPh2c_timeout == _TRUE )
- {
- C2H_event =_FALSE;
-
- return _FALSE;
- }
-
- return _TRUE;
-
-}
-
-BT_CTRL_STATUS
-mptbt_CheckC2hFrame(
- PADAPTER Adapter,
- PBT_H2C pH2c,
- PBT_EXT_C2H pExtC2h
- )
-{
- BT_CTRL_STATUS c2hStatus = BT_STATUS_C2H_SUCCESS;
-
- //DBG_8192C("[MPT], MPT rsp C2H hex: %x %x %x %x %x %x \n"), pExtC2h , pExtC2h+1 ,pExtC2h+2 ,pExtC2h+3 ,pExtC2h+4 ,pExtC2h+5);
-
- DBG_8192C("[MPT], statusCode = 0x%x\n", pExtC2h->statusCode);
- DBG_8192C("[MPT], retLen = %d\n", pExtC2h->retLen);
- DBG_8192C("[MPT], opCodeVer : req/rsp=%d/%d\n", pH2c->opCodeVer, pExtC2h->opCodeVer);
- DBG_8192C("[MPT], reqNum : req/rsp=%d/%d\n", pH2c->reqNum, pExtC2h->reqNum);
- if(pExtC2h->reqNum != pH2c->reqNum)
- {
- c2hStatus = BT_STATUS_C2H_REQNUM_MISMATCH;
- DBG_8192C("[MPT], Error!! C2H reqNum Mismatch!!\n");
- }
- else if(pExtC2h->opCodeVer != pH2c->opCodeVer)
- {
- c2hStatus = BT_STATUS_OPCODE_L_VERSION_MISMATCH;
- DBG_8192C("[MPT], Error!! OPCode version L mismatch!!\n");
- }
-
- return c2hStatus;
-}
-
-extern s32 FillH2CCmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer);
-
-BT_CTRL_STATUS
-mptbt_SendH2c(
- PADAPTER Adapter,
- PBT_H2C pH2c,
- u2Byte h2cCmdLen
- )
-{
- //KIRQL OldIrql = KeGetCurrentIrql();
- BT_CTRL_STATUS h2cStatus=BT_STATUS_H2C_SUCCESS;
- PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
- u1Byte i;
-
- DBG_8192C("[MPT], mptbt_SendH2c()=========>\n");
-
- //PlatformResetEvent(&pMptCtx->MptH2cRspEvent);
- //PlatformResetEvent(&pMptCtx->MptBtC2hEvent);
-
-// if(OldIrql == PASSIVE_LEVEL)
-// {
- //RTPRINT_DATA(FMPBT, FMPBT_H2C_CONTENT, ("[MPT], MPT H2C hex: \n"), pH2c, h2cCmdLen);
-
- for(i=0; i<BT_H2C_MAX_RETRY; i++)
- {
- DBG_8192C("[MPT], Send H2C command to wifi!!!\n");
- FillH2CCmd(Adapter, 70, h2cCmdLen, (pu1Byte)pH2c);
- pMptCtx->h2cReqNum++;
- pMptCtx->h2cReqNum %= 16;
-
- if(WaitC2Hevent(Adapter, &pMptCtx->MptH2cRspEvent, 100))
- {
- DBG_8192C("[MPT], Received WiFi MptH2cRspEvent!!!\n");
- if(WaitC2Hevent(Adapter, &pMptCtx->MptBtC2hEvent, 400))
- {
- DBG_8192C("[MPT], Received MptBtC2hEvent!!!\n");
- break;
- }
- else
- {
- DBG_8192C("[MPT], Error!!BT MptBtC2hEvent timeout!!\n");
- h2cStatus = BT_STATUS_H2C_BT_NO_RSP;
- }
- }
- else
- {
- DBG_8192C("[MPT], Error!!WiFi MptH2cRspEvent timeout!!\n");
- h2cStatus = BT_STATUS_H2C_TIMTOUT;
- }
- }
-// }
-// else
-// {
-// RT_ASSERT(FALSE, ("[MPT], mptbt_SendH2c() can only run under PASSIVE_LEVEL!!\n"));
-// h2cStatus = BT_STATUS_WRONG_LEVEL;
-// }
-
- DBG_8192C("[MPT], mptbt_SendH2c()<=========\n");
- return h2cStatus;
-}
-
-
-
-BT_CTRL_STATUS
-mptbt_CheckBtRspStatus(
- PADAPTER Adapter,
- PBT_EXT_C2H pExtC2h
- )
-{
- BT_CTRL_STATUS retStatus=BT_OP_STATUS_SUCCESS;
-
- switch(pExtC2h->statusCode)
- {
- case BT_OP_STATUS_SUCCESS:
- retStatus = BT_STATUS_BT_OP_SUCCESS;
- DBG_8192C("[MPT], BT status : BT_STATUS_SUCCESS\n");
- break;
- case BT_OP_STATUS_VERSION_MISMATCH:
- retStatus = BT_STATUS_OPCODE_L_VERSION_MISMATCH;
- DBG_8192C("[MPT], BT status : BT_STATUS_OPCODE_L_VERSION_MISMATCH\n");
- break;
- case BT_OP_STATUS_UNKNOWN_OPCODE:
- retStatus = BT_STATUS_UNKNOWN_OPCODE_L;
- DBG_8192C("[MPT], BT status : BT_STATUS_UNKNOWN_OPCODE_L\n");
- break;
- case BT_OP_STATUS_ERROR_PARAMETER:
- retStatus = BT_STATUS_PARAMETER_FORMAT_ERROR_L;
- DBG_8192C("[MPT], BT status : BT_STATUS_PARAMETER_FORMAT_ERROR_L\n");
- break;
- default:
- retStatus = BT_STATUS_UNKNOWN_STATUS_L;
- DBG_8192C("[MPT], BT status : BT_STATUS_UNKNOWN_STATUS_L\n");
- break;
- }
-
- return retStatus;
-}
-
-
-
-BT_CTRL_STATUS
-mptbt_BtFwOpCodeProcess(
- PADAPTER Adapter,
- u1Byte btFwOpCode,
- u1Byte opCodeVer,
- pu1Byte pH2cPar,
- u1Byte h2cParaLen
- )
-{
- u1Byte H2C_Parameter[6] ={0};
- PBT_H2C pH2c=(PBT_H2C)&H2C_Parameter[0];
- PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
- PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
- u2Byte paraLen=0,i;
- BT_CTRL_STATUS h2cStatus=BT_STATUS_H2C_SUCCESS, c2hStatus=BT_STATUS_C2H_SUCCESS;
- BT_CTRL_STATUS retStatus=BT_STATUS_H2C_BT_NO_RSP;
-
- pH2c->opCode = btFwOpCode;
- pH2c->opCodeVer = opCodeVer;
- pH2c->reqNum = pMptCtx->h2cReqNum;
- //PlatformMoveMemory(&pH2c->buf[0], pH2cPar, h2cParaLen);
- //_rtw_memcpy(&pH2c->buf[0], pH2cPar, h2cParaLen);
- _rtw_memcpy(pH2c->buf, pH2cPar, h2cParaLen);
-
- DBG_8192C("[MPT], pH2c->opCode=%d\n", pH2c->opCode);
- DBG_8192C("[MPT], pH2c->opCodeVer=%d\n", pH2c->opCodeVer);
- DBG_8192C("[MPT], pH2c->reqNum=%d\n", pH2c->reqNum);
- DBG_8192C("[MPT], h2c parameter length=%d\n", h2cParaLen);
- if(h2cParaLen)
- {
- DBG_8192C("[MPT], parameters(hex): \n");
- for(i=0;i<h2cParaLen;i++)
- {
- DBG_8192C(" 0x%x \n", pH2c->buf[i]);
- }
- }
-
- h2cStatus = mptbt_SendH2c(Adapter, pH2c, h2cParaLen+2);
- if(BT_STATUS_H2C_SUCCESS == h2cStatus)
- {
- // if reach here, it means H2C get the correct c2h response,
- c2hStatus = mptbt_CheckC2hFrame(Adapter, pH2c, pExtC2h);
- if(BT_STATUS_C2H_SUCCESS == c2hStatus)
- {
- retStatus = mptbt_CheckBtRspStatus(Adapter, pExtC2h);
- }
- else
- {
- DBG_8192C("[MPT], Error!! C2H failed for pH2c->opCode=%d\n", pH2c->opCode);
- // check c2h status error, return error status code to upper layer.
- retStatus = c2hStatus;
- }
- }
- else
- {
- DBG_8192C("[MPT], Error!! H2C failed for pH2c->opCode=%d\n", pH2c->opCode);
- // check h2c status error, return error status code to upper layer.
- retStatus = h2cStatus;
- }
-
- return retStatus;
-}
-
-
-
-
-u2Byte
-mptbt_BtReady(
- PADAPTER Adapter,
- PBT_REQ_CMD pBtReq,
- PBT_RSP_CMD pBtRsp
- )
-{
- u1Byte h2cParaBuf[6] ={0};
- u1Byte h2cParaLen=0;
- u2Byte paraLen=0;
- u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
- u1Byte btOpcode;
- u1Byte btOpcodeVer=0;
- PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
- PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
- u1Byte i;
- u1Byte btFwVer=0, bdAddr[6]={0};
- u2Byte btRealFwVer=0;
- pu2Byte pu2Tmp=NULL;
-
- //
- // check upper layer parameters
- //
-
- // 1. check upper layer opcode version
- if(pBtReq->opCodeVer != 1)
- {
- DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
- pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
- return paraLen;
- }
-
- pBtRsp->pParamStart[0] = MP_BT_NOT_READY;
- paraLen = 10;
- //
- // execute lower layer opcodes
- //
-
- // Get BT FW version
- // fill h2c parameters
- btOpcode = BT_LO_OP_GET_BT_VERSION;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- else
- {
- pu2Tmp = (pu2Byte)&pExtC2h->buf[0];
- btRealFwVer = *pu2Tmp;
- btFwVer = pExtC2h->buf[1];
- DBG_8192C("[MPT], btRealFwVer=0x%x, btFwVer=0x%x\n", btRealFwVer, btFwVer);
- }
-
- // Get BD Address
- // fill h2c parameters
- btOpcode = BT_LO_OP_GET_BD_ADDR_L;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- else
- {
- bdAddr[5] = pExtC2h->buf[0];
- bdAddr[4] = pExtC2h->buf[1];
- bdAddr[3] = pExtC2h->buf[2];
- }
-
- // fill h2c parameters
- btOpcode = BT_LO_OP_GET_BD_ADDR_H;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- else
- {
- bdAddr[2] = pExtC2h->buf[0];
- bdAddr[1] = pExtC2h->buf[1];
- bdAddr[0] = pExtC2h->buf[2];
- }
- DBG_8192C("[MPT], Local BDAddr:");
- for(i=0; i<6; i++)
- {
- DBG_8192C(" 0x%x ", bdAddr[i]);
- }
- pBtRsp->status = BT_STATUS_SUCCESS;
- pBtRsp->pParamStart[0] = MP_BT_READY;
- pu2Tmp = (pu2Byte)&pBtRsp->pParamStart[1];
- *pu2Tmp = btRealFwVer;
- pBtRsp->pParamStart[3] = btFwVer;
- for(i=0; i<6; i++)
- {
- pBtRsp->pParamStart[4+i] = bdAddr[5-i];
- }
-
- return paraLen;
-}
-
-void mptbt_close_WiFiRF(PADAPTER Adapter)
-{
- PHY_SetBBReg(Adapter, 0x824, 0xF, 0x0);
- PHY_SetBBReg(Adapter, 0x824, 0x700000, 0x0);
- PHY_SetRFReg(Adapter, RF90_PATH_A, 0x0, 0xF0000, 0x0);
-}
-
-void mptbt_open_WiFiRF(PADAPTER Adapter)
-{
- PHY_SetBBReg(Adapter, 0x824, 0x700000, 0x3);
- PHY_SetBBReg(Adapter, 0x824, 0xF, 0x2);
- PHY_SetRFReg(Adapter, RF90_PATH_A, 0x0, 0xF0000, 0x3);
-}
-
-u4Byte mptbt_switch_RF(PADAPTER Adapter, u1Byte Enter)
-{
- u2Byte tmp_2byte = 0;
-
- //Enter test mode
- if (Enter) {
- ////1>. close WiFi RF
- mptbt_close_WiFiRF(Adapter);
-
- ////2>. change ant switch to BT
- tmp_2byte = rtw_read16(Adapter, 0x860);
- tmp_2byte = tmp_2byte | BIT(9);
- tmp_2byte = tmp_2byte & (~BIT(8));
- rtw_write16(Adapter, 0x860, tmp_2byte);
- rtw_write16(Adapter, 0x870, 0x300);
- } else {
- ////1>. Open WiFi RF
- mptbt_open_WiFiRF(Adapter);
-
- ////2>. change ant switch back
- tmp_2byte = rtw_read16(Adapter, 0x860);
- tmp_2byte = tmp_2byte | BIT(8);
- tmp_2byte = tmp_2byte & (~BIT(9));
- rtw_write16(Adapter, 0x860, tmp_2byte);
- rtw_write16(Adapter, 0x870, 0x300);
- }
-
- return 0;
-}
-
-u2Byte
-mptbt_BtSetMode(
- PADAPTER Adapter,
- PBT_REQ_CMD pBtReq,
- PBT_RSP_CMD pBtRsp
- )
-{
- u1Byte h2cParaBuf[6] ={0};
- u1Byte h2cParaLen=0;
- u2Byte paraLen=0;
- u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
- u1Byte btOpcode;
- u1Byte btOpcodeVer=0;
- u1Byte btModeToSet=0;
-
- //
- // check upper layer parameters
- //
- // 1. check upper layer opcode version
- if(pBtReq->opCodeVer != 1)
- {
- DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
- pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
- return paraLen;
- }
- // 2. check upper layer parameter length
- if(1 == pBtReq->paraLength)
- {
- btModeToSet = pBtReq->pParamStart[0];
- DBG_8192C("[MPT], BtTestMode=%d \n", btModeToSet);
- }
- else
- {
- DBG_8192C("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength);
- pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
- return paraLen;
- }
-
- //
- // execute lower layer opcodes
- //
-
- // 1. fill h2c parameters
- // check bt mode
- btOpcode = BT_LO_OP_SET_BT_MODE;
- if(btModeToSet >= MP_BT_MODE_MAX)
- {
- pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- else
- {
- mptbt_switch_RF(Adapter, 1);
-
- h2cParaBuf[0] = btModeToSet;
- h2cParaLen = 1;
- // 2. execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- }
-
- // 3. construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS == retStatus)
- {
- pBtRsp->status = BT_STATUS_SUCCESS;
- }
- else
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- }
-
- return paraLen;
-}
-
-
-VOID
-MPTBT_FwC2hBtMpCtrl(
- PADAPTER Adapter,
- pu1Byte tmpBuf,
- u1Byte length
- )
-{
- u32 i;
- PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
- PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)tmpBuf;
-
- if(Adapter->bBTFWReady == _FALSE || Adapter->registrypriv.mp_mode == 0 )
- {
- DBG_8192C("[MPT], %s,bBTFWReady == _FALSE\n",__func__);
- return;
- }
- //cancel_timeout for h2c handle
- _cancel_timer_ex( &pMptCtx->MPh2c_timeout_timer);
-
- DBG_8192C("[MPT], MPTBT_FwC2hBtMpCtrl(), hex: \n");
- for(i=0;i<=length;i++)
- {
- //DBG_8192C("[MPT], MPTBT_FwC2hBtMpCtrl(), hex: \n",tmpBuf[i], length);
- DBG_8192C(" 0x%x ",tmpBuf[i]);
- }
- DBG_8192C("\n [MPT], pExtC2h->extendId=0x%x\n", pExtC2h->extendId);
-
- switch(pExtC2h->extendId)
- {
- case EXT_C2H_WIFI_FW_ACTIVE_RSP:
- DBG_8192C("[MPT], EXT_C2H_WIFI_FW_ACTIVE_RSP\n");
- DBG_8192C("[MPT], pExtC2h->buf hex: \n");
- if( length > 32 || length < 3 )
- break ;
- for(i=0;i<=(length-3);i++)
- DBG_8192C(" 0x%x ",pExtC2h->buf[i]);
- //PlatformSetEvent(&pMptCtx->MptH2cRspEvent);
- pMptCtx->MptH2cRspEvent=_TRUE;
- _rtw_up_sema(&pMptCtx->MPh2c_Sema);
- break;
- case EXT_C2H_TRIG_BY_BT_FW:
- DBG_8192C("[MPT], EXT_C2H_TRIG_BY_BT_FW\n");
- //PlatformMoveMemory(&pMptCtx->c2hBuf[0], tmpBuf, length);
- _rtw_memcpy(&pMptCtx->c2hBuf[0], tmpBuf, length);
- DBG_8192C("[MPT], pExtC2h->statusCode=0x%x\n", pExtC2h->statusCode);
- DBG_8192C("[MPT], pExtC2h->retLen=0x%x\n", pExtC2h->retLen);
- DBG_8192C("[MPT], pExtC2h->opCodeVer=0x%x\n", pExtC2h->opCodeVer);
- DBG_8192C("[MPT], pExtC2h->reqNum=0x%x\n", pExtC2h->reqNum);
- DBG_8192C("[MPT], pExtC2h->buf hex: \n");
- for(i=0;i<=(length-3);i++)
- DBG_8192C(" 0x%x ",pExtC2h->buf[0]);
- //PlatformSetEvent(&pMptCtx->MptBtC2hEvent);
- pMptCtx->MptBtC2hEvent=_TRUE;
- _rtw_up_sema(&pMptCtx->MPh2c_Sema);
- break;
- default:
- break;
- }
-
-
-
-}
-
-
-u2Byte
-mptbt_BtGetGeneral(
- IN PADAPTER Adapter,
- IN PBT_REQ_CMD pBtReq,
- IN PBT_RSP_CMD pBtRsp
- )
-{
- PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
- PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
- u1Byte h2cParaBuf[6] ={0};
- u1Byte h2cParaLen=0;
- u2Byte paraLen=0;
- u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
- u1Byte btOpcode, bdAddr[6]={0};
- u1Byte btOpcodeVer=0;
- u1Byte getType=0, i;
- u2Byte getParaLen=0, validParaLen=0;
- u1Byte regType=0, reportType=0;
- u4Byte regAddr=0, regValue=0;
- pu4Byte pu4Tmp;
- pu2Byte pu2Tmp;
- pu1Byte pu1Tmp;
-
- //
- // check upper layer parameters
- //
-
- // check upper layer opcode version
- if(pBtReq->opCodeVer != 1)
- {
- DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
- pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
- return paraLen;
- }
- // check upper layer parameter length
- if(pBtReq->paraLength < 1)
- {
- DBG_8192C("[MPT], Error!! wrong parameter length=%d (should larger than 1)\n", pBtReq->paraLength);
- pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
- return paraLen;
- }
- getParaLen = pBtReq->paraLength - 1;
- getType = pBtReq->pParamStart[0];
-
- DBG_8192C("[MPT], getType=%d, getParaLen=%d\n", getType, getParaLen);
-
- // check parameter first
- switch(getType)
- {
- case BT_GGET_REG:
- DBG_8192C("[MPT], [BT_GGET_REG]\n");
- validParaLen = 5;
- if(getParaLen == validParaLen)
- {
- btOpcode = BT_LO_OP_READ_REG;
- regType = pBtReq->pParamStart[1];
- pu4Tmp = (pu4Byte)&pBtReq->pParamStart[2];
- regAddr = *pu4Tmp;
- DBG_8192C("[MPT], BT_GGET_REG regType=0x%x, regAddr=0x%x!!\n",
- regType, regAddr);
- if(regType >= BT_REG_MAX)
- {
- pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- else
- {
- if( ((BT_REG_RF==regType)&&(regAddr>0x7f)) ||
- ((BT_REG_MODEM==regType)&&(regAddr>0x1ff)) ||
- ((BT_REG_BLUEWIZE==regType)&&(regAddr>0xfff)) ||
- ((BT_REG_VENDOR==regType)&&(regAddr>0xfff)) ||
- ((BT_REG_LE==regType)&&(regAddr>0xfff)) )
- {
- pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- }
- }
- break;
- case BT_GGET_STATUS:
- DBG_8192C("[MPT], [BT_GGET_STATUS]\n");
- validParaLen = 0;
- break;
- case BT_GGET_REPORT:
- DBG_8192C("[MPT], [BT_GGET_REPORT]\n");
- validParaLen = 1;
- if(getParaLen == validParaLen)
- {
- reportType = pBtReq->pParamStart[1];
- DBG_8192C("[MPT], BT_GGET_REPORT reportType=0x%x!!\n", reportType);
- if(reportType >= BT_REPORT_MAX)
- {
- pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- }
- break;
- default:
- {
- DBG_8192C("[MPT], Error!! getType=%d, out of range\n", getType);
- pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- break;
- }
- if(getParaLen != validParaLen)
- {
- DBG_8192C("[MPT], Error!! wrong parameter length=%d for BT_GET_GEN_CMD cmd id=0x%x, paraLen should=0x%x\n",
- getParaLen, getType, validParaLen);
- pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
- return paraLen;
- }
-
- //
- // execute lower layer opcodes
- //
- if(BT_GGET_REG == getType)
- {
- // fill h2c parameters
- // here we should write reg value first then write the address, adviced by Austin
- btOpcode = BT_LO_OP_READ_REG;
- h2cParaBuf[0] = regType;
- h2cParaBuf[1] = pBtReq->pParamStart[2];
- h2cParaBuf[2] = pBtReq->pParamStart[3];
- h2cParaLen = 3;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- pu2Tmp = (pu2Byte)&pExtC2h->buf[0];
- regValue = *pu2Tmp;
- DBG_8192C("[MPT], read reg regType=0x%x, regAddr=0x%x, regValue=0x%x\n",
- regType, regAddr, regValue);
-
- pu4Tmp = (pu4Byte)&pBtRsp->pParamStart[0];
- *pu4Tmp = regValue;
- paraLen = 4;
- }
- else if(BT_GGET_STATUS == getType)
- {
- btOpcode = BT_LO_OP_GET_BT_STATUS;
- h2cParaLen = 0;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- pBtRsp->pParamStart[0] = pExtC2h->buf[0];
- pBtRsp->pParamStart[1] = pExtC2h->buf[1];
- DBG_8192C("[MPT], read bt status, testMode=0x%x, testStatus=0x%x\n",
- pBtRsp->pParamStart[0], pBtRsp->pParamStart[1]);
- paraLen = 2;
- }
- else if(BT_GGET_REPORT == getType)
- {
- switch(reportType)
- {
- case BT_REPORT_RX_PACKET_CNT:
- {
- DBG_8192C("[MPT], [Rx Packet Counts]\n");
- btOpcode = BT_LO_OP_GET_RX_PKT_CNT_L;
- h2cParaLen = 0;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- pBtRsp->pParamStart[0] = pExtC2h->buf[0];
- pBtRsp->pParamStart[1] = pExtC2h->buf[1];
-
- btOpcode = BT_LO_OP_GET_RX_PKT_CNT_H;
- h2cParaLen = 0;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- pBtRsp->pParamStart[2] = pExtC2h->buf[0];
- pBtRsp->pParamStart[3] = pExtC2h->buf[1];
- paraLen = 4;
- }
- break;
- case BT_REPORT_RX_ERROR_BITS:
- {
- DBG_8192C("[MPT], [Rx Error Bits]\n");
- btOpcode = BT_LO_OP_GET_RX_ERROR_BITS_L;
- h2cParaLen = 0;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- pBtRsp->pParamStart[0] = pExtC2h->buf[0];
- pBtRsp->pParamStart[1] = pExtC2h->buf[1];
-
- btOpcode = BT_LO_OP_GET_RX_ERROR_BITS_H;
- h2cParaLen = 0;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- pBtRsp->pParamStart[2] = pExtC2h->buf[0];
- pBtRsp->pParamStart[3] = pExtC2h->buf[1];
- paraLen = 4;
- }
- break;
- case BT_REPORT_RSSI:
- {
- DBG_8192C("[MPT], [RSSI]\n");
- btOpcode = BT_LO_OP_GET_RSSI;
- h2cParaLen = 0;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- pBtRsp->pParamStart[0] = pExtC2h->buf[0];
- pBtRsp->pParamStart[1] = pExtC2h->buf[1];
- paraLen = 2;
- }
- break;
- case BT_REPORT_CFO_HDR_QUALITY:
- {
- DBG_8192C("[MPT], [CFO & Header Quality]\n");
- btOpcode = BT_LO_OP_GET_CFO_HDR_QUALITY_L;
- h2cParaLen = 0;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- pBtRsp->pParamStart[0] = pExtC2h->buf[0];
- pBtRsp->pParamStart[1] = pExtC2h->buf[1];
-
- btOpcode = BT_LO_OP_GET_CFO_HDR_QUALITY_H;
- h2cParaLen = 0;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- pBtRsp->pParamStart[2] = pExtC2h->buf[0];
- pBtRsp->pParamStart[3] = pExtC2h->buf[1];
- paraLen = 4;
- }
- break;
- case BT_REPORT_CONNECT_TARGET_BD_ADDR:
- {
- DBG_8192C("[MPT], [Connected Target BD ADDR]\n");
- btOpcode = BT_LO_OP_GET_TARGET_BD_ADDR_L;
- h2cParaLen = 0;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- bdAddr[5] = pExtC2h->buf[0];
- bdAddr[4] = pExtC2h->buf[1];
- bdAddr[3] = pExtC2h->buf[2];
-
- btOpcode = BT_LO_OP_GET_TARGET_BD_ADDR_H;
- h2cParaLen = 0;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- bdAddr[2] = pExtC2h->buf[0];
- bdAddr[1] = pExtC2h->buf[1];
- bdAddr[0] = pExtC2h->buf[2];
-
- DBG_8192C("[MPT], Connected Target BDAddr:%s", bdAddr);
- for(i=0; i<6; i++)
- {
- pBtRsp->pParamStart[i] = bdAddr[5-i];
- }
- paraLen = 6;
- }
- break;
- default:
- pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- break;
- }
- }
-
- pBtRsp->status = BT_STATUS_SUCCESS;
- return paraLen;
-}
-
-
-
-u2Byte
-mptbt_BtSetGeneral(
- IN PADAPTER Adapter,
- IN PBT_REQ_CMD pBtReq,
- IN PBT_RSP_CMD pBtRsp
- )
-{
- u1Byte h2cParaBuf[6] ={0};
- u1Byte h2cParaLen=0;
- u2Byte paraLen=0;
- u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
- u1Byte btOpcode;
- u1Byte btOpcodeVer=0;
- u1Byte setType=0;
- u2Byte setParaLen=0, validParaLen=0;
- u1Byte regType=0, bdAddr[6]={0}, calVal=0;
- u4Byte regAddr=0, regValue=0;
- pu4Byte pu4Tmp;
- pu2Byte pu2Tmp;
- pu1Byte pu1Tmp;
-
- //
- // check upper layer parameters
- //
-
- // check upper layer opcode version
- if(pBtReq->opCodeVer != 1)
- {
- DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
- pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
- return paraLen;
- }
- // check upper layer parameter length
- if(pBtReq->paraLength < 1)
- {
- DBG_8192C("[MPT], Error!! wrong parameter length=%d (should larger than 1)\n", pBtReq->paraLength);
- pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
- return paraLen;
- }
- setParaLen = pBtReq->paraLength - 1;
- setType = pBtReq->pParamStart[0];
-
- DBG_8192C("[MPT], setType=%d, setParaLen=%d\n", setType, setParaLen);
-
- // check parameter first
- switch(setType)
- {
- case BT_GSET_REG:
- DBG_8192C ("[MPT], [BT_GSET_REG]\n");
- validParaLen = 9;
- if(setParaLen == validParaLen)
- {
- btOpcode = BT_LO_OP_WRITE_REG_VALUE;
- regType = pBtReq->pParamStart[1];
- pu4Tmp = (pu4Byte)&pBtReq->pParamStart[2];
- regAddr = *pu4Tmp;
- pu4Tmp = (pu4Byte)&pBtReq->pParamStart[6];
- regValue = *pu4Tmp;
- DBG_8192C("[MPT], BT_GSET_REG regType=0x%x, regAddr=0x%x, regValue=0x%x!!\n",
- regType, regAddr, regValue);
- if(regType >= BT_REG_MAX)
- {
- pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- else
- {
- if( ((BT_REG_RF==regType)&&(regAddr>0x7f)) ||
- ((BT_REG_MODEM==regType)&&(regAddr>0x1ff)) ||
- ((BT_REG_BLUEWIZE==regType)&&(regAddr>0xfff)) ||
- ((BT_REG_VENDOR==regType)&&(regAddr>0xfff)) ||
- ((BT_REG_LE==regType)&&(regAddr>0xfff)) )
- {
- pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- }
- }
- break;
- case BT_GSET_RESET:
- DBG_8192C("[MPT], [BT_GSET_RESET]\n");
- validParaLen = 0;
- break;
- case BT_GSET_TARGET_BD_ADDR:
- DBG_8192C("[MPT], [BT_GSET_TARGET_BD_ADDR]\n");
- validParaLen = 6;
- if(setParaLen == validParaLen)
- {
- btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_H;
- if( (pBtReq->pParamStart[1]==0) &&
- (pBtReq->pParamStart[2]==0) &&
- (pBtReq->pParamStart[3]==0) &&
- (pBtReq->pParamStart[4]==0) &&
- (pBtReq->pParamStart[5]==0) &&
- (pBtReq->pParamStart[6]==0) )
- {
- DBG_8192C("[MPT], Error!! targetBDAddr=all zero\n");
- pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- if( (pBtReq->pParamStart[1]==0xff) &&
- (pBtReq->pParamStart[2]==0xff) &&
- (pBtReq->pParamStart[3]==0xff) &&
- (pBtReq->pParamStart[4]==0xff) &&
- (pBtReq->pParamStart[5]==0xff) &&
- (pBtReq->pParamStart[6]==0xff) )
- {
- DBG_8192C("[MPT], Error!! targetBDAddr=all 0xf\n");
- pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- bdAddr[0] = pBtReq->pParamStart[6];
- bdAddr[1] = pBtReq->pParamStart[5];
- bdAddr[2] = pBtReq->pParamStart[4];
- bdAddr[3] = pBtReq->pParamStart[3];
- bdAddr[4] = pBtReq->pParamStart[2];
- bdAddr[5] = pBtReq->pParamStart[1];
- DBG_8192C ("[MPT], target BDAddr:%x,%x,%x,%x,%x,%x\n",
- bdAddr[0],bdAddr[1],bdAddr[2],bdAddr[3],bdAddr[4],bdAddr[5]);
- }
- break;
- case BT_GSET_TX_PWR_FINETUNE:
- DBG_8192C("[MPT], [BT_GSET_TX_PWR_FINETUNE]\n");
- validParaLen = 1;
- if(setParaLen == validParaLen)
- {
- btOpcode = BT_LO_OP_SET_TX_POWER_CALIBRATION;
- calVal = pBtReq->pParamStart[1];
- if( (calVal<1) || (calVal>9) )
- {
- pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- DBG_8192C ("[MPT], calVal=%d\n", calVal);
- }
- break;
- case BT_SET_TRACKING_INTERVAL:
- DBG_871X("[MPT], [BT_SET_TRACKING_INTERVAL] setParaLen =%d \n",setParaLen);
-
- validParaLen = 1;
- if(setParaLen == validParaLen)
- calVal = pBtReq->pParamStart[1];
- break;
- case BT_SET_THERMAL_METER:
- DBG_871X("[MPT], [BT_SET_THERMAL_METER] setParaLen =%d \n",setParaLen);
- validParaLen = 1;
- if(setParaLen == validParaLen)
- calVal = pBtReq->pParamStart[1];
- break;
- case BT_ENABLE_CFO_TRACKING:
- DBG_871X("[MPT], [BT_ENABLE_CFO_TRACKING] setParaLen =%d \n",setParaLen);
- validParaLen = 1;
- if(setParaLen == validParaLen)
- calVal = pBtReq->pParamStart[1];
- break;
- case BT_GSET_UPDATE_BT_PATCH:
- if(IS_HARDWARE_TYPE_8723AE(Adapter) && Adapter->bFWReady)
- {
- u1Byte i;
- DBG_8192C ("[MPT], write regs for load patch\n");
- //BTFwPatch8723A(Adapter);
- PlatformEFIOWrite1Byte(Adapter, 0xCC, 0x2d);
- rtw_msleep_os(50);
- PlatformEFIOWrite4Byte(Adapter, 0x68, 0xa005000c);
- rtw_msleep_os(50);
- PlatformEFIOWrite4Byte(Adapter, 0x68, 0xb005000c);
- rtw_msleep_os(50);
- PlatformEFIOWrite1Byte(Adapter, 0xCC, 0x29);
- for(i=0; i<12; i++)
- rtw_msleep_os(100);
-//#if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
-// BTFwPatch8723A(Adapter);
-//#endif
- DBG_8192C("[MPT], load BT FW Patch finished!!!\n");
- }
- break;
- default:
- {
- DBG_8192C ("[MPT], Error!! setType=%d, out of range\n", setType);
- pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- break;
- }
- if(setParaLen != validParaLen)
- {
- DBG_8192C("[MPT], Error!! wrong parameter length=%d for BT_SET_GEN_CMD cmd id=0x%x, paraLen should=0x%x\n",
- setParaLen, setType, validParaLen);
- pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
- return paraLen;
- }
-
- //
- // execute lower layer opcodes
- //
- if(BT_GSET_REG == setType)
- {
- // fill h2c parameters
- // here we should write reg value first then write the address, adviced by Austin
- btOpcode = BT_LO_OP_WRITE_REG_VALUE;
- h2cParaBuf[0] = pBtReq->pParamStart[6];
- h2cParaBuf[1] = pBtReq->pParamStart[7];
- h2cParaBuf[2] = pBtReq->pParamStart[8];
- h2cParaLen = 3;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- // write reg address
- btOpcode = BT_LO_OP_WRITE_REG_ADDR;
- h2cParaBuf[0] = regType;
- h2cParaBuf[1] = pBtReq->pParamStart[2];
- h2cParaBuf[2] = pBtReq->pParamStart[3];
- h2cParaLen = 3;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- }
- else if(BT_GSET_RESET == setType)
- {
- btOpcode = BT_LO_OP_RESET;
- h2cParaLen = 0;
- // execute h2c and check respond c2h from bt fw is correct or not
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- }
- else if(BT_GSET_TARGET_BD_ADDR == setType)
- {
- // fill h2c parameters
- btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_L;
- h2cParaBuf[0] = pBtReq->pParamStart[1];
- h2cParaBuf[1] = pBtReq->pParamStart[2];
- h2cParaBuf[2] = pBtReq->pParamStart[3];
- h2cParaLen = 3;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_H;
- h2cParaBuf[0] = pBtReq->pParamStart[4];
- h2cParaBuf[1] = pBtReq->pParamStart[5];
- h2cParaBuf[2] = pBtReq->pParamStart[6];
- h2cParaLen = 3;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- }
- else if(BT_GSET_TX_PWR_FINETUNE == setType)
- {
- // fill h2c parameters
- btOpcode = BT_LO_OP_SET_TX_POWER_CALIBRATION;
- h2cParaBuf[0] = calVal;
- h2cParaLen = 1;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- }
- else if(BT_SET_TRACKING_INTERVAL == setType)
- {
- // BT_LO_OP_SET_TRACKING_INTERVAL = 0x22,
- // BT_LO_OP_SET_THERMAL_METER = 0x23,
- // BT_LO_OP_ENABLE_CFO_TRACKING = 0x24,
- btOpcode = BT_LO_OP_SET_TRACKING_INTERVAL;
- h2cParaBuf[0] = calVal;
- h2cParaLen = 1;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- }
- else if(BT_SET_THERMAL_METER == setType)
- {
- btOpcode = BT_LO_OP_SET_THERMAL_METER;
- h2cParaBuf[0] = calVal;
- h2cParaLen = 1;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- }
- else if(BT_ENABLE_CFO_TRACKING == setType)
- {
- btOpcode = BT_LO_OP_ENABLE_CFO_TRACKING;
- h2cParaBuf[0] = calVal;
- h2cParaLen = 1;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
- }
-
- pBtRsp->status = BT_STATUS_SUCCESS;
- return paraLen;
-}
-
-
-
-u2Byte
-mptbt_BtSetTxRxPars(
- IN PADAPTER Adapter,
- IN PBT_REQ_CMD pBtReq,
- IN PBT_RSP_CMD pBtRsp
- )
-{
- u1Byte h2cParaBuf[6] ={0};
- u1Byte h2cParaLen=0;
- u2Byte paraLen=0;
- u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
- u1Byte btOpcode;
- u1Byte btOpcodeVer=0;
- PBT_TXRX_PARAMETERS pTxRxPars=(PBT_TXRX_PARAMETERS)&pBtReq->pParamStart[0];
- u2Byte lenTxRx=sizeof(BT_TXRX_PARAMETERS);
- u1Byte i;
- u1Byte bdAddr[6]={0};
-
- //
- // check upper layer parameters
- //
-
- // 1. check upper layer opcode version
- if(pBtReq->opCodeVer != 1)
- {
- DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
- pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
- return paraLen;
- }
- // 2. check upper layer parameter length
- if(pBtReq->paraLength == sizeof(BT_TXRX_PARAMETERS))
- {
- DBG_8192C ("[MPT], pTxRxPars->txrxChannel=0x%x \n", pTxRxPars->txrxChannel);
- DBG_8192C ("[MPT], pTxRxPars->txrxTxPktCnt=0x%8x \n", pTxRxPars->txrxTxPktCnt);
- DBG_8192C ("[MPT], pTxRxPars->txrxTxPktInterval=0x%x \n", pTxRxPars->txrxTxPktInterval);
- DBG_8192C ("[MPT], pTxRxPars->txrxPayloadType=0x%x \n", pTxRxPars->txrxPayloadType);
- DBG_8192C ("[MPT], pTxRxPars->txrxPktType=0x%x \n", pTxRxPars->txrxPktType);
- DBG_8192C ("[MPT], pTxRxPars->txrxPayloadLen=0x%x \n", pTxRxPars->txrxPayloadLen);
- DBG_8192C ("[MPT], pTxRxPars->txrxPktHeader=0x%x \n", pTxRxPars->txrxPktHeader);
- DBG_8192C ("[MPT], pTxRxPars->txrxWhitenCoeff=0x%x \n", pTxRxPars->txrxWhitenCoeff);
- bdAddr[0] = pTxRxPars->txrxBdaddr[5];
- bdAddr[1] = pTxRxPars->txrxBdaddr[4];
- bdAddr[2] = pTxRxPars->txrxBdaddr[3];
- bdAddr[3] = pTxRxPars->txrxBdaddr[2];
- bdAddr[4] = pTxRxPars->txrxBdaddr[1];
- bdAddr[5] = pTxRxPars->txrxBdaddr[0];
- DBG_8192C ("[MPT], pTxRxPars->txrxBdaddr: %s", &bdAddr[0]);
- DBG_8192C ("[MPT], pTxRxPars->txrxTxGainIndex=0x%x \n", pTxRxPars->txrxTxGainIndex);
- }
- else
- {
- DBG_8192C ("[MPT], Error!! pBtReq->paraLength=%d, correct Len=%d\n", pBtReq->paraLength, lenTxRx);
- pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
- return paraLen;
- }
-
- //
- // execute lower layer opcodes
- //
-
- // fill h2c parameters
- btOpcode = BT_LO_OP_SET_PKT_HEADER;
- if(pTxRxPars->txrxPktHeader > 0x3ffff)
- {
- DBG_8192C ("[MPT], Error!! pTxRxPars->txrxPktHeader=0x%x is out of range, (should be between 0x0~0x3ffff)\n", pTxRxPars->txrxPktHeader);
- pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- else
- {
- h2cParaBuf[0] = (u1Byte)(pTxRxPars->txrxPktHeader&0xff);
- h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxPktHeader&0xff00)>>8);
- h2cParaBuf[2] = (u1Byte)((pTxRxPars->txrxPktHeader&0xff0000)>>16);
- h2cParaLen = 3;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- }
-
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- // fill h2c parameters
- btOpcode = BT_LO_OP_SET_PKT_TYPE_LEN;
- {
- u2Byte payloadLenLimit=0;
- switch(pTxRxPars->txrxPktType)
- {
- case MP_BT_PKT_DH1:
- payloadLenLimit = 27*8;
- break;
- case MP_BT_PKT_DH3:
- payloadLenLimit = 183*8;
- break;
- case MP_BT_PKT_DH5:
- payloadLenLimit = 339*8;
- break;
- case MP_BT_PKT_2DH1:
- payloadLenLimit = 54*8;
- break;
- case MP_BT_PKT_2DH3:
- payloadLenLimit = 367*8;
- break;
- case MP_BT_PKT_2DH5:
- payloadLenLimit = 679*8;
- break;
- case MP_BT_PKT_3DH1:
- payloadLenLimit = 83*8;
- break;
- case MP_BT_PKT_3DH3:
- payloadLenLimit = 552*8;
- break;
- case MP_BT_PKT_3DH5:
- payloadLenLimit = 1021*8;
- break;
- case MP_BT_PKT_LE:
- payloadLenLimit = 39*8;
- break;
- default:
- {
- DBG_8192C ("[MPT], Error!! Unknown pTxRxPars->txrxPktType=0x%x\n", pTxRxPars->txrxPktType);
- pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- break;
- }
-
- if(pTxRxPars->txrxPayloadLen > payloadLenLimit)
- {
- DBG_8192C ("[MPT], Error!! pTxRxPars->txrxPayloadLen=0x%x, (should smaller than %d)\n",
- pTxRxPars->txrxPayloadLen, payloadLenLimit);
- pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
-
- h2cParaBuf[0] = pTxRxPars->txrxPktType;
- h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxPayloadLen&0xff));
- h2cParaBuf[2] = (u1Byte)((pTxRxPars->txrxPayloadLen&0xff00)>>8);
- h2cParaLen = 3;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- }
-
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- // fill h2c parameters
- btOpcode = BT_LO_OP_SET_PKT_CNT_L_PL_TYPE;
- if(pTxRxPars->txrxPayloadType > MP_BT_PAYLOAD_MAX)
- {
- DBG_8192C ("[MPT], Error!! pTxRxPars->txrxPayloadType=0x%x, (should be between 0~4)\n", pTxRxPars->txrxPayloadType);
- pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- else
- {
- h2cParaBuf[0] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff));
- h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff00)>>8);
- h2cParaBuf[2] = pTxRxPars->txrxPayloadType;
- h2cParaLen = 3;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- }
-
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- // fill h2c parameters
- btOpcode = BT_LO_OP_SET_PKT_CNT_H_PKT_INTV;
- if(pTxRxPars->txrxTxPktInterval > 15)
- {
- DBG_8192C ("[MPT], Error!! pTxRxPars->txrxTxPktInterval=0x%x, (should be between 0~15)\n", pTxRxPars->txrxTxPktInterval);
- pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- else
- {
- h2cParaBuf[0] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff0000)>>16);
- h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff000000)>>24);
- h2cParaBuf[2] = pTxRxPars->txrxTxPktInterval;
- h2cParaLen = 3;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- }
-
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- // fill h2c parameters
- btOpcode = BT_LO_OP_SET_WHITENCOEFF;
- {
- h2cParaBuf[0] = pTxRxPars->txrxWhitenCoeff;
- h2cParaLen = 1;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- }
-
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
-
- // fill h2c parameters
- btOpcode = BT_LO_OP_SET_CHNL_TX_GAIN;
- if( (pTxRxPars->txrxChannel > 78) ||
- (pTxRxPars->txrxTxGainIndex > 7) )
- {
- DBG_8192C ("[MPT], Error!! pTxRxPars->txrxChannel=0x%x, (should be between 0~78)\n", pTxRxPars->txrxChannel);
- DBG_8192C ("[MPT], Error!! pTxRxPars->txrxTxGainIndex=0x%x, (should be between 0~7)\n", pTxRxPars->txrxTxGainIndex);
- pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- else
- {
- h2cParaBuf[0] = pTxRxPars->txrxChannel;
- h2cParaBuf[1] = pTxRxPars->txrxTxGainIndex;
- h2cParaLen = 2;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- }
-
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- // fill h2c parameters
- btOpcode = BT_LO_OP_SET_BD_ADDR_L;
- if( (pTxRxPars->txrxBdaddr[0]==0) &&
- (pTxRxPars->txrxBdaddr[1]==0) &&
- (pTxRxPars->txrxBdaddr[2]==0) &&
- (pTxRxPars->txrxBdaddr[3]==0) &&
- (pTxRxPars->txrxBdaddr[4]==0) &&
- (pTxRxPars->txrxBdaddr[5]==0) )
- {
- DBG_8192C ("[MPT], Error!! pTxRxPars->txrxBdaddr=all zero\n");
- pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- if( (pTxRxPars->txrxBdaddr[0]==0xff) &&
- (pTxRxPars->txrxBdaddr[1]==0xff) &&
- (pTxRxPars->txrxBdaddr[2]==0xff) &&
- (pTxRxPars->txrxBdaddr[3]==0xff) &&
- (pTxRxPars->txrxBdaddr[4]==0xff) &&
- (pTxRxPars->txrxBdaddr[5]==0xff) )
- {
- DBG_8192C ("[MPT], Error!! pTxRxPars->txrxBdaddr=all 0xf\n");
- pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
-
- {
- h2cParaBuf[0] = pTxRxPars->txrxBdaddr[0];
- h2cParaBuf[1] = pTxRxPars->txrxBdaddr[1];
- h2cParaBuf[2] = pTxRxPars->txrxBdaddr[2];
- h2cParaLen = 3;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- }
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- btOpcode = BT_LO_OP_SET_BD_ADDR_H;
- {
- h2cParaBuf[0] = pTxRxPars->txrxBdaddr[3];
- h2cParaBuf[1] = pTxRxPars->txrxBdaddr[4];
- h2cParaBuf[2] = pTxRxPars->txrxBdaddr[5];
- h2cParaLen = 3;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- }
- // ckeck bt return status.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- pBtRsp->status = BT_STATUS_SUCCESS;
- return paraLen;
-}
-
-
-
-u2Byte
-mptbt_BtTestCtrl(
- IN PADAPTER Adapter,
- IN PBT_REQ_CMD pBtReq,
- IN PBT_RSP_CMD pBtRsp
- )
-{
- u1Byte h2cParaBuf[6] ={0};
- u1Byte h2cParaLen=0;
- u2Byte paraLen=0;
- u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
- u1Byte btOpcode;
- u1Byte btOpcodeVer=0;
- u1Byte testCtrl=0;
-
- //
- // check upper layer parameters
- //
-
- // 1. check upper layer opcode version
- if(pBtReq->opCodeVer != 1)
- {
- DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
- pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
- return paraLen;
- }
- // 2. check upper layer parameter length
- if(1 == pBtReq->paraLength)
- {
- testCtrl = pBtReq->pParamStart[0];
- DBG_8192C("[MPT], testCtrl=%d \n", testCtrl);
- }
- else
- {
- DBG_8192C("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength);
- pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
- return paraLen;
- }
-
- //
- // execute lower layer opcodes
- //
-
- // 1. fill h2c parameters
- // check bt mode
- btOpcode = BT_LO_OP_TEST_CTRL;
- if(testCtrl >= MP_BT_TEST_MAX)
- {
- DBG_8192C("[MPT], Error!! testCtrl=0x%x, (should be between smaller or equal to 0x%x)\n",
- testCtrl, MP_BT_TEST_MAX-1);
- pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
- return paraLen;
- }
- else
- {
- h2cParaBuf[0] = testCtrl;
- h2cParaLen = 1;
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- }
-
- // 3. construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- pBtRsp->status = BT_STATUS_SUCCESS;
- return paraLen;
-}
-
-
-u2Byte
-mptbt_TestBT(
- IN PADAPTER Adapter,
- IN PBT_REQ_CMD pBtReq,
- IN PBT_RSP_CMD pBtRsp
- )
-{
-
- u1Byte h2cParaBuf[6] ={0};
- u1Byte h2cParaLen=0;
- u2Byte paraLen=0;
- u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
- u1Byte btOpcode;
- u1Byte btOpcodeVer=0;
- u1Byte testCtrl=0;
-
- // 1. fill h2c parameters
- btOpcode = 0x11;
- h2cParaBuf[0] = 0x11;
- h2cParaBuf[1] = 0x0;
- h2cParaBuf[2] = 0x0;
- h2cParaBuf[3] = 0x0;
- h2cParaBuf[4] = 0x0;
- h2cParaLen = 1;
- // retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
- retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, h2cParaBuf, h2cParaLen);
-
-
- // 3. construct respond status code and data.
- if(BT_STATUS_BT_OP_SUCCESS != retStatus)
- {
- pBtRsp->status = ((btOpcode<<8)|retStatus);
- DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
- return paraLen;
- }
-
- pBtRsp->status = BT_STATUS_SUCCESS;
- return paraLen;
-}
-
-VOID
-mptbt_BtControlProcess(
- PADAPTER Adapter,
- PVOID pInBuf
- )
-{
- u1Byte H2C_Parameter[6] ={0};
- PBT_H2C pH2c=(PBT_H2C)&H2C_Parameter[0];
- PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
- PBT_REQ_CMD pBtReq=(PBT_REQ_CMD)pInBuf;
- PBT_RSP_CMD pBtRsp=(PBT_RSP_CMD)&pMptCtx->mptOutBuf[0];
- u1Byte i;
-
- DBG_8192C("[MPT], mptbt_BtControlProcess()=========>\n");
-
- DBG_8192C("[MPT], input opCodeVer=%d\n", pBtReq->opCodeVer);
- DBG_8192C("[MPT], input OpCode=%d\n", pBtReq->OpCode);
- DBG_8192C("[MPT], paraLength=%d \n", pBtReq->paraLength);
- if(pBtReq->paraLength)
- {
- //DBG_8192C("[MPT], parameters(hex):0x%x %d \n",&pBtReq->pParamStart[0], pBtReq->paraLength);
- }
-
- // The following we should maintain the User OP codes sent by upper layer
-
- pBtRsp->status = BT_STATUS_SUCCESS;
- pMptCtx->mptOutLen = 4; //length of (BT_RSP_CMD.status+BT_RSP_CMD.paraLength)
- pBtRsp->paraLength = 0x0;
-
- _rtw_memset((PVOID)&pMptCtx->mptOutBuf[0], '\0',100);
-
- switch(pBtReq->OpCode)
- {
- case BT_UP_OP_BT_READY:
- DBG_8192C("[MPT], OPcode : [BT_READY]\n");
- pBtRsp->paraLength = mptbt_BtReady(Adapter, pBtReq, pBtRsp);
- break;
- case BT_UP_OP_BT_SET_MODE:
- DBG_8192C("[MPT], OPcode : [BT_SET_MODE]\n");
- pBtRsp->paraLength = mptbt_BtSetMode(Adapter, pBtReq, pBtRsp);
- break;
- case BT_UP_OP_BT_SET_TX_RX_PARAMETER:
- DBG_8192C("[MPT], OPcode : [BT_SET_TXRX_PARAMETER]\n");
- pBtRsp->paraLength = mptbt_BtSetTxRxPars(Adapter, pBtReq, pBtRsp);
- break;
- case BT_UP_OP_BT_SET_GENERAL:
- DBG_8192C("[MPT], OPcode : [BT_SET_GENERAL]\n");
- pBtRsp->paraLength = mptbt_BtSetGeneral(Adapter, pBtReq, pBtRsp);
- break;
- case BT_UP_OP_BT_GET_GENERAL:
- DBG_8192C("[MPT], OPcode : [BT_GET_GENERAL]\n");
- pBtRsp->paraLength = mptbt_BtGetGeneral(Adapter, pBtReq, pBtRsp);
- break;
- case BT_UP_OP_BT_TEST_CTRL:
- DBG_8192C("[MPT], OPcode : [BT_TEST_CTRL]\n");
- pBtRsp->paraLength = mptbt_BtTestCtrl(Adapter, pBtReq, pBtRsp);
- break;
- case BT_UP_OP_TEST_BT:
- DBG_8192C("[MPT], OPcode : [TEST_BT]\n");
- pBtRsp->paraLength = mptbt_TestBT(Adapter, pBtReq, pBtRsp);
- break;
- default:
- DBG_8192C("[MPT], Error!! OPcode : UNDEFINED!!!!\n");
- pBtRsp->status = BT_STATUS_UNKNOWN_OPCODE_U;
- pBtRsp->paraLength = 0x0;
- break;
- }
-
- DBG_8192C("pBtRsp->paraLength =%d \n",pBtRsp->paraLength);
-
- pMptCtx->mptOutLen += pBtRsp->paraLength;
-
- DBG_8192C("\n [MPT], OUT to DLL pMptCtx->mptOutLen=%d ,pBtRsp->paraLength =%d ",pMptCtx->mptOutLen,pBtRsp->paraLength);
-
- DBG_8192C("\n [MPT], mptbt_BtControlProcess()<=========\n");
-}
-
-#endif
-
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ *
+ ******************************************************************************/
+
+
+#include "rtw_bt_mp.h"
+#include <drv_types.h>
+#include <rtl8723a_hal.h>
+
+#ifdef CONFIG_RTL8723A
+
+void MPh2c_timeout_handle(void *FunctionContext)
+{
+ _adapter *pAdapter = (_adapter *)FunctionContext;
+ PMPT_CONTEXT pMptCtx=&pAdapter->mppriv.MptCtx;
+
+ DBG_8192C("[MPT], MPh2c_timeout_handle \n");
+
+ pMptCtx->bMPh2c_timeout=_TRUE;
+
+ _rtw_up_sema(&pMptCtx->MPh2c_Sema);
+
+ //_cancel_timer_ex( &pMptCtx->MPh2c_timeout_timer);
+
+ return;
+}
+u32 WaitC2Hevent( PADAPTER pAdapter,BOOLEAN *C2H_event ,u32 delay_time)
+{
+ PMPT_CONTEXT pMptCtx=&(pAdapter->mppriv.MptCtx);
+ pMptCtx->bMPh2c_timeout=_FALSE;
+ DBG_8192C("WaitC2Hevent _set_timer \n");
+ _set_timer( &pMptCtx->MPh2c_timeout_timer, delay_time );
+
+ _rtw_down_sema(&pMptCtx->MPh2c_Sema);
+
+ if( pMptCtx->bMPh2c_timeout == _TRUE )
+ {
+ C2H_event =_FALSE;
+ DBG_8192C("WaitC2Hevent bMPh2c_timeout _TRUE \n");
+ return _FALSE;
+ }
+
+ return _TRUE;
+
+}
+
+BT_CTRL_STATUS
+mptbt_CheckC2hFrame(
+ PADAPTER Adapter,
+ PBT_H2C pH2c,
+ PBT_EXT_C2H pExtC2h
+ )
+{
+ BT_CTRL_STATUS c2hStatus = BT_STATUS_C2H_SUCCESS;
+
+ //DBG_8192C("[MPT], MPT rsp C2H hex: %x %x %x %x %x %x \n"), pExtC2h , pExtC2h+1 ,pExtC2h+2 ,pExtC2h+3 ,pExtC2h+4 ,pExtC2h+5);
+
+ DBG_8192C("[MPT], statusCode = 0x%x\n", pExtC2h->statusCode);
+ DBG_8192C("[MPT], retLen = %d\n", pExtC2h->retLen);
+ DBG_8192C("[MPT], opCodeVer : req/rsp=%d/%d\n", pH2c->opCodeVer, pExtC2h->opCodeVer);
+ DBG_8192C("[MPT], reqNum : req/rsp=%d/%d\n", pH2c->reqNum, pExtC2h->reqNum);
+ if(pExtC2h->reqNum != pH2c->reqNum)
+ {
+ c2hStatus = BT_STATUS_C2H_REQNUM_MISMATCH;
+ DBG_8192C("[MPT], Error!! C2H reqNum Mismatch!!\n");
+ }
+ else if(pExtC2h->opCodeVer != pH2c->opCodeVer)
+ {
+ c2hStatus = BT_STATUS_OPCODE_L_VERSION_MISMATCH;
+ DBG_8192C("[MPT], Error!! OPCode version L mismatch!!\n");
+ }
+
+ return c2hStatus;
+}
+
+extern s32 FillH2CCmd(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer);
+
+BT_CTRL_STATUS
+mptbt_SendH2c(
+ PADAPTER Adapter,
+ PBT_H2C pH2c,
+ u2Byte h2cCmdLen
+ )
+{
+ //KIRQL OldIrql = KeGetCurrentIrql();
+ BT_CTRL_STATUS h2cStatus=BT_STATUS_H2C_SUCCESS;
+ PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
+ u1Byte i;
+
+ DBG_8192C("[MPT], mptbt_SendH2c()=========>\n");
+
+ //PlatformResetEvent(&pMptCtx->MptH2cRspEvent);
+ //PlatformResetEvent(&pMptCtx->MptBtC2hEvent);
+
+// if(OldIrql == PASSIVE_LEVEL)
+// {
+ //RTPRINT_DATA(FMPBT, FMPBT_H2C_CONTENT, ("[MPT], MPT H2C hex: \n"), pH2c, h2cCmdLen);
+
+ for(i=0; i<BT_H2C_MAX_RETRY; i++)
+ {
+ DBG_8192C("[MPT], Send H2C command to wifi!!!\n");
+ FillH2CCmd(Adapter, 70, h2cCmdLen, (pu1Byte)pH2c);
+ pMptCtx->h2cReqNum++;
+ pMptCtx->h2cReqNum %= 16;
+
+ if(WaitC2Hevent(Adapter, &pMptCtx->MptH2cRspEvent, 200))
+ {
+ DBG_8192C("[MPT], Received WiFi MptH2cRspEvent!!!\n");
+ if(WaitC2Hevent(Adapter, &pMptCtx->MptBtC2hEvent, 800))
+ {
+ DBG_8192C("[MPT], Received BT MptBtC2hEvent!!!\n");
+ break;
+ }
+ else
+ {
+ DBG_8192C("[MPT], Error!!BT MptBtC2hEvent timeout!!\n");
+ h2cStatus = BT_STATUS_H2C_BT_NO_RSP;
+ }
+ }
+ else
+ {
+ DBG_8192C("[MPT], Error!!WiFi MptH2cRspEvent timeout!!\n");
+ h2cStatus = BT_STATUS_H2C_TIMTOUT;
+ }
+ }
+// }
+// else
+// {
+// RT_ASSERT(FALSE, ("[MPT], mptbt_SendH2c() can only run under PASSIVE_LEVEL!!\n"));
+// h2cStatus = BT_STATUS_WRONG_LEVEL;
+// }
+
+ DBG_8192C("[MPT], mptbt_SendH2c()<=========\n");
+ return h2cStatus;
+}
+
+
+
+BT_CTRL_STATUS
+mptbt_CheckBtRspStatus(
+ PADAPTER Adapter,
+ PBT_EXT_C2H pExtC2h
+ )
+{
+ BT_CTRL_STATUS retStatus=BT_OP_STATUS_SUCCESS;
+
+ switch(pExtC2h->statusCode)
+ {
+ case BT_OP_STATUS_SUCCESS:
+ retStatus = BT_STATUS_BT_OP_SUCCESS;
+ DBG_8192C("[MPT], BT status : BT_STATUS_SUCCESS\n");
+ break;
+ case BT_OP_STATUS_VERSION_MISMATCH:
+ retStatus = BT_STATUS_OPCODE_L_VERSION_MISMATCH;
+ DBG_8192C("[MPT], BT status : BT_STATUS_OPCODE_L_VERSION_MISMATCH\n");
+ break;
+ case BT_OP_STATUS_UNKNOWN_OPCODE:
+ retStatus = BT_STATUS_UNKNOWN_OPCODE_L;
+ DBG_8192C("[MPT], BT status : BT_STATUS_UNKNOWN_OPCODE_L\n");
+ break;
+ case BT_OP_STATUS_ERROR_PARAMETER:
+ retStatus = BT_STATUS_PARAMETER_FORMAT_ERROR_L;
+ DBG_8192C("[MPT], BT status : BT_STATUS_PARAMETER_FORMAT_ERROR_L\n");
+ break;
+ default:
+ retStatus = BT_STATUS_UNKNOWN_STATUS_L;
+ DBG_8192C("[MPT], BT status : BT_STATUS_UNKNOWN_STATUS_L\n");
+ break;
+ }
+
+ return retStatus;
+}
+
+
+
+BT_CTRL_STATUS
+mptbt_BtFwOpCodeProcess(
+ PADAPTER Adapter,
+ u1Byte btFwOpCode,
+ u1Byte opCodeVer,
+ pu1Byte pH2cPar,
+ u1Byte h2cParaLen
+ )
+{
+ u1Byte H2C_Parameter[6] ={0};
+ PBT_H2C pH2c=(PBT_H2C)&H2C_Parameter[0];
+ PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
+ PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
+ u2Byte paraLen=0,i;
+ BT_CTRL_STATUS h2cStatus=BT_STATUS_H2C_SUCCESS, c2hStatus=BT_STATUS_C2H_SUCCESS;
+ BT_CTRL_STATUS retStatus=BT_STATUS_H2C_BT_NO_RSP;
+
+ pH2c->opCode = btFwOpCode;
+ pH2c->opCodeVer = opCodeVer;
+ pH2c->reqNum = pMptCtx->h2cReqNum;
+ //PlatformMoveMemory(&pH2c->buf[0], pH2cPar, h2cParaLen);
+ //_rtw_memcpy(&pH2c->buf[0], pH2cPar, h2cParaLen);
+ _rtw_memcpy(pH2c->buf, pH2cPar, h2cParaLen);
+
+ DBG_8192C("[MPT], pH2c->opCode=%d\n", pH2c->opCode);
+ DBG_8192C("[MPT], pH2c->opCodeVer=%d\n", pH2c->opCodeVer);
+ DBG_8192C("[MPT], pH2c->reqNum=%d\n", pH2c->reqNum);
+ DBG_8192C("[MPT], h2c parameter length=%d\n", h2cParaLen);
+ if(h2cParaLen)
+ {
+ DBG_8192C("[MPT], parameters(hex): \n");
+ for(i=0;i<h2cParaLen;i++)
+ {
+ DBG_8192C(" 0x%x \n", pH2c->buf[i]);
+ }
+ }
+
+ h2cStatus = mptbt_SendH2c(Adapter, pH2c, h2cParaLen+2);
+ if(BT_STATUS_H2C_SUCCESS == h2cStatus)
+ {
+ // if reach here, it means H2C get the correct c2h response,
+ c2hStatus = mptbt_CheckC2hFrame(Adapter, pH2c, pExtC2h);
+ if(BT_STATUS_C2H_SUCCESS == c2hStatus)
+ {
+ retStatus = mptbt_CheckBtRspStatus(Adapter, pExtC2h);
+ }
+ else
+ {
+ DBG_8192C("[MPT], Error!! C2H failed for pH2c->opCode=%d\n", pH2c->opCode);
+ // check c2h status error, return error status code to upper layer.
+ retStatus = c2hStatus;
+ }
+ }
+ else
+ {
+ DBG_8192C("[MPT], Error!! H2C failed for pH2c->opCode=%d\n", pH2c->opCode);
+ // check h2c status error, return error status code to upper layer.
+ retStatus = h2cStatus;
+ }
+
+ return retStatus;
+}
+
+
+
+
+u2Byte
+mptbt_BtReady(
+ PADAPTER Adapter,
+ PBT_REQ_CMD pBtReq,
+ PBT_RSP_CMD pBtRsp
+ )
+{
+ u1Byte h2cParaBuf[6] ={0};
+ u1Byte h2cParaLen=0;
+ u2Byte paraLen=0;
+ u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
+ u1Byte btOpcode;
+ u1Byte btOpcodeVer=0;
+ PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
+ PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
+ u1Byte i;
+ u1Byte btFwVer=0, bdAddr[6]={0};
+ u2Byte btRealFwVer=0;
+ pu2Byte pu2Tmp=NULL;
+
+ //
+ // check upper layer parameters
+ //
+
+ // 1. check upper layer opcode version
+ if(pBtReq->opCodeVer != 1)
+ {
+ DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
+ pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
+ return paraLen;
+ }
+
+ pBtRsp->pParamStart[0] = MP_BT_NOT_READY;
+ paraLen = 10;
+ //
+ // execute lower layer opcodes
+ //
+
+ // Get BT FW version
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_GET_BT_VERSION;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ else
+ {
+ pu2Tmp = (pu2Byte)&pExtC2h->buf[0];
+ btRealFwVer = *pu2Tmp;
+ btFwVer = pExtC2h->buf[1];
+ DBG_8192C("[MPT], btRealFwVer=0x%x, btFwVer=0x%x\n", btRealFwVer, btFwVer);
+ }
+
+ // Get BD Address
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_GET_BD_ADDR_L;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ else
+ {
+ bdAddr[5] = pExtC2h->buf[0];
+ bdAddr[4] = pExtC2h->buf[1];
+ bdAddr[3] = pExtC2h->buf[2];
+ }
+
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_GET_BD_ADDR_H;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ else
+ {
+ bdAddr[2] = pExtC2h->buf[0];
+ bdAddr[1] = pExtC2h->buf[1];
+ bdAddr[0] = pExtC2h->buf[2];
+ }
+ DBG_8192C("[MPT], Local BDAddr:");
+ for(i=0; i<6; i++)
+ {
+ DBG_8192C(" 0x%x ", bdAddr[i]);
+ }
+ pBtRsp->status = BT_STATUS_SUCCESS;
+ pBtRsp->pParamStart[0] = MP_BT_READY;
+ pu2Tmp = (pu2Byte)&pBtRsp->pParamStart[1];
+ *pu2Tmp = btRealFwVer;
+ pBtRsp->pParamStart[3] = btFwVer;
+ for(i=0; i<6; i++)
+ {
+ pBtRsp->pParamStart[4+i] = bdAddr[5-i];
+ }
+
+ return paraLen;
+}
+
+void mptbt_close_WiFiRF(PADAPTER Adapter)
+{
+ PHY_SetBBReg(Adapter, 0x824, 0xF, 0x0);
+ PHY_SetBBReg(Adapter, 0x824, 0x700000, 0x0);
+ PHY_SetRFReg(Adapter, RF90_PATH_A, 0x0, 0xF0000, 0x0);
+}
+
+void mptbt_open_WiFiRF(PADAPTER Adapter)
+{
+ PHY_SetBBReg(Adapter, 0x824, 0x700000, 0x3);
+ PHY_SetBBReg(Adapter, 0x824, 0xF, 0x2);
+ PHY_SetRFReg(Adapter, RF90_PATH_A, 0x0, 0xF0000, 0x3);
+}
+
+u4Byte mptbt_switch_RF(PADAPTER Adapter, u1Byte Enter)
+{
+ u2Byte tmp_2byte = 0;
+
+ //Enter test mode
+ if (Enter) {
+ ////1>. close WiFi RF
+ mptbt_close_WiFiRF(Adapter);
+
+ ////2>. change ant switch to BT
+ tmp_2byte = rtw_read16(Adapter, 0x860);
+ tmp_2byte = tmp_2byte | BIT(9);
+ tmp_2byte = tmp_2byte & (~BIT(8));
+ rtw_write16(Adapter, 0x860, tmp_2byte);
+ rtw_write16(Adapter, 0x870, 0x300);
+ } else {
+ ////1>. Open WiFi RF
+ mptbt_open_WiFiRF(Adapter);
+
+ ////2>. change ant switch back
+ tmp_2byte = rtw_read16(Adapter, 0x860);
+ tmp_2byte = tmp_2byte | BIT(8);
+ tmp_2byte = tmp_2byte & (~BIT(9));
+ rtw_write16(Adapter, 0x860, tmp_2byte);
+ rtw_write16(Adapter, 0x870, 0x300);
+ }
+
+ return 0;
+}
+
+u2Byte
+mptbt_BtSetMode(
+ PADAPTER Adapter,
+ PBT_REQ_CMD pBtReq,
+ PBT_RSP_CMD pBtRsp
+ )
+{
+ u1Byte h2cParaBuf[6] ={0};
+ u1Byte h2cParaLen=0;
+ u2Byte paraLen=0;
+ u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
+ u1Byte btOpcode;
+ u1Byte btOpcodeVer=0;
+ u1Byte btModeToSet=0;
+
+ //
+ // check upper layer parameters
+ //
+ // 1. check upper layer opcode version
+ if(pBtReq->opCodeVer != 1)
+ {
+ DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
+ pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
+ return paraLen;
+ }
+ // 2. check upper layer parameter length
+ if(1 == pBtReq->paraLength)
+ {
+ btModeToSet = pBtReq->pParamStart[0];
+ DBG_8192C("[MPT], BtTestMode=%d \n", btModeToSet);
+ }
+ else
+ {
+ DBG_8192C("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength);
+ pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
+ return paraLen;
+ }
+
+ //
+ // execute lower layer opcodes
+ //
+
+ // 1. fill h2c parameters
+ // check bt mode
+ btOpcode = BT_LO_OP_SET_BT_MODE;
+ if(btModeToSet >= MP_BT_MODE_MAX)
+ {
+ pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ else
+ {
+ mptbt_switch_RF(Adapter, 1);
+
+ h2cParaBuf[0] = btModeToSet;
+ h2cParaLen = 1;
+ // 2. execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ }
+
+ // 3. construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS == retStatus)
+ {
+ pBtRsp->status = BT_STATUS_SUCCESS;
+ }
+ else
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ }
+
+ return paraLen;
+}
+
+
+VOID
+MPTBT_FwC2hBtMpCtrl(
+ PADAPTER Adapter,
+ pu1Byte tmpBuf,
+ u1Byte length
+ )
+{
+ u32 i;
+ PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
+ PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)tmpBuf;
+
+ if(Adapter->bBTFWReady == _FALSE || Adapter->registrypriv.mp_mode == 0 )
+ {
+ DBG_8192C("[MPT], %s,bBTFWReady == _FALSE\n",__func__);
+ return;
+ }
+ //cancel_timeout for h2c handle
+ _cancel_timer_ex( &pMptCtx->MPh2c_timeout_timer);
+
+ DBG_8192C("[MPT], MPTBT_FwC2hBtMpCtrl(), hex: \n");
+ for(i=0;i<=length;i++)
+ {
+ //DBG_8192C("[MPT], MPTBT_FwC2hBtMpCtrl(), hex: \n",tmpBuf[i], length);
+ DBG_8192C(" 0x%x ",tmpBuf[i]);
+ }
+ DBG_8192C("\n [MPT], pExtC2h->extendId=0x%x\n", pExtC2h->extendId);
+
+ switch(pExtC2h->extendId)
+ {
+ case EXT_C2H_WIFI_FW_ACTIVE_RSP:
+ DBG_8192C("[MPT], EXT_C2H_WIFI_FW_ACTIVE_RSP\n");
+ DBG_8192C("[MPT], pExtC2h->buf hex: \n");
+ if( length > 32 || length < 3 )
+ break ;
+ for(i=0;i<=(length-3);i++)
+ DBG_8192C(" 0x%x ",pExtC2h->buf[i]);
+ //PlatformSetEvent(&pMptCtx->MptH2cRspEvent);
+ pMptCtx->MptH2cRspEvent=_TRUE;
+ _rtw_up_sema(&pMptCtx->MPh2c_Sema);
+ break;
+ case EXT_C2H_TRIG_BY_BT_FW:
+ DBG_8192C("[MPT], EXT_C2H_TRIG_BY_BT_FW\n");
+ //PlatformMoveMemory(&pMptCtx->c2hBuf[0], tmpBuf, length);
+ _rtw_memcpy(&pMptCtx->c2hBuf[0], tmpBuf, length);
+ DBG_8192C("[MPT], pExtC2h->statusCode=0x%x\n", pExtC2h->statusCode);
+ DBG_8192C("[MPT], pExtC2h->retLen=0x%x\n", pExtC2h->retLen);
+ DBG_8192C("[MPT], pExtC2h->opCodeVer=0x%x\n", pExtC2h->opCodeVer);
+ DBG_8192C("[MPT], pExtC2h->reqNum=0x%x\n", pExtC2h->reqNum);
+ DBG_8192C("[MPT], pExtC2h->buf hex: \n");
+ for(i=0;i<=(length-3);i++)
+ DBG_8192C(" 0x%x ",pExtC2h->buf[0]);
+ //PlatformSetEvent(&pMptCtx->MptBtC2hEvent);
+ pMptCtx->MptBtC2hEvent=_TRUE;
+ _rtw_up_sema(&pMptCtx->MPh2c_Sema);
+ break;
+ default:
+ DBG_8192C("[MPT], EXT_C2H Target not found,pExtC2h->extendId =%d ,pExtC2h->reqNum=%d\n",pExtC2h->extendId,pExtC2h->reqNum);
+ break;
+ }
+
+
+
+}
+
+
+u2Byte
+mptbt_BtGetGeneral(
+ IN PADAPTER Adapter,
+ IN PBT_REQ_CMD pBtReq,
+ IN PBT_RSP_CMD pBtRsp
+ )
+{
+ PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
+ PBT_EXT_C2H pExtC2h=(PBT_EXT_C2H)&pMptCtx->c2hBuf[0];
+ u1Byte h2cParaBuf[6] ={0};
+ u1Byte h2cParaLen=0;
+ u2Byte paraLen=0;
+ u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
+ u1Byte btOpcode, bdAddr[6]={0};
+ u1Byte btOpcodeVer=0;
+ u1Byte getType=0, i;
+ u2Byte getParaLen=0, validParaLen=0;
+ u1Byte regType=0, reportType=0;
+ u4Byte regAddr=0, regValue=0;
+ pu4Byte pu4Tmp;
+ pu2Byte pu2Tmp;
+ pu1Byte pu1Tmp;
+
+ //
+ // check upper layer parameters
+ //
+
+ // check upper layer opcode version
+ if(pBtReq->opCodeVer != 1)
+ {
+ DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
+ pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
+ return paraLen;
+ }
+ // check upper layer parameter length
+ if(pBtReq->paraLength < 1)
+ {
+ DBG_8192C("[MPT], Error!! wrong parameter length=%d (should larger than 1)\n", pBtReq->paraLength);
+ pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
+ return paraLen;
+ }
+ getParaLen = pBtReq->paraLength - 1;
+ getType = pBtReq->pParamStart[0];
+
+ DBG_8192C("[MPT], getType=%d, getParaLen=%d\n", getType, getParaLen);
+
+ // check parameter first
+ switch(getType)
+ {
+ case BT_GGET_REG:
+ DBG_8192C("[MPT], [BT_GGET_REG]\n");
+ validParaLen = 5;
+ if(getParaLen == validParaLen)
+ {
+ btOpcode = BT_LO_OP_READ_REG;
+ regType = pBtReq->pParamStart[1];
+ pu4Tmp = (pu4Byte)&pBtReq->pParamStart[2];
+ regAddr = *pu4Tmp;
+ DBG_8192C("[MPT], BT_GGET_REG regType=0x%x, regAddr=0x%x!!\n",
+ regType, regAddr);
+ if(regType >= BT_REG_MAX)
+ {
+ pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ else
+ {
+ if( ((BT_REG_RF==regType)&&(regAddr>0x7f)) ||
+ ((BT_REG_MODEM==regType)&&(regAddr>0x1ff)) ||
+ ((BT_REG_BLUEWIZE==regType)&&(regAddr>0xfff)) ||
+ ((BT_REG_VENDOR==regType)&&(regAddr>0xfff)) ||
+ ((BT_REG_LE==regType)&&(regAddr>0xfff)) )
+ {
+ pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ }
+ }
+ break;
+ case BT_GGET_STATUS:
+ DBG_8192C("[MPT], [BT_GGET_STATUS]\n");
+ validParaLen = 0;
+ break;
+ case BT_GGET_REPORT:
+ DBG_8192C("[MPT], [BT_GGET_REPORT]\n");
+ validParaLen = 1;
+ if(getParaLen == validParaLen)
+ {
+ reportType = pBtReq->pParamStart[1];
+ DBG_8192C("[MPT], BT_GGET_REPORT reportType=0x%x!!\n", reportType);
+ if(reportType >= BT_REPORT_MAX)
+ {
+ pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ }
+ break;
+ default:
+ {
+ DBG_8192C("[MPT], Error!! getType=%d, out of range\n", getType);
+ pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ break;
+ }
+ if(getParaLen != validParaLen)
+ {
+ DBG_8192C("[MPT], Error!! wrong parameter length=%d for BT_GET_GEN_CMD cmd id=0x%x, paraLen should=0x%x\n",
+ getParaLen, getType, validParaLen);
+ pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
+ return paraLen;
+ }
+
+ //
+ // execute lower layer opcodes
+ //
+ if(BT_GGET_REG == getType)
+ {
+ // fill h2c parameters
+ // here we should write reg value first then write the address, adviced by Austin
+ btOpcode = BT_LO_OP_READ_REG;
+ h2cParaBuf[0] = regType;
+ h2cParaBuf[1] = pBtReq->pParamStart[2];
+ h2cParaBuf[2] = pBtReq->pParamStart[3];
+ h2cParaLen = 3;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ pu2Tmp = (pu2Byte)&pExtC2h->buf[0];
+ regValue = *pu2Tmp;
+ DBG_8192C("[MPT], read reg regType=0x%x, regAddr=0x%x, regValue=0x%x\n",
+ regType, regAddr, regValue);
+
+ pu4Tmp = (pu4Byte)&pBtRsp->pParamStart[0];
+ *pu4Tmp = regValue;
+ paraLen = 4;
+ }
+ else if(BT_GGET_STATUS == getType)
+ {
+ btOpcode = BT_LO_OP_GET_BT_STATUS;
+ h2cParaLen = 0;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ pBtRsp->pParamStart[0] = pExtC2h->buf[0];
+ pBtRsp->pParamStart[1] = pExtC2h->buf[1];
+ DBG_8192C("[MPT], read bt status, testMode=0x%x, testStatus=0x%x\n",
+ pBtRsp->pParamStart[0], pBtRsp->pParamStart[1]);
+ paraLen = 2;
+ }
+ else if(BT_GGET_REPORT == getType)
+ {
+ switch(reportType)
+ {
+ case BT_REPORT_RX_PACKET_CNT:
+ {
+ DBG_8192C("[MPT], [Rx Packet Counts]\n");
+ btOpcode = BT_LO_OP_GET_RX_PKT_CNT_L;
+ h2cParaLen = 0;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ pBtRsp->pParamStart[0] = pExtC2h->buf[0];
+ pBtRsp->pParamStart[1] = pExtC2h->buf[1];
+
+ btOpcode = BT_LO_OP_GET_RX_PKT_CNT_H;
+ h2cParaLen = 0;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ pBtRsp->pParamStart[2] = pExtC2h->buf[0];
+ pBtRsp->pParamStart[3] = pExtC2h->buf[1];
+ paraLen = 4;
+ }
+ break;
+ case BT_REPORT_RX_ERROR_BITS:
+ {
+ DBG_8192C("[MPT], [Rx Error Bits]\n");
+ btOpcode = BT_LO_OP_GET_RX_ERROR_BITS_L;
+ h2cParaLen = 0;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ pBtRsp->pParamStart[0] = pExtC2h->buf[0];
+ pBtRsp->pParamStart[1] = pExtC2h->buf[1];
+
+ btOpcode = BT_LO_OP_GET_RX_ERROR_BITS_H;
+ h2cParaLen = 0;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ pBtRsp->pParamStart[2] = pExtC2h->buf[0];
+ pBtRsp->pParamStart[3] = pExtC2h->buf[1];
+ paraLen = 4;
+ }
+ break;
+ case BT_REPORT_RSSI:
+ {
+ DBG_8192C("[MPT], [RSSI]\n");
+ btOpcode = BT_LO_OP_GET_RSSI;
+ h2cParaLen = 0;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ pBtRsp->pParamStart[0] = pExtC2h->buf[0];
+ pBtRsp->pParamStart[1] = pExtC2h->buf[1];
+ paraLen = 2;
+ }
+ break;
+ case BT_REPORT_CFO_HDR_QUALITY:
+ {
+ DBG_8192C("[MPT], [CFO & Header Quality]\n");
+ btOpcode = BT_LO_OP_GET_CFO_HDR_QUALITY_L;
+ h2cParaLen = 0;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ pBtRsp->pParamStart[0] = pExtC2h->buf[0];
+ pBtRsp->pParamStart[1] = pExtC2h->buf[1];
+
+ btOpcode = BT_LO_OP_GET_CFO_HDR_QUALITY_H;
+ h2cParaLen = 0;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ pBtRsp->pParamStart[2] = pExtC2h->buf[0];
+ pBtRsp->pParamStart[3] = pExtC2h->buf[1];
+ paraLen = 4;
+ }
+ break;
+ case BT_REPORT_CONNECT_TARGET_BD_ADDR:
+ {
+ DBG_8192C("[MPT], [Connected Target BD ADDR]\n");
+ btOpcode = BT_LO_OP_GET_TARGET_BD_ADDR_L;
+ h2cParaLen = 0;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ bdAddr[5] = pExtC2h->buf[0];
+ bdAddr[4] = pExtC2h->buf[1];
+ bdAddr[3] = pExtC2h->buf[2];
+
+ btOpcode = BT_LO_OP_GET_TARGET_BD_ADDR_H;
+ h2cParaLen = 0;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ bdAddr[2] = pExtC2h->buf[0];
+ bdAddr[1] = pExtC2h->buf[1];
+ bdAddr[0] = pExtC2h->buf[2];
+
+ DBG_8192C("[MPT], Connected Target BDAddr:%s", bdAddr);
+ for(i=0; i<6; i++)
+ {
+ pBtRsp->pParamStart[i] = bdAddr[5-i];
+ }
+ paraLen = 6;
+ }
+ break;
+ default:
+ pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ break;
+ }
+ }
+
+ pBtRsp->status = BT_STATUS_SUCCESS;
+ return paraLen;
+}
+
+
+
+u2Byte
+mptbt_BtSetGeneral(
+ IN PADAPTER Adapter,
+ IN PBT_REQ_CMD pBtReq,
+ IN PBT_RSP_CMD pBtRsp
+ )
+{
+ u1Byte h2cParaBuf[6] ={0};
+ u1Byte h2cParaLen=0;
+ u2Byte paraLen=0;
+ u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
+ u1Byte btOpcode;
+ u1Byte btOpcodeVer=0;
+ u1Byte setType=0;
+ u2Byte setParaLen=0, validParaLen=0;
+ u1Byte regType=0, bdAddr[6]={0}, calVal=0;
+ u4Byte regAddr=0, regValue=0;
+ pu4Byte pu4Tmp;
+ pu2Byte pu2Tmp;
+ pu1Byte pu1Tmp;
+
+ //
+ // check upper layer parameters
+ //
+
+ // check upper layer opcode version
+ if(pBtReq->opCodeVer != 1)
+ {
+ DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
+ pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
+ return paraLen;
+ }
+ // check upper layer parameter length
+ if(pBtReq->paraLength < 1)
+ {
+ DBG_8192C("[MPT], Error!! wrong parameter length=%d (should larger than 1)\n", pBtReq->paraLength);
+ pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
+ return paraLen;
+ }
+ setParaLen = pBtReq->paraLength - 1;
+ setType = pBtReq->pParamStart[0];
+
+ DBG_8192C("[MPT], setType=%d, setParaLen=%d\n", setType, setParaLen);
+
+ // check parameter first
+ switch(setType)
+ {
+ case BT_GSET_REG:
+ DBG_8192C ("[MPT], [BT_GSET_REG]\n");
+ validParaLen = 9;
+ if(setParaLen == validParaLen)
+ {
+ btOpcode = BT_LO_OP_WRITE_REG_VALUE;
+ regType = pBtReq->pParamStart[1];
+ pu4Tmp = (pu4Byte)&pBtReq->pParamStart[2];
+ regAddr = *pu4Tmp;
+ pu4Tmp = (pu4Byte)&pBtReq->pParamStart[6];
+ regValue = *pu4Tmp;
+ DBG_8192C("[MPT], BT_GSET_REG regType=0x%x, regAddr=0x%x, regValue=0x%x!!\n",
+ regType, regAddr, regValue);
+ if(regType >= BT_REG_MAX)
+ {
+ pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ else
+ {
+ if( ((BT_REG_RF==regType)&&(regAddr>0x7f)) ||
+ ((BT_REG_MODEM==regType)&&(regAddr>0x1ff)) ||
+ ((BT_REG_BLUEWIZE==regType)&&(regAddr>0xfff)) ||
+ ((BT_REG_VENDOR==regType)&&(regAddr>0xfff)) ||
+ ((BT_REG_LE==regType)&&(regAddr>0xfff)) )
+ {
+ pBtRsp->status = (btOpcode<<8)| BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ }
+ }
+ break;
+ case BT_GSET_RESET:
+ DBG_8192C("[MPT], [BT_GSET_RESET]\n");
+ validParaLen = 0;
+ break;
+ case BT_GSET_TARGET_BD_ADDR:
+ DBG_8192C("[MPT], [BT_GSET_TARGET_BD_ADDR]\n");
+ validParaLen = 6;
+ if(setParaLen == validParaLen)
+ {
+ btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_H;
+ if( (pBtReq->pParamStart[1]==0) &&
+ (pBtReq->pParamStart[2]==0) &&
+ (pBtReq->pParamStart[3]==0) &&
+ (pBtReq->pParamStart[4]==0) &&
+ (pBtReq->pParamStart[5]==0) &&
+ (pBtReq->pParamStart[6]==0) )
+ {
+ DBG_8192C("[MPT], Error!! targetBDAddr=all zero\n");
+ pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ if( (pBtReq->pParamStart[1]==0xff) &&
+ (pBtReq->pParamStart[2]==0xff) &&
+ (pBtReq->pParamStart[3]==0xff) &&
+ (pBtReq->pParamStart[4]==0xff) &&
+ (pBtReq->pParamStart[5]==0xff) &&
+ (pBtReq->pParamStart[6]==0xff) )
+ {
+ DBG_8192C("[MPT], Error!! targetBDAddr=all 0xf\n");
+ pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ bdAddr[0] = pBtReq->pParamStart[6];
+ bdAddr[1] = pBtReq->pParamStart[5];
+ bdAddr[2] = pBtReq->pParamStart[4];
+ bdAddr[3] = pBtReq->pParamStart[3];
+ bdAddr[4] = pBtReq->pParamStart[2];
+ bdAddr[5] = pBtReq->pParamStart[1];
+ DBG_8192C ("[MPT], target BDAddr:%x,%x,%x,%x,%x,%x\n",
+ bdAddr[0],bdAddr[1],bdAddr[2],bdAddr[3],bdAddr[4],bdAddr[5]);
+ }
+ break;
+ case BT_GSET_TX_PWR_FINETUNE:
+ DBG_8192C("[MPT], [BT_GSET_TX_PWR_FINETUNE]\n");
+ validParaLen = 1;
+ if(setParaLen == validParaLen)
+ {
+ btOpcode = BT_LO_OP_SET_TX_POWER_CALIBRATION;
+ calVal = pBtReq->pParamStart[1];
+ if( (calVal<1) || (calVal>9) )
+ {
+ pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ DBG_8192C ("[MPT], calVal=%d\n", calVal);
+ }
+ break;
+ case BT_SET_TRACKING_INTERVAL:
+ DBG_871X("[MPT], [BT_SET_TRACKING_INTERVAL] setParaLen =%d \n",setParaLen);
+
+ validParaLen = 1;
+ if(setParaLen == validParaLen)
+ calVal = pBtReq->pParamStart[1];
+ break;
+ case BT_SET_THERMAL_METER:
+ DBG_871X("[MPT], [BT_SET_THERMAL_METER] setParaLen =%d \n",setParaLen);
+ validParaLen = 1;
+ if(setParaLen == validParaLen)
+ calVal = pBtReq->pParamStart[1];
+ break;
+ case BT_ENABLE_CFO_TRACKING:
+ DBG_871X("[MPT], [BT_ENABLE_CFO_TRACKING] setParaLen =%d \n",setParaLen);
+ validParaLen = 1;
+ if(setParaLen == validParaLen)
+ calVal = pBtReq->pParamStart[1];
+ break;
+ case BT_GSET_UPDATE_BT_PATCH:
+ if(IS_HARDWARE_TYPE_8723AE(Adapter) && Adapter->bFWReady)
+ {
+ u1Byte i;
+ DBG_8192C ("[MPT], write regs for load patch\n");
+ //BTFwPatch8723A(Adapter);
+ PlatformEFIOWrite1Byte(Adapter, 0xCC, 0x2d);
+ rtw_msleep_os(50);
+ PlatformEFIOWrite4Byte(Adapter, 0x68, 0xa005000c);
+ rtw_msleep_os(50);
+ PlatformEFIOWrite4Byte(Adapter, 0x68, 0xb005000c);
+ rtw_msleep_os(50);
+ PlatformEFIOWrite1Byte(Adapter, 0xCC, 0x29);
+ for(i=0; i<12; i++)
+ rtw_msleep_os(100);
+//#if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
+// BTFwPatch8723A(Adapter);
+//#endif
+ DBG_8192C("[MPT], load BT FW Patch finished!!!\n");
+ }
+ break;
+ default:
+ {
+ DBG_8192C ("[MPT], Error!! setType=%d, out of range\n", setType);
+ pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ break;
+ }
+ if(setParaLen != validParaLen)
+ {
+ DBG_8192C("[MPT], Error!! wrong parameter length=%d for BT_SET_GEN_CMD cmd id=0x%x, paraLen should=0x%x\n",
+ setParaLen, setType, validParaLen);
+ pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
+ return paraLen;
+ }
+
+ //
+ // execute lower layer opcodes
+ //
+ if(BT_GSET_REG == setType)
+ {
+ // fill h2c parameters
+ // here we should write reg value first then write the address, adviced by Austin
+ btOpcode = BT_LO_OP_WRITE_REG_VALUE;
+ h2cParaBuf[0] = pBtReq->pParamStart[6];
+ h2cParaBuf[1] = pBtReq->pParamStart[7];
+ h2cParaBuf[2] = pBtReq->pParamStart[8];
+ h2cParaLen = 3;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ // write reg address
+ btOpcode = BT_LO_OP_WRITE_REG_ADDR;
+ h2cParaBuf[0] = regType;
+ h2cParaBuf[1] = pBtReq->pParamStart[2];
+ h2cParaBuf[2] = pBtReq->pParamStart[3];
+ h2cParaLen = 3;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ }
+ else if(BT_GSET_RESET == setType)
+ {
+ btOpcode = BT_LO_OP_RESET;
+ h2cParaLen = 0;
+ // execute h2c and check respond c2h from bt fw is correct or not
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ }
+ else if(BT_GSET_TARGET_BD_ADDR == setType)
+ {
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_L;
+ h2cParaBuf[0] = pBtReq->pParamStart[1];
+ h2cParaBuf[1] = pBtReq->pParamStart[2];
+ h2cParaBuf[2] = pBtReq->pParamStart[3];
+ h2cParaLen = 3;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ btOpcode = BT_LO_OP_SET_TARGET_BD_ADDR_H;
+ h2cParaBuf[0] = pBtReq->pParamStart[4];
+ h2cParaBuf[1] = pBtReq->pParamStart[5];
+ h2cParaBuf[2] = pBtReq->pParamStart[6];
+ h2cParaLen = 3;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ }
+ else if(BT_GSET_TX_PWR_FINETUNE == setType)
+ {
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_SET_TX_POWER_CALIBRATION;
+ h2cParaBuf[0] = calVal;
+ h2cParaLen = 1;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ }
+ else if(BT_SET_TRACKING_INTERVAL == setType)
+ {
+ // BT_LO_OP_SET_TRACKING_INTERVAL = 0x22,
+ // BT_LO_OP_SET_THERMAL_METER = 0x23,
+ // BT_LO_OP_ENABLE_CFO_TRACKING = 0x24,
+ btOpcode = BT_LO_OP_SET_TRACKING_INTERVAL;
+ h2cParaBuf[0] = calVal;
+ h2cParaLen = 1;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ }
+ else if(BT_SET_THERMAL_METER == setType)
+ {
+ btOpcode = BT_LO_OP_SET_THERMAL_METER;
+ h2cParaBuf[0] = calVal;
+ h2cParaLen = 1;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ }
+ else if(BT_ENABLE_CFO_TRACKING == setType)
+ {
+ btOpcode = BT_LO_OP_ENABLE_CFO_TRACKING;
+ h2cParaBuf[0] = calVal;
+ h2cParaLen = 1;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+ }
+
+ pBtRsp->status = BT_STATUS_SUCCESS;
+ return paraLen;
+}
+
+
+
+u2Byte
+mptbt_BtSetTxRxPars(
+ IN PADAPTER Adapter,
+ IN PBT_REQ_CMD pBtReq,
+ IN PBT_RSP_CMD pBtRsp
+ )
+{
+ u1Byte h2cParaBuf[6] ={0};
+ u1Byte h2cParaLen=0;
+ u2Byte paraLen=0;
+ u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
+ u1Byte btOpcode;
+ u1Byte btOpcodeVer=0;
+ PBT_TXRX_PARAMETERS pTxRxPars=(PBT_TXRX_PARAMETERS)&pBtReq->pParamStart[0];
+ u2Byte lenTxRx=sizeof(BT_TXRX_PARAMETERS);
+ u1Byte i;
+ u1Byte bdAddr[6]={0};
+
+ //
+ // check upper layer parameters
+ //
+
+ // 1. check upper layer opcode version
+ if(pBtReq->opCodeVer != 1)
+ {
+ DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
+ pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
+ return paraLen;
+ }
+ // 2. check upper layer parameter length
+ if(pBtReq->paraLength == sizeof(BT_TXRX_PARAMETERS))
+ {
+ DBG_8192C ("[MPT], pTxRxPars->txrxChannel=0x%x \n", pTxRxPars->txrxChannel);
+ DBG_8192C ("[MPT], pTxRxPars->txrxTxPktCnt=0x%8x \n", pTxRxPars->txrxTxPktCnt);
+ DBG_8192C ("[MPT], pTxRxPars->txrxTxPktInterval=0x%x \n", pTxRxPars->txrxTxPktInterval);
+ DBG_8192C ("[MPT], pTxRxPars->txrxPayloadType=0x%x \n", pTxRxPars->txrxPayloadType);
+ DBG_8192C ("[MPT], pTxRxPars->txrxPktType=0x%x \n", pTxRxPars->txrxPktType);
+ DBG_8192C ("[MPT], pTxRxPars->txrxPayloadLen=0x%x \n", pTxRxPars->txrxPayloadLen);
+ DBG_8192C ("[MPT], pTxRxPars->txrxPktHeader=0x%x \n", pTxRxPars->txrxPktHeader);
+ DBG_8192C ("[MPT], pTxRxPars->txrxWhitenCoeff=0x%x \n", pTxRxPars->txrxWhitenCoeff);
+ bdAddr[0] = pTxRxPars->txrxBdaddr[5];
+ bdAddr[1] = pTxRxPars->txrxBdaddr[4];
+ bdAddr[2] = pTxRxPars->txrxBdaddr[3];
+ bdAddr[3] = pTxRxPars->txrxBdaddr[2];
+ bdAddr[4] = pTxRxPars->txrxBdaddr[1];
+ bdAddr[5] = pTxRxPars->txrxBdaddr[0];
+ DBG_8192C ("[MPT], pTxRxPars->txrxBdaddr: %s", &bdAddr[0]);
+ DBG_8192C ("[MPT], pTxRxPars->txrxTxGainIndex=0x%x \n", pTxRxPars->txrxTxGainIndex);
+ }
+ else
+ {
+ DBG_8192C ("[MPT], Error!! pBtReq->paraLength=%d, correct Len=%d\n", pBtReq->paraLength, lenTxRx);
+ pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
+ return paraLen;
+ }
+
+ //
+ // execute lower layer opcodes
+ //
+
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_SET_PKT_HEADER;
+ if(pTxRxPars->txrxPktHeader > 0x3ffff)
+ {
+ DBG_8192C ("[MPT], Error!! pTxRxPars->txrxPktHeader=0x%x is out of range, (should be between 0x0~0x3ffff)\n", pTxRxPars->txrxPktHeader);
+ pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ else
+ {
+ h2cParaBuf[0] = (u1Byte)(pTxRxPars->txrxPktHeader&0xff);
+ h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxPktHeader&0xff00)>>8);
+ h2cParaBuf[2] = (u1Byte)((pTxRxPars->txrxPktHeader&0xff0000)>>16);
+ h2cParaLen = 3;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ }
+
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_SET_PKT_TYPE_LEN;
+ {
+ u2Byte payloadLenLimit=0;
+ switch(pTxRxPars->txrxPktType)
+ {
+ case MP_BT_PKT_DH1:
+ payloadLenLimit = 27*8;
+ break;
+ case MP_BT_PKT_DH3:
+ payloadLenLimit = 183*8;
+ break;
+ case MP_BT_PKT_DH5:
+ payloadLenLimit = 339*8;
+ break;
+ case MP_BT_PKT_2DH1:
+ payloadLenLimit = 54*8;
+ break;
+ case MP_BT_PKT_2DH3:
+ payloadLenLimit = 367*8;
+ break;
+ case MP_BT_PKT_2DH5:
+ payloadLenLimit = 679*8;
+ break;
+ case MP_BT_PKT_3DH1:
+ payloadLenLimit = 83*8;
+ break;
+ case MP_BT_PKT_3DH3:
+ payloadLenLimit = 552*8;
+ break;
+ case MP_BT_PKT_3DH5:
+ payloadLenLimit = 1021*8;
+ break;
+ case MP_BT_PKT_LE:
+ payloadLenLimit = 39*8;
+ break;
+ default:
+ {
+ DBG_8192C ("[MPT], Error!! Unknown pTxRxPars->txrxPktType=0x%x\n", pTxRxPars->txrxPktType);
+ pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ break;
+ }
+
+ if(pTxRxPars->txrxPayloadLen > payloadLenLimit)
+ {
+ DBG_8192C ("[MPT], Error!! pTxRxPars->txrxPayloadLen=0x%x, (should smaller than %d)\n",
+ pTxRxPars->txrxPayloadLen, payloadLenLimit);
+ pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+
+ h2cParaBuf[0] = pTxRxPars->txrxPktType;
+ h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxPayloadLen&0xff));
+ h2cParaBuf[2] = (u1Byte)((pTxRxPars->txrxPayloadLen&0xff00)>>8);
+ h2cParaLen = 3;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ }
+
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_SET_PKT_CNT_L_PL_TYPE;
+ if(pTxRxPars->txrxPayloadType > MP_BT_PAYLOAD_MAX)
+ {
+ DBG_8192C ("[MPT], Error!! pTxRxPars->txrxPayloadType=0x%x, (should be between 0~4)\n", pTxRxPars->txrxPayloadType);
+ pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ else
+ {
+ h2cParaBuf[0] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff));
+ h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff00)>>8);
+ h2cParaBuf[2] = pTxRxPars->txrxPayloadType;
+ h2cParaLen = 3;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ }
+
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_SET_PKT_CNT_H_PKT_INTV;
+ if(pTxRxPars->txrxTxPktInterval > 15)
+ {
+ DBG_8192C ("[MPT], Error!! pTxRxPars->txrxTxPktInterval=0x%x, (should be between 0~15)\n", pTxRxPars->txrxTxPktInterval);
+ pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ else
+ {
+ h2cParaBuf[0] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff0000)>>16);
+ h2cParaBuf[1] = (u1Byte)((pTxRxPars->txrxTxPktCnt&0xff000000)>>24);
+ h2cParaBuf[2] = pTxRxPars->txrxTxPktInterval;
+ h2cParaLen = 3;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ }
+
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_SET_WHITENCOEFF;
+ {
+ h2cParaBuf[0] = pTxRxPars->txrxWhitenCoeff;
+ h2cParaLen = 1;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ }
+
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_SET_CHNL_TX_GAIN;
+ if( (pTxRxPars->txrxChannel > 78) ||
+ (pTxRxPars->txrxTxGainIndex > 7) )
+ {
+ DBG_8192C ("[MPT], Error!! pTxRxPars->txrxChannel=0x%x, (should be between 0~78)\n", pTxRxPars->txrxChannel);
+ DBG_8192C ("[MPT], Error!! pTxRxPars->txrxTxGainIndex=0x%x, (should be between 0~7)\n", pTxRxPars->txrxTxGainIndex);
+ pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ else
+ {
+ h2cParaBuf[0] = pTxRxPars->txrxChannel;
+ h2cParaBuf[1] = pTxRxPars->txrxTxGainIndex;
+ h2cParaLen = 2;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ }
+
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ // fill h2c parameters
+ btOpcode = BT_LO_OP_SET_BD_ADDR_L;
+ if( (pTxRxPars->txrxBdaddr[0]==0) &&
+ (pTxRxPars->txrxBdaddr[1]==0) &&
+ (pTxRxPars->txrxBdaddr[2]==0) &&
+ (pTxRxPars->txrxBdaddr[3]==0) &&
+ (pTxRxPars->txrxBdaddr[4]==0) &&
+ (pTxRxPars->txrxBdaddr[5]==0) )
+ {
+ DBG_8192C ("[MPT], Error!! pTxRxPars->txrxBdaddr=all zero\n");
+ pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ if( (pTxRxPars->txrxBdaddr[0]==0xff) &&
+ (pTxRxPars->txrxBdaddr[1]==0xff) &&
+ (pTxRxPars->txrxBdaddr[2]==0xff) &&
+ (pTxRxPars->txrxBdaddr[3]==0xff) &&
+ (pTxRxPars->txrxBdaddr[4]==0xff) &&
+ (pTxRxPars->txrxBdaddr[5]==0xff) )
+ {
+ DBG_8192C ("[MPT], Error!! pTxRxPars->txrxBdaddr=all 0xf\n");
+ pBtRsp->status = (btOpcode<<8)|BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+
+ {
+ h2cParaBuf[0] = pTxRxPars->txrxBdaddr[0];
+ h2cParaBuf[1] = pTxRxPars->txrxBdaddr[1];
+ h2cParaBuf[2] = pTxRxPars->txrxBdaddr[2];
+ h2cParaLen = 3;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ }
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ btOpcode = BT_LO_OP_SET_BD_ADDR_H;
+ {
+ h2cParaBuf[0] = pTxRxPars->txrxBdaddr[3];
+ h2cParaBuf[1] = pTxRxPars->txrxBdaddr[4];
+ h2cParaBuf[2] = pTxRxPars->txrxBdaddr[5];
+ h2cParaLen = 3;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ }
+ // ckeck bt return status.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C ("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ pBtRsp->status = BT_STATUS_SUCCESS;
+ return paraLen;
+}
+
+
+
+u2Byte
+mptbt_BtTestCtrl(
+ IN PADAPTER Adapter,
+ IN PBT_REQ_CMD pBtReq,
+ IN PBT_RSP_CMD pBtRsp
+ )
+{
+ u1Byte h2cParaBuf[6] ={0};
+ u1Byte h2cParaLen=0;
+ u2Byte paraLen=0;
+ u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
+ u1Byte btOpcode;
+ u1Byte btOpcodeVer=0;
+ u1Byte testCtrl=0;
+
+ //
+ // check upper layer parameters
+ //
+
+ // 1. check upper layer opcode version
+ if(pBtReq->opCodeVer != 1)
+ {
+ DBG_8192C("[MPT], Error!! Upper OP code version not match!!!\n");
+ pBtRsp->status = BT_STATUS_OPCODE_U_VERSION_MISMATCH;
+ return paraLen;
+ }
+ // 2. check upper layer parameter length
+ if(1 == pBtReq->paraLength)
+ {
+ testCtrl = pBtReq->pParamStart[0];
+ DBG_8192C("[MPT], testCtrl=%d \n", testCtrl);
+ }
+ else
+ {
+ DBG_8192C("[MPT], Error!! wrong parameter length=%d (should be 1)\n", pBtReq->paraLength);
+ pBtRsp->status = BT_STATUS_PARAMETER_FORMAT_ERROR_U;
+ return paraLen;
+ }
+
+ //
+ // execute lower layer opcodes
+ //
+
+ // 1. fill h2c parameters
+ // check bt mode
+ btOpcode = BT_LO_OP_TEST_CTRL;
+ if(testCtrl >= MP_BT_TEST_MAX)
+ {
+ DBG_8192C("[MPT], Error!! testCtrl=0x%x, (should be between smaller or equal to 0x%x)\n",
+ testCtrl, MP_BT_TEST_MAX-1);
+ pBtRsp->status = BT_STATUS_PARAMETER_OUT_OF_RANGE_U;
+ return paraLen;
+ }
+ else
+ {
+ h2cParaBuf[0] = testCtrl;
+ h2cParaLen = 1;
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ }
+
+ // 3. construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ pBtRsp->status = BT_STATUS_SUCCESS;
+ return paraLen;
+}
+
+
+u2Byte
+mptbt_TestBT(
+ IN PADAPTER Adapter,
+ IN PBT_REQ_CMD pBtReq,
+ IN PBT_RSP_CMD pBtRsp
+ )
+{
+
+ u1Byte h2cParaBuf[6] ={0};
+ u1Byte h2cParaLen=0;
+ u2Byte paraLen=0;
+ u1Byte retStatus=BT_STATUS_BT_OP_SUCCESS;
+ u1Byte btOpcode;
+ u1Byte btOpcodeVer=0;
+ u1Byte testCtrl=0;
+
+ // 1. fill h2c parameters
+ btOpcode = 0x11;
+ h2cParaBuf[0] = 0x11;
+ h2cParaBuf[1] = 0x0;
+ h2cParaBuf[2] = 0x0;
+ h2cParaBuf[3] = 0x0;
+ h2cParaBuf[4] = 0x0;
+ h2cParaLen = 1;
+ // retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, &h2cParaBuf[0], h2cParaLen);
+ retStatus = mptbt_BtFwOpCodeProcess(Adapter, btOpcode, btOpcodeVer, h2cParaBuf, h2cParaLen);
+
+
+ // 3. construct respond status code and data.
+ if(BT_STATUS_BT_OP_SUCCESS != retStatus)
+ {
+ pBtRsp->status = ((btOpcode<<8)|retStatus);
+ DBG_8192C("[MPT], Error!! status code=0x%x \n", pBtRsp->status);
+ return paraLen;
+ }
+
+ pBtRsp->status = BT_STATUS_SUCCESS;
+ return paraLen;
+}
+
+VOID
+mptbt_BtControlProcess(
+ PADAPTER Adapter,
+ PVOID pInBuf
+ )
+{
+ u1Byte H2C_Parameter[6] ={0};
+ PBT_H2C pH2c=(PBT_H2C)&H2C_Parameter[0];
+ PMPT_CONTEXT pMptCtx=&(Adapter->mppriv.MptCtx);
+ PBT_REQ_CMD pBtReq=(PBT_REQ_CMD)pInBuf;
+ PBT_RSP_CMD pBtRsp=(PBT_RSP_CMD)&pMptCtx->mptOutBuf[0];
+ u1Byte i;
+
+ DBG_8192C("[MPT], mptbt_BtControlProcess()=========>\n");
+
+ DBG_8192C("[MPT], input opCodeVer=%d\n", pBtReq->opCodeVer);
+ DBG_8192C("[MPT], input OpCode=%d\n", pBtReq->OpCode);
+ DBG_8192C("[MPT], paraLength=%d \n", pBtReq->paraLength);
+ if(pBtReq->paraLength)
+ {
+ //DBG_8192C("[MPT], parameters(hex):0x%x %d \n",&pBtReq->pParamStart[0], pBtReq->paraLength);
+ }
+
+ // The following we should maintain the User OP codes sent by upper layer
+
+ pBtRsp->status = BT_STATUS_SUCCESS;
+ pMptCtx->mptOutLen = 4; //length of (BT_RSP_CMD.status+BT_RSP_CMD.paraLength)
+ pBtRsp->paraLength = 0x0;
+
+ _rtw_memset((PVOID)&pMptCtx->mptOutBuf[0], '\0',100);
+
+ switch(pBtReq->OpCode)
+ {
+ case BT_UP_OP_BT_READY:
+ DBG_8192C("[MPT], OPcode : [BT_READY]\n");
+ pBtRsp->paraLength = mptbt_BtReady(Adapter, pBtReq, pBtRsp);
+ break;
+ case BT_UP_OP_BT_SET_MODE:
+ DBG_8192C("[MPT], OPcode : [BT_SET_MODE]\n");
+ pBtRsp->paraLength = mptbt_BtSetMode(Adapter, pBtReq, pBtRsp);
+ break;
+ case BT_UP_OP_BT_SET_TX_RX_PARAMETER:
+ DBG_8192C("[MPT], OPcode : [BT_SET_TXRX_PARAMETER]\n");
+ pBtRsp->paraLength = mptbt_BtSetTxRxPars(Adapter, pBtReq, pBtRsp);
+ break;
+ case BT_UP_OP_BT_SET_GENERAL:
+ DBG_8192C("[MPT], OPcode : [BT_SET_GENERAL]\n");
+ pBtRsp->paraLength = mptbt_BtSetGeneral(Adapter, pBtReq, pBtRsp);
+ break;
+ case BT_UP_OP_BT_GET_GENERAL:
+ DBG_8192C("[MPT], OPcode : [BT_GET_GENERAL]\n");
+ pBtRsp->paraLength = mptbt_BtGetGeneral(Adapter, pBtReq, pBtRsp);
+ break;
+ case BT_UP_OP_BT_TEST_CTRL:
+ DBG_8192C("[MPT], OPcode : [BT_TEST_CTRL]\n");
+ pBtRsp->paraLength = mptbt_BtTestCtrl(Adapter, pBtReq, pBtRsp);
+ break;
+ case BT_UP_OP_TEST_BT:
+ DBG_8192C("[MPT], OPcode : [TEST_BT]\n");
+ pBtRsp->paraLength = mptbt_TestBT(Adapter, pBtReq, pBtRsp);
+ break;
+ default:
+ DBG_8192C("[MPT], Error!! OPcode : UNDEFINED!!!!\n");
+ pBtRsp->status = BT_STATUS_UNKNOWN_OPCODE_U;
+ pBtRsp->paraLength = 0x0;
+ break;
+ }
+
+ DBG_8192C("pBtRsp->paraLength =%d \n",pBtRsp->paraLength);
+
+ pMptCtx->mptOutLen += pBtRsp->paraLength;
+
+ DBG_8192C("\n [MPT], OUT to DLL pMptCtx->mptOutLen=%d ,pBtRsp->paraLength =%d ",pMptCtx->mptOutLen,pBtRsp->paraLength);
+
+ DBG_8192C("\n [MPT], mptbt_BtControlProcess()<=========\n");
+}
+
+#endif
+
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_cmd.c b/drivers/net/wireless/rtl8723as/core/rtw_cmd.c
index 75d1e766c698..5da4fb23be54 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_cmd.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_cmd.c
@@ -182,6 +182,7 @@ _func_enter_;
rtw_mfree(c2h, 16);
}
}
+ rtw_cbuf_free(pevtpriv->c2h_queue);
#endif
RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("-_rtw_free_evt_priv \n"));
@@ -309,7 +310,7 @@ int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj)
#ifdef SUPPORT_HW_RFOFF_DETECTED
//To decide allow or not
- if( (pcmdpriv->padapter->pwrctrlpriv.bHWPwrPindetect)
+ if( (adapter_to_pwrctl(pcmdpriv->padapter)->bHWPwrPindetect)
&&(!pcmdpriv->padapter->registrypriv.usbss_enable)
)
{
@@ -426,6 +427,18 @@ _func_enter_;
_func_exit_;
}
+
+void rtw_stop_cmd_thread(_adapter *adapter)
+{
+ if(adapter->cmdThread && adapter->cmdpriv.cmdthd_running == _TRUE
+ && adapter->cmdpriv.stop_req == 0)
+ {
+ adapter->cmdpriv.stop_req = 1;
+ _rtw_up_sema(&adapter->cmdpriv.cmd_queue_sema);
+ _rtw_down_sema(&adapter->cmdpriv.terminate_cmdthread_sema);
+ }
+}
+
thread_return rtw_cmd_thread(thread_context context)
{
u8 ret;
@@ -443,6 +456,7 @@ _func_enter_;
pcmdbuf = pcmdpriv->cmd_buf;
prspbuf = pcmdpriv->rsp_buf;
+ pcmdpriv->stop_req = 0;
pcmdpriv->cmdthd_running=_TRUE;
_rtw_up_sema(&pcmdpriv->terminate_cmdthread_sema);
@@ -450,16 +464,29 @@ _func_enter_;
while(1)
{
- if (_rtw_down_sema(&pcmdpriv->cmd_queue_sema) == _FAIL)
+ if (_rtw_down_sema(&pcmdpriv->cmd_queue_sema) == _FAIL) {
+ DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" _rtw_down_sema(&pcmdpriv->cmd_queue_sema) return _FAIL, break\n", FUNC_ADPT_ARG(padapter));
break;
+ }
if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved == _TRUE))
{
- DBG_871X("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
+ DBG_871X_LEVEL(_drv_always_, "%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
__FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__);
break;
}
+ if (pcmdpriv->stop_req) {
+ DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" stop_req:%u, break\n", FUNC_ADPT_ARG(padapter), pcmdpriv->stop_req);
+ break;
+ }
+
+ if(rtw_is_list_empty(&(pcmdpriv->cmd_queue.queue)))
+ {
+ //DBG_871X("%s: cmd queue is empty!\n", __func__);
+ continue;
+ }
+
#ifdef CONFIG_LPS_LCLK
if (rtw_register_cmd_alive(padapter) != _SUCCESS)
{
@@ -472,7 +499,7 @@ _func_enter_;
_next:
if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE))
{
- DBG_871X("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
+ DBG_871X_LEVEL(_drv_always_, "%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
__FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__);
break;
}
@@ -774,7 +801,7 @@ _func_enter_;
#ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE)
- _set_timer(&pmlmepriv->scan_to_timer, SURVEY_TO * ( 38 + ( 38 / RTW_SCAN_NUM_OF_CH ) * RTW_STAY_AP_CH_MILLISECOND ) + 1000 );
+ _set_timer(&pmlmepriv->scan_to_timer, SURVEY_TO * ( padapter->mlmeextpriv.max_chan_nums + ( padapter->mlmeextpriv.max_chan_nums / RTW_SCAN_NUM_OF_CH ) * RTW_STAY_AP_CH_MILLISECOND ) + 1000 );
else
#endif //CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
_set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT);
@@ -1302,11 +1329,11 @@ _func_enter_;
pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength);
if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_TENDA)
- padapter->pwrctrlpriv.smart_ps = 0;
+ adapter_to_pwrctl(padapter)->smart_ps = 0;
else
- padapter->pwrctrlpriv.smart_ps = padapter->registrypriv.smart_ps;
+ adapter_to_pwrctl(padapter)->smart_ps = padapter->registrypriv.smart_ps;
- DBG_871X("%s: smart_ps=%d\n", __func__, padapter->pwrctrlpriv.smart_ps);
+ DBG_871X("%s: smart_ps=%d\n", __func__, adapter_to_pwrctl(padapter)->smart_ps);
#if 0
psecuritypriv->supplicant_ie[0]=(u8)psecnetwork->IELength;
@@ -1400,7 +1427,7 @@ _func_exit_;
return res;
}
-u8 rtw_setopmode_cmd(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
+u8 rtw_setopmode_cmd(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE networktype, bool enqueue)
{
struct cmd_obj* ph2c;
struct setopmode_parm* psetop;
@@ -1409,25 +1436,29 @@ u8 rtw_setopmode_cmd(_adapter *padapter, NDIS_802_11_NETWORK_INFRASTRUCTURE net
u8 res=_SUCCESS;
_func_enter_;
-
- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
- if(ph2c==NULL){
- res= _FALSE;
- goto exit;
- }
psetop = (struct setopmode_parm*)rtw_zmalloc(sizeof(struct setopmode_parm));
- if(psetop==NULL){
- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));
- res=_FALSE;
+ if(psetop==NULL){
+ res=_FAIL;
goto exit;
}
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
psetop->mode = (u8)networktype;
+
+ if(enqueue){
+ ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
+ if(ph2c==NULL){
+ rtw_mfree((u8 *)psetop, sizeof(*psetop));
+ res= _FAIL;
+ goto exit;
+ }
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
-
+ init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
+ res = rtw_enqueue_cmd(pcmdpriv, ph2c);
+ }
+ else{
+ setopmode_hdl(padapter, (u8 *)psetop);
+ rtw_mfree((u8 *)psetop, sizeof(*psetop));
+ }
exit:
_func_exit_;
@@ -1435,7 +1466,7 @@ _func_exit_;
return res;
}
-u8 rtw_setstakey_cmd(_adapter *padapter, u8 *psta, u8 unicast_key)
+u8 rtw_setstakey_cmd(_adapter *padapter, u8 *psta, u8 unicast_key, bool enqueue)
{
struct cmd_obj* ph2c;
struct set_stakey_parm *psetstakey_para;
@@ -1449,40 +1480,21 @@ u8 rtw_setstakey_cmd(_adapter *padapter, u8 *psta, u8 unicast_key)
_func_enter_;
- ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
- if ( ph2c == NULL){
- res= _FAIL;
- goto exit;
- }
-
psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm));
- if(psetstakey_para==NULL){
- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));
+ if(psetstakey_para==NULL){
res=_FAIL;
goto exit;
}
-
- psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp));
- if(psetstakey_rsp == NULL){
- rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));
- rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
- res=_FAIL;
- goto exit;
- }
-
- init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
- ph2c->rsp = (u8 *) psetstakey_rsp;
- ph2c->rspsz = sizeof(struct set_stakey_rsp);
-
+
_rtw_memcpy(psetstakey_para->addr, sta->hwaddr,ETH_ALEN);
-
+
if(check_fwstate(pmlmepriv, WIFI_STATION_STATE)){
#ifdef CONFIG_TDLS
if(sta->tdls_sta_state&TDLS_LINKED_STATE)
psetstakey_para->algorithm=(u8)sta->dot118021XPrivacy;
else
#endif //CONFIG_TDLS
- psetstakey_para->algorithm =(unsigned char) psecuritypriv->dot11PrivacyAlgrthm;
+ psetstakey_para->algorithm =(unsigned char) psecuritypriv->dot11PrivacyAlgrthm;
}else{
GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, _FALSE);
}
@@ -1494,15 +1506,40 @@ _func_enter_;
else
#endif //CONFIG_TDLS
_rtw_memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16);
- } else {
+ }
+ else {
_rtw_memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16);
- }
+ }
//jeff: set this becasue at least sw key is ready
padapter->securitypriv.busetkipkey=_TRUE;
- res = rtw_enqueue_cmd(pcmdpriv, ph2c);
+ if(enqueue)
+ {
+ ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
+ if ( ph2c == NULL){
+ rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
+ res= _FAIL;
+ goto exit;
+ }
+ psetstakey_rsp = (struct set_stakey_rsp*)rtw_zmalloc(sizeof(struct set_stakey_rsp));
+ if(psetstakey_rsp == NULL){
+ rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));
+ rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
+ res=_FAIL;
+ goto exit;
+ }
+
+ init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
+ ph2c->rsp = (u8 *) psetstakey_rsp;
+ ph2c->rspsz = sizeof(struct set_stakey_rsp);
+ res = rtw_enqueue_cmd(pcmdpriv, ph2c);
+ }
+ else{
+ set_stakey_hdl(padapter, (u8 *)psetstakey_para);
+ rtw_mfree((u8 *) psetstakey_para, sizeof(struct set_stakey_parm));
+ }
exit:
_func_exit_;
@@ -1727,6 +1764,86 @@ _func_exit_;
return res;
}
+//add for CONFIG_IEEE80211W, none 11w can use it
+u8 rtw_reset_securitypriv_cmd(_adapter*padapter)
+{
+ struct cmd_obj* ph2c;
+ struct drvextra_cmd_parm *pdrvextra_cmd_parm;
+ struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
+ u8 res=_SUCCESS;
+
+_func_enter_;
+
+ ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
+ if(ph2c==NULL){
+ res= _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+ if(pdrvextra_cmd_parm==NULL){
+ rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
+ res= _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm->ec_id = RESET_SECURITYPRIV;
+ pdrvextra_cmd_parm->type_size = 0;
+ pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
+
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
+
+
+ //rtw_enqueue_cmd(pcmdpriv, ph2c);
+ res = rtw_enqueue_cmd(pcmdpriv, ph2c);
+
+exit:
+
+_func_exit_;
+
+ return res;
+
+}
+
+u8 rtw_free_assoc_resources_cmd(_adapter*padapter)
+{
+ struct cmd_obj* ph2c;
+ struct drvextra_cmd_parm *pdrvextra_cmd_parm;
+ struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
+ u8 res=_SUCCESS;
+
+_func_enter_;
+
+ ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
+ if(ph2c==NULL){
+ res= _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+ if(pdrvextra_cmd_parm==NULL){
+ rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
+ res= _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm->ec_id = FREE_ASSOC_RESOURCES;
+ pdrvextra_cmd_parm->type_size = 0;
+ pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
+
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
+
+
+ //rtw_enqueue_cmd(pcmdpriv, ph2c);
+ res = rtw_enqueue_cmd(pcmdpriv, ph2c);
+
+exit:
+
+_func_exit_;
+
+ return res;
+
+}
u8 rtw_dynamic_chk_wk_cmd(_adapter*padapter)
{
@@ -2007,12 +2124,60 @@ _func_exit_;
return res;
}
+#ifdef CONFIG_DETECT_C2H_BY_POLLING
+u8 rtw_event_polling_cmd(_adapter*padapter)
+{
+ struct cmd_obj* ph2c;
+ struct drvextra_cmd_parm *pdrvextra_cmd_parm;
+ struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
+ u8 res=_SUCCESS;
+
+_func_enter_;
+
+#if defined(CONFIG_CONCURRENT_MODE)
+ if (padapter->adapter_type != PRIMARY_ADAPTER)
+ {
+ return _FAIL;
+ }
+#endif
+
+ ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
+ if(ph2c==NULL){
+ res= _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
+ if(pdrvextra_cmd_parm==NULL){
+ rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
+ res= _FAIL;
+ goto exit;
+ }
+
+ pdrvextra_cmd_parm->ec_id = EVENT_POLLING_CID;
+ pdrvextra_cmd_parm->type_size = 0;
+ pdrvextra_cmd_parm->pbuf = (u8 *)padapter;
+
+ init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
+
+
+ //rtw_enqueue_cmd(pcmdpriv, ph2c);
+ res = rtw_enqueue_cmd(pcmdpriv, ph2c);
+
+exit:
+
+ _func_exit_;
+
+ return res;
+}
+#endif
+
static void traffic_status_watchdog(_adapter *padapter)
{
#ifdef CONFIG_LPS
u8 bEnterPS;
#endif
- u16 BusyThreshold = 100;
+ u16 BusyThreshold = 200;// 100;
u8 bBusyTraffic = _FALSE, bTxBusyTraffic = _FALSE, bRxBusyTraffic = _FALSE;
u8 bHigherBusyTraffic = _FALSE, bHigherBusyRxTraffic = _FALSE, bHigherBusyTxTraffic = _FALSE;
#ifdef CONFIG_FTP_PROTECT
@@ -2023,23 +2188,19 @@ static void traffic_status_watchdog(_adapter *padapter)
struct tdls_info *ptdlsinfo = &(padapter->tdlsinfo);
#endif //CONFIG_TDLS
+ RT_LINK_DETECT_T * link_detect = &pmlmepriv->LinkDetectInfo;
+
//
// Determine if our traffic is busy now
//
if((check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
/*&& !MgntInitAdapterInProgress(pMgntInfo)*/)
{
-
-#ifdef CONFIG_BT_COEXIST
- if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 50 ||
- pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 50 )
-#else // !CONFIG_BT_COEXIST
// if we raise bBusyTraffic in last watchdog, using lower threshold.
if (pmlmepriv->LinkDetectInfo.bBusyTraffic)
- BusyThreshold = 75;
+ BusyThreshold =180; // 75;
if( pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold ||
pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold )
-#endif // !CONFIG_BT_COEXIST
{
bBusyTraffic = _TRUE;
@@ -2076,7 +2237,25 @@ static void traffic_status_watchdog(_adapter *padapter)
rtw_unlock_suspend();
}
#endif //CONFIG_KEEP_FTP_TRANSMIT
-
+
+#ifdef CONFIG_TRAFFIC_PROTECT
+#define TX_ACTIVE_TH 2
+#define RX_ACTIVE_TH 1
+#define TRAFFIC_PROTECT_PERIOD_MS 4500
+
+ if (link_detect->NumTxOkInPeriod > TX_ACTIVE_TH
+ || link_detect->NumRxUnicastOkInPeriod > RX_ACTIVE_TH) {
+
+ DBG_871X_LEVEL(_drv_info_, FUNC_ADPT_FMT" acqiure wake_lock for %u ms(tx:%d,rx_unicast:%d)\n",
+ FUNC_ADPT_ARG(padapter),
+ TRAFFIC_PROTECT_PERIOD_MS,
+ link_detect->NumTxOkInPeriod,
+ link_detect->NumRxUnicastOkInPeriod);
+
+ rtw_lock_suspend_timeout(TRAFFIC_PROTECT_PERIOD_MS);
+ }
+#endif
+
#ifdef CONFIG_TDLS
#ifdef CONFIG_TDLS_AUTOSETUP
if( ( ptdlsinfo->watchdog_count % TDLS_WATCHDOG_PERIOD ) == 0 ) //10 * 2sec, periodically sending
@@ -2176,7 +2355,7 @@ void dynamic_chk_wk_hdl(_adapter *padapter, u8 *pbuf, int sz)
void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type);
void lps_ctrl_wk_hdl(_adapter *padapter, u8 lps_ctrl_type)
{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
u8 mstatus;
@@ -2211,7 +2390,7 @@ _func_enter_;
//DBG_871X("LPS_CTRL_CONNECT \n");
mstatus = 1;//connect
// Reset LPS Setting
- padapter->pwrctrlpriv.LpsIdleCount = 0;
+ pwrpriv->LpsIdleCount = 0;
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus));
#ifdef CONFIG_BT_COEXIST
BT_WifiMediaStatusNotify(padapter, mstatus);
@@ -2263,7 +2442,7 @@ u8 rtw_lps_ctrl_wk_cmd(_adapter*padapter, u8 lps_ctrl_type, u8 enqueue)
struct cmd_obj *ph2c;
struct drvextra_cmd_parm *pdrvextra_cmd_parm;
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
- //struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
+ //struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
u8 res = _SUCCESS;
_func_enter_;
@@ -2271,6 +2450,11 @@ _func_enter_;
//if(!pwrctrlpriv->bLeisurePs)
// return res;
+#ifdef CONFIG_CONCURRENT_MODE
+ if (padapter->iface_type != IFACE_PORT0)
+ return res;
+#endif
+
if(enqueue)
{
ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
@@ -2410,6 +2594,17 @@ void power_saving_wk_hdl(_adapter *padapter, u8 *pbuf, int sz)
rtw_ps_processor(padapter);
}
+//add for CONFIG_IEEE80211W, none 11w can use it
+void reset_securitypriv_hdl(_adapter *padapter)
+{
+ rtw_reset_securitypriv(padapter);
+}
+
+void free_assoc_resources_hdl(_adapter *padapter)
+{
+ rtw_free_assoc_resources(padapter, 1);
+}
+
#ifdef CONFIG_P2P
u8 p2p_protocol_wk_cmd(_adapter*padapter, int intCmdType )
{
@@ -2683,6 +2878,51 @@ static void c2h_wk_callback(_workitem *work)
}
#endif
+#ifdef CONFIG_DETECT_C2H_BY_POLLING
+void event_polling_hdl(_adapter *padapter, u8 *pbuf, int sz)
+{
+ c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(padapter);
+ u8 check_c2hcmd, check_ccx;
+
+ //check_c2hcmd = rtw_read8(padapter, REG_C2HEVT_CLEAR);
+ //check_ccx= rtw_read8(padapter, REG_C2HEVT_MSG_NORMAL);
+
+ rtw_hal_get_hwreg(padapter, HW_VAR_C2HEVT_CLEAR, (u8 *)(&check_c2hcmd));
+ rtw_hal_get_hwreg(padapter, HW_VAR_C2HEVT_MSG_NORMAL, (u8 *)(&check_ccx));
+
+ if (check_c2hcmd != 0)
+ {
+ struct c2h_evt_hdr *c2h_evt;
+
+ if (check_c2hcmd != 0xFF)
+ {
+ c2h_evt_clear(padapter);
+ }
+ else if (ccx_id_filter(check_ccx & 0x0F) == _FALSE)
+ {
+ if ((c2h_evt = (struct c2h_evt_hdr *)rtw_zmalloc(16)) != NULL) {
+ if (c2h_evt_read(padapter, (u8 *)c2h_evt) == _SUCCESS) {
+ rtw_hal_c2h_handler(padapter, c2h_evt);
+ }
+ rtw_mfree((u8*)c2h_evt, 16);
+ } else {
+ /* Error handling for malloc fail */
+ if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, (void*)NULL) != _SUCCESS)
+ DBG_871X("%s rtw_cbuf_push fail\n", __func__);
+ _set_workitem(&padapter->evtpriv.c2h_wk);
+ }
+ }
+ else
+ {
+ if (padapter->xmitpriv.ack_tx == _FALSE)
+ {
+ c2h_evt_clear(padapter);
+ }
+ }
+ }
+}
+#endif
+
u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf)
{
struct drvextra_cmd_parm *pdrvextra_cmd;
@@ -2735,11 +2975,21 @@ u8 rtw_drvextra_cmd_hdl(_adapter *padapter, unsigned char *pbuf)
intel_widi_wk_hdl(padapter, pdrvextra_cmd->type_size, pdrvextra_cmd->pbuf);
break;
#endif //CONFIG_INTEL_WIDI
-
+ //add for CONFIG_IEEE80211W, none 11w can use it
+ case RESET_SECURITYPRIV:
+ reset_securitypriv_hdl(padapter);
+ break;
+ case FREE_ASSOC_RESOURCES:
+ free_assoc_resources_hdl(padapter);
+ break;
case C2H_WK_CID:
c2h_evt_hdl(padapter, (struct c2h_evt_hdr *)pdrvextra_cmd->pbuf, NULL);
break;
-
+#ifdef CONFIG_DETECT_C2H_BY_POLLING
+ case EVENT_POLLING_CID:
+ event_polling_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size);
+ break;
+#endif
default:
break;
}
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_debug.c b/drivers/net/wireless/rtl8723as/core/rtw_debug.c
index 509ed8106410..d2fc13c061b9 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_debug.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_debug.c
@@ -76,6 +76,20 @@ int proc_get_drv_version(char *page, char **start,
return len;
}
+#ifdef DBG_MEM_ALLOC
+int proc_get_mstat(char *page, char **start,
+ off_t offset, int count,
+ int *eof, void *data)
+{
+ int len = 0;
+
+ len += _rtw_mstat_dump(page+len, count-len);
+ *eof = 1;
+
+ return len;
+}
+#endif /* DBG_MEM_ALLOC */
+
int proc_get_write_reg(char *page, char **start,
off_t offset, int count,
int *eof, void *data)
@@ -1121,6 +1135,31 @@ int proc_get_best_channel(char *page, char **start,
return len;
}
+
+int proc_set_best_channel(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ char tmp[32];
+
+ if(count < 1)
+ return -EFAULT;
+
+ if(buffer && !copy_from_user(tmp, buffer, sizeof(tmp)))
+ {
+ int i;
+ for(i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++)
+ {
+ pmlmeext->channel_set[i].rx_count = 0;
+ }
+
+ DBG_871X("set %s\n", "Clean Best Channel Count");
+ }
+
+ return count;
+}
#endif /* CONFIG_FIND_BEST_CHANNEL */
#ifdef CONFIG_BT_COEXIST
#define _bt_dbg_off_ 0
@@ -1214,5 +1253,118 @@ int proc_set_sreset(struct file *file, const char *buffer, unsigned long count,
}
#endif /* DBG_CONFIG_ERROR_DETECT */
+int proc_get_odm_dbg_comp(char *page, char **start, off_t offset, int count, int *eof, void *data)
+{
+ struct net_device *dev = data;
+ _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
+ int len = 0;
+
+ len += _rtw_odm_dbg_comp_msg(adapter, page, count);
+
+ *eof = 1;
+ return len;
+}
+
+int proc_set_odm_dbg_comp(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
+ char tmp[32];
+
+ u64 dbg_comp;
+
+ if (count < 1)
+ return -EFAULT;
+
+ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
+
+ int num = sscanf(tmp, "%llx", &dbg_comp);
+
+ if (num != 1)
+ return count;
+
+ rtw_odm_dbg_comp_set(adapter, dbg_comp);
+ }
+
+ return count;
+}
+
+int proc_get_odm_dbg_level(char *page, char **start, off_t offset, int count, int *eof, void *data)
+{
+ struct net_device *dev = data;
+ _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
+ int len = 0;
+
+ len += _rtw_odm_dbg_level_msg(adapter, page, count);
+
+ *eof = 1;
+ return len;
+}
+
+int proc_set_odm_dbg_level(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ _adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
+ char tmp[32];
+
+ u32 dbg_level;
+
+ if (count < 1)
+ return -EFAULT;
+
+ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
+
+ int num = sscanf(tmp, "%u", &dbg_level);
+
+ if (num != 1)
+ return count;
+
+ rtw_odm_dbg_level_set(adapter, dbg_level);
+ }
+
+ return count;
+}
+
+int proc_get_odm_adaptivity(char *page, char **start, off_t offset, int count, int *eof, void *data)
+{
+ struct net_device *dev = data;
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
+ int len = 0;
+
+ len += _rtw_odm_adaptivity_parm_msg(padapter, page, count);
+
+ *eof = 1;
+ return len;
+}
+
+int proc_set_odm_adaptivity(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
+ char tmp[32];
+ u32 TH_L2H_ini;
+ s8 TH_EDCCA_HL_diff;
+ u32 IGI_Base;
+ int ForceEDCCA;
+ u8 AdapEn_RSSI;
+ u8 IGI_LowerBound;
+
+ if (count < 1)
+ return -EFAULT;
+
+ if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
+
+ int num = sscanf(tmp, "%x %hhd %x %d %hhu %hhu",
+ &TH_L2H_ini, &TH_EDCCA_HL_diff, &IGI_Base, &ForceEDCCA, &AdapEn_RSSI, &IGI_LowerBound);
+
+ if (num != 6)
+ return count;
+
+ rtw_odm_adaptivity_parm_set(padapter, (s8)TH_L2H_ini, TH_EDCCA_HL_diff, (s8)IGI_Base, (bool)ForceEDCCA, AdapEn_RSSI, IGI_LowerBound);
+ }
+
+ return count;
+}
+
#endif
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_ieee80211.c b/drivers/net/wireless/rtl8723as/core/rtw_ieee80211.c
index ea353d4cfe2a..af32123cbcc0 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_ieee80211.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_ieee80211.c
@@ -886,6 +886,28 @@ u8 rtw_is_wps_ie(u8 *ie_ptr, uint *wps_ielen)
return match;
}
+u8 *rtw_get_wps_ie_from_scan_queue(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen, u8 frame_type)
+{
+ u8* wps = NULL;
+
+ DBG_871X( "[%s] frame_type = %d\n", __FUNCTION__, frame_type );
+ switch( frame_type )
+ {
+ case 1:
+ case 3:
+ { // Beacon or Probe Response
+ wps = rtw_get_wps_ie(in_ie + _PROBERSP_IE_OFFSET_, in_len - _PROBERSP_IE_OFFSET_, wps_ie, wps_ielen);
+ break;
+ }
+ case 2:
+ { // Probe Request
+ wps = rtw_get_wps_ie(in_ie + _PROBEREQ_IE_OFFSET_ , in_len - _PROBEREQ_IE_OFFSET_ , wps_ie, wps_ielen);
+ break;
+ }
+ }
+ return wps;
+}
+
/**
* rtw_get_wps_ie - Search WPS IE from a series of IEs
* @in_ie: Address of IEs to search
@@ -1331,32 +1353,37 @@ void rtw_macaddr_cfg(u8 *mac_addr)
DBG_871X("rtw_macaddr_cfg MAC Address = "MAC_FMT"\n", MAC_ARG(mac_addr));
}
-void dump_ies(u8 *buf, u32 buf_len) {
+void dump_ies(u8 *buf, u32 buf_len)
+{
u8* pos = (u8*)buf;
u8 id, len;
-
+
while(pos-buf<=buf_len){
id = *pos;
len = *(pos+1);
DBG_871X("%s ID:%u, LEN:%u\n", __FUNCTION__, id, len);
+ dump_wps_ie(pos, len);
#ifdef CONFIG_P2P
dump_p2p_ie(pos, len);
+ #ifdef CONFIG_WFD
+ dump_wfd_ie(pos, len);
+ #endif
#endif
- dump_wps_ie(pos, len);
pos+=(2+len);
- }
+ }
}
-void dump_wps_ie(u8 *ie, u32 ie_len) {
+void dump_wps_ie(u8 *ie, u32 ie_len)
+{
u8* pos = (u8*)ie;
u16 id;
u16 len;
u8 *wps_ie;
uint wps_ielen;
-
+
wps_ie = rtw_get_wps_ie(ie, ie_len, NULL, &wps_ielen);
if(wps_ie != ie || wps_ielen == 0)
return;
@@ -1369,10 +1396,81 @@ void dump_wps_ie(u8 *ie, u32 ie_len) {
DBG_871X("%s ID:0x%04x, LEN:%u\n", __FUNCTION__, id, len);
pos+=(4+len);
- }
+ }
}
#ifdef CONFIG_P2P
+/**
+ * rtw_get_p2p_merged_len - Get merged ie length from muitiple p2p ies.
+ * @in_ie: Pointer of the first p2p ie
+ * @in_len: Total len of muiltiple p2p ies
+ * Returns: Length of merged p2p ie length
+ */
+u32 rtw_get_p2p_merged_ies_len(u8 *in_ie, u32 in_len)
+{
+ PNDIS_802_11_VARIABLE_IEs pIE;
+ u8 OUI[4] = { 0x50, 0x6f, 0x9a, 0x09 };
+ int i=0;
+ int j=0, len=0;
+
+ while( i < in_len)
+ {
+ pIE = (PNDIS_802_11_VARIABLE_IEs)(in_ie+ i);
+
+ if( pIE->ElementID == _VENDOR_SPECIFIC_IE_ && _rtw_memcmp(pIE->data, OUI, 4) )
+ {
+ len += pIE->Length-4; // 4 is P2P OUI length, don't count it in this loop
+ }
+
+ i += (pIE->Length + 2);
+ }
+
+ return len + 4; // Append P2P OUI length at last.
+}
+
+/**
+ * rtw_p2p_merge_ies - Merge muitiple p2p ies into one
+ * @in_ie: Pointer of the first p2p ie
+ * @in_len: Total len of muiltiple p2p ies
+ * @merge_ie: Pointer of merged ie
+ * Returns: Length of merged p2p ie
+ */
+int rtw_p2p_merge_ies(u8 *in_ie, u32 in_len, u8 *merge_ie)
+{
+ PNDIS_802_11_VARIABLE_IEs pIE;
+ u8 len = 0;
+ u8 OUI[4] = { 0x50, 0x6f, 0x9a, 0x09 };
+ u8 ELOUI[6] = { 0xDD, 0x00, 0x50, 0x6f, 0x9a, 0x09 }; //EID;Len;OUI, Len would copy at the end of function
+ int i=0;
+
+ if( merge_ie != NULL)
+ {
+ //Set first P2P OUI
+ _rtw_memcpy(merge_ie, ELOUI, 6);
+ merge_ie += 6;
+
+ while( i < in_len)
+ {
+ pIE = (PNDIS_802_11_VARIABLE_IEs)(in_ie+ i);
+
+ // Take out the rest of P2P OUIs
+ if( pIE->ElementID == _VENDOR_SPECIFIC_IE_ && _rtw_memcmp(pIE->data, OUI, 4) )
+ {
+ _rtw_memcpy( merge_ie, pIE->data +4, pIE->Length -4);
+ len += pIE->Length-4;
+ merge_ie += pIE->Length-4;
+ }
+
+ i += (pIE->Length + 2);
+ }
+
+ return len + 4; // 4 is for P2P OUI
+
+ }
+
+ return 0;
+}
+
void dump_p2p_ie(u8 *ie, u32 ie_len) {
u8* pos = (u8*)ie;
u8 id;
@@ -1396,6 +1494,28 @@ void dump_p2p_ie(u8 *ie, u32 ie_len) {
}
}
+u8 *rtw_get_p2p_ie_from_scan_queue(u8 *in_ie, int in_len, u8 *p2p_ie, uint *p2p_ielen, u8 frame_type)
+{
+ u8* p2p = NULL;
+
+ DBG_871X( "[%s] frame_type = %d\n", __FUNCTION__, frame_type );
+ switch( frame_type )
+ {
+ case 1:
+ case 3:
+ { // Beacon or Probe Response
+ p2p = rtw_get_p2p_ie(in_ie + _PROBERSP_IE_OFFSET_, in_len - _PROBERSP_IE_OFFSET_, p2p_ie, p2p_ielen);
+ break;
+ }
+ case 2:
+ { // Probe Request
+ p2p = rtw_get_p2p_ie(in_ie + _PROBEREQ_IE_OFFSET_ , in_len - _PROBEREQ_IE_OFFSET_ , p2p_ie, p2p_ielen);
+ break;
+ }
+ }
+ return p2p;
+}
+
/**
* rtw_get_p2p_ie - Search P2P IE from a series of IEs
* @in_ie: Address of IEs to search
@@ -1640,6 +1760,29 @@ void rtw_WLAN_BSSID_EX_remove_p2p_attr(WLAN_BSSID_EX *bss_ex, u8 attr_id)
#endif //CONFIG_P2P
#ifdef CONFIG_WFD
+void dump_wfd_ie(u8 *ie, u32 ie_len)
+{
+ u8* pos = (u8*)ie;
+ u8 id;
+ u16 len;
+
+ u8 *wfd_ie;
+ uint wfd_ielen;
+
+ if(rtw_get_wfd_ie(ie, ie_len, NULL, &wfd_ielen) == _FALSE)
+ return;
+
+ pos+=6;
+ while(pos-ie < ie_len){
+ id = *pos;
+ len = RTW_GET_BE16(pos+1);
+
+ DBG_871X("%s ID:%u, LEN:%u\n", __FUNCTION__, id, len);
+
+ pos+=(3+len);
+ }
+}
+
int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen)
{
int match;
@@ -1699,6 +1842,30 @@ int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen)
}
+int rtw_get_wfd_ie_from_scan_queue(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen, u8 frame_type)
+{
+ int match;
+
+ match=_FALSE;
+
+ DBG_871X( "[%s] frame_type = %d\n", __FUNCTION__, frame_type );
+ switch( frame_type )
+ {
+ case 1:
+ case 3:
+ { // Beacon or Probe Response
+ match = rtw_get_wfd_ie(in_ie + _PROBERSP_IE_OFFSET_, in_len - _PROBERSP_IE_OFFSET_, wfd_ie, wfd_ielen);
+ break;
+ }
+ case 2:
+ { // Probe Request
+ match = rtw_get_wfd_ie(in_ie + _PROBEREQ_IE_OFFSET_ , in_len - _PROBEREQ_IE_OFFSET_ , wfd_ie, wfd_ielen);
+ break;
+ }
+ }
+ return match;
+}
+
// attr_content: The output buffer, contains the "body field" of WFD attribute.
// attr_contentlen: The data length of the "body field" of WFD attribute.
int rtw_get_wfd_attr_content(u8 *wfd_ie, uint wfd_ielen, u8 target_attr_id ,u8 *attr_content, uint *attr_contentlen)
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_io.c b/drivers/net/wireless/rtl8723as/core/rtw_io.c
index 83cd2fbbd395..26797830ffc3 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_io.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_io.c
@@ -384,6 +384,32 @@ int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(struct _io_ops *po
return _SUCCESS;
}
+/*
+* Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR
+* @return _TRUE:
+* @return _FALSE:
+*/
+int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj)
+{
+ int ret = _FALSE;
+ int value;
+ if( (value=ATOMIC_INC_RETURN(&dvobj->continual_io_error)) > MAX_CONTINUAL_IO_ERR) {
+ DBG_871X("[dvobj:%p][ERROR] continual_io_error:%d > %d\n", dvobj, value, MAX_CONTINUAL_IO_ERR);
+ ret = _TRUE;
+ } else {
+ //DBG_871X("[dvobj:%p] continual_io_error:%d\n", dvobj, value);
+ }
+ return ret;
+}
+
+/*
+* Set the continual_io_error of this @param dvobjprive to 0
+*/
+void rtw_reset_continual_io_error(struct dvobj_priv *dvobj)
+{
+ ATOMIC_SET(&dvobj->continual_io_error, 0);
+}
+
#ifdef DBG_IO
u16 read_sniff_ranges[][2] = {
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_ioctl_set.c b/drivers/net/wireless/rtl8723as/core/rtw_ioctl_set.c
index 4df2e4e19425..d2d07d7ef386 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_ioctl_set.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_ioctl_set.c
@@ -47,6 +47,20 @@ extern void indicate_wx_scan_complete_event(_adapter *padapter);
(addr[4] == 0xff) && (addr[5] == 0xff) ) ? _TRUE : _FALSE \
)
+u8 rtw_validate_bssid(u8 *bssid)
+{
+ u8 ret = _TRUE;
+
+ if (is_zero_mac_addr(bssid)
+ || is_broadcast_mac_addr(bssid)
+ || is_multicast_mac_addr(bssid)
+ ) {
+ ret = _FALSE;
+ }
+
+ return ret;
+}
+
u8 rtw_validate_ssid(NDIS_802_11_SSID *ssid)
{
u8 i;
@@ -60,6 +74,7 @@ _func_enter_;
goto exit;
}
+#ifdef CONFIG_VALIDATE_SSID
for(i = 0; i < ssid->SsidLength; i++)
{
//wifi, printable ascii code must be supported
@@ -69,6 +84,7 @@ _func_enter_;
break;
}
}
+#endif /* CONFIG_VALIDATE_SSID */
exit:
@@ -374,24 +390,10 @@ _func_enter_;
}
handle_tkip_countermeasure:
- //should we add something here...?
-
-#ifdef PLATFORM_LINUX
- if (padapter->securitypriv.btkip_countermeasure == _TRUE) {
- cur_time = rtw_get_current_time();
-
- if( (cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ )
- {
- padapter->securitypriv.btkip_countermeasure = _FALSE;
- padapter->securitypriv.btkip_countermeasure_time = 0;
- }
- else
- {
- status = _FAIL;
- goto release_mlme_lock;
- }
+ if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
+ status = _FAIL;
+ goto release_mlme_lock;
}
-#endif
_rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
pmlmepriv->assoc_by_bssid=_TRUE;
@@ -506,56 +508,15 @@ _func_enter_;
}
handle_tkip_countermeasure:
-#ifdef PLATFORM_WINDOWS
- if (padapter->securitypriv.btkip_countermeasure==_TRUE)
- {
- LARGE_INTEGER sys_time;
- u32 diff_time,cur_time ;
- RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:padapter->securitypriv.btkip_countermeasure==_TRUE\n"));
- NdisGetCurrentSystemTime(&sys_time);
- cur_time=(u32)(sys_time.QuadPart/10); // In micro-second.
- RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:cur_time=0x%x\n",cur_time));
- RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:psecuritypriv->last_mic_err_time=0x%x\n",padapter->securitypriv.btkip_countermeasure_time));
- diff_time = cur_time -padapter->securitypriv.btkip_countermeasure_time; // In micro-second.
- RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid:diff_time=0x%x\n",diff_time));
-
- if (diff_time > 60000000) {
- RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid(): countermeasure time >60s.\n"));
- padapter->securitypriv.btkip_countermeasure=_FALSE;
- // Update MIC error time.
- padapter->securitypriv.btkip_countermeasure_time=0;
- } else {
- // can't join in 60 seconds.
- status = _FAIL;
- RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_info_,("rtw_set_802_11_ssid(): countermeasure time <60s.\n"));
- goto release_mlme_lock;
- }
- }
-#endif
-
-#ifdef PLATFORM_LINUX
- if (padapter->securitypriv.btkip_countermeasure == _TRUE) {
- cur_time = rtw_get_current_time();
-
- if( (cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ )
- {
- padapter->securitypriv.btkip_countermeasure = _FALSE;
- padapter->securitypriv.btkip_countermeasure_time = 0;
- }
- else
- {
- status = _FAIL;
- goto release_mlme_lock;
- }
+ if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
+ status = _FAIL;
+ goto release_mlme_lock;
}
-#endif
- #ifdef CONFIG_VALIDATE_SSID
if (rtw_validate_ssid(ssid) == _FALSE) {
status = _FAIL;
goto release_mlme_lock;
}
- #endif
_rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
pmlmepriv->assoc_by_bssid=_FALSE;
@@ -580,6 +541,79 @@ _func_exit_;
}
+u8 rtw_set_802_11_connect(_adapter* padapter, u8 *bssid, NDIS_802_11_SSID *ssid)
+{
+ _irqL irqL;
+ u8 status = _SUCCESS;
+ u32 cur_time = 0;
+ bool bssid_valid = _TRUE;
+ bool ssid_valid = _TRUE;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+_func_enter_;
+
+ if (!ssid || rtw_validate_ssid(ssid) == _FALSE)
+ ssid_valid = _FALSE;
+
+ if (!bssid || rtw_validate_bssid(bssid) == _FALSE)
+ bssid_valid = _FALSE;
+
+ if (ssid_valid == _FALSE && bssid_valid == _FALSE) {
+ DBG_871X(FUNC_ADPT_FMT" ssid:%p, ssid_valid:%d, bssid:%p, bssid_valid:%d\n",
+ FUNC_ADPT_ARG(padapter), ssid, ssid_valid, bssid, bssid_valid);
+ status = _FAIL;
+ goto exit;
+ }
+
+ if(padapter->hw_init_completed==_FALSE){
+ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
+ ("set_ssid: hw_init_completed==_FALSE=>exit!!!\n"));
+ status = _FAIL;
+ goto exit;
+ }
+
+ _enter_critical_bh(&pmlmepriv->lock, &irqL);
+
+ DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" fw_state=0x%08x\n",
+ FUNC_ADPT_ARG(padapter), get_fwstate(pmlmepriv));
+
+ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
+ goto handle_tkip_countermeasure;
+ } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
+ goto release_mlme_lock;
+ }
+
+handle_tkip_countermeasure:
+ if (rtw_handle_tkip_countermeasure(padapter, __func__) == _FAIL) {
+ status = _FAIL;
+ goto release_mlme_lock;
+ }
+
+ if (ssid && ssid_valid)
+ _rtw_memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(NDIS_802_11_SSID));
+
+ if (bssid && bssid_valid) {
+ _rtw_memcpy(&pmlmepriv->assoc_bssid, bssid, ETH_ALEN);
+ pmlmepriv->assoc_by_bssid = _TRUE;
+ }
+
+ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
+ pmlmepriv->to_join = _TRUE;
+ }
+ else {
+ status = rtw_do_join(padapter);
+ }
+
+release_mlme_lock:
+ _exit_critical_bh(&pmlmepriv->lock, &irqL);
+
+exit:
+
+_func_exit_;
+
+ return status;
+}
+
u8 rtw_set_802_11_infrastructure_mode(_adapter* padapter,
NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
{
@@ -683,7 +717,8 @@ _func_enter_;
rtw_disassoc_cmd(padapter, 0, _TRUE);
rtw_indicate_disconnect(padapter);
- rtw_free_assoc_resources(padapter, 1);
+ //modify for CONFIG_IEEE80211W, none 11w can use it
+ rtw_free_assoc_resources_cmd(padapter);
rtw_pwr_wakeup(padapter);
}
@@ -832,7 +867,7 @@ _func_enter_;
psecuritypriv->dot11DefKey[keyid].skey[9],psecuritypriv->dot11DefKey[keyid].skey[10],psecuritypriv->dot11DefKey[keyid].skey[11],
psecuritypriv->dot11DefKey[keyid].skey[12]));
- res=rtw_set_key(padapter,psecuritypriv, keyid, 1);
+ res=rtw_set_key(padapter,psecuritypriv, keyid, 1,_TRUE);
if(res==_FAIL)
ret= _FALSE;
@@ -864,7 +899,7 @@ _func_enter_;
_rtw_memset(&psecuritypriv->dot11DefKey[keyindex], 0, 16);
- res=rtw_set_key(padapter,psecuritypriv,keyindex, 0);
+ res=rtw_set_key(padapter,psecuritypriv,keyindex, 0,_TRUE);
psecuritypriv->dot11DefKeylen[keyindex]=0;
@@ -1180,7 +1215,7 @@ _func_enter_;
RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("reset group key"));
- res=rtw_set_key(padapter,&padapter->securitypriv, key->KeyIndex, 1);
+ res=rtw_set_key(padapter,&padapter->securitypriv, key->KeyIndex, 1,_TRUE);
if(res==_FAIL)
ret= _FAIL;
@@ -1230,11 +1265,11 @@ _func_enter_;
//Set key to CAM through H2C command
if(bgrouptkey)//never go to here
{
- res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _FALSE);
+ res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _FALSE, _TRUE);
RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(group)\n"));
}
else{
- res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _TRUE);
+ res=rtw_setstakey_cmd(padapter, (unsigned char *)stainfo, _TRUE, _TRUE);
RT_TRACE(_module_rtl871x_ioctl_set_c_,_drv_err_,("\n rtw_set_802_11_add_key:rtw_setstakey_cmd(unicast)\n"));
}
@@ -1441,6 +1476,8 @@ int rtw_set_country(_adapter *adapter, const char *country_code)
channel_plan = RT_CHANNEL_DOMAIN_MKK;
else if(0 == strcmp(country_code, "CN"))
channel_plan = RT_CHANNEL_DOMAIN_CHINA;
+ else if(0 == strcmp(country_code, "IN"))
+ channel_plan = RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN;
else
DBG_871X("%s unknown country_code:%s\n", __FUNCTION__, country_code);
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_led.c b/drivers/net/wireless/rtl8723as/core/rtw_led.c
index f8de4329ff45..7710f324c3a0 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_led.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_led.c
@@ -1,2422 +1,2422 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-
-#include <drv_types.h>
-
-//
-// Description:
-// Callback function of LED BlinkTimer,
-// it just schedules to corresponding BlinkWorkItem/led_blink_hdl
-//
-void BlinkTimerCallback(void *data)
-{
- PLED_871x pLed = (PLED_871x)data;
- _adapter *padapter = pLed->padapter;
-
- //DBG_871X("%s\n", __FUNCTION__);
-
- if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
- {
- //DBG_871X("%s bSurpriseRemoved:%d, bDriverStopped:%d\n", __FUNCTION__, padapter->bSurpriseRemoved, padapter->bDriverStopped);
- return;
- }
-
-#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
- #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
- rtw_led_blink_cmd(padapter, pLed);
- #else
- _set_workitem(&(pLed->BlinkWorkItem));
- #endif
-#elif defined(CONFIG_PCI_HCI)
- BlinkHandler(pLed);
-#endif
-
-}
-
-#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
-//
-// Description:
-// Callback function of LED BlinkWorkItem.
-// We dispatch acture LED blink action according to LedStrategy.
-//
-void BlinkWorkItemCallback(struct work_struct *work)
-{
- PLED_871x pLed = container_of(work, LED_871x, BlinkWorkItem);
- BlinkHandler(pLed);
-}
-#endif
-
-//
-// Description:
-// Reset status of LED_871x object.
-//
-void ResetLedStatus(PLED_871x pLed) {
-
- pLed->CurrLedState = RTW_LED_OFF; // Current LED state.
- pLed->bLedOn = _FALSE; // true if LED is ON, false if LED is OFF.
-
- pLed->bLedBlinkInProgress = _FALSE; // true if it is blinking, false o.w..
- pLed->bLedWPSBlinkInProgress = _FALSE;
-
- pLed->BlinkTimes = 0; // Number of times to toggle led state for blinking.
- pLed->BlinkingLedState = LED_UNKNOWN; // Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are.
-
-#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- pLed->bLedLinkBlinkInProgress = _FALSE;
- pLed->bLedStartToLinkBlinkInProgress = _FALSE;
- pLed->bLedScanBlinkInProgress = _FALSE;
-#endif
-}
-
- //
-// Description:
-// Initialize an LED_871x object.
-//
-void
-InitLed871x(
- _adapter *padapter,
- PLED_871x pLed,
- LED_PIN_871x LedPin
- )
-{
- pLed->padapter = padapter;
- pLed->LedPin = LedPin;
-
- ResetLedStatus(pLed);
-
- _init_timer(&(pLed->BlinkTimer), padapter->pnetdev, BlinkTimerCallback, pLed);
-
-#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
- _init_workitem(&(pLed->BlinkWorkItem), BlinkWorkItemCallback, pLed);
-#endif
-}
-
-
-//
-// Description:
-// DeInitialize an LED_871x object.
-//
-void
-DeInitLed871x(
- PLED_871x pLed
- )
-{
-#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
- _cancel_workitem_sync(&(pLed->BlinkWorkItem));
-#endif
- _cancel_timer_ex(&(pLed->BlinkTimer));
- ResetLedStatus(pLed);
-}
-
-
-//
-// Description:
-// Implementation of LED blinking behavior.
-// It toggle off LED and schedule corresponding timer if necessary.
-//
-#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
-
-void SwLedOn(_adapter *padapter, PLED_871x pLed);
-void SwLedOff(_adapter *padapter, PLED_871x pLed);
-
-#define CONFIG_LED_REMOVE_HAL
-
-void
-SwLedBlink(
- PLED_871x pLed
- )
-{
- _adapter *padapter = pLed->padapter;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- u8 bStopBlinking = _FALSE;
-
- // Change LED according to BlinkingLedState specified.
- if( pLed->BlinkingLedState == RTW_LED_ON )
- {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- }
- else
- {
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,( "Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- // Determine if we shall change LED state again.
- pLed->BlinkTimes--;
- switch(pLed->CurrLedState)
- {
-
- case LED_BLINK_NORMAL:
- if(pLed->BlinkTimes == 0)
- {
- bStopBlinking = _TRUE;
- }
- break;
-
- case LED_BLINK_StartToBlink:
- if( check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE) )
- {
- bStopBlinking = _TRUE;
- }
- if( check_fwstate(pmlmepriv, _FW_LINKED) &&
- (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) )
- {
- bStopBlinking = _TRUE;
- }
- else if(pLed->BlinkTimes == 0)
- {
- bStopBlinking = _TRUE;
- }
- break;
-
- case LED_BLINK_WPS:
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = _TRUE;
- }
- break;
-
-
- default:
- bStopBlinking = _TRUE;
- break;
-
- }
-
- if(bStopBlinking)
- {
- //if( padapter->pwrctrlpriv.cpwm >= PS_STATE_S2)
- if(0)
- {
- SwLedOff(padapter, pLed);
- }
- else if( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (pLed->bLedOn == _FALSE))
- {
- SwLedOn(padapter, pLed);
- }
- else if( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && pLed->bLedOn == _TRUE)
- {
- SwLedOff(padapter, pLed);
- }
-
- pLed->BlinkTimes = 0;
- pLed->bLedBlinkInProgress = _FALSE;
- }
- else
- {
- // Assign LED state to toggle.
- if( pLed->BlinkingLedState == RTW_LED_ON )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
-
- // Schedule a timer to toggle LED state.
- switch( pLed->CurrLedState )
- {
- case LED_BLINK_NORMAL:
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- break;
-
- case LED_BLINK_SLOWLY:
- case LED_BLINK_StartToBlink:
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- break;
-
- case LED_BLINK_WPS:
- {
- if( pLed->BlinkingLedState == RTW_LED_ON )
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
- else
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
- }
- break;
-
- default:
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- break;
- }
- }
-}
-
-void
-SwLedBlink1(
- PLED_871x pLed
- )
-{
- _adapter *padapter = pLed->padapter;
-#ifndef CONFIG_LED_REMOVE_HAL
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
-#endif
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- PLED_871x pLed1 = &(ledpriv->SwLed1);
- u8 bStopBlinking = _FALSE;
-
-#ifndef CONFIG_LED_REMOVE_HAL
- if(pHalData->EEPROMCustomerID == RT_CID_819x_CAMEO)
- pLed = &(ledpriv->SwLed1);
-#endif
-
- // Change LED according to BlinkingLedState specified.
- if( pLed->BlinkingLedState == RTW_LED_ON )
- {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,( "Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- }
- else
- {
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
-#ifndef CONFIG_LED_REMOVE_HAL
- if(pHalData->EEPROMCustomerID == RT_CID_DEFAULT)
- {
- if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
- {
- if(!pLed1->bSWLedCtrl)
- {
- SwLedOn(padapter, pLed1);
- pLed1->bSWLedCtrl = _TRUE;
- }
- else if(!pLed1->bLedOn)
- SwLedOn(padapter, pLed1);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (): turn on pLed1\n"));
- }
- else
- {
- if(!pLed1->bSWLedCtrl)
- {
- SwLedOff(padapter, pLed1);
- pLed1->bSWLedCtrl = _TRUE;
- }
- else if(pLed1->bLedOn)
- SwLedOff(padapter, pLed1);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (): turn off pLed1\n"));
- }
- }
-
-#endif
-
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on )
- {
- SwLedOff(padapter, pLed);
- ResetLedStatus(pLed);
- return;
- }
-
- switch(pLed->CurrLedState)
- {
- case LED_BLINK_SLOWLY:
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- break;
-
- case LED_BLINK_NORMAL:
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
- break;
-
- case LED_BLINK_SCAN:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = _TRUE;
- }
-
- if(bStopBlinking)
- {
- if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
- {
- pLed->bLedLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_NORMAL;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
-
- }
- else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
- {
- pLed->bLedNoLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
-
- case LED_BLINK_TXRX:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = _TRUE;
- }
- if(bStopBlinking)
- {
- if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
- {
- pLed->bLedLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_NORMAL;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
- }
- else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
- {
- pLed->bLedNoLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->BlinkTimes = 0;
- pLed->bLedBlinkInProgress = _FALSE;
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- break;
-
- case LED_BLINK_WPS:
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- break;
-
- case LED_BLINK_WPS_STOP: //WPS success
- if(pLed->BlinkingLedState == RTW_LED_ON)
- bStopBlinking = _FALSE;
- else
- bStopBlinking = _TRUE;
-
- if(bStopBlinking)
- {
- pLed->bLedLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_NORMAL;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
-
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
- else
- {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
- }
- break;
-
- default:
- break;
- }
-
-}
-
-void
-SwLedBlink2(
- PLED_871x pLed
- )
-{
- _adapter *padapter = pLed->padapter;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- u8 bStopBlinking = _FALSE;
-
- // Change LED according to BlinkingLedState specified.
- if( pLed->BlinkingLedState == RTW_LED_ON)
- {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- }
- else
- {
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- switch(pLed->CurrLedState)
- {
- case LED_BLINK_SCAN:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = _TRUE;
- }
-
- if(bStopBlinking)
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on )
- {
- SwLedOff(padapter, pLed);
- }
- else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
- {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop scan blink CurrLedState %d\n", pLed->CurrLedState));
-
- }
- else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
- {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop scan blink CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- else
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on )
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- }
- break;
-
- case LED_BLINK_TXRX:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = _TRUE;
- }
- if(bStopBlinking)
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on )
- {
- SwLedOff(padapter, pLed);
- }
- else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
- {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop CurrLedState %d\n", pLed->CurrLedState));
-
- }
- else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
- {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->bLedBlinkInProgress = _FALSE;
- }
- else
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on )
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- }
- break;
-
- default:
- break;
- }
-
-}
-
-void
-SwLedBlink3(
- PLED_871x pLed
- )
-{
- _adapter *padapter = pLed->padapter;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- u8 bStopBlinking = _FALSE;
-
- // Change LED according to BlinkingLedState specified.
- if( pLed->BlinkingLedState == RTW_LED_ON )
- {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- }
- else
- {
- if(pLed->CurrLedState != LED_BLINK_WPS_STOP)
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- switch(pLed->CurrLedState)
- {
- case LED_BLINK_SCAN:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = _TRUE;
- }
-
- if(bStopBlinking)
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on )
- {
- SwLedOff(padapter, pLed);
- }
- else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
- {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- if( !pLed->bLedOn )
- SwLedOn(padapter, pLed);
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
- }
- else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
- {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if( pLed->bLedOn )
- SwLedOff(padapter, pLed);
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- else
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on )
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- }
- break;
-
- case LED_BLINK_TXRX:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = _TRUE;
- }
- if(bStopBlinking)
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on )
- {
- SwLedOff(padapter, pLed);
- }
- else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
- {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
-
- if( !pLed->bLedOn )
- SwLedOn(padapter, pLed);
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
- }
- else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
- {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
-
- if( pLed->bLedOn )
- SwLedOff(padapter, pLed);
-
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->bLedBlinkInProgress = _FALSE;
- }
- else
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on )
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- }
- break;
-
- case LED_BLINK_WPS:
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- break;
-
- case LED_BLINK_WPS_STOP: //WPS success
- if(pLed->BlinkingLedState == RTW_LED_ON)
- {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
- bStopBlinking = _FALSE;
- }
- else
- {
- bStopBlinking = _TRUE;
- }
-
- if(bStopBlinking)
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on )
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
- }
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
- break;
-
-
- default:
- break;
- }
-
-}
-
-
-void
-SwLedBlink4(
- PLED_871x pLed
- )
-{
- _adapter *padapter = pLed->padapter;
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- PLED_871x pLed1 = &(ledpriv->SwLed1);
- u8 bStopBlinking = _FALSE;
-
- // Change LED according to BlinkingLedState specified.
- if( pLed->BlinkingLedState == RTW_LED_ON )
- {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- }
- else
- {
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- if(!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN)
- {
- pLed1->BlinkingLedState = RTW_LED_OFF;
- pLed1->CurrLedState = RTW_LED_OFF;
- SwLedOff(padapter, pLed1);
- }
-
- switch(pLed->CurrLedState)
- {
- case LED_BLINK_SLOWLY:
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- break;
-
- case LED_BLINK_StartToBlink:
- if( pLed->bLedOn )
- {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- }
- else
- {
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- }
- break;
-
- case LED_BLINK_SCAN:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = _FALSE;
- }
-
- if(bStopBlinking)
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS)
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- }
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- else
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS)
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- }
- break;
-
- case LED_BLINK_TXRX:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = _TRUE;
- }
- if(bStopBlinking)
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS)
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- pLed->bLedNoLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- }
- pLed->bLedBlinkInProgress = _FALSE;
- }
- else
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS)
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- }
- break;
-
- case LED_BLINK_WPS:
- if( pLed->bLedOn )
- {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- }
- else
- {
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- }
- break;
-
- case LED_BLINK_WPS_STOP: //WPS authentication fail
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
-
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- break;
-
- case LED_BLINK_WPS_STOP_OVERLAP: //WPS session overlap
- pLed->BlinkTimes--;
- if(pLed->BlinkTimes == 0)
- {
- if(pLed->bLedOn)
- {
- pLed->BlinkTimes = 1;
- }
- else
- {
- bStopBlinking = _TRUE;
- }
- }
-
- if(bStopBlinking)
- {
- pLed->BlinkTimes = 10;
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
-
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- }
- break;
-
-
- default:
- break;
- }
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("SwLedBlink4 CurrLedState %d\n", pLed->CurrLedState));
-
-
-}
-
-void
-SwLedBlink5(
- PLED_871x pLed
- )
-{
- _adapter *padapter = pLed->padapter;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- u8 bStopBlinking = _FALSE;
-
- // Change LED according to BlinkingLedState specified.
- if( pLed->BlinkingLedState == RTW_LED_ON )
- {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- }
- else
- {
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- switch(pLed->CurrLedState)
- {
- case LED_BLINK_SCAN:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = _TRUE;
- }
-
- if(bStopBlinking)
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS)
- {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if(pLed->bLedOn)
- SwLedOff(padapter, pLed);
- }
- else
- { pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- if(!pLed->bLedOn)
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
-
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- else
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS)
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- }
- break;
-
-
- case LED_BLINK_TXRX:
- pLed->BlinkTimes--;
- if( pLed->BlinkTimes == 0 )
- {
- bStopBlinking = _TRUE;
- }
-
- if(bStopBlinking)
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS)
- {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if(pLed->bLedOn)
- SwLedOff(padapter, pLed);
- }
- else
- {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- if(!pLed->bLedOn)
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
-
- pLed->bLedBlinkInProgress = _FALSE;
- }
- else
- {
- if( padapter->pwrctrlpriv.rf_pwrstate != rf_on && padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS)
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- }
- break;
-
- default:
- break;
- }
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("SwLedBlink5 CurrLedState %d\n", pLed->CurrLedState));
-
-
-}
-
-void
-SwLedBlink6(
- PLED_871x pLed
- )
-{
- _adapter *padapter = pLed->padapter;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- u8 bStopBlinking = _FALSE;
-
- // Change LED according to BlinkingLedState specified.
- if( pLed->BlinkingLedState == RTW_LED_ON )
- {
- SwLedOn(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
- }
- else
- {
- SwLedOff(padapter, pLed);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
- }
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("<==== blink6\n"));
-}
-
-static void
-SwLedControlMode0(
- _adapter *padapter,
- LED_CTL_MODE LedAction
-)
-{
- struct led_priv *ledpriv = &(padapter->ledpriv);
- PLED_871x pLed = &(ledpriv->SwLed1);
-
- // Decide led state
- switch(LedAction)
- {
- case LED_CTL_TX:
- case LED_CTL_RX:
- if( pLed->bLedBlinkInProgress == _FALSE )
- {
- pLed->bLedBlinkInProgress = _TRUE;
-
- pLed->CurrLedState = LED_BLINK_NORMAL;
- pLed->BlinkTimes = 2;
-
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- }
- break;
-
- case LED_CTL_START_TO_LINK:
- if( pLed->bLedBlinkInProgress == _FALSE )
- {
- pLed->bLedBlinkInProgress = _TRUE;
-
- pLed->CurrLedState = LED_BLINK_StartToBlink;
- pLed->BlinkTimes = 24;
-
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- }
- else
- {
- pLed->CurrLedState = LED_BLINK_StartToBlink;
- }
- break;
-
- case LED_CTL_LINK:
- pLed->CurrLedState = RTW_LED_ON;
- if( pLed->bLedBlinkInProgress == _FALSE )
- {
- SwLedOn(padapter, pLed);
- }
- break;
-
- case LED_CTL_NO_LINK:
- pLed->CurrLedState = RTW_LED_OFF;
- if( pLed->bLedBlinkInProgress == _FALSE )
- {
- SwLedOff(padapter, pLed);
- }
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = RTW_LED_OFF;
- if(pLed->bLedBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- SwLedOff(padapter, pLed);
- break;
-
- case LED_CTL_START_WPS:
- if( pLed->bLedBlinkInProgress == _FALSE || pLed->CurrLedState == RTW_LED_ON)
- {
- pLed->bLedBlinkInProgress = _TRUE;
-
- pLed->CurrLedState = LED_BLINK_WPS;
- pLed->BlinkTimes = 20;
-
- if( pLed->bLedOn )
- {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
- }
- else
- {
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
- }
- }
- break;
-
- case LED_CTL_STOP_WPS:
- if(pLed->bLedBlinkInProgress)
- {
- pLed->CurrLedState = RTW_LED_OFF;
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- break;
-
-
- default:
- break;
- }
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
-
-}
-
- //ALPHA, added by chiyoko, 20090106
-static void
-SwLedControlMode1(
- _adapter *padapter,
- LED_CTL_MODE LedAction
-)
-{
-#ifndef CONFIG_LED_REMOVE_HAL
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
-#endif
- struct led_priv *ledpriv = &(padapter->ledpriv);
- PLED_871x pLed = &(ledpriv->SwLed0);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
-
-#ifndef CONFIG_LED_REMOVE_HAL
- if(pHalData->EEPROMCustomerID == RT_CID_819x_CAMEO)
- pLed = &(ledpriv->SwLed1);
-#endif
-
- switch(LedAction)
- {
- case LED_CTL_POWER_ON:
- case LED_CTL_START_TO_LINK:
- case LED_CTL_NO_LINK:
- if( pLed->bLedNoLinkBlinkInProgress == _FALSE )
- {
- if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
- if( pLed->bLedLinkBlinkInProgress == _TRUE )
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = _FALSE;
- }
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_LINK:
- if( pLed->bLedLinkBlinkInProgress == _FALSE )
- {
- if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
- if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- }
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- pLed->bLedLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_NORMAL;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_SITE_SURVEY:
- if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
- ;
- else if(pLed->bLedScanBlinkInProgress ==_FALSE)
- {
- if(IS_LED_WPS_BLINKING(pLed))
- return;
-
- if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress == _TRUE )
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = _FALSE;
- }
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- pLed->bLedScanBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SCAN;
- pLed->BlinkTimes = 24;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_TX:
- case LED_CTL_RX:
- if(pLed->bLedBlinkInProgress ==_FALSE)
- {
- if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
- if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress == _TRUE )
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = _FALSE;
- }
- pLed->bLedBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_TXRX;
- pLed->BlinkTimes = 2;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_START_WPS: //wait until xinpin finish
- case LED_CTL_START_WPS_BOTTON:
- if(pLed->bLedWPSBlinkInProgress ==_FALSE)
- {
- if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress == _TRUE )
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = _FALSE;
- }
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if(pLed->bLedScanBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- pLed->bLedWPSBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_WPS;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
-
-
- case LED_CTL_STOP_WPS:
- if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress == _TRUE )
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = _FALSE;
- }
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if(pLed->bLedScanBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- if(pLed->bLedWPSBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- }
- else
- {
- pLed->bLedWPSBlinkInProgress = _TRUE;
- }
-
- pLed->CurrLedState = LED_BLINK_WPS_STOP;
- if(pLed->bLedOn)
- {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
- }
- else
- {
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), 0);
- }
- break;
-
- case LED_CTL_STOP_WPS_FAIL:
- if(pLed->bLedWPSBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if( pLed->bLedNoLinkBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = _FALSE;
- }
- if( pLed->bLedBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if( pLed->bLedWPSBlinkInProgress )
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
-
- SwLedOff(padapter, pLed);
- break;
-
- default:
- break;
-
- }
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
-}
-
- //Arcadyan/Sitecom , added by chiyoko, 20090216
-static void
-SwLedControlMode2(
- _adapter *padapter,
- LED_CTL_MODE LedAction
-)
-{
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- PLED_871x pLed = &(ledpriv->SwLed0);
-
- switch(LedAction)
- {
- case LED_CTL_SITE_SURVEY:
- if(pmlmepriv->LinkDetectInfo.bBusyTraffic)
- ;
- else if(pLed->bLedScanBlinkInProgress ==_FALSE)
- {
- if(IS_LED_WPS_BLINKING(pLed))
- return;
-
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- pLed->bLedScanBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SCAN;
- pLed->BlinkTimes = 24;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_TX:
- case LED_CTL_RX:
- if((pLed->bLedBlinkInProgress ==_FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
- {
- if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
-
- pLed->bLedBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_TXRX;
- pLed->BlinkTimes = 2;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_LINK:
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- if( pLed->bLedBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
-
- _set_timer(&(pLed->BlinkTimer), 0);
- break;
-
- case LED_CTL_START_WPS: //wait until xinpin finish
- case LED_CTL_START_WPS_BOTTON:
- if(pLed->bLedWPSBlinkInProgress ==_FALSE)
- {
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if(pLed->bLedScanBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- pLed->bLedWPSBlinkInProgress = _TRUE;
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), 0);
- }
- break;
-
- case LED_CTL_STOP_WPS:
- pLed->bLedWPSBlinkInProgress = _FALSE;
- if(padapter->pwrctrlpriv.rf_pwrstate != rf_on)
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), 0);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
- }
- break;
-
- case LED_CTL_STOP_WPS_FAIL:
- pLed->bLedWPSBlinkInProgress = _FALSE;
- if(padapter->pwrctrlpriv.rf_pwrstate != rf_on)
- {
- SwLedOff(padapter, pLed);
- }
- else
- {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), 0);
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
- }
- break;
-
- case LED_CTL_START_TO_LINK:
- case LED_CTL_NO_LINK:
- if(!IS_LED_BLINKING(pLed))
- {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), 0);
- }
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if( pLed->bLedBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- if( pLed->bLedWPSBlinkInProgress )
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
-
- _set_timer(&(pLed->BlinkTimer), 0);
- break;
-
- default:
- break;
-
- }
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
-}
-
- //COREGA, added by chiyoko, 20090316
- static void
- SwLedControlMode3(
- _adapter *padapter,
- LED_CTL_MODE LedAction
-)
-{
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- PLED_871x pLed = &(ledpriv->SwLed0);
-
- switch(LedAction)
- {
- case LED_CTL_SITE_SURVEY:
- if(pmlmepriv->LinkDetectInfo.bBusyTraffic)
- ;
- else if(pLed->bLedScanBlinkInProgress ==_FALSE)
- {
- if(IS_LED_WPS_BLINKING(pLed))
- return;
-
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- pLed->bLedScanBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SCAN;
- pLed->BlinkTimes = 24;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_TX:
- case LED_CTL_RX:
- if((pLed->bLedBlinkInProgress ==_FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
- {
- if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
-
- pLed->bLedBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_TXRX;
- pLed->BlinkTimes = 2;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_LINK:
- if(IS_LED_WPS_BLINKING(pLed))
- return;
-
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
- if( pLed->bLedBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
-
- _set_timer(&(pLed->BlinkTimer), 0);
- break;
-
- case LED_CTL_START_WPS: //wait until xinpin finish
- case LED_CTL_START_WPS_BOTTON:
- if(pLed->bLedWPSBlinkInProgress ==_FALSE)
- {
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if(pLed->bLedScanBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- pLed->bLedWPSBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_WPS;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_STOP_WPS:
- if(pLed->bLedWPSBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
- else
- {
- pLed->bLedWPSBlinkInProgress = _TRUE;
- }
-
- pLed->CurrLedState = LED_BLINK_WPS_STOP;
- if(pLed->bLedOn)
- {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
- }
- else
- {
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), 0);
- }
-
- break;
-
- case LED_CTL_STOP_WPS_FAIL:
- if(pLed->bLedWPSBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
-
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), 0);
- break;
-
- case LED_CTL_START_TO_LINK:
- case LED_CTL_NO_LINK:
- if(!IS_LED_BLINKING(pLed))
- {
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), 0);
- }
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
- if( pLed->bLedBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- if( pLed->bLedWPSBlinkInProgress )
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
-
- _set_timer(&(pLed->BlinkTimer), 0);
- break;
-
- default:
- break;
-
- }
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
-}
-
-
- //Edimax-Belkin, added by chiyoko, 20090413
-static void
-SwLedControlMode4(
- _adapter *padapter,
- LED_CTL_MODE LedAction
-)
-{
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- PLED_871x pLed = &(ledpriv->SwLed0);
- PLED_871x pLed1 = &(ledpriv->SwLed1);
-
- switch(LedAction)
- {
- case LED_CTL_START_TO_LINK:
- if(pLed1->bLedWPSBlinkInProgress)
- {
- pLed1->bLedWPSBlinkInProgress = _FALSE;
- _cancel_timer_ex(&(pLed1->BlinkTimer));
-
- pLed1->BlinkingLedState = RTW_LED_OFF;
- pLed1->CurrLedState = RTW_LED_OFF;
-
- if(pLed1->bLedOn)
- _set_timer(&(pLed->BlinkTimer), 0);
- }
-
- if( pLed->bLedStartToLinkBlinkInProgress == _FALSE )
- {
- if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if(pLed->bLedNoLinkBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- }
-
- pLed->bLedStartToLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_StartToBlink;
- if( pLed->bLedOn )
- {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- }
- else
- {
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- }
- }
- break;
-
- case LED_CTL_LINK:
- case LED_CTL_NO_LINK:
- //LED1 settings
- if(LedAction == LED_CTL_LINK)
- {
- if(pLed1->bLedWPSBlinkInProgress)
- {
- pLed1->bLedWPSBlinkInProgress = _FALSE;
- _cancel_timer_ex(&(pLed1->BlinkTimer));
-
- pLed1->BlinkingLedState = RTW_LED_OFF;
- pLed1->CurrLedState = RTW_LED_OFF;
-
- if(pLed1->bLedOn)
- _set_timer(&(pLed->BlinkTimer), 0);
- }
- }
-
- if( pLed->bLedNoLinkBlinkInProgress == _FALSE )
- {
- if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_SITE_SURVEY:
- if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
- ;
- else if(pLed->bLedScanBlinkInProgress ==_FALSE)
- {
- if(IS_LED_WPS_BLINKING(pLed))
- return;
-
- if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- }
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- pLed->bLedScanBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SCAN;
- pLed->BlinkTimes = 24;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_TX:
- case LED_CTL_RX:
- if(pLed->bLedBlinkInProgress ==_FALSE)
- {
- if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
- {
- return;
- }
- if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- }
- pLed->bLedBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_TXRX;
- pLed->BlinkTimes = 2;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_START_WPS: //wait until xinpin finish
- case LED_CTL_START_WPS_BOTTON:
- if(pLed1->bLedWPSBlinkInProgress)
- {
- pLed1->bLedWPSBlinkInProgress = _FALSE;
- _cancel_timer_ex(&(pLed1->BlinkTimer));
-
- pLed1->BlinkingLedState = RTW_LED_OFF;
- pLed1->CurrLedState = RTW_LED_OFF;
-
- if(pLed1->bLedOn)
- _set_timer(&(pLed->BlinkTimer), 0);
- }
-
- if(pLed->bLedWPSBlinkInProgress ==_FALSE)
- {
- if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- }
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if(pLed->bLedScanBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- pLed->bLedWPSBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_WPS;
- if( pLed->bLedOn )
- {
- pLed->BlinkingLedState = RTW_LED_OFF;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
- }
- else
- {
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
- }
- }
- break;
-
- case LED_CTL_STOP_WPS: //WPS connect success
- if(pLed->bLedWPSBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
-
- break;
-
- case LED_CTL_STOP_WPS_FAIL: //WPS authentication fail
- if(pLed->bLedWPSBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
-
- //LED1 settings
- if(pLed1->bLedWPSBlinkInProgress)
- _cancel_timer_ex(&(pLed1->BlinkTimer));
- else
- pLed1->bLedWPSBlinkInProgress = _TRUE;
-
- pLed1->CurrLedState = LED_BLINK_WPS_STOP;
- if( pLed1->bLedOn )
- pLed1->BlinkingLedState = RTW_LED_OFF;
- else
- pLed1->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
-
- break;
-
- case LED_CTL_STOP_WPS_FAIL_OVERLAP: //WPS session overlap
- if(pLed->bLedWPSBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
-
- pLed->bLedNoLinkBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SLOWLY;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
-
- //LED1 settings
- if(pLed1->bLedWPSBlinkInProgress)
- _cancel_timer_ex(&(pLed1->BlinkTimer));
- else
- pLed1->bLedWPSBlinkInProgress = _TRUE;
-
- pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
- pLed1->BlinkTimes = 10;
- if( pLed1->bLedOn )
- pLed1->BlinkingLedState = RTW_LED_OFF;
- else
- pLed1->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
-
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
-
- if( pLed->bLedNoLinkBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedNoLinkBlinkInProgress = _FALSE;
- }
- if( pLed->bLedLinkBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedLinkBlinkInProgress = _FALSE;
- }
- if( pLed->bLedBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- if( pLed->bLedWPSBlinkInProgress )
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedWPSBlinkInProgress = _FALSE;
- }
- if( pLed->bLedScanBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedScanBlinkInProgress = _FALSE;
- }
- if( pLed->bLedStartToLinkBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedStartToLinkBlinkInProgress = _FALSE;
- }
-
- if( pLed1->bLedWPSBlinkInProgress )
- {
- _cancel_timer_ex(&(pLed1->BlinkTimer));
- pLed1->bLedWPSBlinkInProgress = _FALSE;
- }
-
- pLed1->BlinkingLedState = LED_UNKNOWN;
- SwLedOff(padapter, pLed);
- SwLedOff(padapter, pLed1);
- break;
-
- default:
- break;
-
- }
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
-}
-
-
-
- //Sercomm-Belkin, added by chiyoko, 20090415
-static void
-SwLedControlMode5(
- _adapter *padapter,
- LED_CTL_MODE LedAction
-)
-{
-#ifndef CONFIG_LED_REMOVE_HAL
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
-#endif
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- PLED_871x pLed = &(ledpriv->SwLed0);
-
-#ifndef CONFIG_LED_REMOVE_HAL
- if(pHalData->EEPROMCustomerID == RT_CID_819x_CAMEO)
- pLed = &(ledpriv->SwLed1);
-#endif
-
- switch(LedAction)
- {
- case LED_CTL_POWER_ON:
- case LED_CTL_NO_LINK:
- case LED_CTL_LINK: //solid blue
- pLed->CurrLedState = RTW_LED_ON;
- pLed->BlinkingLedState = RTW_LED_ON;
-
- _set_timer(&(pLed->BlinkTimer), 0);
- break;
-
- case LED_CTL_SITE_SURVEY:
- if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
- ;
- else if(pLed->bLedScanBlinkInProgress ==_FALSE)
- {
- if(pLed->bLedBlinkInProgress ==_TRUE)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
- pLed->bLedScanBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_SCAN;
- pLed->BlinkTimes = 24;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_TX:
- case LED_CTL_RX:
- if(pLed->bLedBlinkInProgress ==_FALSE)
- {
- if(pLed->CurrLedState == LED_BLINK_SCAN)
- {
- return;
- }
- pLed->bLedBlinkInProgress = _TRUE;
- pLed->CurrLedState = LED_BLINK_TXRX;
- pLed->BlinkTimes = 2;
- if( pLed->bLedOn )
- pLed->BlinkingLedState = RTW_LED_OFF;
- else
- pLed->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
- }
- break;
-
- case LED_CTL_POWER_OFF:
- pLed->CurrLedState = RTW_LED_OFF;
- pLed->BlinkingLedState = RTW_LED_OFF;
-
- if( pLed->bLedBlinkInProgress)
- {
- _cancel_timer_ex(&(pLed->BlinkTimer));
- pLed->bLedBlinkInProgress = _FALSE;
- }
-
- SwLedOff(padapter, pLed);
- break;
-
- default:
- break;
-
- }
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
-}
-
- //WNC-Corega, added by chiyoko, 20090902
-static void
-SwLedControlMode6(
- _adapter *padapter,
- LED_CTL_MODE LedAction
-)
-{
- struct led_priv *ledpriv = &(padapter->ledpriv);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- PLED_871x pLed0 = &(ledpriv->SwLed0);
-
- switch(LedAction)
- {
- case LED_CTL_POWER_ON:
- case LED_CTL_LINK:
- case LED_CTL_NO_LINK:
- _cancel_timer_ex(&(pLed0->BlinkTimer));
- pLed0->CurrLedState = RTW_LED_ON;
- pLed0->BlinkingLedState = RTW_LED_ON;
- _set_timer(&(pLed0->BlinkTimer), 0);
- break;
-
- case LED_CTL_POWER_OFF:
- SwLedOff(padapter, pLed0);
- break;
-
- default:
- break;
- }
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("ledcontrol 6 Led %d\n", pLed0->CurrLedState));
-}
-
-//
-// Description:
-// Handler function of LED Blinking.
-// We dispatch acture LED blink action according to LedStrategy.
-//
-void BlinkHandler(PLED_871x pLed)
-{
- _adapter *padapter = pLed->padapter;
- struct led_priv *ledpriv = &(padapter->ledpriv);
-
- //DBG_871X("%s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
-
- if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
- {
- //DBG_871X("%s bSurpriseRemoved:%d, bDriverStopped:%d\n", __FUNCTION__, padapter->bSurpriseRemoved, padapter->bDriverStopped);
- return;
- }
-
- switch(ledpriv->LedStrategy)
- {
- case SW_LED_MODE0:
- SwLedBlink(pLed);
- break;
-
- case SW_LED_MODE1:
- SwLedBlink1(pLed);
- break;
-
- case SW_LED_MODE2:
- SwLedBlink2(pLed);
- break;
-
- case SW_LED_MODE3:
- SwLedBlink3(pLed);
- break;
-
- case SW_LED_MODE4:
- SwLedBlink4(pLed);
- break;
-
- case SW_LED_MODE5:
- SwLedBlink5(pLed);
- break;
-
- case SW_LED_MODE6:
- SwLedBlink6(pLed);
- break;
-
- default:
- //RT_TRACE(COMP_LED, DBG_LOUD, ("BlinkWorkItemCallback 0x%x \n", pHalData->LedStrategy));
- //SwLedBlink(pLed);
- break;
- }
-}
-
-void
-LedControl871x(
- _adapter *padapter,
- LED_CTL_MODE LedAction
- )
-{
- struct led_priv *ledpriv = &(padapter->ledpriv);
-
- if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)
- ||(padapter->hw_init_completed == _FALSE) )
- {
- return;
- }
-
-
- if( ledpriv->bRegUseLed == _FALSE)
- return;
-
- //if (!priv->up)
- // return;
-
- //if(priv->bInHctTest)
- // return;
-
- if( (padapter->pwrctrlpriv.rf_pwrstate != rf_on &&
- padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) &&
- (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX ||
- LedAction == LED_CTL_SITE_SURVEY ||
- LedAction == LED_CTL_LINK ||
- LedAction == LED_CTL_NO_LINK ||
- LedAction == LED_CTL_POWER_ON) )
- {
- return;
- }
-
- switch(ledpriv->LedStrategy)
- {
- case SW_LED_MODE0:
- //SwLedControlMode0(padapter, LedAction);
- break;
-
- case SW_LED_MODE1:
- SwLedControlMode1(padapter, LedAction);
- break;
- case SW_LED_MODE2:
- SwLedControlMode2(padapter, LedAction);
- break;
-
- case SW_LED_MODE3:
- SwLedControlMode3(padapter, LedAction);
- break;
-
- case SW_LED_MODE4:
- SwLedControlMode4(padapter, LedAction);
- break;
-
- case SW_LED_MODE5:
- SwLedControlMode5(padapter, LedAction);
- break;
-
- case SW_LED_MODE6:
- SwLedControlMode6(padapter, LedAction);
- break;
-
- default:
- break;
- }
-
- RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("LedStrategy:%d, LedAction %d\n", ledpriv->LedStrategy,LedAction));
-}
-
-#endif
-
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ *
+ ******************************************************************************/
+
+#include <drv_types.h>
+
+//
+// Description:
+// Callback function of LED BlinkTimer,
+// it just schedules to corresponding BlinkWorkItem/led_blink_hdl
+//
+void BlinkTimerCallback(void *data)
+{
+ PLED_871x pLed = (PLED_871x)data;
+ _adapter *padapter = pLed->padapter;
+
+ //DBG_871X("%s\n", __FUNCTION__);
+
+ if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
+ {
+ //DBG_871X("%s bSurpriseRemoved:%d, bDriverStopped:%d\n", __FUNCTION__, padapter->bSurpriseRemoved, padapter->bDriverStopped);
+ return;
+ }
+
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
+ #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
+ rtw_led_blink_cmd(padapter, pLed);
+ #else
+ _set_workitem(&(pLed->BlinkWorkItem));
+ #endif
+#elif defined(CONFIG_PCI_HCI)
+ BlinkHandler(pLed);
+#endif
+
+}
+
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
+//
+// Description:
+// Callback function of LED BlinkWorkItem.
+// We dispatch acture LED blink action according to LedStrategy.
+//
+void BlinkWorkItemCallback(struct work_struct *work)
+{
+ PLED_871x pLed = container_of(work, LED_871x, BlinkWorkItem);
+ BlinkHandler(pLed);
+}
+#endif
+
+//
+// Description:
+// Reset status of LED_871x object.
+//
+void ResetLedStatus(PLED_871x pLed) {
+
+ pLed->CurrLedState = RTW_LED_OFF; // Current LED state.
+ pLed->bLedOn = _FALSE; // true if LED is ON, false if LED is OFF.
+
+ pLed->bLedBlinkInProgress = _FALSE; // true if it is blinking, false o.w..
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+
+ pLed->BlinkTimes = 0; // Number of times to toggle led state for blinking.
+ pLed->BlinkingLedState = LED_UNKNOWN; // Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are.
+
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ pLed->bLedLinkBlinkInProgress = _FALSE;
+ pLed->bLedStartToLinkBlinkInProgress = _FALSE;
+ pLed->bLedScanBlinkInProgress = _FALSE;
+#endif
+}
+
+ //
+// Description:
+// Initialize an LED_871x object.
+//
+void
+InitLed871x(
+ _adapter *padapter,
+ PLED_871x pLed,
+ LED_PIN_871x LedPin
+ )
+{
+ pLed->padapter = padapter;
+ pLed->LedPin = LedPin;
+
+ ResetLedStatus(pLed);
+
+ _init_timer(&(pLed->BlinkTimer), padapter->pnetdev, BlinkTimerCallback, pLed);
+
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
+ _init_workitem(&(pLed->BlinkWorkItem), BlinkWorkItemCallback, pLed);
+#endif
+}
+
+
+//
+// Description:
+// DeInitialize an LED_871x object.
+//
+void
+DeInitLed871x(
+ PLED_871x pLed
+ )
+{
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+ _cancel_workitem_sync(&(pLed->BlinkWorkItem));
+#endif
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ ResetLedStatus(pLed);
+}
+
+
+//
+// Description:
+// Implementation of LED blinking behavior.
+// It toggle off LED and schedule corresponding timer if necessary.
+//
+#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
+
+void SwLedOn(_adapter *padapter, PLED_871x pLed);
+void SwLedOff(_adapter *padapter, PLED_871x pLed);
+
+#define CONFIG_LED_REMOVE_HAL
+
+void
+SwLedBlink(
+ PLED_871x pLed
+ )
+{
+ _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = _FALSE;
+
+ // Change LED according to BlinkingLedState specified.
+ if( pLed->BlinkingLedState == RTW_LED_ON )
+ {
+ SwLedOn(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+ }
+ else
+ {
+ SwLedOff(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,( "Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+ }
+
+ // Determine if we shall change LED state again.
+ pLed->BlinkTimes--;
+ switch(pLed->CurrLedState)
+ {
+
+ case LED_BLINK_NORMAL:
+ if(pLed->BlinkTimes == 0)
+ {
+ bStopBlinking = _TRUE;
+ }
+ break;
+
+ case LED_BLINK_StartToBlink:
+ if( check_fwstate(pmlmepriv, _FW_LINKED) && check_fwstate(pmlmepriv, WIFI_STATION_STATE) )
+ {
+ bStopBlinking = _TRUE;
+ }
+ if( check_fwstate(pmlmepriv, _FW_LINKED) &&
+ (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) )
+ {
+ bStopBlinking = _TRUE;
+ }
+ else if(pLed->BlinkTimes == 0)
+ {
+ bStopBlinking = _TRUE;
+ }
+ break;
+
+ case LED_BLINK_WPS:
+ if( pLed->BlinkTimes == 0 )
+ {
+ bStopBlinking = _TRUE;
+ }
+ break;
+
+
+ default:
+ bStopBlinking = _TRUE;
+ break;
+
+ }
+
+ if(bStopBlinking)
+ {
+ //if(adapter_to_pwrctl(padapter)->cpwm >= PS_STATE_S2)
+ if(0)
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else if( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (pLed->bLedOn == _FALSE))
+ {
+ SwLedOn(padapter, pLed);
+ }
+ else if( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && pLed->bLedOn == _TRUE)
+ {
+ SwLedOff(padapter, pLed);
+ }
+
+ pLed->BlinkTimes = 0;
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ // Assign LED state to toggle.
+ if( pLed->BlinkingLedState == RTW_LED_ON )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ // Schedule a timer to toggle LED state.
+ switch( pLed->CurrLedState )
+ {
+ case LED_BLINK_NORMAL:
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ break;
+
+ case LED_BLINK_SLOWLY:
+ case LED_BLINK_StartToBlink:
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ break;
+
+ case LED_BLINK_WPS:
+ {
+ if( pLed->BlinkingLedState == RTW_LED_ON )
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+ else
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+ }
+ break;
+
+ default:
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ break;
+ }
+ }
+}
+
+void
+SwLedBlink1(
+ PLED_871x pLed
+ )
+{
+ _adapter *padapter = pLed->padapter;
+#ifndef CONFIG_LED_REMOVE_HAL
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+#endif
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ PLED_871x pLed1 = &(ledpriv->SwLed1);
+ u8 bStopBlinking = _FALSE;
+
+#ifndef CONFIG_LED_REMOVE_HAL
+ if(pHalData->EEPROMCustomerID == RT_CID_819x_CAMEO)
+ pLed = &(ledpriv->SwLed1);
+#endif
+
+ // Change LED according to BlinkingLedState specified.
+ if( pLed->BlinkingLedState == RTW_LED_ON )
+ {
+ SwLedOn(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,( "Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+ }
+ else
+ {
+ SwLedOff(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+ }
+
+#ifndef CONFIG_LED_REMOVE_HAL
+ if(pHalData->EEPROMCustomerID == RT_CID_DEFAULT)
+ {
+ if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+ {
+ if(!pLed1->bSWLedCtrl)
+ {
+ SwLedOn(padapter, pLed1);
+ pLed1->bSWLedCtrl = _TRUE;
+ }
+ else if(!pLed1->bLedOn)
+ SwLedOn(padapter, pLed1);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (): turn on pLed1\n"));
+ }
+ else
+ {
+ if(!pLed1->bSWLedCtrl)
+ {
+ SwLedOff(padapter, pLed1);
+ pLed1->bSWLedCtrl = _TRUE;
+ }
+ else if(pLed1->bLedOn)
+ SwLedOff(padapter, pLed1);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (): turn off pLed1\n"));
+ }
+ }
+
+#endif
+
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+ {
+ SwLedOff(padapter, pLed);
+ ResetLedStatus(pLed);
+ return;
+ }
+
+ switch(pLed->CurrLedState)
+ {
+ case LED_BLINK_SLOWLY:
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_NORMAL:
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if( pLed->BlinkTimes == 0 )
+ {
+ bStopBlinking = _TRUE;
+ }
+
+ if(bStopBlinking)
+ {
+ if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+ {
+ pLed->bLedLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+
+ }
+ else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+ {
+ pLed->bLedNoLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+ }
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if( pLed->BlinkTimes == 0 )
+ {
+ bStopBlinking = _TRUE;
+ }
+ if(bStopBlinking)
+ {
+ if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+ {
+ pLed->bLedLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+ }
+ else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+ {
+ pLed->bLedNoLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+ }
+ pLed->BlinkTimes = 0;
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_BLINK_WPS:
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_WPS_STOP: //WPS success
+ if(pLed->BlinkingLedState == RTW_LED_ON)
+ bStopBlinking = _FALSE;
+ else
+ bStopBlinking = _TRUE;
+
+ if(bStopBlinking)
+ {
+ pLed->bLedLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+void
+SwLedBlink2(
+ PLED_871x pLed
+ )
+{
+ _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = _FALSE;
+
+ // Change LED according to BlinkingLedState specified.
+ if( pLed->BlinkingLedState == RTW_LED_ON)
+ {
+ SwLedOn(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+ }
+ else
+ {
+ SwLedOff(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+ }
+
+ switch(pLed->CurrLedState)
+ {
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if( pLed->BlinkTimes == 0 )
+ {
+ bStopBlinking = _TRUE;
+ }
+
+ if(bStopBlinking)
+ {
+ if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+ {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ SwLedOn(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop scan blink CurrLedState %d\n", pLed->CurrLedState));
+
+ }
+ else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+ {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ SwLedOff(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop scan blink CurrLedState %d\n", pLed->CurrLedState));
+ }
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ if( adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if( pLed->BlinkTimes == 0 )
+ {
+ bStopBlinking = _TRUE;
+ }
+ if(bStopBlinking)
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+ {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ SwLedOn(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop CurrLedState %d\n", pLed->CurrLedState));
+
+ }
+ else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+ {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ SwLedOff(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("stop CurrLedState %d\n", pLed->CurrLedState));
+ }
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+void
+SwLedBlink3(
+ PLED_871x pLed
+ )
+{
+ _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = _FALSE;
+
+ // Change LED according to BlinkingLedState specified.
+ if( pLed->BlinkingLedState == RTW_LED_ON )
+ {
+ SwLedOn(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+ }
+ else
+ {
+ if(pLed->CurrLedState != LED_BLINK_WPS_STOP)
+ SwLedOff(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+ }
+
+ switch(pLed->CurrLedState)
+ {
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if( pLed->BlinkTimes == 0 )
+ {
+ bStopBlinking = _TRUE;
+ }
+
+ if(bStopBlinking)
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+ {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if( !pLed->bLedOn )
+ SwLedOn(padapter, pLed);
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+ }
+ else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+ {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if( pLed->bLedOn )
+ SwLedOff(padapter, pLed);
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+ }
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if( pLed->BlinkTimes == 0 )
+ {
+ bStopBlinking = _TRUE;
+ }
+ if(bStopBlinking)
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else if(check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE)
+ {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ if( !pLed->bLedOn )
+ SwLedOn(padapter, pLed);
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+ }
+ else if(check_fwstate(pmlmepriv, _FW_LINKED)== _FALSE)
+ {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ if( pLed->bLedOn )
+ SwLedOff(padapter, pLed);
+
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+ }
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_WPS:
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_WPS_STOP: //WPS success
+ if(pLed->BlinkingLedState == RTW_LED_ON)
+ {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ bStopBlinking = _FALSE;
+ }
+ else
+ {
+ bStopBlinking = _TRUE;
+ }
+
+ if(bStopBlinking)
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on )
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ SwLedOn(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+ }
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+ break;
+
+
+ default:
+ break;
+ }
+
+}
+
+
+void
+SwLedBlink4(
+ PLED_871x pLed
+ )
+{
+ _adapter *padapter = pLed->padapter;
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ PLED_871x pLed1 = &(ledpriv->SwLed1);
+ u8 bStopBlinking = _FALSE;
+
+ // Change LED according to BlinkingLedState specified.
+ if( pLed->BlinkingLedState == RTW_LED_ON )
+ {
+ SwLedOn(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+ }
+ else
+ {
+ SwLedOff(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+ }
+
+ if(!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN)
+ {
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ pLed1->CurrLedState = RTW_LED_OFF;
+ SwLedOff(padapter, pLed1);
+ }
+
+ switch(pLed->CurrLedState)
+ {
+ case LED_BLINK_SLOWLY:
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ break;
+
+ case LED_BLINK_StartToBlink:
+ if( pLed->bLedOn )
+ {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ }
+ else
+ {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if( pLed->BlinkTimes == 0 )
+ {
+ bStopBlinking = _FALSE;
+ }
+
+ if(bStopBlinking)
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if( pLed->BlinkTimes == 0 )
+ {
+ bStopBlinking = _TRUE;
+ }
+ if(bStopBlinking)
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ pLed->bLedNoLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ case LED_BLINK_WPS:
+ if( pLed->bLedOn )
+ {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ }
+ else
+ {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+
+ case LED_BLINK_WPS_STOP: //WPS authentication fail
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ break;
+
+ case LED_BLINK_WPS_STOP_OVERLAP: //WPS session overlap
+ pLed->BlinkTimes--;
+ if(pLed->BlinkTimes == 0)
+ {
+ if(pLed->bLedOn)
+ {
+ pLed->BlinkTimes = 1;
+ }
+ else
+ {
+ bStopBlinking = _TRUE;
+ }
+ }
+
+ if(bStopBlinking)
+ {
+ pLed->BlinkTimes = 10;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ }
+ else
+ {
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+
+
+ default:
+ break;
+ }
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("SwLedBlink4 CurrLedState %d\n", pLed->CurrLedState));
+
+
+}
+
+void
+SwLedBlink5(
+ PLED_871x pLed
+ )
+{
+ _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = _FALSE;
+
+ // Change LED according to BlinkingLedState specified.
+ if( pLed->BlinkingLedState == RTW_LED_ON )
+ {
+ SwLedOn(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+ }
+ else
+ {
+ SwLedOff(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+ }
+
+ switch(pLed->CurrLedState)
+ {
+ case LED_BLINK_SCAN:
+ pLed->BlinkTimes--;
+ if( pLed->BlinkTimes == 0 )
+ {
+ bStopBlinking = _TRUE;
+ }
+
+ if(bStopBlinking)
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if(pLed->bLedOn)
+ SwLedOff(padapter, pLed);
+ }
+ else
+ { pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if(!pLed->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+
+ case LED_BLINK_TXRX:
+ pLed->BlinkTimes--;
+ if( pLed->BlinkTimes == 0 )
+ {
+ bStopBlinking = _TRUE;
+ }
+
+ if(bStopBlinking)
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if(pLed->bLedOn)
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if(!pLed->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on && adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS)
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("SwLedBlink5 CurrLedState %d\n", pLed->CurrLedState));
+
+
+}
+
+void
+SwLedBlink6(
+ PLED_871x pLed
+ )
+{
+ _adapter *padapter = pLed->padapter;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ u8 bStopBlinking = _FALSE;
+
+ // Change LED according to BlinkingLedState specified.
+ if( pLed->BlinkingLedState == RTW_LED_ON )
+ {
+ SwLedOn(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
+ }
+ else
+ {
+ SwLedOff(padapter, pLed);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
+ }
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("<==== blink6\n"));
+}
+
+static void
+SwLedControlMode0(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ PLED_871x pLed = &(ledpriv->SwLed1);
+
+ // Decide led state
+ switch(LedAction)
+ {
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if( pLed->bLedBlinkInProgress == _FALSE )
+ {
+ pLed->bLedBlinkInProgress = _TRUE;
+
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ pLed->BlinkTimes = 2;
+
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ break;
+
+ case LED_CTL_START_TO_LINK:
+ if( pLed->bLedBlinkInProgress == _FALSE )
+ {
+ pLed->bLedBlinkInProgress = _TRUE;
+
+ pLed->CurrLedState = LED_BLINK_StartToBlink;
+ pLed->BlinkTimes = 24;
+
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ }
+ else
+ {
+ pLed->CurrLedState = LED_BLINK_StartToBlink;
+ }
+ break;
+
+ case LED_CTL_LINK:
+ pLed->CurrLedState = RTW_LED_ON;
+ if( pLed->bLedBlinkInProgress == _FALSE )
+ {
+ SwLedOn(padapter, pLed);
+ }
+ break;
+
+ case LED_CTL_NO_LINK:
+ pLed->CurrLedState = RTW_LED_OFF;
+ if( pLed->bLedBlinkInProgress == _FALSE )
+ {
+ SwLedOff(padapter, pLed);
+ }
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ if(pLed->bLedBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ SwLedOff(padapter, pLed);
+ break;
+
+ case LED_CTL_START_WPS:
+ if( pLed->bLedBlinkInProgress == _FALSE || pLed->CurrLedState == RTW_LED_ON)
+ {
+ pLed->bLedBlinkInProgress = _TRUE;
+
+ pLed->CurrLedState = LED_BLINK_WPS;
+ pLed->BlinkTimes = 20;
+
+ if( pLed->bLedOn )
+ {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+ }
+ else
+ {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL);
+ }
+ }
+ break;
+
+ case LED_CTL_STOP_WPS:
+ if(pLed->bLedBlinkInProgress)
+ {
+ pLed->CurrLedState = RTW_LED_OFF;
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ break;
+
+
+ default:
+ break;
+ }
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
+
+}
+
+ //ALPHA, added by chiyoko, 20090106
+static void
+SwLedControlMode1(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+#ifndef CONFIG_LED_REMOVE_HAL
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+#endif
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ PLED_871x pLed = &(ledpriv->SwLed0);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+
+#ifndef CONFIG_LED_REMOVE_HAL
+ if(pHalData->EEPROMCustomerID == RT_CID_819x_CAMEO)
+ pLed = &(ledpriv->SwLed1);
+#endif
+
+ switch(LedAction)
+ {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_START_TO_LINK:
+ case LED_CTL_NO_LINK:
+ if( pLed->bLedNoLinkBlinkInProgress == _FALSE )
+ {
+ if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ {
+ return;
+ }
+ if( pLed->bLedLinkBlinkInProgress == _TRUE )
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_LINK:
+ if( pLed->bLedLinkBlinkInProgress == _FALSE )
+ {
+ if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ {
+ return;
+ }
+ if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ pLed->bLedLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_NORMAL;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_SITE_SURVEY:
+ if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
+ ;
+ else if(pLed->bLedScanBlinkInProgress ==_FALSE)
+ {
+ if(IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedLinkBlinkInProgress == _TRUE )
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ pLed->bLedScanBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 24;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if(pLed->bLedBlinkInProgress ==_FALSE)
+ {
+ if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ {
+ return;
+ }
+ if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedLinkBlinkInProgress == _TRUE )
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = _FALSE;
+ }
+ pLed->bLedBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_START_WPS: //wait until xinpin finish
+ case LED_CTL_START_WPS_BOTTON:
+ if(pLed->bLedWPSBlinkInProgress ==_FALSE)
+ {
+ if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedLinkBlinkInProgress == _TRUE )
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedScanBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ pLed->bLedWPSBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+
+ case LED_CTL_STOP_WPS:
+ if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedLinkBlinkInProgress == _TRUE )
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedScanBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedWPSBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ }
+ else
+ {
+ pLed->bLedWPSBlinkInProgress = _TRUE;
+ }
+
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ if(pLed->bLedOn)
+ {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ }
+ else
+ {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL:
+ if(pLed->bLedWPSBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if( pLed->bLedNoLinkBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedLinkBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedWPSBlinkInProgress )
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedScanBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+
+ SwLedOff(padapter, pLed);
+ break;
+
+ default:
+ break;
+
+ }
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
+}
+
+ //Arcadyan/Sitecom , added by chiyoko, 20090216
+static void
+SwLedControlMode2(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ PLED_871x pLed = &(ledpriv->SwLed0);
+
+ switch(LedAction)
+ {
+ case LED_CTL_SITE_SURVEY:
+ if(pmlmepriv->LinkDetectInfo.bBusyTraffic)
+ ;
+ else if(pLed->bLedScanBlinkInProgress ==_FALSE)
+ {
+ if(IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ pLed->bLedScanBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 24;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if((pLed->bLedBlinkInProgress ==_FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
+ {
+ if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ {
+ return;
+ }
+
+ pLed->bLedBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_LINK:
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if( pLed->bLedBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedScanBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_WPS: //wait until xinpin finish
+ case LED_CTL_START_WPS_BOTTON:
+ if(pLed->bLedWPSBlinkInProgress ==_FALSE)
+ {
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedScanBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ pLed->bLedWPSBlinkInProgress = _TRUE;
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_STOP_WPS:
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+ }
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL:
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ if(adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on)
+ {
+ SwLedOff(padapter, pLed);
+ }
+ else
+ {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+ }
+ break;
+
+ case LED_CTL_START_TO_LINK:
+ case LED_CTL_NO_LINK:
+ if(!IS_LED_BLINKING(pLed))
+ {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if( pLed->bLedBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedScanBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedWPSBlinkInProgress )
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ default:
+ break;
+
+ }
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+}
+
+ //COREGA, added by chiyoko, 20090316
+ static void
+ SwLedControlMode3(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ PLED_871x pLed = &(ledpriv->SwLed0);
+
+ switch(LedAction)
+ {
+ case LED_CTL_SITE_SURVEY:
+ if(pmlmepriv->LinkDetectInfo.bBusyTraffic)
+ ;
+ else if(pLed->bLedScanBlinkInProgress ==_FALSE)
+ {
+ if(IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ pLed->bLedScanBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 24;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if((pLed->bLedBlinkInProgress ==_FALSE) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
+ {
+ if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ {
+ return;
+ }
+
+ pLed->bLedBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_LINK:
+ if(IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+ if( pLed->bLedBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedScanBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_WPS: //wait until xinpin finish
+ case LED_CTL_START_WPS_BOTTON:
+ if(pLed->bLedWPSBlinkInProgress ==_FALSE)
+ {
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedScanBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ pLed->bLedWPSBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_STOP_WPS:
+ if(pLed->bLedWPSBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+ else
+ {
+ pLed->bLedWPSBlinkInProgress = _TRUE;
+ }
+
+ pLed->CurrLedState = LED_BLINK_WPS_STOP;
+ if(pLed->bLedOn)
+ {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA);
+ }
+ else
+ {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL:
+ if(pLed->bLedWPSBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_START_TO_LINK:
+ case LED_CTL_NO_LINK:
+ if(!IS_LED_BLINKING(pLed))
+ {
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ if( pLed->bLedBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedScanBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedWPSBlinkInProgress )
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ default:
+ break;
+
+ }
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("CurrLedState %d\n", pLed->CurrLedState));
+}
+
+
+ //Edimax-Belkin, added by chiyoko, 20090413
+static void
+SwLedControlMode4(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ PLED_871x pLed = &(ledpriv->SwLed0);
+ PLED_871x pLed1 = &(ledpriv->SwLed1);
+
+ switch(LedAction)
+ {
+ case LED_CTL_START_TO_LINK:
+ if(pLed1->bLedWPSBlinkInProgress)
+ {
+ pLed1->bLedWPSBlinkInProgress = _FALSE;
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ pLed1->CurrLedState = RTW_LED_OFF;
+
+ if(pLed1->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+
+ if( pLed->bLedStartToLinkBlinkInProgress == _FALSE )
+ {
+ if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ {
+ return;
+ }
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedNoLinkBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ }
+
+ pLed->bLedStartToLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_StartToBlink;
+ if( pLed->bLedOn )
+ {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ }
+ else
+ {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ }
+ break;
+
+ case LED_CTL_LINK:
+ case LED_CTL_NO_LINK:
+ //LED1 settings
+ if(LedAction == LED_CTL_LINK)
+ {
+ if(pLed1->bLedWPSBlinkInProgress)
+ {
+ pLed1->bLedWPSBlinkInProgress = _FALSE;
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ pLed1->CurrLedState = RTW_LED_OFF;
+
+ if(pLed1->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+ }
+
+ if( pLed->bLedNoLinkBlinkInProgress == _FALSE )
+ {
+ if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ {
+ return;
+ }
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_SITE_SURVEY:
+ if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
+ ;
+ else if(pLed->bLedScanBlinkInProgress ==_FALSE)
+ {
+ if(IS_LED_WPS_BLINKING(pLed))
+ return;
+
+ if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ pLed->bLedScanBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 24;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if(pLed->bLedBlinkInProgress ==_FALSE)
+ {
+ if(pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
+ {
+ return;
+ }
+ if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ }
+ pLed->bLedBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_START_WPS: //wait until xinpin finish
+ case LED_CTL_START_WPS_BOTTON:
+ if(pLed1->bLedWPSBlinkInProgress)
+ {
+ pLed1->bLedWPSBlinkInProgress = _FALSE;
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ pLed1->CurrLedState = RTW_LED_OFF;
+
+ if(pLed1->bLedOn)
+ _set_timer(&(pLed->BlinkTimer), 0);
+ }
+
+ if(pLed->bLedWPSBlinkInProgress ==_FALSE)
+ {
+ if(pLed->bLedNoLinkBlinkInProgress == _TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if(pLed->bLedScanBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ pLed->bLedWPSBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_WPS;
+ if( pLed->bLedOn )
+ {
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL);
+ }
+ else
+ {
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+ }
+ }
+ break;
+
+ case LED_CTL_STOP_WPS: //WPS connect success
+ if(pLed->bLedWPSBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL: //WPS authentication fail
+ if(pLed->bLedWPSBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+
+ //LED1 settings
+ if(pLed1->bLedWPSBlinkInProgress)
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ else
+ pLed1->bLedWPSBlinkInProgress = _TRUE;
+
+ pLed1->CurrLedState = LED_BLINK_WPS_STOP;
+ if( pLed1->bLedOn )
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed1->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+
+ break;
+
+ case LED_CTL_STOP_WPS_FAIL_OVERLAP: //WPS session overlap
+ if(pLed->bLedWPSBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+
+ pLed->bLedNoLinkBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SLOWLY;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA);
+
+ //LED1 settings
+ if(pLed1->bLedWPSBlinkInProgress)
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ else
+ pLed1->bLedWPSBlinkInProgress = _TRUE;
+
+ pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
+ pLed1->BlinkTimes = 10;
+ if( pLed1->bLedOn )
+ pLed1->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed1->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL);
+
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ if( pLed->bLedNoLinkBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedNoLinkBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedLinkBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedLinkBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedWPSBlinkInProgress )
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedWPSBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedScanBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedScanBlinkInProgress = _FALSE;
+ }
+ if( pLed->bLedStartToLinkBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedStartToLinkBlinkInProgress = _FALSE;
+ }
+
+ if( pLed1->bLedWPSBlinkInProgress )
+ {
+ _cancel_timer_ex(&(pLed1->BlinkTimer));
+ pLed1->bLedWPSBlinkInProgress = _FALSE;
+ }
+
+ pLed1->BlinkingLedState = LED_UNKNOWN;
+ SwLedOff(padapter, pLed);
+ SwLedOff(padapter, pLed1);
+ break;
+
+ default:
+ break;
+
+ }
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
+}
+
+
+
+ //Sercomm-Belkin, added by chiyoko, 20090415
+static void
+SwLedControlMode5(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+#ifndef CONFIG_LED_REMOVE_HAL
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+#endif
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ PLED_871x pLed = &(ledpriv->SwLed0);
+
+#ifndef CONFIG_LED_REMOVE_HAL
+ if(pHalData->EEPROMCustomerID == RT_CID_819x_CAMEO)
+ pLed = &(ledpriv->SwLed1);
+#endif
+
+ switch(LedAction)
+ {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_NO_LINK:
+ case LED_CTL_LINK: //solid blue
+ pLed->CurrLedState = RTW_LED_ON;
+ pLed->BlinkingLedState = RTW_LED_ON;
+
+ _set_timer(&(pLed->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_SITE_SURVEY:
+ if((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE))
+ ;
+ else if(pLed->bLedScanBlinkInProgress ==_FALSE)
+ {
+ if(pLed->bLedBlinkInProgress ==_TRUE)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+ pLed->bLedScanBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_SCAN;
+ pLed->BlinkTimes = 24;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_TX:
+ case LED_CTL_RX:
+ if(pLed->bLedBlinkInProgress ==_FALSE)
+ {
+ if(pLed->CurrLedState == LED_BLINK_SCAN)
+ {
+ return;
+ }
+ pLed->bLedBlinkInProgress = _TRUE;
+ pLed->CurrLedState = LED_BLINK_TXRX;
+ pLed->BlinkTimes = 2;
+ if( pLed->bLedOn )
+ pLed->BlinkingLedState = RTW_LED_OFF;
+ else
+ pLed->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA);
+ }
+ break;
+
+ case LED_CTL_POWER_OFF:
+ pLed->CurrLedState = RTW_LED_OFF;
+ pLed->BlinkingLedState = RTW_LED_OFF;
+
+ if( pLed->bLedBlinkInProgress)
+ {
+ _cancel_timer_ex(&(pLed->BlinkTimer));
+ pLed->bLedBlinkInProgress = _FALSE;
+ }
+
+ SwLedOff(padapter, pLed);
+ break;
+
+ default:
+ break;
+
+ }
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("Led %d\n", pLed->CurrLedState));
+}
+
+ //WNC-Corega, added by chiyoko, 20090902
+static void
+SwLedControlMode6(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+)
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ PLED_871x pLed0 = &(ledpriv->SwLed0);
+
+ switch(LedAction)
+ {
+ case LED_CTL_POWER_ON:
+ case LED_CTL_LINK:
+ case LED_CTL_NO_LINK:
+ _cancel_timer_ex(&(pLed0->BlinkTimer));
+ pLed0->CurrLedState = RTW_LED_ON;
+ pLed0->BlinkingLedState = RTW_LED_ON;
+ _set_timer(&(pLed0->BlinkTimer), 0);
+ break;
+
+ case LED_CTL_POWER_OFF:
+ SwLedOff(padapter, pLed0);
+ break;
+
+ default:
+ break;
+ }
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("ledcontrol 6 Led %d\n", pLed0->CurrLedState));
+}
+
+//
+// Description:
+// Handler function of LED Blinking.
+// We dispatch acture LED blink action according to LedStrategy.
+//
+void BlinkHandler(PLED_871x pLed)
+{
+ _adapter *padapter = pLed->padapter;
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+
+ //DBG_871X("%s (%s:%d)\n",__FUNCTION__, current->comm, current->pid);
+
+ if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE))
+ {
+ //DBG_871X("%s bSurpriseRemoved:%d, bDriverStopped:%d\n", __FUNCTION__, padapter->bSurpriseRemoved, padapter->bDriverStopped);
+ return;
+ }
+
+ switch(ledpriv->LedStrategy)
+ {
+ case SW_LED_MODE0:
+ SwLedBlink(pLed);
+ break;
+
+ case SW_LED_MODE1:
+ SwLedBlink1(pLed);
+ break;
+
+ case SW_LED_MODE2:
+ SwLedBlink2(pLed);
+ break;
+
+ case SW_LED_MODE3:
+ SwLedBlink3(pLed);
+ break;
+
+ case SW_LED_MODE4:
+ SwLedBlink4(pLed);
+ break;
+
+ case SW_LED_MODE5:
+ SwLedBlink5(pLed);
+ break;
+
+ case SW_LED_MODE6:
+ SwLedBlink6(pLed);
+ break;
+
+ default:
+ //RT_TRACE(COMP_LED, DBG_LOUD, ("BlinkWorkItemCallback 0x%x \n", pHalData->LedStrategy));
+ //SwLedBlink(pLed);
+ break;
+ }
+}
+
+void
+LedControl871x(
+ _adapter *padapter,
+ LED_CTL_MODE LedAction
+ )
+{
+ struct led_priv *ledpriv = &(padapter->ledpriv);
+
+ if( (padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)
+ ||(padapter->hw_init_completed == _FALSE) )
+ {
+ return;
+ }
+
+
+ if( ledpriv->bRegUseLed == _FALSE)
+ return;
+
+ //if (!priv->up)
+ // return;
+
+ //if(priv->bInHctTest)
+ // return;
+
+ if( (adapter_to_pwrctl(padapter)->rf_pwrstate != rf_on &&
+ adapter_to_pwrctl(padapter)->rfoff_reason > RF_CHANGE_BY_PS) &&
+ (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX ||
+ LedAction == LED_CTL_SITE_SURVEY ||
+ LedAction == LED_CTL_LINK ||
+ LedAction == LED_CTL_NO_LINK ||
+ LedAction == LED_CTL_POWER_ON) )
+ {
+ return;
+ }
+
+ switch(ledpriv->LedStrategy)
+ {
+ case SW_LED_MODE0:
+ //SwLedControlMode0(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE1:
+ SwLedControlMode1(padapter, LedAction);
+ break;
+ case SW_LED_MODE2:
+ SwLedControlMode2(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE3:
+ SwLedControlMode3(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE4:
+ SwLedControlMode4(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE5:
+ SwLedControlMode5(padapter, LedAction);
+ break;
+
+ case SW_LED_MODE6:
+ SwLedControlMode6(padapter, LedAction);
+ break;
+
+ default:
+ break;
+ }
+
+ RT_TRACE(_module_rtl8712_led_c_,_drv_info_,("LedStrategy:%d, LedAction %d\n", ledpriv->LedStrategy,LedAction));
+}
+
+#endif
+
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_mlme.c b/drivers/net/wireless/rtl8723as/core/rtw_mlme.c
index a827c0221b36..b5e1807c69d7 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_mlme.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_mlme.c
@@ -119,7 +119,7 @@ static void rtw_free_mlme_ie_data(u8 **ppie, u32 *plen)
{
if(*ppie)
{
- _rtw_mfree(*ppie, *plen);
+ rtw_mfree(*ppie, *plen);
*plen = 0;
*ppie=NULL;
}
@@ -628,7 +628,7 @@ inline int is_same_ess(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b)
&& _rtw_memcmp(a->Ssid.Ssid, b->Ssid.Ssid, a->Ssid.SsidLength)==_TRUE;
}
-int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst)
+int is_same_network(WLAN_BSSID_EX *src, WLAN_BSSID_EX *dst, u8 feature)
{
u16 s_cap, d_cap;
@@ -658,6 +658,14 @@ _func_enter_;
_func_exit_;
+#ifdef CONFIG_P2P
+ if ((feature == 1) && // 1: P2P supported
+ (_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN) == _TRUE)
+ ) {
+ return _TRUE;
+ }
+#endif
+
return ((src->Ssid.SsidLength == dst->Ssid.SsidLength) &&
// (src->Configuration.DSConfig == dst->Configuration.DSConfig) &&
( (_rtw_memcmp(src->MacAddress, dst->MacAddress, ETH_ALEN)) == _TRUE) &&
@@ -723,10 +731,10 @@ _func_enter_;
rtw_hal_antdiv_rssi_compared(padapter, dst, src); //this will update src.Rssi, need consider again
#endif
- #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
+ #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1
if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
- DBG_871X("%s %s("MAC_FMT", ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n"
- , __FUNCTION__
+ DBG_871X(FUNC_ADPT_FMT" %s("MAC_FMT", ch%u) ss_ori:%3u, sq_ori:%3u, rssi_ori:%3ld, ss_smp:%3u, sq_smp:%3u, rssi_smp:%3ld\n"
+ , FUNC_ADPT_ARG(padapter)
, src->Ssid.Ssid, MAC_ARG(src->MacAddress), src->Configuration.DSConfig
,ss_ori, sq_ori, rssi_ori
,ss_smp, sq_smp, rssi_smp
@@ -735,7 +743,7 @@ _func_enter_;
#endif
/* The rule below is 1/5 for sample value, 4/5 for history value */
- if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src)) {
+ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src, 0)) {
/* Take the recvpriv's value for the connected AP*/
ss_final = padapter->recvpriv.signal_strength;
sq_final = padapter->recvpriv.signal_qual;
@@ -759,24 +767,27 @@ _func_enter_;
}
- if (update_ie)
+ if (update_ie) {
+ dst->Reserved[0] = src->Reserved[0];
+ dst->Reserved[1] = src->Reserved[1];
_rtw_memcpy((u8 *)dst, (u8 *)src, get_WLAN_BSSID_EX_sz(src));
+ }
dst->PhyInfo.SignalStrength = ss_final;
dst->PhyInfo.SignalQuality = sq_final;
dst->Rssi = rssi_final;
- #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
+ #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) && 1
if(strcmp(dst->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
- DBG_871X("%s %s("MAC_FMT"), SignalStrength:%u, SignalQuality:%u, RawRSSI:%ld\n"
- , __FUNCTION__
+ DBG_871X(FUNC_ADPT_FMT" %s("MAC_FMT"), SignalStrength:%u, SignalQuality:%u, RawRSSI:%ld\n"
+ , FUNC_ADPT_ARG(padapter)
, dst->Ssid.Ssid, MAC_ARG(dst->MacAddress), dst->PhyInfo.SignalStrength, dst->PhyInfo.SignalQuality, dst->Rssi);
}
#endif
#if 0 // old codes, may be useful one day...
// DBG_871X("update_network: rssi=0x%lx dst->Rssi=%d ,dst->Rssi=0x%lx , src->Rssi=0x%lx",(dst->Rssi+src->Rssi)/2,dst->Rssi,dst->Rssi,src->Rssi);
- if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src))
+ if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) && is_same_network(&(padapter->mlmepriv.cur_network.network), src, 0))
{
//DBG_871X("b:ssid=%s update_network: src->rssi=0x%d padapter->recvpriv.ui_rssi=%d\n",src->Ssid.Ssid,src->Rssi,padapter->recvpriv.signal);
@@ -825,7 +836,7 @@ _func_enter_;
}
#endif
- if ( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork)))
+ if ( (check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork, 0)))
{
//RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,"Same Network\n");
@@ -854,9 +865,13 @@ void rtw_update_scanned_network(_adapter *adapter, WLAN_BSSID_EX *target)
_list *plist, *phead;
ULONG bssid_ex_sz;
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
+ struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
+ struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
_queue *queue = &(pmlmepriv->scanned_queue);
struct wlan_network *pnetwork = NULL;
struct wlan_network *oldest = NULL;
+ int target_find = 0;
+ u8 feature = 0;
_func_enter_;
@@ -864,6 +879,11 @@ _func_enter_;
phead = get_list_head(queue);
plist = get_next(phead);
+#ifdef CONFIG_P2P
+ if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
+ feature = 1; // p2p enable
+#endif
+
while(1)
{
if (rtw_end_of_queue_search(phead,plist)== _TRUE)
@@ -878,8 +898,10 @@ _func_enter_;
#endif
}
- if (is_same_network(&(pnetwork->network), target))
+ if (is_same_network(&(pnetwork->network), target, feature)) {
+ target_find = 1;
break;
+ }
if ((oldest == ((struct wlan_network *)0)) ||
time_after(oldest->last_scanned, pnetwork->last_scanned))
@@ -892,7 +914,8 @@ _func_enter_;
/* If we didn't find a match, then get a new network slot to initialize
* with this beacon's information */
- if (rtw_end_of_queue_search(phead,plist)== _TRUE) {
+ //if (rtw_end_of_queue_search(phead,plist)== _TRUE) {
+ if (!target_find) {
if (_rtw_queue_empty(&(pmlmepriv->free_bss_pool)) == _TRUE) {
/* If there are no more slots, expire the oldest */
@@ -955,8 +978,15 @@ _func_enter_;
pnetwork->last_scanned = rtw_get_current_time();
//target.Reserved[0]==1, means that scaned network is a bcn frame.
- if((pnetwork->network.IELength>target->IELength) && (target->Reserved[0]==1))
+ // probe resp(3) > beacon(1) > probe req(2)
+ if ((target->Reserved[0] != 2) &&
+ (target->Reserved[0] >= pnetwork->network.Reserved[0])
+ ) {
+ update_ie = _TRUE;
+ }
+ else {
update_ie = _FALSE;
+ }
update_network(&(pnetwork->network), target,adapter, update_ie);
}
@@ -1026,8 +1056,20 @@ int rtw_is_desired_network(_adapter *adapter, struct wlan_network *pnetwork)
}
if (adapter->registrypriv.wifi_spec == 1) //for correct flow of 8021X to do....
{
+ u8 *p=NULL;
+ uint ie_len=0;
+
if ((desired_encmode == Ndis802_11EncryptionDisabled) && (privacy != 0))
bselected = _FALSE;
+
+ if ( psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK) {
+ p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
+ if (p && ie_len>0) {
+ bselected = _TRUE;
+ } else {
+ bselected = _FALSE;
+ }
+ }
}
@@ -1129,7 +1171,7 @@ _func_enter_;
pnetwork->Ssid.SsidLength = 0;
}
rtw_add_network(adapter, pnetwork);
- }
+ }
exit:
@@ -1145,6 +1187,7 @@ _func_exit_;
void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf)
{
_irqL irqL;
+ u8 timer_cancelled = _FALSE;
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
#ifdef CONFIG_MLME_EXT
@@ -1156,7 +1199,6 @@ void rtw_surveydone_event_callback(_adapter *adapter, u8 *pbuf)
_func_enter_;
_enter_critical_bh(&pmlmepriv->lock, &irqL);
-
if(pmlmepriv->wps_probe_req_ie)
{
u32 free_len = pmlmepriv->wps_probe_req_ie_len;
@@ -1169,9 +1211,10 @@ _func_enter_;
if (check_fwstate(pmlmepriv,_FW_UNDER_SURVEY))
{
- u8 timer_cancelled;
-
- _cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled);
+ //u8 timer_cancelled;
+
+ timer_cancelled = _TRUE;
+ //_cancel_timer(&pmlmepriv->scan_to_timer, &timer_cancelled);
_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
}
@@ -1179,6 +1222,13 @@ _func_enter_;
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);
+
+
+ _enter_critical_bh(&pmlmepriv->lock, &irqL);
#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
rtw_set_signal_stat_timer(&adapter->recvpriv);
@@ -1293,7 +1343,7 @@ _func_enter_;
{
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
if(pmlmeext->sitesurvey_res.bss_cnt == 0){
- rtw_hal_sreset_reset(adapter);
+ //rtw_hal_sreset_reset(adapter);
}
}
#endif
@@ -1413,6 +1463,32 @@ _func_enter_;
if(pwlan)
{
pwlan->fixed = _FALSE;
+#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);
+ }
+#endif //CONFIG_P2P
}
else
{
@@ -1429,7 +1505,7 @@ _func_enter_;
if(lock_scanned_queue)
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
- pmlmepriv->key_mask = 0;
+ adapter->securitypriv.key_mask = 0;
_func_exit_;
@@ -1536,7 +1612,7 @@ _func_enter_;
rtw_os_indicate_disconnect(padapter);
//set ips_deny_time to avoid enter IPS before LPS leave
- padapter->pwrctrlpriv.ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(3000);
+ adapter_to_pwrctl(padapter)->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(3000);
_clr_fwstate_(pmlmepriv, _FW_LINKED);
@@ -1551,9 +1627,6 @@ _func_enter_;
#endif // CONFIG_P2P_PS
#ifdef CONFIG_LPS
-#ifdef CONFIG_WOWLAN
- if(padapter->pwrctrlpriv.wowlan_mode==_FALSE)
-#endif //CONFIG_WOWLAN
rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_DISCONNECT, 1);
#endif
@@ -1587,7 +1660,7 @@ void rtw_scan_abort(_adapter *adapter)
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
if (!adapter->bDriverStopped && !adapter->bSurpriseRemoved)
DBG_871X(FUNC_NDEV_FMT"waiting for scan_abort time out!\n", FUNC_NDEV_ARG(adapter->pnetdev));
- #ifdef CONFIG_PLATFORM_MSTAR_TITANIA12
+ #ifdef CONFIG_PLATFORM_MSTAR
//_clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY);
set_survey_timer(pmlmeext, 0);
_set_timer(&pmlmepriv->scan_to_timer, 50);
@@ -1642,7 +1715,10 @@ static struct sta_info *rtw_joinbss_update_stainfo(_adapter *padapter, struct wl
_rtw_memset((u8 *)&psta->dot11tkiprxmickey, 0, sizeof (union Keytype));
_rtw_memset((u8 *)&psta->dot11tkiptxmickey, 0, sizeof (union Keytype));
- _rtw_memset((u8 *)&psta->dot11txpn, 0, sizeof (union pn48));
+ _rtw_memset((u8 *)&psta->dot11txpn, 0, sizeof (union pn48));
+#ifdef CONFIG_IEEE80211W
+ _rtw_memset((u8 *)&psta->dot11wtxpn, 0, sizeof (union pn48));
+#endif //CONFIG_IEEE80211W
_rtw_memset((u8 *)&psta->dot11rxpn, 0, sizeof (union pn48));
}
@@ -1732,9 +1808,9 @@ static void rtw_joinbss_update_network(_adapter *padapter, struct wlan_network *
//the ptarget_wlan->network.Rssi is raw data, we use ptarget_wlan->network.PhyInfo.SignalStrength instead (has scaled)
padapter->recvpriv.rssi = translate_percentage_to_dbm(ptarget_wlan->network.PhyInfo.SignalStrength);
#if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
- DBG_871X("%s signal_strength:%3u, rssi:%3d, signal_qual:%3u"
+ DBG_871X(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
"\n"
- , __FUNCTION__
+ , FUNC_ADPT_ARG(padapter)
, padapter->recvpriv.signal_strength
, padapter->recvpriv.rssi
, padapter->recvpriv.signal_qual
@@ -1911,15 +1987,16 @@ _func_enter_;
}
//s4. indicate connect
- if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
- {
- rtw_indicate_connect(adapter);
- }
- else
- {
- //adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback
- RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv)));
- }
+ if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
+ {
+ pmlmepriv->cur_network_scanned = ptarget_wlan;
+ rtw_indicate_connect(adapter);
+ }
+ else
+ {
+ //adhoc mode will rtw_indicate_connect when rtw_stassoc_event_callback
+ RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("adhoc mode, fw_state:%x", get_fwstate(pmlmepriv)));
+ }
//s5. Cancle assoc_timer
@@ -2057,10 +2134,10 @@ u8 search_max_mac_id(_adapter *padapter)
}
-//FOR AP ,AD-HOC mode
-void rtw_stassoc_hw_rpt(_adapter *adapter,struct sta_info *psta)
+//FOR STA, AP ,AD-HOC mode
+void rtw_sta_media_status_rpt(_adapter *adapter,struct sta_info *psta, u32 mstatus)
{
- u16 media_status;
+ u16 media_status_rpt;
if(psta==NULL) return;
@@ -2070,8 +2147,8 @@ void rtw_stassoc_hw_rpt(_adapter *adapter,struct sta_info *psta)
rtw_hal_set_hwreg(adapter,HW_VAR_TX_RPT_MAX_MACID, (u8*)&macid);
}
#endif
- media_status = (psta->mac_id<<8)|1; // MACID|OPMODE:1 connect
- rtw_hal_set_hwreg(adapter,HW_VAR_H2C_MEDIA_STATUS_RPT,(u8 *)&media_status);
+ media_status_rpt = (u16)((psta->mac_id<<8)|mstatus); // MACID|OPMODE:1 connect
+ rtw_hal_set_hwreg(adapter,HW_VAR_H2C_MEDIA_STATUS_RPT,(u8 *)&media_status_rpt);
}
void rtw_stassoc_event_callback(_adapter *adapter, u8 *pbuf)
@@ -2094,13 +2171,18 @@ _func_enter_;
psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
if(psta)
{
-#ifdef CONFIG_IOCTL_CFG80211
- #ifdef COMPAT_KERNEL_RELEASE
-
- #elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
u8 *passoc_req = NULL;
- u32 assoc_req_len;
+ u32 assoc_req_len = 0;
+
+ rtw_sta_media_status_rpt(adapter, psta, 1);
+
+#ifndef CONFIG_AUTO_AP_MODE
+
+ ap_sta_info_defer_update(adapter, psta);
+ //report to upper layer
+ DBG_871X("indicate_sta_assoc_event to upper layer - hostapd\n");
+#ifdef CONFIG_IOCTL_CFG80211
_enter_critical_bh(&psta->lock, &irqL);
if(psta->passoc_req && psta->assoc_req_len>0)
{
@@ -2110,7 +2192,7 @@ _func_enter_;
assoc_req_len = psta->assoc_req_len;
_rtw_memcpy(passoc_req, psta->passoc_req, assoc_req_len);
- _rtw_mfree(psta->passoc_req , psta->assoc_req_len);
+ rtw_mfree(psta->passoc_req , psta->assoc_req_len);
psta->passoc_req = NULL;
psta->assoc_req_len = 0;
}
@@ -2120,23 +2202,18 @@ _func_enter_;
if(passoc_req && assoc_req_len>0)
{
rtw_cfg80211_indicate_sta_assoc(adapter, passoc_req, assoc_req_len);
-
- _rtw_mfree(passoc_req, assoc_req_len);
- }
- #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)) || defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
-#endif //CONFIG_IOCTL_CFG80211
-
- //bss_cap_update_on_sta_join(adapter, psta);
- //sta_info_update(adapter, psta);
- ap_sta_info_defer_update(adapter, psta);
-
- rtw_stassoc_hw_rpt(adapter,psta);
-
- }
+ rtw_mfree(passoc_req, assoc_req_len);
+ }
+#else //!CONFIG_IOCTL_CFG80211
+ rtw_indicate_sta_assoc_event(adapter, psta);
+#endif //!CONFIG_IOCTL_CFG80211
+#endif //!CONFIG_AUTO_AP_MODE
+ }
goto exit;
}
-#endif
+#endif //defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
+
//for AD-HOC mode
psta = rtw_get_stainfo(&adapter->stapriv, pstassoc->macaddr);
if( psta != NULL)
@@ -2162,7 +2239,7 @@ _func_enter_;
//for ad-hoc mode
rtw_hal_set_odm_var(adapter,HAL_ODM_STA_INFO,psta,_TRUE);
- rtw_stassoc_hw_rpt(adapter,psta);
+ rtw_sta_media_status_rpt(adapter, psta, 1);
if(adapter->securitypriv.dot11AuthAlgrthm==dot11AuthAlgrthm_8021X)
psta->dot118021XPrivacy = adapter->securitypriv.dot11PrivacyAlgrthm;
@@ -2193,7 +2270,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, (unsigned char*)psta, _FALSE);
+ rtw_setstakey_cmd(adapter, (unsigned char*)psta, _FALSE, _TRUE);
#endif
exit:
@@ -2253,7 +2330,9 @@ _func_enter_;
if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) )
{
#ifdef CONFIG_LAYER2_ROAMING
- if (rtw_to_roaming(adapter) > 0)
+ if(adapter->registrypriv.wifi_spec==1)
+ rtw_set_roaming(adapter, 0); /* don't roam */
+ else if (rtw_to_roaming(adapter) > 0)
pmlmepriv->to_roaming--; /* this stadel_event is caused by roaming, decrease to_roaming */
else if (rtw_to_roaming(adapter) == 0)
rtw_set_roaming(adapter, adapter->registrypriv.max_roaming_times);
@@ -2357,7 +2436,7 @@ _func_enter_;
RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("+rtw_cpwm_event_callback !!!\n"));
#ifdef CONFIG_LPS_LCLK
preportpwrstate = (struct reportpwrstate_parm*)pbuf;
- preportpwrstate->state |= (u8)(padapter->pwrctrlpriv.cpwm_tog + 0x80);
+ preportpwrstate->state |= (u8)(adapter_to_pwrctl(padapter)->cpwm_tog + 0x80);
cpwm_int_hdl(padapter, preportpwrstate);
#endif
@@ -2489,7 +2568,7 @@ void rtw_scan_timeout_handler (_adapter *adapter)
static void rtw_auto_scan_handler(_adapter *padapter)
{
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
//auto site survey per 60sec
if(pmlmepriv->scan_interval >0)
@@ -2549,7 +2628,12 @@ void rtw_dynamic_check_timer_handlder(_adapter *adapter)
return;
#if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
if(adapter->HalFunc.hal_checke_bt_hang)
- adapter->HalFunc.hal_checke_bt_hang(adapter);
+ {
+#ifdef CONFIG_CONCURRENT_MODE
+ if (adapter->adapter_type == PRIMARY_ADAPTER)
+#endif
+ adapter->HalFunc.hal_checke_bt_hang(adapter);
+ }
#endif
if(adapter->hw_init_completed == _FALSE)
return;
@@ -2678,6 +2762,13 @@ void rtw_set_scan_deny(_adapter *adapter, u32 ms)
}
#endif
+#ifdef CONFIG_DETECT_C2H_BY_POLLING
+void rtw_event_polling_timer_hdl(_adapter *adapter)
+{
+ rtw_event_polling_cmd(adapter);
+}
+#endif
+
#if defined(IEEE80211_SCAN_RESULT_EXPIRE)
#define RTW_SCAN_RESULT_EXPIRE IEEE80211_SCAN_RESULT_EXPIRE/HZ*1000 -1000 //3000 -1000
#else
@@ -2953,7 +3044,7 @@ _func_enter_;
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
{
- if(is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network))
+ if(is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network), 0)
{
//DBG_871X("select_and_join(1): _FW_LINKED and is same network, it needn't join again\n");
@@ -2987,7 +3078,7 @@ _func_enter_;
if( (roaming_candidate == NULL ||roaming_candidate->network.Rssi<pnetwork->network.Rssi )
&& is_same_ess(&pnetwork->network, &pmlmepriv->cur_network.network)
- //&&(!is_same_network(&pnetwork->network, &pmlmepriv->cur_network.network))
+ //&&(!is_same_network(&pnetwork->network, &pmlmepriv->cur_network.network, 0))
&& rtw_get_time_interval_ms((u32)pnetwork->last_scanned,cur_time) < 5000
) {
roaming_candidate = pnetwork;
@@ -3030,7 +3121,7 @@ _func_enter_;
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
{
#if 0
- if(is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network))
+ if(is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0))
{
DBG_871X("select_and_join(2): _FW_LINKED and is same network, it needn't join again\n");
@@ -3141,7 +3232,7 @@ _func_exit_;
}
-sint rtw_set_key(_adapter * adapter,struct security_priv *psecuritypriv,sint keyid, u8 set_tx)
+sint rtw_set_key(_adapter * adapter,struct security_priv *psecuritypriv,sint keyid, u8 set_tx, bool enqueue)
{
u8 keylen;
struct cmd_obj *pcmd;
@@ -3151,19 +3242,12 @@ sint rtw_set_key(_adapter * adapter,struct security_priv *psecuritypriv,sint key
sint res=_SUCCESS;
_func_enter_;
-
- pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
- if(pcmd==NULL){
- res= _FAIL; //try again
- goto exit;
- }
+
psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm));
- if(psetkeyparm==NULL){
- rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj));
+ if(psetkeyparm==NULL){
res= _FAIL;
goto exit;
}
-
_rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
if(psecuritypriv->dot11AuthAlgrthm ==dot11AuthAlgrthm_8021X){
@@ -3178,20 +3262,13 @@ _func_enter_;
psetkeyparm->keyid = (u8)keyid;//0~3
psetkeyparm->set_tx = set_tx;
if (is_wep_enc(psetkeyparm->algorithm))
- pmlmepriv->key_mask |= BIT(psetkeyparm->keyid);
+ psecuritypriv->key_mask |= BIT(psetkeyparm->keyid);
-#ifdef CONFIG_AUTOSUSPEND
- if( _TRUE == adapter->pwrctrlpriv.bInternalAutoSuspend)
- {
- adapter->pwrctrlpriv.wepkeymask = pmlmepriv->key_mask;
- DBG_871X("....AutoSuspend pwrctrlpriv.wepkeymask(%x)\n",adapter->pwrctrlpriv.wepkeymask);
- }
-#endif
- DBG_871X("==> rtw_set_key algorithm(%x),keyid(%x),key_mask(%x)\n",psetkeyparm->algorithm,psetkeyparm->keyid,pmlmepriv->key_mask);
+ DBG_871X("==> rtw_set_key algorithm(%x),keyid(%x),key_mask(%x)\n",psetkeyparm->algorithm,psetkeyparm->keyid, psecuritypriv->key_mask);
RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key: psetkeyparm->algorithm=%d psetkeyparm->keyid=(u8)keyid=%d \n",psetkeyparm->algorithm, keyid));
switch(psetkeyparm->algorithm){
-
+
case _WEP40_:
keylen=5;
_rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
@@ -3201,7 +3278,7 @@ _func_enter_;
_rtw_memcpy(&(psetkeyparm->key[0]), &(psecuritypriv->dot11DefKey[keyid].skey[0]), keylen);
break;
case _TKIP_:
- keylen=16;
+ keylen=16;
_rtw_memcpy(&psetkeyparm->key, &psecuritypriv->dot118021XGrpKey[keyid], keylen);
psetkeyparm->grpkey=1;
break;
@@ -3213,23 +3290,35 @@ _func_enter_;
default:
RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("\n rtw_set_key:psecuritypriv->dot11PrivacyAlgrthm = %x (must be 1 or 2 or 4 or 5)\n",psecuritypriv->dot11PrivacyAlgrthm));
res= _FAIL;
+ rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm));
goto exit;
}
+
+
+ if(enqueue){
+ pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
+ if(pcmd==NULL){
+ rtw_mfree((unsigned char *)psetkeyparm, sizeof(struct setkey_parm));
+ res= _FAIL; //try again
+ goto exit;
+ }
+
+ pcmd->cmdcode = _SetKey_CMD_;
+ pcmd->parmbuf = (u8 *)psetkeyparm;
+ pcmd->cmdsz = (sizeof(struct setkey_parm));
+ pcmd->rsp = NULL;
+ pcmd->rspsz = 0;
-
- pcmd->cmdcode = _SetKey_CMD_;
- pcmd->parmbuf = (u8 *)psetkeyparm;
- pcmd->cmdsz = (sizeof(struct setkey_parm));
- pcmd->rsp = NULL;
- pcmd->rspsz = 0;
-
-
- _rtw_init_listhead(&pcmd->list);
-
- //_rtw_init_sema(&(pcmd->cmd_sem), 0);
+ _rtw_init_listhead(&pcmd->list);
- res = rtw_enqueue_cmd(pcmdpriv, pcmd);
+ //_rtw_init_sema(&(pcmd->cmd_sem), 0);
+ res = rtw_enqueue_cmd(pcmdpriv, pcmd);
+ }
+ else{
+ setkey_hdl(adapter, (u8 *)psetkeyparm);
+ rtw_mfree((u8 *) psetkeyparm, sizeof(struct setkey_parm));
+ }
exit:
_func_exit_;
return res;
@@ -3389,6 +3478,14 @@ _func_enter_;
{
//copy RSN or SSN
_rtw_memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1]+2);
+ /* debug for CONFIG_IEEE80211W
+ {
+ int jj;
+ printk("supplicant_ie_length=%d &&&&&&&&&&&&&&&&&&&\n", psecuritypriv->supplicant_ie[1]+2);
+ for(jj=0; jj < psecuritypriv->supplicant_ie[1]+2; jj++)
+ printk(" %02x ", psecuritypriv->supplicant_ie[jj]);
+ printk("\n");
+ }*/
ielength+=psecuritypriv->supplicant_ie[1]+2;
rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie);
@@ -3655,7 +3752,7 @@ unsigned int rtw_restructure_ht_ie(_adapter *padapter, u8 *in_ie, u8 *out_ie, ui
p = rtw_get_ie(in_ie+12, _HT_ADD_INFO_IE_, &ielen, in_len-12);
if(p && (ielen==sizeof(struct ieee80211_ht_addt_info)))
{
- out_len = *pout_len;
+ out_len = *pout_len;
pframe = rtw_set_ie(out_ie+out_len, _HT_ADD_INFO_IE_, ielen, p+2 , pout_len);
}
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_mlme_ext.c b/drivers/net/wireless/rtl8723as/core/rtw_mlme_ext.c
index fbf4b0668014..79961ad7df62 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_mlme_ext.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_mlme_ext.c
@@ -85,7 +85,14 @@ struct action_handler OnAction_tbl[]={
{RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
{RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved},
{RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
+#ifdef CONFIG_IEEE80211W
+ {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
+#else
{RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
+#endif //CONFIG_IEEE80211W
+ //add for CONFIG_IEEE80211W
+ {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
+ {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved},
{RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
{RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
};
@@ -307,7 +314,11 @@ static void init_mlme_ext_priv_value(_adapter* padapter)
ATOMIC_SET(&pmlmeext->event_seq, 0);
pmlmeext->mgnt_seq = 0;//reset to zero when disconnect at client mode
-
+#ifdef CONFIG_IEEE80211W
+ pmlmeext->sa_query_seq = 0;
+ pmlmeext->mgnt_80211w_IPN=0;
+ pmlmeext->mgnt_80211w_IPN_rx=0;
+#endif //CONFIG_IEEE80211W
pmlmeext->cur_channel = padapter->registrypriv.channel;
pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
@@ -754,7 +765,7 @@ void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
}
#else
- _mgt_dispatcher(padapter, ptable, precv_frame);
+ _mgt_dispatcher(padapter, ptable, precv_frame);
#endif
@@ -764,27 +775,32 @@ void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
{
bool response = _TRUE;
-
+
#ifdef CONFIG_IOCTL_CFG80211
- if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == _FALSE
- || padapter->mlmepriv.wps_probe_resp_ie == NULL
- || padapter->mlmepriv.p2p_probe_resp_ie == NULL
- )
+ if( padapter->wdinfo.driver_interface == DRIVER_CFG80211 )
{
- DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n",
- wdev_to_priv(padapter->rtw_wdev)->p2p_enabled,
- padapter->mlmepriv.wps_probe_resp_ie,
- padapter->mlmepriv.p2p_probe_resp_ie);
- response = _FALSE;
+ if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == _FALSE
+ || padapter->mlmepriv.wps_probe_resp_ie == NULL
+ || padapter->mlmepriv.p2p_probe_resp_ie == NULL
+ )
+ {
+ DBG_871X("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n",
+ wdev_to_priv(padapter->rtw_wdev)->p2p_enabled,
+ padapter->mlmepriv.wps_probe_resp_ie,
+ padapter->mlmepriv.p2p_probe_resp_ie);
+ response = _FALSE;
+ }
}
-#else
-
- // do nothing if the device name is empty
- if ( !padapter->wdinfo.device_name_len )
+ else
+#endif //CONFIG_IOCTL_CFG80211
+ if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
{
- response = _FALSE;
+ // do nothing if the device name is empty
+ if ( !padapter->wdinfo.device_name_len )
+ {
+ response = _FALSE;
+ }
}
-#endif
if (response == _TRUE)
issue_probersp_p2p( padapter, da);
@@ -910,8 +926,8 @@ _continue:
_issue_probersp:
- if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
- pmlmepriv->cur_network.join_res == _TRUE)
+ if(((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
+ pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
{
//DBG_871X("+issue_probersp during ap mode\n");
issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
@@ -986,7 +1002,7 @@ unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
}
}
}
-#endif
+#endif //CONFIG_P2P
if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
@@ -994,10 +1010,10 @@ unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
report_survey_event(padapter, precv_frame);
#ifdef CONFIG_CONCURRENT_MODE
report_survey_event(padapter->pbuddy_adapter, precv_frame);
-#endif
+#endif //CONFIG_CONCURRENT_MODE
#ifdef CONFIG_DUALMAC_CONCURRENT
dc_report_survey_event(padapter, precv_frame);
-#endif
+#endif //CONFIG_DUALMAC_CONCURRENT
return _SUCCESS;
}
@@ -1105,7 +1121,7 @@ unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
ret = rtw_check_bcn_info(padapter, pframe, len);
if (!ret) {
DBG_871X_LEVEL(_drv_always_, "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
@@ -2104,56 +2120,34 @@ unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
bss_cap_update_on_sta_join(padapter, pstat);
sta_info_update(padapter, pstat);
- //issue assoc rsp before notify station join event.
+ //.2 issue assoc rsp before notify station join event.
if (frame_type == WIFI_ASSOCREQ)
issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
else
issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
- //.2 - report to upper layer
- DBG_871X("indicate_sta_join_event to upper layer - hostapd\n");
- #ifdef CONFIG_IOCTL_CFG80211
- if (1) {
- #ifdef COMPAT_KERNEL_RELEASE
- rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
- #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
- rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
- #else //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
- _enter_critical_bh(&pstat->lock, &irqL);
- if(pstat->passoc_req)
- {
- rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
- pstat->passoc_req = NULL;
- pstat->assoc_req_len = 0;
- }
-
- pstat->passoc_req = rtw_zmalloc(pkt_len);
- if(pstat->passoc_req)
- {
- _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
- pstat->assoc_req_len = pkt_len;
- }
- _exit_critical_bh(&pstat->lock, &irqL);
- #endif //(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
+#ifdef CONFIG_IOCTL_CFG80211
+ _enter_critical_bh(&pstat->lock, &irqL);
+ if(pstat->passoc_req)
+ {
+ rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
+ pstat->passoc_req = NULL;
+ pstat->assoc_req_len = 0;
}
- else
- #endif //CONFIG_IOCTL_CFG80211
+
+ pstat->passoc_req = rtw_zmalloc(pkt_len);
+ if(pstat->passoc_req)
{
- rtw_indicate_sta_assoc_event(padapter, pstat);
+ _rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
+ pstat->assoc_req_len = pkt_len;
}
+ _exit_critical_bh(&pstat->lock, &irqL);
+#endif //CONFIG_IOCTL_CFG80211
//.3-(1) report sta add event
report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
-/*
- //issue assoc rsp before notify station join event.
- if (frame_type == WIFI_ASSOCREQ)
- issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
- else
- issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
-*/
-
-#endif
+#endif //CONFIG_NATIVEAP_MLME
}
return _SUCCESS;
@@ -2364,10 +2358,32 @@ unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
else
#endif
{
- DBG_871X_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM\n",
- reason, GetAddr3Ptr(pframe));
+ int ignore_received_deauth = 0;
+
+ // Commented by Albert 20130604
+ // 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_871X_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM, ignore = %d\n",
+ reason, GetAddr3Ptr(pframe), ignore_received_deauth);
- receive_disconnect(padapter, GetAddr3Ptr(pframe) ,reason);
+ if ( 0 == ignore_received_deauth )
+ {
+ receive_disconnect(padapter, GetAddr3Ptr(pframe) ,reason);
+ }
}
pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
return _SUCCESS;
@@ -3835,13 +3851,60 @@ void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
// Type:
p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
- // Length:
- *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( pwdinfo->channel_list_attr_len );
+ *(u16*) ( p2pie + p2pielen ) = 6;
p2pielen += 2;
+ // Country String
+ p2pie[ p2pielen++ ] = 'X';
+ p2pie[ p2pielen++ ] = 'X';
+
+ // The third byte should be set to 0x04.
+ // Described in the "Operating Channel Attribute" section.
+ p2pie[ p2pielen++ ] = 0x04;
+
// Value:
- _rtw_memcpy( p2pie + p2pielen, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len );
- p2pielen += pwdinfo->channel_list_attr_len;
+ if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
+ {
+ if ( pwdinfo->peer_operating_ch <= 14 )
+ {
+ // Operating Class
+ p2pie[ p2pielen++ ] = 0x51;
+ }
+ else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
+ {
+ // Operating Class
+ p2pie[ p2pielen++ ] = 0x73;
+ }
+ else
+ {
+ // Operating Class
+ p2pie[ p2pielen++ ] = 0x7c;
+ }
+ p2pie[ p2pielen++ ] = 1;
+ p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
+ }
+ else
+ {
+ if ( pwdinfo->operating_channel <= 14 )
+ {
+ // Operating Class
+ p2pie[ p2pielen++ ] = 0x51;
+ }
+ else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
+ {
+ // Operating Class
+ p2pie[ p2pielen++ ] = 0x73;
+ }
+ else
+ {
+ // Operating Class
+ p2pie[ p2pielen++ ] = 0x7c;
+ }
+
+ // Channel Number
+ p2pie[ p2pielen++ ] = 1;
+ p2pie[ p2pielen++ ] = pwdinfo->operating_channel; // Use the listen channel as the operating channel
+ }
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
{
@@ -4655,11 +4718,6 @@ void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
#ifdef CONFIG_WFD
u32 wfdielen = 0;
#endif //CONFIG_WFD
-#ifdef CONFIG_IOCTL_CFG80211
- struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
- struct ieee80211_channel *ieee_ch = &pcfg80211_wdinfo->remain_on_ch_channel;
- u8 listen_channel = (u8) ieee80211_frequency_to_channel(ieee_ch->center_freq);
-#endif //CONFIG_IOCTL_CFG80211
#ifdef CONFIG_INTEL_WIDI
u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
#endif //CONFIG_INTEL_WIDI
@@ -4725,20 +4783,10 @@ void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
// DS parameter set
-#ifdef CONFIG_IOCTL_CFG80211
- if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && listen_channel !=0 )
- {
- pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&listen_channel, &pattrib->pktlen);
- }
- else
-#endif //CONFIG_IOCTL_CFG80211
- {
- pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
- }
-
+ pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
#ifdef CONFIG_IOCTL_CFG80211
- if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
+ if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
{
if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
{
@@ -4781,7 +4829,8 @@ void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
#ifdef CONFIG_INTEL_WIDI
// Commented by Kurt
// Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext.
- if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
+ if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE
+ || pmlmepriv->num_p2p_sdt != 0 )
{
//Sec dev type
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
@@ -4803,9 +4852,12 @@ void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
*(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
wpsielen += 2;
- // Vendor Extension
- _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
- wpsielen += L2SDTA_SERVICE_VE_LEN;
+ if( _rtw_memcmp(pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN) == _FALSE )
+ {
+ // Vendor Extension
+ _rtw_memcpy( wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
+ wpsielen += L2SDTA_SERVICE_VE_LEN;
+ }
}
#endif //CONFIG_INTEL_WIDI
@@ -4843,7 +4895,12 @@ void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
wpsielen += 2;
// Value:
- _rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
+ if (pwdinfo->external_uuid == 0) {
+ _rtw_memset( wpsie + wpsielen, 0x0, 16 );
+ _rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
+ } else {
+ _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
+ }
wpsielen += 0x10;
// Manufacturer
@@ -4967,7 +5024,7 @@ void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
pattrib->pktlen += wfdielen;
}
#ifdef CONFIG_IOCTL_CFG80211
- else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
+ else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
{
//WFD IE
_rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len);
@@ -5069,7 +5126,7 @@ int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
#ifdef CONFIG_IOCTL_CFG80211
- if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
+ if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
{
if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
{
@@ -5121,7 +5178,12 @@ int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
wpsielen += 2;
// Value:
- _rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
+ if (pwdinfo->external_uuid == 0) {
+ _rtw_memset( wpsie + wpsielen, 0x0, 16 );
+ _rtw_memcpy( wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
+ } else {
+ _rtw_memcpy( wpsie + wpsielen, pwdinfo->uuid, 0x10 );
+ }
wpsielen += 0x10;
// Config Method
@@ -5430,6 +5492,8 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
u8 result = P2P_STATUS_SUCCESS;
u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ u8 *merged_p2pie = NULL;
+ u32 merged_p2p_ielen = 0;
#endif //CONFIG_P2P
frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
@@ -5442,7 +5506,7 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
#ifdef CONFIG_P2P
_cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
#ifdef CONFIG_IOCTL_CFG80211
- if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
+ if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
{
rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
}
@@ -5499,6 +5563,7 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
{
padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
+ _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
}
#endif //CONFIG_INTEL_WIDI
@@ -5530,6 +5595,11 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
{
pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
+ #ifdef P2P_OP_CHECK_SOCIAL_CH
+ pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1;
+ pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6;
+ pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11;
+ #endif //P2P_OP_CHECK_SOCIAL_CH
pwdinfo->p2p_info.scan_op_ch_only = 1;
_set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
}
@@ -5559,6 +5629,11 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
{
pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
+ #ifdef P2P_OP_CHECK_SOCIAL_CH
+ pwdinfo->p2p_info.operation_ch[ 1 ] = 1; //Check whether GO is operating in channel 1;
+ pwdinfo->p2p_info.operation_ch[ 2 ] = 6; //Check whether GO is operating in channel 6;
+ pwdinfo->p2p_info.operation_ch[ 3 ] = 11; //Check whether GO is operating in channel 11;
+ #endif //P2P_OP_CHECK_SOCIAL_CH
pwdinfo->p2p_info.scan_op_ch_only = 1;
_set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
}
@@ -5580,11 +5655,24 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
struct group_id_info group_id;
u8 invitation_flag = 0;
- rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
+
+ merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
+
+ merged_p2pie = rtw_malloc(merged_p2p_ielen);
+ if (merged_p2pie == NULL)
+ {
+ DBG_871X( "[%s] Malloc p2p ie fail\n", __FUNCTION__);
+ goto exit;
+ }
+ _rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
+
+ merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
+
+ rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
if ( attr_contentlen )
{
- rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
+ rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
// Commented by Albert 20120510
// Copy to the pwdinfo->p2p_peer_interface_addr.
// So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command.
@@ -5604,7 +5692,7 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
// Re-invoke the persistent group.
_rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
- rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
+ rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
if ( attr_contentlen )
{
if ( _rtw_memcmp( group_id.go_device_addr, myid( &padapter->eeprompriv ), ETH_ALEN ) )
@@ -5620,18 +5708,24 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
{
u8 operatingch_info[5] = { 0x00 };
- if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
+
+ if ( rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
{
if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) )
{
// The operating channel is acceptable for this device.
pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
+ #ifdef P2P_OP_CHECK_SOCIAL_CH
+ pwdinfo->rx_invitereq_info.operation_ch[1]= 1; //Check whether GO is operating in channel 1;
+ pwdinfo->rx_invitereq_info.operation_ch[2]= 6; //Check whether GO is operating in channel 6;
+ pwdinfo->rx_invitereq_info.operation_ch[3]= 11; //Check whether GO is operating in channel 11;
+ #endif //P2P_OP_CHECK_SOCIAL_CH
pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
_set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
status_code = P2P_STATUS_SUCCESS;
- }
+ }
else
{
// The operating channel isn't supported by this device.
@@ -5674,7 +5768,7 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
// Received the invitation to join a P2P group.
_rtw_memset( &group_id, 0x00, sizeof( struct group_id_info ) );
- rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
+ rtw_get_p2p_attr_content( merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
if ( attr_contentlen )
{
if ( _rtw_memcmp( group_id.go_device_addr, myid( &padapter->eeprompriv ), ETH_ALEN ) )
@@ -5714,11 +5808,13 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
pwdinfo->inviteresp_info.token = frame_body[ 7 ];
issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
+ _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
}
#ifdef CONFIG_INTEL_WIDI
if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
{
padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
+ _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
}
#endif //CONFIG_INTEL_WIDI
@@ -5804,6 +5900,7 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
{
padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
+ _cancel_timer_ex(&(padapter->mlmepriv.listen_timer));
intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
}
#endif //CONFIG_INTEL_WIDI
@@ -5824,7 +5921,14 @@ unsigned int on_action_public_p2p(union recv_frame *precv_frame)
}
}
#endif //CONFIG_P2P
-
+
+exit:
+
+ if(merged_p2pie)
+ {
+ rtw_mfree(merged_p2pie, merged_p2p_ielen);
+ }
+
return _SUCCESS;
}
@@ -5904,6 +6008,45 @@ unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
return _SUCCESS;
}
+#ifdef CONFIG_IEEE80211W
+unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
+{
+ u8 *pframe = precv_frame->u.hdr.rx_data;
+ struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ unsigned short tid;
+ //Baron
+
+ DBG_871X("OnAction_sa_query\n");
+
+ switch (pframe[WLAN_HDR_A3_LEN+1])
+ {
+ case 0: //SA Query req
+ _rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(unsigned short));
+ DBG_871X("OnAction_sa_query request,action=%d, tid=%04x\n", pframe[WLAN_HDR_A3_LEN+1], tid);
+ issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid);
+ break;
+
+ case 1: //SA Query rsp
+ _cancel_timer_ex(&pmlmeext->sa_query_timer);
+ DBG_871X("OnAction_sa_query response,action=%d, tid=%04x, cahcel timer\n", pframe[WLAN_HDR_A3_LEN+1], pframe[WLAN_HDR_A3_LEN+2]);
+ break;
+ default:
+ break;
+ }
+ if(0)
+ {
+ int pp;
+ printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
+ for(pp=0;pp< pattrib->pkt_len; pp++)
+ printk(" %02x ", pframe[pp]);
+ printk("\n");
+ }
+
+ return _SUCCESS;
+}
+#endif //CONFIG_IEEE80211W
+
unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
{
return _SUCCESS;
@@ -5935,7 +6078,7 @@ unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
return _SUCCESS;
#ifdef CONFIG_IOCTL_CFG80211
- if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
+ if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
{
rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
return _SUCCESS;
@@ -6087,7 +6230,7 @@ void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
pattrib->raid = 5;//a/g mode
pattrib->encrypt = _NO_PRIVACY_;
- pattrib->bswenc = _FALSE;
+ pattrib->bswenc = _FALSE;
pattrib->qos_en = _FALSE;
pattrib->ht_en = _FALSE;
@@ -6105,7 +6248,11 @@ void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
{
if(padapter->bSurpriseRemoved == _TRUE ||
padapter->bDriverStopped == _TRUE)
+ {
+ rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
return;
+ }
rtw_hal_mgnt_xmit(padapter, pmgntframe);
}
@@ -6120,7 +6267,11 @@ s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, i
if(padapter->bSurpriseRemoved == _TRUE ||
padapter->bDriverStopped == _TRUE)
+ {
+ rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
return ret;
+ }
rtw_sctx_init(&sctx, timeout_ms);
pxmitbuf->sctx = &sctx;
@@ -6147,10 +6298,14 @@ s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntfram
if (padapter->pbuddy_adapter && !padapter->isprimary)
pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
#endif
-
+
if(padapter->bSurpriseRemoved == _TRUE ||
padapter->bDriverStopped == _TRUE)
+ {
+ rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
return -1;
+ }
_enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
pxmitpriv->ack_tx = _TRUE;
@@ -6288,7 +6443,7 @@ void issue_beacon(_adapter *padapter, int timeout_ms)
remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
#ifdef CONFIG_IOCTL_CFG80211
- if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
+ if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
{
if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
{
@@ -6405,7 +6560,7 @@ void issue_beacon(_adapter *padapter, int timeout_ms)
{
u32 len;
#ifdef CONFIG_IOCTL_CFG80211
- if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
+ if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
{
len = pmlmepriv->p2p_beacon_ie_len;
if(pmlmepriv->p2p_beacon_ie && len>0)
@@ -6434,7 +6589,7 @@ void issue_beacon(_adapter *padapter, int timeout_ms)
{
len = pmlmepriv->wfd_beacon_ie_len;
_rtw_memcpy(pframe, pmlmepriv->wfd_beacon_ie, len);
- }
+ }
}
#endif //CONFIG_IOCTL_CFG80211
pframe += len;
@@ -6725,11 +6880,11 @@ void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probe
}
#ifdef CONFIG_P2P
- if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq)
+ if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) /*&& is_valid_p2p_probereq*/)
{
u32 len;
#ifdef CONFIG_IOCTL_CFG80211
- if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
+ if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
{
//if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
len = pmlmepriv->p2p_go_probe_resp_ie_len;
@@ -7236,17 +7391,18 @@ void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *p
}
#ifdef CONFIG_P2P
-#ifndef CONFIG_IOCTL_CFG80211
- if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE))
+ if( padapter->wdinfo.driver_interface == DRIVER_WEXT )
{
- u32 len;
+ if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE))
+ {
+ u32 len;
- len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
+ len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
- pframe += len;
- pattrib->pktlen += len;
+ pframe += len;
+ pattrib->pktlen += len;
+ }
}
-#endif //CONFIG_IOCTL_CFG80211
#ifdef CONFIG_WFD
if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
#ifdef CONFIG_IOCTL_CFG80211
@@ -7564,7 +7720,7 @@ void issue_assocreq(_adapter *padapter)
#ifdef CONFIG_P2P
#ifdef CONFIG_IOCTL_CFG80211
- if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
+ if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
{
if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
{
@@ -8202,6 +8358,84 @@ void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_of
}
+#ifdef CONFIG_IEEE80211W
+void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid)
+{
+ u8 category = RTW_WLAN_CATEGORY_SA_QUERY;
+ u16 reason_code;
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ u8 *pframe;
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ u16 *fctrl;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct sta_info *psta;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct registry_priv *pregpriv = &padapter->registrypriv;
+
+
+ DBG_871X("%s\n", __FUNCTION__);
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ DBG_871X("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+ update_mgntframe_attrib(padapter, pattrib);
+
+ _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+
+ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+
+ if(raddr)
+ _rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
+ else
+ _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+ _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
+ _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
+ pmlmeext->mgnt_seq++;
+ SetFrameSubType(pframe, WIFI_ACTION);
+
+ pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+
+ pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
+ pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
+
+ switch (action)
+ {
+ case 0: //SA Query req
+ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
+ pmlmeext->sa_query_seq++;
+ //send sa query request to AP, AP should reply sa query response in 1 second
+ set_sa_query_timer(pmlmeext, 1000);
+ break;
+
+ case 1: //SA Query rsp
+ tid = cpu_to_le16(tid);
+ pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
+ break;
+ default:
+ break;
+ }
+
+ pattrib->last_txcmdsz = pattrib->pktlen;
+
+ dump_mgntframe(padapter, pmgntframe);
+}
+#endif //CONFIG_IEEE80211W
+
void issue_action_BA(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status)
{
u8 category = RTW_WLAN_CATEGORY_BACK;
@@ -8776,7 +9010,6 @@ void site_survey(_adapter *padapter)
{
pmlmeinfo->scan_cnt = 0;
survey_channel = pbuddy_mlmeext->cur_channel;
- ScanType = SCAN_ACTIVE;
stay_buddy_ch = 1;
}
else
@@ -8877,19 +9110,24 @@ void site_survey(_adapter *padapter)
u8 cur_bwmode;
u8 cur_ch_offset;
- if(check_fwstate(pmlmepriv, _FW_LINKED))
+ if (rtw_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0)
{
- cur_channel = pmlmeext->cur_channel;
- cur_bwmode = pmlmeext->cur_bwmode;
- cur_ch_offset = pmlmeext->cur_ch_offset;
+ if (0)
+ DBG_871X(FUNC_ADPT_FMT" back to linked union - ch:%u, bw:%u, offset:%u\n",
+ FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
}
- //else if((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
- else if(check_buddy_fwstate(padapter, _FW_LINKED)) // for AP or STA
+ #ifdef CONFIG_IOCTL_CFG80211
+ else if(padapter->pbuddy_adapter
+ && pbuddy_adapter->wdinfo.driver_interface == DRIVER_CFG80211
+ && wdev_to_priv(pbuddy_adapter->rtw_wdev)->p2p_enabled
+ && rtw_p2p_chk_state(&pbuddy_adapter->wdinfo, P2P_STATE_LISTEN)
+ )
{
- cur_channel = pbuddy_mlmeext->cur_channel;
+ cur_channel = pbuddy_adapter->wdinfo.listen_channel;
cur_bwmode = pbuddy_mlmeext->cur_bwmode;
cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
}
+ #endif
else
{
cur_channel = pmlmeext->cur_channel;
@@ -8954,12 +9192,13 @@ void site_survey(_adapter *padapter)
if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
{
#ifdef CONFIG_CONCURRENT_MODE
- #ifndef CONFIG_IOCTL_CFG80211
- if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
+ if( pwdinfo->driver_interface == DRIVER_WEXT )
{
- _set_timer( &pwdinfo->ap_p2p_switch_timer, 500 );
- }
- #endif //CONFIG_IOCTL_CFG80211
+ if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
+ {
+ _set_timer( &pwdinfo->ap_p2p_switch_timer, 500 );
+ }
+ }
rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
#else
rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
@@ -8974,20 +9213,25 @@ void site_survey(_adapter *padapter)
//SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset);
{
+#ifdef CONFIG_CONCURRENT_MODE
+ set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
+#else
#ifdef CONFIG_DUALMAC_CONCURRENT
dc_set_channel_bwmode_survey_done(padapter);
#else
-#ifndef CONFIG_IOCTL_CFG80211
- if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) )
+ if( pwdinfo->driver_interface == DRIVER_WEXT )
{
- set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
+ if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) )
+ {
+ set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
+ }
+ else
+ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
}
- else
-#endif //CONFIG_IOCTL_CFG80211
-#ifdef CONFIG_CONCURRENT_MODE
- set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
-#else
+ else if( pwdinfo->driver_interface == DRIVER_CFG80211 )
+ {
set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
+ }
#endif //CONFIG_DUALMAC_CONCURRENT
#endif //CONFIG_CONCURRENT_MODE
}
@@ -9030,7 +9274,19 @@ void site_survey(_adapter *padapter)
report_surveydone_event(padapter);
+#if defined(CONFIG_BT_COEXIST) && defined(CONFIG_RTL8723A)
+ if ((BT_1Ant(padapter) == _TRUE) && (BT_GetBtState(padapter) > BT_INFO_STATE_NO_CONNECTION))
+ {
+ pmlmeext->chan_scan_time = SURVEY_TO * 2;
+ }
+ else
+ {
+ pmlmeext->chan_scan_time = SURVEY_TO;
+ }
+#else
pmlmeext->chan_scan_time = SURVEY_TO;
+#endif
+
pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
issue_action_BSSCoexistPacket(padapter);
@@ -9089,12 +9345,12 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI
ie_offset = _BEACON_IE_OFFSET_;
} else {
// FIXME : more type
- if (subtype == WIFI_PROBEREQ) {
- ie_offset = _PROBEREQ_IE_OFFSET_;
- bssid->Reserved[0] = 2;
- } else if (subtype == WIFI_PROBERSP) {
+ if (subtype == WIFI_PROBERSP) {
ie_offset = _PROBERSP_IE_OFFSET_;
bssid->Reserved[0] = 3;
+ } else if (subtype == WIFI_PROBEREQ) {
+ ie_offset = _PROBEREQ_IE_OFFSET_;
+ bssid->Reserved[0] = 2;
} else {
bssid->Reserved[0] = 0;
ie_offset = _FIXED_IE_LENGTH_;
@@ -9109,7 +9365,7 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI
//get the signal strength
//bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; // 0-100 index.
- bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data
+ bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; // in dBM.raw data
bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;//in percentage
bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;//in percentage
#ifdef CONFIG_ANTENNA_DIVERSITY
@@ -9181,6 +9437,31 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI
if (bssid->IELength < 12)
return _FAIL;
+#ifdef CONFIG_P2P
+ if (subtype == WIFI_PROBEREQ) {
+ u8 *p2p_ie;
+ u32 p2p_ielen;
+ // Set Listion Channel
+ if ((p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen))) {
+ u32 attr_contentlen = 0;
+ u8 listen_ch[5] = { 0x00 };
+
+ rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen);
+ bssid->Configuration.DSConfig = listen_ch[4];
+ }
+ else { // use current channel
+ bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
+ DBG_871X("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
+ }
+
+ // FIXME
+ bssid->InfrastructureMode = Ndis802_11Infrastructure;
+ _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
+ bssid->Privacy = 1;
+ return _SUCCESS;
+ }
+#endif //CONFIG_P2P
+
// Checking for DSConfig
p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
@@ -9206,15 +9487,6 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI
}
}
- if (subtype==WIFI_PROBEREQ)
- {
- // FIXME
- bssid->InfrastructureMode = Ndis802_11Infrastructure;
- _rtw_memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
- bssid->Privacy = 1;
- return _SUCCESS;
- }
-
_rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
@@ -9270,7 +9542,7 @@ u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSI
}
#endif // CONFIG_INTEL_WIDI
- #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) & 1
+ #if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
DBG_871X("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
, bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
@@ -9346,6 +9618,8 @@ void start_create_ibss(_adapter* padapter)
DBG_871X("start_create_ibss, invalid cap:%x\n", caps);
return;
}
+ //update bc/mc sta_info
+ update_bmc_sta(padapter);
}
@@ -9358,9 +9632,6 @@ void start_clnt_join(_adapter* padapter)
WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
int beacon_timeout;
- pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
- pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
-
//update wireless mode
update_wireless_mode(padapter);
@@ -9369,23 +9640,6 @@ void start_clnt_join(_adapter* padapter)
update_capinfo(padapter, caps);
if (caps&cap_ESS)
{
-
-#ifdef CONFIG_DUALMAC_CONCURRENT
- if(dc_handle_join_request(padapter) == _FAIL)
- {
- DBG_871X("dc_handle_join_request fail !!!\n");
- return;
- }
- //switch channel
- set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-#elif defined (CONFIG_CONCURRENT_MODE)
- if(concurrent_chk_start_clnt_join(padapter) == _FAIL)
- return;
-#else //NON CONCURRENT_MODE
- //switch channel
- set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-#endif
-
Set_MSR(padapter, WIFI_FW_STATION_STATE);
val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
@@ -9399,8 +9653,48 @@ void start_clnt_join(_adapter* padapter)
#endif
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
- //switch channel
- //set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
+ #ifdef CONFIG_DEAUTH_BEFORE_CONNECT
+ // Because of AP's not receiving deauth before
+ // AP may: 1)not response auth or 2)deauth us after link is complete
+ // issue deauth before issuing auth to deal with the situation
+
+ // Commented by Albert 2012/07/21
+ // For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
+ {
+ #ifdef CONFIG_P2P
+ _queue *queue = &(padapter->mlmepriv.scanned_queue);
+ _list *head = get_list_head(queue);
+ _list *pos = get_next(head);
+ struct wlan_network *scanned = NULL;
+ u8 ie_offset = 0;
+ _irqL irqL;
+ bool has_p2p_ie = _FALSE;
+
+ _enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
+
+ for (pos = get_next(head);!rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
+
+ scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
+ if(scanned==NULL)
+ rtw_warn_on(1);
+
+ if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
+ && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
+ ) {
+ ie_offset = (scanned->network.Reserved[0] == 2? 0:12);
+ if (rtw_get_p2p_ie(scanned->network.IEs+ie_offset, scanned->network.IELength-ie_offset, NULL, NULL))
+ has_p2p_ie = _TRUE;
+ break;
+ }
+ }
+
+ _exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
+
+ if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
+ #endif /* CONFIG_P2P */
+ issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100);
+ }
+ #endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
//here wait for receiving the beacon to start auth
//and enable a timer
@@ -9410,6 +9704,20 @@ void start_clnt_join(_adapter* padapter)
(REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
+
+ {//only for STA mode
+ u16 media_status;
+ u8 mac_id = 0;
+
+ #ifdef CONFIG_CONCURRENT_MODE
+ if(PRIMARY_ADAPTER == padapter->adapter_type)
+ mac_id=0;
+ else
+ mac_id=2;
+ #endif
+ media_status = (mac_id<<8)|1; // MACID|OPMODE:1 connect
+ rtw_hal_set_hwreg(padapter,HW_VAR_H2C_MEDIA_STATUS_RPT,(u8 *)&media_status);
+ }
}
else if (caps&cap_IBSS) //adhoc client
{
@@ -9426,9 +9734,6 @@ void start_clnt_join(_adapter* padapter)
val8 = 0xcf;
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
- //switch channel
- set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
beacon_timing_control(padapter);
pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
@@ -9460,15 +9765,6 @@ void start_clnt_auth(_adapter* padapter)
pmlmeext->retry = 0;
- // Because of AP's not receiving deauth before
- // AP may: 1)not response auth or 2)deauth us after link is complete
- // issue deauth before issuing auth to deal with the situation
-#ifndef CONFIG_PLATFORM_RTK_DMP
- // Commented by Albert 2012/07/21
- // For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it.
- issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
-#endif
-
DBG_871X_LEVEL(_drv_always_, "start auth\n");
issue_auth(padapter, NULL, 0);
@@ -10159,6 +10455,8 @@ void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
u8 join_type;
u16 media_status;
+ psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
+
if(join_res < 0)
{
join_type = 1;
@@ -10168,6 +10466,11 @@ void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
//restore to initial setting.
update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
+ if (psta){//only for STA mode
+ media_status = (psta->mac_id<<8)|0; // MACID|OPMODE:1 connect
+ rtw_hal_set_hwreg(padapter,HW_VAR_H2C_MEDIA_STATUS_RPT,(u8 *)&media_status);
+ }
+
goto exit_mlmeext_joinbss_event_callback;
}
@@ -10181,6 +10484,8 @@ void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
update_bmc_sta_support_rate(padapter, psta_bmc->mac_id);
Update_RA_Entry(padapter, psta_bmc);
}
+ //update bc/mc sta_info
+ update_bmc_sta(padapter);
}
@@ -10210,7 +10515,7 @@ void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
#endif
- psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
+
if (psta) //only for infra. mode
{
pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
@@ -10222,11 +10527,7 @@ void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
//set per sta rate after updating HT cap.
set_sta_rate(padapter, psta);
- #if (RATE_ADAPTIVE_SUPPORT==1) //for 88E RA
- rtw_hal_set_hwreg(padapter,HW_VAR_TX_RPT_MAX_MACID, (u8*)&psta->mac_id);
- #endif
- media_status = (psta->mac_id<<8)|1; // MACID|OPMODE: 1 means connect
- rtw_hal_set_hwreg(padapter,HW_VAR_H2C_MEDIA_STATUS_RPT,(u8 *)&media_status);
+ rtw_sta_media_status_rpt(padapter, psta, 1);
}
join_type = 2;
@@ -10403,8 +10704,8 @@ void _linked_rx_signal_strehgth_display(_adapter *padapter)
#endif
- rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
- DBG_871X("UndecoratedSmoothedPWDB:%d\n",UndecoratedSmoothedPWDB);
+ //rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
+ //DBG_871X("UndecoratedSmoothedPWDB:%d\n",UndecoratedSmoothedPWDB);
}
@@ -10483,10 +10784,13 @@ void linked_status_chk(_adapter *padapter)
rx_chk_limit = 8;
#endif
- #ifdef CONFIG_INTEL_WIDI
- if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE)
- rx_chk_limit = 1;
- #endif
+ // Marked by Kurt 20130715
+ // For WiDi 3.5 and latered on, they don't ask WiDi sink to do roaming, so we could not check rx limit that strictly.
+ // todo: To check why we under miracast session, rx_chk would be _FALSE
+ //#ifdef CONFIG_INTEL_WIDI
+ //if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE)
+ // rx_chk_limit = 1;
+ //#endif
if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
{
@@ -10861,6 +11165,27 @@ void addba_timer_hdl(struct sta_info *psta)
#endif //CONFIG_80211N_HT
}
+#ifdef CONFIG_IEEE80211W
+void sa_query_timer_hdl(_adapter *padapter)
+{
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_priv * pmlmepriv = &padapter->mlmepriv;
+ _irqL irqL;
+ //disconnect
+ _enter_critical_bh(&pmlmepriv->lock, &irqL);
+
+ if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
+ {
+ rtw_disassoc_cmd(padapter, 0, _TRUE);
+ rtw_indicate_disconnect(padapter);
+ rtw_free_assoc_resources(padapter, 1);
+ }
+
+ _exit_critical_bh(&pmlmepriv->lock, &irqL);
+ DBG_871X("SA query timeout disconnect\n");
+}
+#endif //CONFIG_IEEE80211W
+
u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
{
return H2C_SUCCESS;
@@ -11037,6 +11362,9 @@ u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
_rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
+ pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
+ pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
+
//Check AP vendor to move rtw_joinbss_cmd()
//pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength);
@@ -11135,6 +11463,20 @@ u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
//initialgain = 0x1E;
//rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
+ /* check channel, bandwidth, offset and switch */
+#ifdef CONFIG_DUALMAC_CONCURRENT
+ if(dc_handle_join_request(padapter) == _FAIL) {
+ DBG_871X("dc_handle_join_request fail !!!\n");
+ return H2C_SUCCESS;
+ }
+ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
+#else //NON CONFIG_DUALMAC_CONCURRENT
+ if(rtw_chk_start_clnt_join(padapter) == _FAIL) {
+ report_join_res(padapter, (-4));
+ return H2C_SUCCESS;
+ }
+#endif
+
rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
join_type = 0;
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
@@ -11290,8 +11632,10 @@ u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE)
{
+#ifdef CONFIG_CONCURRENT_MODE
//for first time sitesurvey_cmd
rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
+#endif //CONFIG_CONCURRENT_MODE
pmlmeext->sitesurvey_res.state = SCAN_START;
pmlmeext->sitesurvey_res.bss_cnt = 0;
@@ -11379,23 +11723,17 @@ u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
//config the initial gain under scaning, need to write the BB registers
+#ifdef CONFIG_P2P
#ifdef CONFIG_IOCTL_CFG80211
- if((wdev_to_priv(padapter->rtw_wdev))->p2p_enabled == _TRUE)
- {
+ if((wdev_to_priv(padapter->rtw_wdev))->p2p_enabled == _TRUE && pwdinfo->driver_interface == DRIVER_CFG80211 )
initialgain = 0x30;
- }
- else
- initialgain = 0x1E;
-#else // go through the WEXT interface //CONFIG_IOCTL_CFG80211
-#ifdef CONFIG_P2P
- if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) )
- initialgain = 0x1E;
else
+#endif //CONFIG_IOCTL_CFG80211
+ if ( !rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) )
initialgain = 0x28;
-#else // CONFIG_P2P
- initialgain = 0x1E;
-#endif // CONFIG_P2P
-#endif // CONFIG_IOCTL_CFG80211
+ else
+#endif //CONFIG_P2P
+ initialgain = 0x1e;
rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
@@ -12461,108 +12799,6 @@ sint check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
}
-int concurrent_chk_start_clnt_join(_adapter *padapter)
-{
- int ret = _FAIL;
- PADAPTER pbuddy_adapter;
- struct mlme_ext_priv *pbuddy_mlmeext;
- struct mlme_ext_info *pbuddy_pmlmeinfo;
- struct mlme_priv *pbuddy_mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- unsigned char cur_ch = pmlmeext->cur_channel;
- unsigned char cur_bw = pmlmeext->cur_bwmode;
- unsigned char cur_ch_offset = pmlmeext->cur_ch_offset;
-
- if(!rtw_buddy_adapter_up(padapter))
- {
- goto start_join_set_ch_bw;
- }
-
- pbuddy_adapter = padapter->pbuddy_adapter;
- pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
- pbuddy_pmlmeinfo = &(pbuddy_mlmeext->mlmext_info);
- pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
-
- if((pbuddy_pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)//for AP MODE
- {
- bool inform_ch_switch = _FALSE;
- if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
- {
- inform_ch_switch = _TRUE;
- }
- else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
- (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
- (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
- {
- inform_ch_switch = _TRUE;
- }
- else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20) &&
- (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40))
- {
- inform_ch_switch = _FALSE;
- cur_ch = pmlmeext->cur_channel;
- cur_bw = pbuddy_mlmeext->cur_bwmode;
- cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
- }
-
-
- if (inform_ch_switch) {
- #ifdef CONFIG_SPCT_CH_SWITCH
- if (1) {
- rtw_ap_inform_ch_switch(pbuddy_adapter, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
- } else
- #endif
- {
- //issue deauth to all stas if if2 is at ap mode
- rtw_sta_flush(pbuddy_adapter);
- }
- rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
- }
- }
- else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE &&
- check_fwstate(pbuddy_mlmepriv, WIFI_STATION_STATE) == _TRUE) //for Client Mode/p2p client
- {
-#if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
- struct wifidirect_info *pbuddy_wdinfo = &(pbuddy_adapter->wdinfo);
- if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
- {
- goto start_join_set_ch_bw;//wlan0-sta mode has higher priority than p2p0-p2p client
- }
-#endif //CONFIG_P2P && CONFIG_IOCTL_CFG80211
-
- if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
- {
- DBG_871X("start_clnt_join(ch=%d), but channel mismatch with buddy(ch=%d) interface\n",
- pmlmeext->cur_channel, pbuddy_mlmeext->cur_channel);
-
- report_join_res(padapter, (-4));
-
- return ret;
- }
-
- if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
- (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
- (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
- {
- DBG_871X("start_clnt_join(bwmode=%d, ch_offset=%d), but bwmode & ch_offset mismatch with buddy(bwmode=%d, ch_offset=%d) interface\n",
- pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
-
- report_join_res(padapter, (-4));
-
- return ret;
- }
-
- }
-
-
-start_join_set_ch_bw:
-
- set_channel_bwmode(padapter, cur_ch, cur_ch_offset, cur_bw);
-
- return _SUCCESS;
-
-}
-
void concurrent_chk_joinbss_done(_adapter *padapter, int join_res)
{
struct mlme_ext_priv *pmlmeext;
@@ -12573,15 +12809,16 @@ void concurrent_chk_joinbss_done(_adapter *padapter, int join_res)
struct mlme_ext_info *pbuddy_mlmeinfo;
WLAN_BSSID_EX *pbuddy_network_mlmeext;
+ pmlmeext = &padapter->mlmeextpriv;
+ pmlmeinfo = &(pmlmeext->mlmext_info);
+
+
if(!rtw_buddy_adapter_up(padapter))
{
set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
return;
}
- pmlmeext = &padapter->mlmeextpriv;
- pmlmeinfo = &(pmlmeext->mlmext_info);
-
pbuddy_adapter = padapter->pbuddy_adapter;
pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
@@ -12772,6 +13009,181 @@ void concurrent_chk_joinbss_done(_adapter *padapter, int join_res)
}
#endif //CONFIG_CONCURRENT_MODE
+int rtw_chk_start_clnt_join(_adapter *padapter)
+{
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ unsigned char cur_ch = pmlmeext->cur_channel;
+ unsigned char cur_bw = pmlmeext->cur_bwmode;
+ unsigned char cur_ch_offset = pmlmeext->cur_ch_offset;
+ bool chbw_allow = _TRUE;
+ bool connect_allow = _TRUE;
+
+#ifdef CONFIG_CONCURRENT_MODE
+ PADAPTER pbuddy_adapter;
+ struct mlme_ext_priv *pbuddy_mlmeext;
+ struct mlme_ext_info *pbuddy_pmlmeinfo;
+ struct mlme_priv *pbuddy_mlmepriv;
+
+ if (!rtw_buddy_adapter_up(padapter)) {
+ goto start_join_set_ch_bw;
+ }
+
+ pbuddy_adapter = padapter->pbuddy_adapter;
+ pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
+ pbuddy_pmlmeinfo = &(pbuddy_mlmeext->mlmext_info);
+ pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
+
+ if((pbuddy_pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)//for AP MODE
+ {
+ DBG_871X("start_clnt_join: "ADPT_FMT"(ch=%d, bw=%d, ch_offset=%d)"
+ ", "ADPT_FMT" AP mode(ch=%d, bw=%d, ch_offset=%d)\n",
+ ADPT_ARG(padapter), pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset,
+ ADPT_ARG(pbuddy_adapter), pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
+
+ if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
+ {
+ chbw_allow = _FALSE;
+ }
+ else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
+ (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
+ (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
+ {
+ chbw_allow = _FALSE;
+ }
+ else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20) &&
+ (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40))
+ {
+ cur_ch = pmlmeext->cur_channel;
+ cur_bw = pbuddy_mlmeext->cur_bwmode;
+ cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
+ }
+
+ DBG_871X("start_clnt_join: connect_allow:%d, chbw_allow:%d\n", connect_allow, chbw_allow);
+ if (chbw_allow == _FALSE) {
+ #ifdef CONFIG_SPCT_CH_SWITCH
+ if (1) {
+ rtw_ap_inform_ch_switch(pbuddy_adapter, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
+ } else
+ #endif
+ {
+ //issue deauth to all stas if if2 is at ap mode
+ rtw_sta_flush(pbuddy_adapter);
+ }
+ rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
+ }
+ }
+ else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE &&
+ check_fwstate(pbuddy_mlmepriv, WIFI_STATION_STATE) == _TRUE) //for Client Mode/p2p client
+ {
+ DBG_871X("start_clnt_join: "ADPT_FMT"(ch=%d, bw=%d, ch_offset=%d)"
+ ", "ADPT_FMT" STA mode(ch=%d, bw=%d, ch_offset=%d)\n",
+ ADPT_ARG(padapter), pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset,
+ ADPT_ARG(pbuddy_adapter), pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
+
+ if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
+ {
+ chbw_allow = _FALSE;
+ }
+ else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20) &&
+ (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40))
+ {
+ cur_bw = HT_CHANNEL_WIDTH_40;
+ cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
+ }
+ else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
+ (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
+ (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
+ {
+ chbw_allow = _FALSE;
+ }
+
+ connect_allow = chbw_allow;
+
+ #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
+ /* wlan0-sta mode has higher priority than p2p0-p2p client */
+ if (!rtw_p2p_chk_state(&(pbuddy_adapter->wdinfo), P2P_STATE_NONE)
+ && pbuddy_adapter->wdinfo.driver_interface == DRIVER_CFG80211)
+ {
+ connect_allow = _TRUE;
+ }
+ #endif /* CONFIG_P2P && CONFIG_IOCTL_CFG80211 */
+
+ DBG_871X("start_clnt_join: connect_allow:%d, chbw_allow:%d\n", connect_allow, chbw_allow);
+ if (connect_allow == _TRUE && chbw_allow == _FALSE) {
+ /* disconnect buddy's connection */
+ rtw_disassoc_cmd(pbuddy_adapter, 500, _FALSE);
+ rtw_indicate_disconnect(pbuddy_adapter);
+ rtw_free_assoc_resources(pbuddy_adapter, 1);
+ }
+ }
+
+start_join_set_ch_bw:
+#endif /* CONFIG_CONCURRENT_MODE */
+
+ if (connect_allow == _TRUE) {
+ DBG_871X("start_join_set_ch_bw: ch=%d, bwmode=%d, ch_offset=%d\n", cur_ch, cur_bw, cur_ch_offset);
+ set_channel_bwmode(padapter, cur_ch, cur_ch_offset, cur_bw);
+ }
+
+ return connect_allow == _TRUE ? _SUCCESS : _FAIL;
+}
+
+/* Find union about ch, bw, ch_offset of all linked interfaces */
+int rtw_get_ch_setting_union(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
+{
+ struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
+ _adapter *iface;
+ struct mlme_ext_priv *mlmeext;
+ int i;
+ u8 ch_ret = 0;
+ u8 bw_ret = HT_CHANNEL_WIDTH_20;
+ u8 offset_ret = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+ int num = 0;
+
+ if (ch) *ch = 0;
+ if (bw) *bw = HT_CHANNEL_WIDTH_20;
+ if (offset) *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+
+ for (i = 0; i<dvobj->iface_nums; i++) {
+ iface = dvobj->padapters[i];
+ mlmeext = &iface->mlmeextpriv;
+
+ if (!check_fwstate(&iface->mlmepriv, _FW_LINKED))
+ continue;
+
+ if (num == 0) {
+ ch_ret = mlmeext->cur_channel;
+ bw_ret = mlmeext->cur_bwmode;
+ offset_ret = mlmeext->cur_ch_offset;
+ num++;
+ continue;
+ }
+
+ if (ch_ret != mlmeext->cur_channel) {
+ num = 0;
+ break;
+ }
+
+ if (bw_ret < mlmeext->cur_bwmode) {
+ bw_ret = mlmeext->cur_bwmode;
+ offset_ret = mlmeext->cur_ch_offset;
+ } else if (bw_ret == mlmeext->cur_bwmode && offset_ret != mlmeext->cur_ch_offset) {
+ num = 0;
+ break;
+ }
+
+ num++;
+ }
+
+ if (num) {
+ if (ch) *ch = ch_ret;
+ if (bw) *bw = bw_ret;
+ if (offset) *offset = offset_ret;
+ }
+
+ return num;
+}
+
u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
{
struct set_ch_parm *set_ch_parm;
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_mp.c b/drivers/net/wireless/rtl8723as/core/rtw_mp.c
index a63604fcc61e..75f0da1ab224 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_mp.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_mp.c
@@ -570,7 +570,7 @@ static void disable_dm(PADAPTER padapter)
#endif
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct dm_priv *pdmpriv = &pHalData->dmpriv;
-
+ PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
//3 1. disable firmware dynamic mechanism
// disable Power Training, Rate Adaptive
@@ -590,7 +590,7 @@ static void disable_dm(PADAPTER padapter)
// enable APK, LCK and IQK but disable power tracking
#ifndef CONFIG_RTL8188E
- pdmpriv->TxPowerTrackControl = _FALSE;
+ pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _FALSE;
#endif
Switch_DM_Func(padapter, DYNAMIC_RF_CALIBRATION, _TRUE);
}
@@ -600,7 +600,7 @@ void MPT_PwrCtlDM(PADAPTER padapter, u32 bstart)
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
struct dm_priv *pdmpriv = &pHalData->dmpriv;
-
+ PDM_ODM_T pDM_Odm = &(pHalData->odmpriv);
//Switch_DM_Func(padapter, DYNAMIC_RF_CALIBRATION, bstart);
if (bstart==1){
DBG_871X("in MPT_PwrCtlDM start \n");
@@ -608,10 +608,16 @@ void MPT_PwrCtlDM(PADAPTER padapter, u32 bstart)
pdmpriv->InitODMFlag |= ODM_RF_TX_PWR_TRACK ;
pdmpriv->InitODMFlag |= ODM_RF_CALIBRATION ;
pdmpriv->TxPowerTrackControl = _TRUE;
+#ifndef CONFIG_RTL8188E
+ pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _TRUE;
+#endif
}else{
DBG_871X("in MPT_PwrCtlDM stop \n");
disable_dm(padapter);
pdmpriv->TxPowerTrackControl = _FALSE;
+ #ifndef CONFIG_RTL8188E
+ pDM_Odm->RFCalibrateInfo.TxPowerTrackControl = _FALSE;
+ #endif
}
@@ -638,7 +644,6 @@ s32 mp_start_test(PADAPTER padapter)
//3 disable dynamic mechanism
disable_dm(padapter);
-
//3 0. update mp_priv
if (padapter->registrypriv.rf_config == RF_819X_MAX_TYPE) {
@@ -1316,16 +1321,17 @@ void SetPacketRx(PADAPTER pAdapter, u8 bStartRx)
if(bStartRx)
{
- #ifdef CONFIG_RTL8723A
- rtl8723a_InitAntenna_Selection(pAdapter);
- #endif //CONFIG_RTL8723A
- // Accept CRC error and destination address
+ // Accept CRC error and destination address
#if 1
//ndef CONFIG_RTL8723A
- pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | ADF | AMF | HTC_LOC_CTRL | APP_MIC | APP_PHYSTS;
-
- pHalData->ReceiveConfig |= ACRC32;
+ //pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | ADF | AMF | HTC_LOC_CTRL | APP_MIC | APP_PHYSTS;
+ //pHalData->ReceiveConfig |= ACRC32;
+
+ pHalData->ReceiveConfig = AAP | APM | AM | AB | APP_ICV | AMF | ADF | APP_FCS | HTC_LOC_CTRL | APP_MIC | APP_PHYSTS;
+
+ pHalData->ReceiveConfig |= (RCR_ACRC32|RCR_AAP);
+
rtw_write32(pAdapter, REG_RCR, pHalData->ReceiveConfig);
// Accept all data frames
@@ -1488,8 +1494,13 @@ void _rtw_mp_xmit_priv (struct xmit_priv *pxmitpriv)
}
else
{
- max_xmit_extbuf_size = 6000;
- num_xmit_extbuf = 8;
+ #ifdef CONFIG_RTL8723A_SDIO
+ max_xmit_extbuf_size = 20000;
+ num_xmit_extbuf = 1;
+ #else
+ max_xmit_extbuf_size = 6000;
+ num_xmit_extbuf = 8;
+ #endif
}
pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
@@ -1506,8 +1517,13 @@ void _rtw_mp_xmit_priv (struct xmit_priv *pxmitpriv)
if(padapter->registrypriv.mp_mode ==0)
{
- max_xmit_extbuf_size = 6000;
- num_xmit_extbuf = 8;
+ #ifdef CONFIG_RTL8723A_SDIO
+ max_xmit_extbuf_size = 20000;
+ num_xmit_extbuf = 1;
+ #else
+ max_xmit_extbuf_size = 6000;
+ num_xmit_extbuf = 8;
+ #endif
}
else
{
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_mp_ioctl.c b/drivers/net/wireless/rtl8723as/core/rtw_mp_ioctl.c
index 4771bc6a050a..95570d1e75e8 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_mp_ioctl.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_mp_ioctl.c
@@ -1677,12 +1677,12 @@ _func_enter_;
return NDIS_STATUS_INVALID_LENGTH;
*poid_par_priv->bytes_rw = 8;
- _rtw_memcpy(poid_par_priv->information_buf, &(Adapter->pwrctrlpriv.pwr_mode), 8);
+ _rtw_memcpy(poid_par_priv->information_buf, &(adapter_to_pwrctl(Adapter)->pwr_mode), 8);
*poid_par_priv->bytes_rw = poid_par_priv->information_buf_len;
RT_TRACE(_module_mp_, _drv_notice_,
("-oid_rt_pro_qry_pwrstate_hdl: pwr_mode=%d smart_ps=%d\n",
- Adapter->pwrctrlpriv.pwr_mode, Adapter->pwrctrlpriv.smart_ps));
+ adapter_to_pwrctl(Adapter)->pwr_mode, adapter_to_pwrctl(Adapter)->smart_ps));
_func_exit_;
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_odm.c b/drivers/net/wireless/rtl8723as/core/rtw_odm.c
new file mode 100755
index 000000000000..b7176266e149
--- /dev/null
+++ b/drivers/net/wireless/rtl8723as/core/rtw_odm.c
@@ -0,0 +1,217 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2013 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ *
+ ******************************************************************************/
+
+#include <rtw_odm.h>
+#ifdef CONFIG_RTL8192C
+#include <rtl8192c_hal.h>
+#endif
+#ifdef CONFIG_RTL8192D
+#include <rtl8192d_hal.h>
+#endif
+#ifdef CONFIG_RTL8723A
+#include <rtl8723a_hal.h>
+#endif
+#ifdef CONFIG_RTL8188E
+#include <rtl8188e_hal.h>
+#endif
+
+const char *odm_comp_str[] = {
+ "ODM_COMP_DIG",
+ "ODM_COMP_RA_MASK",
+ "ODM_COMP_DYNAMIC_TXPWR",
+ "ODM_COMP_FA_CNT",
+ "ODM_COMP_RSSI_MONITOR",
+ "ODM_COMP_CCK_PD",
+ "ODM_COMP_ANT_DIV",
+ "ODM_COMP_PWR_SAVE",
+ "ODM_COMP_PWR_TRAIN",
+ "ODM_COMP_RATE_ADAPTIVE",
+ "ODM_COMP_PATH_DIV",
+ "ODM_COMP_PSD",
+ "ODM_COMP_DYNAMIC_PRICCA",
+ "ODM_COMP_RXHP",
+ NULL,
+ NULL,
+ "ODM_COMP_EDCA_TURBO",
+ "ODM_COMP_EARLY_MODE",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "ODM_COMP_TX_PWR_TRACK",
+ "ODM_COMP_RX_GAIN_TRACK",
+ "ODM_COMP_CALIBRATION",
+ NULL,
+ NULL,
+ NULL,
+ "ODM_COMP_COMMON",
+ "ODM_COMP_INIT",
+};
+
+#define RTW_ODM_COMP_MAX 32
+
+const char *odm_ability_str[] = {
+ "ODM_BB_DIG",
+ "ODM_BB_RA_MASK",
+ "ODM_BB_DYNAMIC_TXPWR",
+ "ODM_BB_FA_CNT",
+ "ODM_BB_RSSI_MONITOR",
+ "ODM_BB_CCK_PD ",
+ "ODM_BB_ANT_DIV",
+ "ODM_BB_PWR_SAVE",
+ "ODM_BB_PWR_TRAIN",
+ "ODM_BB_RATE_ADAPTIVE",
+ "ODM_BB_PATH_DIV",
+ "ODM_BB_PSD",
+ "ODM_BB_RXHP",
+ "ODM_BB_ADAPTIVITY",
+ "ODM_BB_DYNAMIC_ATC",
+ NULL,
+ "ODM_MAC_EDCA_TURBO",
+ "ODM_MAC_EARLY_MODE",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ "ODM_RF_TX_PWR_TRACK",
+ "ODM_RF_RX_GAIN_TRACK",
+ "ODM_RF_CALIBRATION",
+};
+
+#define RTW_ODM_ABILITY_MAX 27
+
+const char *odm_dbg_level_str[] = {
+ NULL,
+ "ODM_DBG_OFF",
+ "ODM_DBG_SERIOUS",
+ "ODM_DBG_WARNING",
+ "ODM_DBG_LOUD",
+ "ODM_DBG_TRACE ",
+};
+
+#define RTW_ODM_DBG_LEVEL_NUM 6
+
+int _rtw_odm_dbg_comp_msg(_adapter *adapter, char *buf, int len)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+ DM_ODM_T *odm = &pHalData->odmpriv;
+ int cnt = 0;
+ u64 dbg_comp;
+ int i;
+
+ rtw_hal_get_def_var(adapter, HW_DEF_ODM_DBG_FLAG, &dbg_comp);
+ cnt += snprintf(buf+cnt, len-cnt, "odm.DebugComponents = 0x%016llx \n", dbg_comp);
+ for (i=0;i<RTW_ODM_COMP_MAX;i++) {
+ if (odm_comp_str[i])
+ cnt += snprintf(buf+cnt, len-cnt, "%cBIT%-2d %s\n",
+ (BIT0 << i) & dbg_comp ? '+' : ' ', i, odm_comp_str[i]);
+ }
+
+ return cnt;
+}
+
+void rtw_odm_dbg_comp_msg(_adapter *adapter)
+{
+ char buf[768] = {0};
+
+ _rtw_odm_dbg_comp_msg(adapter, buf, 768);
+ DBG_871X_LEVEL(_drv_always_, "\n%s", buf);
+}
+
+inline void rtw_odm_dbg_comp_set(_adapter *adapter, u64 comps)
+{
+ rtw_hal_set_def_var(adapter, HW_DEF_ODM_DBG_FLAG, &comps);
+}
+
+int _rtw_odm_dbg_level_msg(_adapter *adapter, char *buf, int len)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+ DM_ODM_T *odm = &pHalData->odmpriv;
+ int cnt = 0;
+ u32 dbg_level;
+ int i;
+
+ rtw_hal_get_def_var(adapter, HW_DEF_ODM_DBG_LEVEL, &dbg_level);
+ cnt += snprintf(buf+cnt, len-cnt, "odm.DebugDebugLevel = %u\n", dbg_level);
+ for (i=0;i<RTW_ODM_DBG_LEVEL_NUM;i++) {
+ if (odm_dbg_level_str[i])
+ cnt += snprintf(buf+cnt, len-cnt, "%u %s\n", i, odm_dbg_level_str[i]);
+ }
+
+ return cnt;
+}
+
+void rtw_odm_dbg_level_msg(_adapter *adapter)
+{
+ char buf[100] = {0};
+
+ _rtw_odm_dbg_comp_msg(adapter, buf, 100);
+ DBG_871X_LEVEL(_drv_always_, "\n%s", buf);
+}
+
+inline void rtw_odm_dbg_level_set(_adapter *adapter, u32 level)
+{
+ rtw_hal_set_def_var(adapter, HW_DEF_ODM_DBG_LEVEL, &level);
+}
+
+int _rtw_odm_adaptivity_parm_msg(_adapter *adapter, char *buf, int len)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+ DM_ODM_T *odm = &pHalData->odmpriv;
+
+ return snprintf(buf, len,
+ "%10s %16s %8s %10s %11s %14s\n"
+ "0x%-8x %-16d 0x%-6x %-10d %-11u %-14u\n",
+ "TH_L2H_ini", "TH_EDCCA_HL_diff", "IGI_Base", "ForceEDCCA", "AdapEn_RSSI", "IGI_LowerBound",
+ (u8)odm->TH_L2H_ini,
+ odm->TH_EDCCA_HL_diff,
+ odm->IGI_Base,
+ odm->ForceEDCCA,
+ odm->AdapEn_RSSI,
+ odm->IGI_LowerBound
+ );
+}
+
+void rtw_odm_adaptivity_parm_msg(_adapter *adapter)
+{
+ char buf[256] = {0};
+
+ _rtw_odm_dbg_comp_msg(adapter, buf, 256);
+ DBG_871X_LEVEL(_drv_always_, "\n%s", buf);
+}
+
+void rtw_odm_adaptivity_parm_set(_adapter *adapter, s8 TH_L2H_ini, s8 TH_EDCCA_HL_diff,
+ s8 IGI_Base, bool ForceEDCCA, u8 AdapEn_RSSI, u8 IGI_LowerBound)
+{
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(adapter);
+ DM_ODM_T *odm = &pHalData->odmpriv;
+
+ odm->TH_L2H_ini = TH_L2H_ini;
+ odm->TH_EDCCA_HL_diff = TH_EDCCA_HL_diff;
+ odm->IGI_Base = IGI_Base;
+ odm->ForceEDCCA = ForceEDCCA;
+ odm->AdapEn_RSSI = AdapEn_RSSI;
+ odm->IGI_LowerBound = IGI_LowerBound;
+}
+
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_p2p.c b/drivers/net/wireless/rtl8723as/core/rtw_p2p.c
index 0ed4b5e31065..348bdb88357c 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_p2p.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_p2p.c
@@ -1888,7 +1888,18 @@ u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
u8 p2pie[ MAX_P2P_IE_LEN] = { 0x00 };
u32 len=0, p2pielen = 0;
#ifdef CONFIG_INTEL_WIDI
+ struct mlme_priv *pmlmepriv = &(pwdinfo->padapter->mlmepriv);
u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
+ u8 widi_version = 0, i = 0;
+
+ if( _rtw_memcmp( pmlmepriv->sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN ) == _FALSE )
+ {
+ widi_version = 35;
+ }
+ else if( pmlmepriv->num_p2p_sdt != 0 )
+ {
+ widi_version = 40;
+ }
#endif //CONFIG_INTEL_WIDI
// P2P OUI
@@ -1977,10 +1988,14 @@ u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
// + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
//*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
#ifdef CONFIG_INTEL_WIDI
- if( _rtw_memcmp( pwdinfo->padapter->mlmepriv.sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN ) == _FALSE )
+ if( widi_version == 35 )
{
RTW_PUT_LE16(p2pie + p2pielen, 21 + 8 + pwdinfo->device_name_len);
}
+ else if( widi_version == 40 )
+ {
+ RTW_PUT_LE16(p2pie + p2pielen, 21 + 8 * pmlmepriv->num_p2p_sdt + pwdinfo->device_name_len);
+ }
else
#endif //CONFIG_INTEL_WIDI
RTW_PUT_LE16(p2pie + p2pielen, 21 + pwdinfo->device_name_len);
@@ -1997,25 +2012,48 @@ u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
RTW_PUT_BE16(p2pie + p2pielen, pwdinfo->supported_wps_cm);
p2pielen += 2;
- // Primary Device Type
- // Category ID
- //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
- RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
- p2pielen += 2;
+#ifdef CONFIG_INTEL_WIDI
+ if( widi_version == 40 )
+ {
+ // Primary Device Type
+ // Category ID
+ //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
+ RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_pdt_cid );
+ p2pielen += 2;
- // OUI
- //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
- RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
- p2pielen += 4;
+ // OUI
+ //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
+ RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
+ p2pielen += 4;
- // Sub Category ID
- //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
- RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
- p2pielen += 2;
+ // Sub Category ID
+ //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
+ RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_pdt_scid);
+ p2pielen += 2;
+ }
+ else
+#endif //CONFIG_INTEL_WIDI
+ {
+ // Primary Device Type
+ // Category ID
+ //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
+ RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_CID_MULIT_MEDIA);
+ p2pielen += 2;
+
+ // OUI
+ //*(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
+ RTW_PUT_BE32(p2pie + p2pielen, WPSOUI);
+ p2pielen += 4;
+
+ // Sub Category ID
+ //*(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
+ RTW_PUT_BE16(p2pie + p2pielen, WPS_PDT_SCID_MEDIA_SERVER);
+ p2pielen += 2;
+ }
// Number of Secondary Device Types
#ifdef CONFIG_INTEL_WIDI
- if( _rtw_memcmp( pwdinfo->padapter->mlmepriv.sa_ext, zero_array_check, L2SDTA_SERVICE_VE_LEN ) == _FALSE )
+ if( widi_version == 35 )
{
p2pie[ p2pielen++ ] = 0x01;
@@ -2028,6 +2066,21 @@ u32 build_probe_resp_p2p_ie(struct wifidirect_info *pwdinfo, u8 *pbuf)
RTW_PUT_BE16(p2pie + p2pielen, P2P_SCID_WIDI_CONSUMER_SINK);
p2pielen += 2;
}
+ else if( widi_version == 40 )
+ {
+ p2pie[ p2pielen++ ] = pmlmepriv->num_p2p_sdt;
+ for( ; i < pmlmepriv->num_p2p_sdt; i++ )
+ {
+ RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_sdt_cid[i]);
+ p2pielen += 2;
+
+ RTW_PUT_BE32(p2pie + p2pielen, INTEL_DEV_TYPE_OUI);
+ p2pielen += 4;
+
+ RTW_PUT_BE16(p2pie + p2pielen, pmlmepriv->p2p_sdt_scid[i]);
+ p2pielen += 2;
+ }
+ }
else
#endif //CONFIG_INTEL_WIDI
p2pie[ p2pielen++ ] = 0x00; // No Secondary Device Type List
@@ -2732,11 +2785,11 @@ u8 process_p2p_group_negotation_req( struct wifidirect_info *pwdinfo, u8 *pframe
{
u8 attr_content = 0x00;
u32 attr_contentlen = 0;
- u8 ch_content[50] = { 0x00 };
+ u8 ch_content[100] = { 0x00 };
uint ch_cnt = 0;
- u8 peer_ch_list[50] = { 0x00 };
+ u8 peer_ch_list[100] = { 0x00 };
u8 peer_ch_num = 0;
- u8 ch_list_inclusioned[50] = { 0x00 };
+ u8 ch_list_inclusioned[100] = { 0x00 };
u8 ch_num_inclusioned = 0;
u16 cap_attr;
@@ -2934,12 +2987,12 @@ u8 process_p2p_group_negotation_resp( struct wifidirect_info *pwdinfo, u8 *pfram
u32 attr_contentlen = 0;
u8 operatingch_info[5] = { 0x00 };
uint ch_cnt = 0;
- u8 ch_content[50] = { 0x00 };
+ u8 ch_content[100] = { 0x00 };
u8 groupid[ 38 ];
u16 cap_attr;
- u8 peer_ch_list[50] = { 0x00 };
+ u8 peer_ch_list[100] = { 0x00 };
u8 peer_ch_num = 0;
- u8 ch_list_inclusioned[50] = { 0x00 };
+ u8 ch_list_inclusioned[100] = { 0x00 };
u8 ch_num_inclusioned = 0;
while ( p2p_ie ) // Found the P2P IE.
@@ -3392,98 +3445,100 @@ _func_enter_;
struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
pwdinfo->operating_channel = pbuddy_mlmeext->cur_channel;
-#ifdef CONFIG_IOCTL_CFG80211
- DBG_871X("%s, switch ch back to buddy's cur_channel=%d\n", __func__, pbuddy_mlmeext->cur_channel);
+ if( pwdinfo->driver_interface == DRIVER_CFG80211 )
+ {
+ DBG_871X("%s, switch ch back to buddy's cur_channel=%d\n", __func__, pbuddy_mlmeext->cur_channel);
- set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
+ set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
- issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
-
-#else //CONFIG_IOCTL_CFG80211
- if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
+ issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
+ }
+ else if( pwdinfo->driver_interface == DRIVER_WEXT )
{
- // Now, the driver stays on the AP's channel.
- // If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel.
- if ( pwdinfo->ext_listen_period > 0 )
+ if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
+ {
+ // Now, the driver stays on the AP's channel.
+ // If the pwdinfo->ext_listen_period = 0, that means the P2P listen state is not available on listen channel.
+ if ( pwdinfo->ext_listen_period > 0 )
+ {
+ DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period );
+
+ if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel )
+ {
+ // Will switch to listen channel so that need to send the NULL data with PW bit to AP.
+ issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
+ set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
+ }
+
+ rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
+ val8 = 1;
+ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+
+ // Todo: To check the value of pwdinfo->ext_listen_period is equal to 0 or not.
+ _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period );
+ }
+ }
+ else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) ||
+ rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) ||
+ ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE ) ||
+ rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ) )
{
- DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_period = %d\n", __FUNCTION__, pwdinfo->ext_listen_period );
+ // Now, the driver is in the listen state of P2P mode.
+ DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval );
+ // Commented by Albert 2012/11/01
+ // If the AP's channel is the same as the listen channel, we should still be in the listen state
+ // Other P2P device is still able to find this device out even this device is in the AP's channel.
+ // So, configure this device to be able to receive the probe request frame and set it to listen state.
if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel )
{
- // Will switch to listen channel so that need to send the NULL data with PW bit to AP.
- issue_nulldata(pbuddy_adapter, NULL, 1, 3, 500);
- set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
+ set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
+ val8 = 0;
+ padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE);
+ issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
}
- rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
- val8 = 1;
- rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
-
- // Todo: To check the value of pwdinfo->ext_listen_period is equal to 0 or not.
- _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period );
+ // Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not.
+ _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval );
}
- }
- else if ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) ||
- rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL) ||
- ( rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _FALSE ) ||
- rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ) )
- {
- // Now, the driver is in the listen state of P2P mode.
- DBG_8192C( "[%s] P2P_STATE_IDLE, ext_listen_interval = %d\n", __FUNCTION__, pwdinfo->ext_listen_interval );
-
- // Commented by Albert 2012/11/01
- // If the AP's channel is the same as the listen channel, we should still be in the listen state
- // Other P2P device is still able to find this device out even this device is in the AP's channel.
- // So, configure this device to be able to receive the probe request frame and set it to listen state.
- if ( pbuddy_mlmeext->cur_channel != pwdinfo->listen_channel )
+ else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
{
- set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
+ // The driver had finished the P2P handshake successfully.
val8 = 0;
- padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- rtw_p2p_set_state(pwdinfo, P2P_STATE_IDLE);
+ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
}
-
- // Todo: To check the value of pwdinfo->ext_listen_interval is equal to 0 or not.
- _set_timer( &pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval );
- }
- else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
- {
- // The driver had finished the P2P handshake successfully.
- val8 = 0;
- rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
- issue_nulldata(pbuddy_adapter, NULL, 0, 3, 500);
- }
- else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
- {
- val8 = 1;
- set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- issue_probereq_p2p(padapter, NULL);
- _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
- }
- else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE)
- {
- val8 = 1;
- set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- issue_probereq_p2p(padapter, NULL);
- _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
- }
- else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) && pwdinfo->invitereq_info.benable == _TRUE)
- {
- /*
- val8 = 1;
- set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
- issue_probereq_p2p(padapter, NULL);
- _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
- */
+ else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
+ {
+ val8 = 1;
+ set_channel_bwmode(padapter, pwdinfo->tx_prov_disc_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
+ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ issue_probereq_p2p(padapter, NULL);
+ _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
+ }
+ else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING) && pwdinfo->nego_req_info.benable == _TRUE)
+ {
+ val8 = 1;
+ set_channel_bwmode(padapter, pwdinfo->nego_req_info.peer_channel_num[0], HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
+ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ issue_probereq_p2p(padapter, NULL);
+ _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
+ }
+ else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) && pwdinfo->invitereq_info.benable == _TRUE)
+ {
+ /*
+ val8 = 1;
+ set_channel_bwmode(padapter, , HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
+ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
+ issue_probereq_p2p(padapter, NULL);
+ _set_timer( &pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT );
+ */
+ }
}
-#endif //CONFIG_IOCTL_CFG80211
- }
+ }
else
{
set_channel_bwmode( padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
@@ -3498,39 +3553,38 @@ static void ro_ch_handler(_adapter *padapter)
{
struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ u8 ch, bw, offset;
_func_enter_;
- {
-
-#ifdef CONFIG_CONCURRENT_MODE
- if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
- {
- PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
- struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
-
- DBG_871X("%s, switch ch back to buddy's cur_channel=%d\n", __func__, pbuddy_mlmeext->cur_channel);
-
- set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
+ if (rtw_get_ch_setting_union(padapter, &ch, &bw, &offset) != 0) {
+ if (0)
+ DBG_871X(FUNC_ADPT_FMT" back to linked union - ch:%u, bw:%u, offset:%u\n",
+ FUNC_ADPT_ARG(padapter), ch, bw, offset);
+ }
+ else if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && pwdinfo->listen_channel) {
+ ch = pwdinfo->listen_channel;
+ bw = HT_CHANNEL_WIDTH_20;
+ offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+ if (0)
+ DBG_871X(FUNC_ADPT_FMT" back to listen ch - ch:%u, bw:%u, offset:%u\n",
+ FUNC_ADPT_ARG(padapter), ch, bw, offset);
+ }
+ else {
+ ch = pcfg80211_wdinfo->restore_channel;
+ bw = HT_CHANNEL_WIDTH_20;
+ offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
+ if (0)
+ DBG_871X(FUNC_ADPT_FMT" back to restore ch - ch:%u, bw:%u, offset:%u\n",
+ FUNC_ADPT_ARG(padapter), ch, bw, offset);
+ }
- pmlmeext->cur_channel = pbuddy_mlmeext->cur_channel;
-
- }else
-#endif //CONFIG_CONCURRENT_MODE
- if( pcfg80211_wdinfo->restore_channel != pmlmeext->cur_channel )
- {
- if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
- pmlmeext->cur_channel = pcfg80211_wdinfo->restore_channel;
+ set_channel_bwmode(padapter, ch, offset, bw);
- set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- }
-
- rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
-#ifdef CONFIG_DEBUG_CFG80211
- DBG_871X("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
+ rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
+#ifdef CONFIG_DEBUG_CFG80211
+ DBG_871X("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
#endif
- }
pcfg80211_wdinfo->is_ro_ch = _FALSE;
@@ -3558,6 +3612,162 @@ static void ro_ch_timer_process (void *FunctionContext)
p2p_protocol_wk_cmd( adapter, P2P_RO_CH_WK);
}
+static void rtw_change_p2pie_op_ch(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch)
+{
+ u8 *ies, *p2p_ie;
+ u32 ies_len, p2p_ielen;
+ PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
+ struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
+
+ ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
+ ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
+
+ p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
+
+ while ( p2p_ie ) {
+ u32 attr_contentlen = 0;
+ u8 *pattr = NULL;
+
+ //Check P2P_ATTR_OPERATING_CH
+ attr_contentlen = 0;
+ pattr = NULL;
+ if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL)
+ {
+ *(pattr+4) = ch;
+ }
+
+ //Get the next P2P IE
+ p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
+ }
+}
+
+static void rtw_change_p2pie_ch_list(_adapter *padapter, const u8 *frame_body, u32 len, u8 ch)
+{
+ u8 *ies, *p2p_ie;
+ u32 ies_len, p2p_ielen;
+ PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
+ struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
+
+ ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
+ ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
+
+ p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
+
+ while (p2p_ie) {
+ u32 attr_contentlen = 0;
+ u8 *pattr = NULL;
+
+ //Check P2P_ATTR_CH_LIST
+ if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) {
+ int i;
+ u32 num_of_ch;
+ u8 *pattr_temp = pattr + 3 ;
+
+ attr_contentlen -= 3;
+
+ while (attr_contentlen>0) {
+ num_of_ch = *(pattr_temp+1);
+
+ for(i=0; i<num_of_ch; i++)
+ *(pattr_temp+2+i) = ch;
+
+ pattr_temp += (2+num_of_ch);
+ attr_contentlen -= (2+num_of_ch);
+ }
+ }
+
+ //Get the next P2P IE
+ p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
+ }
+}
+
+static bool rtw_chk_p2pie_ch_list_with_buddy(_adapter *padapter, const u8 *frame_body, u32 len)
+{
+ bool fit = _FALSE;
+#ifdef CONFIG_CONCURRENT_MODE
+ u8 *ies, *p2p_ie;
+ u32 ies_len, p2p_ielen;
+ PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
+ struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
+ u8 buddy_ch = pbuddy_mlmeext->cur_channel;
+
+ ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
+ ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
+
+ p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
+
+ while (p2p_ie) {
+ u32 attr_contentlen = 0;
+ u8 *pattr = NULL;
+
+ //Check P2P_ATTR_CH_LIST
+ if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, (uint*)&attr_contentlen))!=NULL) {
+ int i;
+ u32 num_of_ch;
+ u8 *pattr_temp = pattr + 3 ;
+
+ attr_contentlen -= 3;
+
+ while (attr_contentlen>0) {
+ num_of_ch = *(pattr_temp+1);
+
+ for(i=0; i<num_of_ch; i++) {
+ if (*(pattr_temp+2+i) == buddy_ch) {
+ DBG_871X(FUNC_ADPT_FMT" ch_list fit buddy_ch:%u\n", FUNC_ADPT_ARG(padapter), buddy_ch);
+ fit = _TRUE;
+ break;
+ }
+ }
+
+ pattr_temp += (2+num_of_ch);
+ attr_contentlen -= (2+num_of_ch);
+ }
+ }
+
+ //Get the next P2P IE
+ p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
+ }
+#endif
+ return fit;
+}
+
+static bool rtw_chk_p2pie_op_ch_with_buddy(_adapter *padapter, const u8 *frame_body, u32 len)
+{
+ bool fit = _FALSE;
+#ifdef CONFIG_CONCURRENT_MODE
+ u8 *ies, *p2p_ie;
+ u32 ies_len, p2p_ielen;
+ PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
+ struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
+ u8 buddy_ch = pbuddy_mlmeext->cur_channel;
+
+ ies = (u8*)(frame_body + _PUBLIC_ACTION_IE_OFFSET_);
+ ies_len = len - _PUBLIC_ACTION_IE_OFFSET_;
+
+ p2p_ie = rtw_get_p2p_ie( ies, ies_len, NULL, &p2p_ielen );
+
+ while (p2p_ie) {
+ u32 attr_contentlen = 0;
+ u8 *pattr = NULL;
+
+ //Check P2P_ATTR_OPERATING_CH
+ attr_contentlen = 0;
+ pattr = NULL;
+ if((pattr = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, (uint*)&attr_contentlen))!=NULL) {
+ if (*(pattr+4) == buddy_ch) {
+ DBG_871X(FUNC_ADPT_FMT" op_ch fit buddy_ch:%u\n", FUNC_ADPT_ARG(padapter), buddy_ch);
+ fit = _TRUE;
+ break;
+ }
+ }
+
+ //Get the next P2P IE
+ p2p_ie = rtw_get_p2p_ie(p2p_ie+p2p_ielen, ies_len -(p2p_ie -ies + p2p_ielen), NULL, &p2p_ielen);
+ }
+#endif
+ return fit;
+}
+
static void rtw_cfg80211_adjust_p2pie_channel(_adapter *padapter, const u8 *frame_body, u32 len)
{
#ifdef CONFIG_CONCURRENT_MODE
@@ -3730,6 +3940,69 @@ void rtw_append_wfd_ie(_adapter *padapter, u8 *buf, u32* len)
}
#endif
+u8 *dump_p2p_attr_ch_list(u8 *p2p_ie, uint p2p_ielen, u8 *buf, u32 buf_len)
+{
+ uint attr_contentlen = 0;
+ u8 *pattr = NULL;
+ int w_sz = 0;
+ u8 ch_cnt = 0;
+ u8 ch_list[40];
+ bool continuous = _FALSE;
+
+ if ((pattr=rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CH_LIST, NULL, &attr_contentlen))!=NULL) {
+ int i, j;
+ u32 num_of_ch;
+ u8 *pattr_temp = pattr + 3 ;
+
+ attr_contentlen -= 3;
+
+ _rtw_memset(ch_list, 0, 40);
+
+ while (attr_contentlen>0) {
+ num_of_ch = *(pattr_temp+1);
+
+ for(i=0; i<num_of_ch; i++) {
+ for (j=0;j<ch_cnt;j++) {
+ if (ch_list[j] == *(pattr_temp+2+i))
+ break;
+ }
+ if (j>=ch_cnt)
+ ch_list[ch_cnt++] = *(pattr_temp+2+i);
+
+ }
+
+ pattr_temp += (2+num_of_ch);
+ attr_contentlen -= (2+num_of_ch);
+ }
+
+ for (j=0;j<ch_cnt;j++) {
+ if (j == 0) {
+ w_sz += snprintf(buf+w_sz, buf_len-w_sz, "%u", ch_list[j]);
+ } else if (ch_list[j] - ch_list[j-1] != 1) {
+ w_sz += snprintf(buf+w_sz, buf_len-w_sz, ", %u", ch_list[j]);
+ } else if (j != ch_cnt-1 && ch_list[j+1] - ch_list[j] == 1) {
+ /* empty */
+ } else {
+ w_sz += snprintf(buf+w_sz, buf_len-w_sz, "-%u", ch_list[j]);
+ }
+ }
+ }
+ return buf;
+}
+
+/*
+ * return _TRUE if requester is GO, _FALSE if responder is GO
+ */
+bool rtw_p2p_nego_intent_compare(u8 req, u8 resp)
+{
+ if (req>>1 == resp >>1)
+ return req&0x01 ? _TRUE : _FALSE;
+ else if (req>>1 > resp>>1)
+ return _TRUE;
+ else
+ return _FALSE;
+}
+
int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx)
{
int is_p2p_frame = (-1);
@@ -3738,6 +4011,11 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx)
u8 *p2p_ie = NULL;
uint p2p_ielen = 0;
struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
+ int status = -1;
+ u8 ch_list_buf[128] = {'\0'};
+ int op_ch = -1;
+ int listen_ch = -1;
+ u8 intent = 0;
frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
category = frame_body[0];
@@ -3767,60 +4045,152 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx)
u8 *cont;
uint cont_len;
case P2P_GO_NEGO_REQ:
- DBG_871X("RTW_%s:P2P_GO_NEGO_REQ, dialogToken=%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken);
-
- if(tx)
- {
-#ifdef CONFIG_DRV_ISSUE_PROV_REQ // IOT FOR S2
+ {
+ struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info;
+
+ if (tx) {
+ #ifdef CONFIG_DRV_ISSUE_PROV_REQ // IOT FOR S2
if(pwdev_priv->provdisc_req_issued == _FALSE)
rtw_cfg80211_issue_p2p_provision_request(padapter, buf, len);
-#endif //CONFIG_DRV_ISSUE_PROV_REQ
+ #endif //CONFIG_DRV_ISSUE_PROV_REQ
//pwdev_priv->provdisc_req_issued = _FALSE;
-
-#ifdef CONFIG_CONCURRENT_MODE
+
+ #ifdef CONFIG_CONCURRENT_MODE
if(check_buddy_fwstate(padapter, _FW_LINKED))
rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
-#endif
+ #endif
}
-
+
+ if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
+ op_ch = *(cont+4);
+ if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, NULL, &cont_len)))
+ listen_ch = *(cont+4);
+ if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len)))
+ intent = *cont;
+
+ if (nego_info->token != dialogToken)
+ rtw_wdev_nego_info_init(nego_info);
+
+ _rtw_memcpy(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN);
+ nego_info->active = tx ? 1 : 0;
+ nego_info->token = dialogToken;
+ nego_info->req_op_ch = op_ch;
+ nego_info->req_listen_ch = listen_ch;
+ nego_info->req_intent = intent;
+ nego_info->state = 0;
+
+ dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
+ DBG_871X("RTW_%s:P2P_GO_NEGO_REQ, dialogToken=%d, intent:%u%s, listen_ch:%d, op_ch:%d, ch_list:%s\n",
+ (tx==_TRUE)?"Tx":"Rx", dialogToken, (intent>>1), intent&0x1 ? "+" : "-", listen_ch, op_ch, ch_list_buf);
+
+ if (!tx) {
+ #ifdef CONFIG_CONCURRENT_MODE
+ if(check_buddy_fwstate(padapter, _FW_LINKED)
+ && rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE)
+ {
+ DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter));
+ rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0);
+ }
+ #endif
+ }
+
break;
+ }
case P2P_GO_NEGO_RESP:
- cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len);
- DBG_871X("RTW_%s:P2P_GO_NEGO_RESP, dialogToken=%d, status:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, cont?*cont:-1);
+ {
+ struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info;
- if(!tx)
- {
- pwdev_priv->provdisc_req_issued = _FALSE;
- }
-#ifdef CONFIG_CONCURRENT_MODE
- else
- {
+ if (tx) {
+ #ifdef CONFIG_CONCURRENT_MODE
if(check_buddy_fwstate(padapter, _FW_LINKED))
rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
+ #endif
}
-#endif
- break;
+
+ if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
+ op_ch = *(cont+4);
+ if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_GO_INTENT, NULL, &cont_len)))
+ intent = *cont;
+ if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len)))
+ status = *cont;
+
+ if (nego_info->token == dialogToken && nego_info->state == 0
+ && _rtw_memcmp(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE
+ ) {
+ nego_info->status = (status==-1) ? 0xff : status;
+ nego_info->rsp_op_ch= op_ch;
+ nego_info->rsp_intent = intent;
+ nego_info->state = 1;
+ if (status != 0)
+ nego_info->token = 0; /* init */
+ }
+
+ dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
+ DBG_871X("RTW_%s:P2P_GO_NEGO_RESP, dialogToken=%d, intent:%u%s, status:%d, op_ch:%d, ch_list:%s\n",
+ (tx==_TRUE)?"Tx":"Rx", dialogToken, (intent>>1), intent&0x1 ? "+" : "-", status, op_ch, ch_list_buf);
+
+ if (!tx) {
+ pwdev_priv->provdisc_req_issued = _FALSE;
+ #ifdef CONFIG_CONCURRENT_MODE
+ if(check_buddy_fwstate(padapter, _FW_LINKED)
+ && rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE)
+ {
+ DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter));
+ rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0);
+ }
+ #endif
+ }
+
+ break;
+ }
case P2P_GO_NEGO_CONF:
- cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len);
- DBG_871X("RTW_%s:P2P_GO_NEGO_CONF, dialogToken=%d, status:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, cont?*cont:-1);
+ {
+ struct rtw_wdev_nego_info* nego_info = &pwdev_priv->nego_info;
+ bool is_go = _FALSE;
-#ifdef CONFIG_CONCURRENT_MODE
- if(tx)
- {
+ if (tx) {
+ #ifdef CONFIG_CONCURRENT_MODE
if(check_buddy_fwstate(padapter, _FW_LINKED))
rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
+ #endif
}
-#endif
- break;
+
+ if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
+ op_ch = *(cont+4);
+ if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len)))
+ status = *cont;
+
+ if (nego_info->token == dialogToken && nego_info->state == 1
+ && _rtw_memcmp(nego_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE
+ ) {
+ nego_info->status = (status==-1) ? 0xff : status;
+ nego_info->conf_op_ch = (op_ch==-1) ? 0 : op_ch;
+ nego_info->state = 2;
+
+ if (status == 0) {
+ if (rtw_p2p_nego_intent_compare(nego_info->req_intent, nego_info->rsp_intent) && tx)
+ is_go = _TRUE;
+ }
+
+ nego_info->token = 0; /* init */
+ }
+
+ dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
+ DBG_871X("RTW_%s:P2P_GO_NEGO_CONF, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n",
+ (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf);
+
+ if (!tx) {
+ }
+
+ break;
+ }
case P2P_INVIT_REQ:
{
struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info;
int flags = -1;
- int op_ch = 0;
- if(tx)
- {
+ if (tx) {
#ifdef CONFIG_CONCURRENT_MODE
if(check_buddy_fwstate(padapter, _FW_LINKED))
rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
@@ -3835,21 +4205,38 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx)
if (invit_info->token != dialogToken)
rtw_wdev_invit_info_init(invit_info);
+ _rtw_memcpy(invit_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN);
+ invit_info->active = tx ? 1 : 0;
invit_info->token = dialogToken;
invit_info->flags = (flags==-1) ? 0x0 : flags;
invit_info->req_op_ch= op_ch;
+ invit_info->state = 0;
+
+ dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
+ DBG_871X("RTW_%s:P2P_INVIT_REQ, dialogToken=%d, flags:0x%02x, op_ch:%d, ch_list:%s\n",
+ (tx==_TRUE)?"Tx":"Rx", dialogToken, flags, op_ch, ch_list_buf);
+
+ if (!tx) {
+ #ifdef CONFIG_CONCURRENT_MODE
+ if(check_buddy_fwstate(padapter, _FW_LINKED)) {
+ if (op_ch != -1 && rtw_chk_p2pie_op_ch_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) {
+ DBG_871X(FUNC_ADPT_FMT" op_ch:%u has no intersect with buddy\n", FUNC_ADPT_ARG(padapter), op_ch);
+ rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0);
+ } else if (rtw_chk_p2pie_ch_list_with_buddy(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr)) == _FALSE) {
+ DBG_871X(FUNC_ADPT_FMT" ch_list has no intersect with buddy\n", FUNC_ADPT_ARG(padapter));
+ rtw_change_p2pie_ch_list(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr), 0);
+ }
+ }
+ #endif
+ }
- DBG_871X("RTW_%s:P2P_INVIT_REQ, dialogToken=%d, flags:0x%02x, op_ch:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, flags, op_ch);
break;
}
case P2P_INVIT_RESP:
{
struct rtw_wdev_invit_info* invit_info = &pwdev_priv->invit_info;
- int status = -1;
- int op_ch = 0;
- if(tx)
- {
+ if (tx) {
#ifdef CONFIG_CONCURRENT_MODE
if(check_buddy_fwstate(padapter, _FW_LINKED))
rtw_cfg80211_adjust_p2pie_channel(padapter, frame_body, len-sizeof(struct rtw_ieee80211_hdr_3addr));
@@ -3857,19 +4244,35 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx)
}
if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, NULL, &cont_len)))
+ {
+#ifdef CONFIG_P2P_INVITE_IOT
+ if(tx && *cont==7)
+ {
+ DBG_871X("TX_P2P_INVITE_RESP, status is no common channel, change to unknown group\n");
+ *cont = 8; //unknow group status
+ }
+#endif //CONFIG_P2P_INVITE_IOT
status = *cont;
+ }
if ((cont = rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, NULL, &cont_len)))
op_ch = *(cont+4);
- if (invit_info->token != dialogToken) {
- rtw_wdev_invit_info_init(invit_info);
- } else {
- invit_info->token = 0;
+ if (invit_info->token == dialogToken && invit_info->state == 0
+ && _rtw_memcmp(invit_info->peer_mac, tx ? GetAddr1Ptr(buf) : GetAddr2Ptr(buf), ETH_ALEN) == _TRUE
+ ) {
invit_info->status = (status==-1) ? 0xff : status;
invit_info->rsp_op_ch= op_ch;
+ invit_info->state = 1;
+ invit_info->token = 0; /* init */
+ }
+
+ dump_p2p_attr_ch_list(p2p_ie, p2p_ielen, ch_list_buf, 128);
+ DBG_871X("RTW_%s:P2P_INVIT_RESP, dialogToken=%d, status:%d, op_ch:%d, ch_list:%s\n",
+ (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch, ch_list_buf);
+
+ if (!tx) {
}
- DBG_871X("RTW_%s:P2P_INVIT_RESP, dialogToken=%d, status:%d, op_ch:%d\n", (tx==_TRUE)?"Tx":"Rx", dialogToken, status, op_ch);
break;
}
case P2P_DEVDISC_REQ:
@@ -3954,10 +4357,9 @@ int rtw_p2p_check_frames(_adapter *padapter, const u8 *buf, u32 len, u8 tx)
}
}
- else
+ else
{
DBG_871X("RTW_%s:action frame category=%d\n", (tx==_TRUE)?"TX":"RX", category);
- //is_p2p_frame = (-1);
}
return is_p2p_frame;
@@ -4138,7 +4540,7 @@ _func_enter_;
{
pwdinfo->p2p_ps_mode = P2P_PS_CTWINDOW;
// driver should wait LPS for entering CTWindow
- if(padapter->pwrctrlpriv.bFwCurrentInPSMode == _TRUE)
+ if(adapter_to_pwrctl(padapter)->bFwCurrentInPSMode == _TRUE)
{
p2p_ps_wk_cmd(padapter, P2P_PS_ENABLE, 1);
}
@@ -4175,7 +4577,7 @@ _func_exit_;
void p2p_ps_wk_hdl(_adapter *padapter, u8 p2p_ps_state)
{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
_func_enter_;
@@ -4193,12 +4595,12 @@ _func_enter_;
pwdinfo->opp_ps = 0;
pwdinfo->noa_num = 0;
pwdinfo->p2p_ps_mode = P2P_PS_NONE;
- if(padapter->pwrctrlpriv.bFwCurrentInPSMode == _TRUE)
+ if(pwrpriv->bFwCurrentInPSMode == _TRUE)
{
if(pwrpriv->smart_ps == 0)
{
pwrpriv->smart_ps = 2;
- rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode)));
+ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode)));
}
}
break;
@@ -4212,7 +4614,7 @@ _func_enter_;
{
pwrpriv->smart_ps = 0;
DBG_871X("%s(): Enter CTW, change SmartPS\n", __FUNCTION__);
- rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(padapter->pwrctrlpriv.pwr_mode)));
+ rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&(pwrpriv->pwr_mode)));
}
}
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_P2P_PS_OFFLOAD, (u8 *)(&p2p_ps_state));
@@ -4300,6 +4702,11 @@ static void reset_ch_sitesurvey_timer_process (void *FunctionContext)
DBG_871X( "[%s] In\n", __FUNCTION__ );
// Reset the operation channel information
pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
+#ifdef P2P_OP_CHECK_SOCIAL_CH
+ pwdinfo->rx_invitereq_info.operation_ch[1] = 0;
+ pwdinfo->rx_invitereq_info.operation_ch[2] = 0;
+ pwdinfo->rx_invitereq_info.operation_ch[3] = 0;
+#endif //P2P_OP_CHECK_SOCIAL_CH
pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
}
@@ -4314,6 +4721,11 @@ static void reset_ch_sitesurvey_timer_process2 (void *FunctionContext)
DBG_871X( "[%s] In\n", __FUNCTION__ );
// Reset the operation channel information
pwdinfo->p2p_info.operation_ch[0] = 0;
+#ifdef P2P_OP_CHECK_SOCIAL_CH
+ pwdinfo->p2p_info.operation_ch[1] = 0;
+ pwdinfo->p2p_info.operation_ch[2] = 0;
+ pwdinfo->p2p_info.operation_ch[3] = 0;
+#endif //P2P_OP_CHECK_SOCIAL_CH
pwdinfo->p2p_info.scan_op_ch_only = 0;
}
@@ -4611,45 +5023,118 @@ void init_wifidirect_info( _adapter* padapter, enum P2P_ROLE role)
pwdinfo->ext_listen_period = 1000;
#endif //!CONFIG_IOCTL_CFG80211
#endif
+
+// Commented by Kurt 20130319
+// For WiDi purpose: Use CFG80211 interface but controled WFD/RDS frame by driver itself.
+#ifdef CONFIG_IOCTL_CFG80211
+ pwdinfo->driver_interface = DRIVER_CFG80211;
+#else
+ pwdinfo->driver_interface = DRIVER_WEXT;
+#endif //CONFIG_IOCTL_CFG80211
+
pwdinfo->wfd_tdls_enable = 0;
_rtw_memset( pwdinfo->p2p_peer_interface_addr, 0x00, ETH_ALEN );
_rtw_memset( pwdinfo->p2p_peer_device_addr, 0x00, ETH_ALEN );
pwdinfo->rx_invitereq_info.operation_ch[0] = 0;
pwdinfo->rx_invitereq_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function
+#ifdef P2P_OP_CHECK_SOCIAL_CH
+ pwdinfo->rx_invitereq_info.operation_ch[2] = 0;
+ pwdinfo->rx_invitereq_info.operation_ch[3] = 0;
+ pwdinfo->rx_invitereq_info.operation_ch[4] = 0;
+#endif //P2P_OP_CHECK_SOCIAL_CH
pwdinfo->rx_invitereq_info.scan_op_ch_only = 0;
pwdinfo->p2p_info.operation_ch[0] = 0;
pwdinfo->p2p_info.operation_ch[1] = 0; // Used to indicate the scan end in site survey function
+#ifdef P2P_OP_CHECK_SOCIAL_CH
+ pwdinfo->p2p_info.operation_ch[2] = 0;
+ pwdinfo->p2p_info.operation_ch[3] = 0;
+ pwdinfo->p2p_info.operation_ch[4] = 0;
+#endif //P2P_OP_CHECK_SOCIAL_CH
pwdinfo->p2p_info.scan_op_ch_only = 0;
}
#ifdef CONFIG_DBG_P2P
-char * p2p_role_str[] = {
- "P2P_ROLE_DISABLE",
- "P2P_ROLE_DEVICE",
- "P2P_ROLE_CLIENT",
- "P2P_ROLE_GO"
-};
-
-char * p2p_state_str[] = {
- "P2P_STATE_NONE",
- "P2P_STATE_IDLE",
- "P2P_STATE_LISTEN",
- "P2P_STATE_SCAN",
- "P2P_STATE_FIND_PHASE_LISTEN",
- "P2P_STATE_FIND_PHASE_SEARCH",
- "P2P_STATE_TX_PROVISION_DIS_REQ",
- "P2P_STATE_RX_PROVISION_DIS_RSP",
- "P2P_STATE_RX_PROVISION_DIS_REQ",
- "P2P_STATE_GONEGO_ING",
- "P2P_STATE_GONEGO_OK",
- "P2P_STATE_GONEGO_FAIL",
- "P2P_STATE_RECV_INVITE_REQ_MATCH",
- "P2P_STATE_PROVISIONING_ING",
- "P2P_STATE_PROVISIONING_DONE",
- "P2P_STATE_RECV_INVITE_REQ_DISMATCH",
- "P2P_STATE_RECV_INVITE_REQ_GO"
-};
+
+/**
+ * rtw_p2p_role_txt - Get the p2p role name as a text string
+ * @role: P2P role
+ * Returns: The state name as a printable text string
+ */
+const char * rtw_p2p_role_txt(enum P2P_ROLE role)
+{
+ switch (role) {
+ case P2P_ROLE_DISABLE:
+ return "P2P_ROLE_DISABLE";
+ case P2P_ROLE_DEVICE:
+ return "P2P_ROLE_DEVICE";
+ case P2P_ROLE_CLIENT:
+ return "P2P_ROLE_CLIENT";
+ case P2P_ROLE_GO:
+ return "P2P_ROLE_GO";
+ default:
+ return "UNKNOWN";
+ }
+}
+
+/**
+ * rtw_p2p_state_txt - Get the p2p state name as a text string
+ * @state: P2P state
+ * Returns: The state name as a printable text string
+ */
+const char * rtw_p2p_state_txt(enum P2P_STATE state)
+{
+ switch (state) {
+ case P2P_STATE_NONE:
+ return "P2P_STATE_NONE";
+ case P2P_STATE_IDLE:
+ return "P2P_STATE_IDLE";
+ case P2P_STATE_LISTEN:
+ return "P2P_STATE_LISTEN";
+ case P2P_STATE_SCAN:
+ return "P2P_STATE_SCAN";
+ case P2P_STATE_FIND_PHASE_LISTEN:
+ return "P2P_STATE_FIND_PHASE_LISTEN";
+ case P2P_STATE_FIND_PHASE_SEARCH:
+ return "P2P_STATE_FIND_PHASE_SEARCH";
+ case P2P_STATE_TX_PROVISION_DIS_REQ:
+ return "P2P_STATE_TX_PROVISION_DIS_REQ";
+ case P2P_STATE_RX_PROVISION_DIS_RSP:
+ return "P2P_STATE_RX_PROVISION_DIS_RSP";
+ case P2P_STATE_RX_PROVISION_DIS_REQ:
+ return "P2P_STATE_RX_PROVISION_DIS_REQ";
+ case P2P_STATE_GONEGO_ING:
+ return "P2P_STATE_GONEGO_ING";
+ case P2P_STATE_GONEGO_OK:
+ return "P2P_STATE_GONEGO_OK";
+ case P2P_STATE_GONEGO_FAIL:
+ return "P2P_STATE_GONEGO_FAIL";
+ case P2P_STATE_RECV_INVITE_REQ_MATCH:
+ return "P2P_STATE_RECV_INVITE_REQ_MATCH";
+ case P2P_STATE_PROVISIONING_ING:
+ return "P2P_STATE_PROVISIONING_ING";
+ case P2P_STATE_PROVISIONING_DONE:
+ return "P2P_STATE_PROVISIONING_DONE";
+ case P2P_STATE_TX_INVITE_REQ:
+ return "P2P_STATE_TX_INVITE_REQ";
+ case P2P_STATE_RX_INVITE_RESP_OK:
+ return "P2P_STATE_RX_INVITE_RESP_OK";
+ case P2P_STATE_RECV_INVITE_REQ_DISMATCH:
+ return "P2P_STATE_RECV_INVITE_REQ_DISMATCH";
+ case P2P_STATE_RECV_INVITE_REQ_GO:
+ return "P2P_STATE_RECV_INVITE_REQ_GO";
+ case P2P_STATE_RECV_INVITE_REQ_JOIN:
+ return "P2P_STATE_RECV_INVITE_REQ_JOIN";
+ case P2P_STATE_RX_INVITE_RESP_FAIL:
+ return "P2P_STATE_RX_INVITE_RESP_FAIL";
+ case P2P_STATE_RX_INFOR_NOREADY:
+ return "P2P_STATE_RX_INFOR_NOREADY";
+ case P2P_STATE_TX_INFOR_NOREADY:
+ return "P2P_STATE_TX_INFOR_NOREADY";
+ default:
+ return "UNKNOWN";
+ }
+}
void dbg_rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state, const char *caller, int line)
{
@@ -4657,11 +5142,11 @@ void dbg_rtw_p2p_set_state(struct wifidirect_info *wdinfo, enum P2P_STATE state,
enum P2P_STATE old_state = _rtw_p2p_state(wdinfo);
_rtw_p2p_set_state(wdinfo, state);
DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state from %s to %s\n", caller, line
- , p2p_state_str[old_state], p2p_state_str[_rtw_p2p_state(wdinfo)]
+ , rtw_p2p_state_txt(old_state), rtw_p2p_state_txt(_rtw_p2p_state(wdinfo))
);
} else {
DBG_871X("[CONFIG_DBG_P2P]%s:%d set_state to same state %s\n", caller, line
- , p2p_state_str[_rtw_p2p_state(wdinfo)]
+ , rtw_p2p_state_txt(_rtw_p2p_state(wdinfo))
);
}
}
@@ -4671,11 +5156,11 @@ void dbg_rtw_p2p_set_pre_state(struct wifidirect_info *wdinfo, enum P2P_STATE st
enum P2P_STATE old_state = _rtw_p2p_pre_state(wdinfo);
_rtw_p2p_set_pre_state(wdinfo, state);
DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state from %s to %s\n", caller, line
- , p2p_state_str[old_state], p2p_state_str[_rtw_p2p_pre_state(wdinfo)]
+ , rtw_p2p_state_txt(old_state), rtw_p2p_state_txt(_rtw_p2p_pre_state(wdinfo))
);
} else {
DBG_871X("[CONFIG_DBG_P2P]%s:%d set_pre_state to same state %s\n", caller, line
- , p2p_state_str[_rtw_p2p_pre_state(wdinfo)]
+ , rtw_p2p_state_txt(_rtw_p2p_pre_state(wdinfo))
);
}
}
@@ -4700,11 +5185,11 @@ void dbg_rtw_p2p_set_role(struct wifidirect_info *wdinfo, enum P2P_ROLE role, co
enum P2P_ROLE old_role = wdinfo->role;
_rtw_p2p_set_role(wdinfo, role);
DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role from %s to %s\n", caller, line
- , p2p_role_str[old_role], p2p_role_str[wdinfo->role]
+ , rtw_p2p_role_txt(old_role), rtw_p2p_role_txt(wdinfo->role)
);
} else {
DBG_871X("[CONFIG_DBG_P2P]%s:%d set_role to same role %s\n", caller, line
- , p2p_role_str[wdinfo->role]
+ , rtw_p2p_role_txt(wdinfo->role)
);
}
}
@@ -4715,7 +5200,6 @@ int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role)
{
int ret = _SUCCESS;
struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
if (role == P2P_ROLE_DEVICE || role == P2P_ROLE_CLIENT|| role == P2P_ROLE_GO)
{
@@ -4757,6 +5241,11 @@ int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role)
}
else if (role == P2P_ROLE_DISABLE)
{
+#ifdef CONFIG_INTEL_WIDI
+ if( padapter->mlmepriv.p2p_reject_disable == _TRUE )
+ return ret;
+#endif //CONFIG_INTEL_WIDI
+
if (_FAIL == rtw_pwr_wakeup(padapter)) {
ret = _FAIL;
goto exit;
@@ -4787,6 +5276,18 @@ int rtw_p2p_enable(_adapter *padapter, enum P2P_ROLE role)
//Restore to initial setting.
update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
+
+#ifdef CONFIG_INTEL_WIDI
+ rtw_reset_widi_info(padapter);
+#endif //CONFIG_INTEL_WIDI
+
+ //For WiDi purpose.
+#ifdef CONFIG_IOCTL_CFG80211
+ pwdinfo->driver_interface = DRIVER_CFG80211;
+#else
+ pwdinfo->driver_interface = DRIVER_WEXT;
+#endif //CONFIG_IOCTL_CFG80211
+
}
exit:
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_pwrctrl.c b/drivers/net/wireless/rtl8723as/core/rtw_pwrctrl.c
index 9e53994211b2..77b86f344dca 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_pwrctrl.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_pwrctrl.c
@@ -29,11 +29,15 @@
#endif
#ifdef CONFIG_IPS
-void ips_enter(_adapter * padapter)
+void _ips_enter(_adapter * padapter)
{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
- _enter_pwrlock(&pwrpriv->lock);
+ if (padapter->hw_init_completed == _FALSE) {
+ DBG_871X("%s: hw_init_completed: %d\n",
+ __func__, padapter->hw_init_completed);
+ return;
+ }
pwrpriv->bips_processing = _TRUE;
@@ -58,20 +62,21 @@ void ips_enter(_adapter * padapter)
}
pwrpriv->bips_processing = _FALSE;
- _exit_pwrlock(&pwrpriv->lock);
-
}
-int ips_leave(_adapter * padapter)
+void ips_enter(_adapter * padapter)
{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct security_priv* psecuritypriv=&(padapter->securitypriv);
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- int result = _SUCCESS;
- sint keyid;
-
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
_enter_pwrlock(&pwrpriv->lock);
+ _ips_enter(padapter);
+ _exit_pwrlock(&pwrpriv->lock);
+}
+
+int _ips_leave(_adapter * padapter)
+{
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+ int result = _SUCCESS;
if((pwrpriv->rf_pwrstate == rf_off) &&(!pwrpriv->bips_processing))
{
@@ -84,20 +89,6 @@ int ips_leave(_adapter * padapter)
pwrpriv->rf_pwrstate = rf_on;
}
DBG_871X_LEVEL(_drv_always_, "nolinked power save leave\n");
-
- if((_WEP40_ == psecuritypriv->dot11PrivacyAlgrthm) ||(_WEP104_ == psecuritypriv->dot11PrivacyAlgrthm))
- {
- DBG_871X("==>%s,channel(%d),processing(%x)\n",__FUNCTION__,padapter->mlmeextpriv.cur_channel,pwrpriv->bips_processing);
- set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
- for(keyid=0;keyid<4;keyid++){
- if(pmlmepriv->key_mask & BIT(keyid)){
- if(keyid == psecuritypriv->dot11PrivacyKeyIndex)
- result=rtw_set_key(padapter,psecuritypriv, keyid, 1);
- else
- result=rtw_set_key(padapter,psecuritypriv, keyid, 0);
- }
- }
- }
DBG_871X("==> ips_leave.....LED(0x%08x)...\n",rtw_read32(padapter,0x4c));
pwrpriv->bips_processing = _FALSE;
@@ -106,13 +97,21 @@ int ips_leave(_adapter * padapter)
pwrpriv->bpower_saving = _FALSE;
}
- _exit_pwrlock(&pwrpriv->lock);
-
return result;
}
+int ips_leave(_adapter * padapter)
+{
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+ int ret;
+
+ _enter_pwrlock(&pwrpriv->lock);
+ ret = _ips_leave(padapter);
+ _exit_pwrlock(&pwrpriv->lock);
-#endif
+ return ret;
+}
+#endif /* CONFIG_IPS */
#ifdef CONFIG_AUTOSUSPEND
extern void autosuspend_enter(_adapter* padapter);
@@ -138,7 +137,7 @@ bool rtw_pwr_unassociated_idle(_adapter *adapter)
bool ret = _FALSE;
- if (adapter->pwrctrlpriv.ips_deny_time >= rtw_get_current_time()) {
+ if (adapter_to_pwrctl(adapter)->ips_deny_time >= rtw_get_current_time()) {
//DBG_871X("%s ips_deny_time\n", __func__);
goto exit;
}
@@ -211,7 +210,7 @@ void rtw_ps_processor(_adapter*padapter)
#ifdef CONFIG_P2P
struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
#endif //CONFIG_P2P
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
#ifdef SUPPORT_HW_RFOFF_DETECTED
rt_rf_power_state rfpwrstate;
@@ -224,7 +223,7 @@ void rtw_ps_processor(_adapter*padapter)
goto exit;
//DBG_871X("==> fw report state(0x%x)\n",rtw_read8(padapter,0x1ca));
- if(padapter->pwrctrlpriv.bHWPwrPindetect)
+ if(pwrpriv->bHWPwrPindetect)
{
#ifdef CONFIG_AUTOSUSPEND
if(padapter->registrypriv.usbss_enable)
@@ -277,11 +276,7 @@ void rtw_ps_processor(_adapter*padapter)
}
#endif //SUPPORT_HW_RFOFF_DETECTED
- if (pwrpriv->ips_mode_req == IPS_NONE
- #ifdef CONFIG_CONCURRENT_MODE
- || padapter->pbuddy_adapter->pwrctrlpriv.ips_mode_req == IPS_NONE
- #endif
- )
+ if (pwrpriv->ips_mode_req == IPS_NONE)
goto exit;
if (rtw_pwr_unassociated_idle(padapter) == _FALSE)
@@ -333,7 +328,7 @@ void rtw_ps_processor(_adapter*padapter)
}
}
exit:
- rtw_set_pwr_state_check_timer(&padapter->pwrctrlpriv);
+ rtw_set_pwr_state_check_timer(pwrpriv);
pwrpriv->ps_processing = _FALSE;
return;
}
@@ -359,7 +354,13 @@ void pwr_state_check_handler(void *FunctionContext)
void rtw_set_rpwm(PADAPTER padapter, u8 pslv)
{
u8 rpwm;
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+#ifdef CONFIG_DETECT_CPWM_BY_POLLING
+ u8 cpwm_orig = 0;
+ u8 cpwm_now = 0;
+ u32 cpwm_polling_start_time = 0;
+ u8 pollingRes = _FAIL;
+#endif
_func_enter_;
@@ -382,8 +383,10 @@ _func_enter_;
{
if ( (pwrpriv->rpwm == pslv)
#ifdef CONFIG_LPS_LCLK
+#ifndef CONFIG_RTL8723A
|| ((pwrpriv->rpwm >= PS_STATE_S2)&&(pslv >= PS_STATE_S2))
#endif
+#endif
)
{
RT_TRACE(_module_rtl871x_pwrctrl_c_,_drv_err_,
@@ -427,10 +430,18 @@ _func_enter_;
pwrpriv->rpwm = pslv;
-#ifdef CONFIG_LPS_RPWM_TIMER
+#ifdef CONFIG_DETECT_CPWM_BY_POLLING
+ if (rpwm & PS_ACK)
+ {
+ //cpwm_orig = rtw_read8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HCPWM1);
+ rtw_hal_get_hwreg(padapter, HW_VAR_GET_CPWM, (u8 *)(&cpwm_orig));
+ }
+#endif
+
+#if defined(CONFIG_LPS_RPWM_TIMER) && !defined(CONFIG_DETECT_CPWM_BY_POLLING)
if (rpwm & PS_ACK)
_set_timer(&pwrpriv->pwr_rpwm_timer, LPS_RPWM_WAIT_MS);
-#endif // CONFIG_LPS_RPWM_TIMER
+#endif // CONFIG_LPS_RPWM_TIMER && !CONFIG_DETECT_CPWM_BY_POLLING
rtw_hal_set_hwreg(padapter, HW_VAR_SET_RPWM, (u8 *)(&rpwm));
pwrpriv->tog += 0x80;
@@ -443,6 +454,42 @@ _func_enter_;
pwrpriv->cpwm = pslv;
}
+#ifdef CONFIG_DETECT_CPWM_BY_POLLING
+ if (rpwm & PS_ACK)
+ {
+ cpwm_polling_start_time = rtw_get_current_time();
+
+ //polling cpwm
+ do{
+ rtw_mdelay_os(1);
+
+ //cpwm_now = rtw_read8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HCPWM1);
+ rtw_hal_get_hwreg(padapter, HW_VAR_GET_CPWM, (u8 *)(&cpwm_now));
+ if ((cpwm_orig ^ cpwm_now) & 0x80)
+ {
+#ifdef CONFIG_LPS_LCLK
+ #ifdef CONFIG_RTL8723A
+ pwrpriv->cpwm = PS_STATE(cpwm_now);
+ #else // !CONFIG_RTL8723A
+ pwrpriv->cpwm = PS_STATE_S4;
+ #endif // !CONFIG_RTL8723A
+ pwrpriv->cpwm_tog = cpwm_now & PS_TOGGLE;
+#endif
+ pollingRes = _SUCCESS;
+ break;
+ }
+ }while (rtw_get_passing_time_ms(cpwm_polling_start_time) < LPS_RPWM_WAIT_MS);
+
+ if (pollingRes == _FAIL)
+ {
+#ifdef CONFIG_LPS_RPWM_TIMER
+ _set_timer(&pwrpriv->pwr_rpwm_timer, 1);
+#endif
+ DBG_871X("%s polling cpwm timeout!!!!!!!!!!\n", __FUNCTION__);
+ }
+ }
+#endif
+
_func_exit_;
}
@@ -450,9 +497,18 @@ u8 PS_RDY_CHECK(_adapter * padapter);
u8 PS_RDY_CHECK(_adapter * padapter)
{
u32 curr_time, delta_time;
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+#ifdef CONFIG_WOWLAN
+ if(_TRUE == pwrpriv->bInSuspend && pwrpriv->wowlan_mode)
+ return _TRUE;
+ else if (_TRUE == pwrpriv->bInSuspend)
+ return _FALSE;
+#else
+ if(_TRUE == pwrpriv->bInSuspend )
+ return _FALSE;
+#endif
curr_time = rtw_get_current_time();
delta_time = curr_time -pwrpriv->DelayLPSLastTimeStamp;
@@ -464,24 +520,18 @@ u8 PS_RDY_CHECK(_adapter * padapter)
if ((check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE) ||
(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) ||
+ (check_fwstate(pmlmepriv, WIFI_UNDER_WPS) == _TRUE) ||
(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) ||
(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) )
return _FALSE;
-#ifdef CONFIG_WOWLAN
- if(_TRUE == pwrpriv->bInSuspend && pwrpriv->wowlan_mode)
- return _TRUE;
- else
- return _FALSE;
-#else
- if(_TRUE == pwrpriv->bInSuspend )
- return _FALSE;
-#endif
+
if( (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) && (padapter->securitypriv.binstallGrpkey == _FALSE) )
{
DBG_871X("Group handshake still in progress !!!\n");
return _FALSE;
}
+
#ifdef CONFIG_IOCTL_CFG80211
if (!rtw_cfg80211_pwr_mgmt(padapter))
return _FALSE;
@@ -492,7 +542,7 @@ u8 PS_RDY_CHECK(_adapter * padapter)
void rtw_set_ps_mode(PADAPTER padapter, u8 ps_mode, u8 smart_ps, u8 bcn_ant_mode)
{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
#ifdef CONFIG_P2P
struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
#endif //CONFIG_P2P
@@ -562,6 +612,26 @@ _func_enter_;
pwrpriv->pwr_mode = ps_mode;
rtw_set_rpwm(padapter, PS_STATE_S4);
+#ifdef CONFIG_WOWLAN
+ if (pwrpriv->wowlan_mode == _TRUE)
+ {
+ u32 start_time, delay_ms;
+ u8 val8;
+ delay_ms = 20;
+ start_time = rtw_get_current_time();
+ do {
+ val8 = rtw_read8(padapter, 0x90);
+ if (!(val8 & BIT(0))) break;
+ if (rtw_get_passing_time_ms(start_time) > delay_ms)
+ {
+ DBG_871X("%s: Wait for FW 32K leave more than %u ms!!!\n", __FUNCTION__, delay_ms);
+ break;
+ }
+ rtw_usleep_os(100);
+ } while (1);
+ pwrpriv->cpwm = PS_STATE_S4;
+ }
+#endif
rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode));
pwrpriv->bFwCurrentInPSMode = _FALSE;
}
@@ -610,8 +680,9 @@ _func_enter_;
#endif //CONFIG_P2P_PS
#ifdef CONFIG_LPS_LCLK
- if (pwrpriv->alives == 0)
- rtw_set_rpwm(padapter, PS_STATE_S0);
+ DBG_871X("%s: alives: %d\n", __FUNCTION__, pwrpriv->alives);
+ if (pwrpriv->alives == 0)
+ rtw_set_rpwm(padapter, PS_STATE_S0);
#else
rtw_set_rpwm(padapter, PS_STATE_S2);
#endif
@@ -670,7 +741,7 @@ s32 LPS_RF_ON_check(PADAPTER padapter, u32 delay_ms)
//
void LPS_Enter(PADAPTER padapter)
{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
_adapter *buddy = padapter->pbuddy_adapter;
@@ -721,7 +792,7 @@ _func_enter_;
pwrpriv->bpower_saving = _TRUE;
DBG_871X("%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
@@ -741,7 +812,7 @@ void LPS_Leave(PADAPTER padapter)
{
#define LPS_LEAVE_TIMEOUT_MS 100
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
u32 start_time;
u8 bAwake = _FALSE;
@@ -758,7 +829,7 @@ _func_enter_;
{
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);
@@ -805,7 +876,7 @@ _func_enter_;
}
else
{
- if(Adapter->pwrctrlpriv.rf_pwrstate== rf_off)
+ if(adapter_to_pwrctl(Adapter)->rf_pwrstate== rf_off)
{
#ifdef CONFIG_AUTOSUSPEND
if(Adapter->registrypriv.usbss_enable)
@@ -844,7 +915,7 @@ void LPS_Leave_check(
_func_enter_;
- pwrpriv = &padapter->pwrctrlpriv;
+ pwrpriv = adapter_to_pwrctl(padapter);
bReady = _FALSE;
start_time = rtw_get_current_time();
@@ -897,7 +968,7 @@ void cpwm_int_hdl(
_func_enter_;
- pwrpriv = &padapter->pwrctrlpriv;
+ pwrpriv = adapter_to_pwrctl(padapter);
#if 0
if (pwrpriv->cpwm_tog == (preportpwrstate->state & PS_TOGGLE)) {
RT_TRACE(_module_rtl871x_pwrctrl_c_, _drv_err_,
@@ -942,7 +1013,8 @@ _func_exit_;
static void cpwm_event_callback(struct work_struct *work)
{
struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, cpwm_event);
- _adapter *adapter = container_of(pwrpriv, _adapter, pwrctrlpriv);
+ struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
+ _adapter *adapter = dvobj->if1;
struct reportpwrstate_parm report;
//DBG_871X("%s\n",__FUNCTION__);
@@ -955,11 +1027,13 @@ static void cpwm_event_callback(struct work_struct *work)
static void rpwmtimeout_workitem_callback(struct work_struct *work)
{
PADAPTER padapter;
+ struct dvobj_priv *dvobj;
struct pwrctrl_priv *pwrpriv;
pwrpriv = container_of(work, struct pwrctrl_priv, rpwmtimeoutwi);
- padapter = container_of(pwrpriv, _adapter, pwrctrlpriv);
+ dvobj = pwrctl_to_dvobj(pwrpriv);
+ padapter = dvobj->if1;
// DBG_871X("+%s: rpwm=0x%02X cpwm=0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
_enter_pwrlock(&pwrpriv->lock);
@@ -1010,7 +1084,7 @@ static void pwr_rpwm_timeout_handler(void *FunctionContext)
padapter = (PADAPTER)FunctionContext;
- pwrpriv = &padapter->pwrctrlpriv;
+ pwrpriv = adapter_to_pwrctl(padapter);
// DBG_871X("+%s: rpwm=0x%02X cpwm=0x%02X\n", __func__, pwrpriv->rpwm, pwrpriv->cpwm);
if ((pwrpriv->rpwm == pwrpriv->cpwm) || (pwrpriv->cpwm >= PS_STATE_S2))
@@ -1055,9 +1129,9 @@ s32 rtw_register_tx_alive(PADAPTER padapter)
_func_enter_;
res = _SUCCESS;
- pwrctrl = &padapter->pwrctrlpriv;
+ pwrctrl = adapter_to_pwrctl(padapter);
#ifdef CONFIG_BT_COEXIST
- if (_TRUE == padapter->pwrctrlpriv.btcoex_rfon)
+ if (_TRUE == adapter_to_pwrctl(padapter)->btcoex_rfon)
pslv = PS_STATE_S3;
else
#endif
@@ -1086,6 +1160,14 @@ _func_enter_;
_exit_pwrlock(&pwrctrl->lock);
+#ifdef CONFIG_DETECT_CPWM_BY_POLLING
+ if (_FAIL == res)
+ {
+ if (pwrctrl->cpwm >= PS_STATE_S2)
+ res = _SUCCESS;
+ }
+#endif // CONFIG_DETECT_CPWM_BY_POLLING
+
_func_exit_;
return res;
@@ -1113,9 +1195,9 @@ s32 rtw_register_cmd_alive(PADAPTER padapter)
_func_enter_;
res = _SUCCESS;
- pwrctrl = &padapter->pwrctrlpriv;
+ pwrctrl = adapter_to_pwrctl(padapter);
#ifdef CONFIG_BT_COEXIST
- if (_TRUE == padapter->pwrctrlpriv.btcoex_rfon)
+ if (_TRUE == adapter_to_pwrctl(padapter)->btcoex_rfon)
pslv = PS_STATE_S3;
else
#endif
@@ -1144,6 +1226,14 @@ _func_enter_;
_exit_pwrlock(&pwrctrl->lock);
+#ifdef CONFIG_DETECT_CPWM_BY_POLLING
+ if (_FAIL == res)
+ {
+ if (pwrctrl->cpwm >= PS_STATE_S2)
+ res = _SUCCESS;
+ }
+#endif // CONFIG_DETECT_CPWM_BY_POLLING
+
_func_exit_;
return res;
@@ -1164,7 +1254,7 @@ s32 rtw_register_rx_alive(PADAPTER padapter)
_func_enter_;
- pwrctrl = &padapter->pwrctrlpriv;
+ pwrctrl = adapter_to_pwrctl(padapter);
_enter_pwrlock(&pwrctrl->lock);
@@ -1195,7 +1285,7 @@ s32 rtw_register_evt_alive(PADAPTER padapter)
_func_enter_;
- pwrctrl = &padapter->pwrctrlpriv;
+ pwrctrl = adapter_to_pwrctl(padapter);
_enter_pwrlock(&pwrctrl->lock);
@@ -1224,7 +1314,7 @@ void rtw_unregister_tx_alive(PADAPTER padapter)
_func_enter_;
- pwrctrl = &padapter->pwrctrlpriv;
+ pwrctrl = adapter_to_pwrctl(padapter);
_enter_pwrlock(&pwrctrl->lock);
@@ -1262,7 +1352,7 @@ void rtw_unregister_cmd_alive(PADAPTER padapter)
_func_enter_;
- pwrctrl = &padapter->pwrctrlpriv;
+ pwrctrl = adapter_to_pwrctl(padapter);
_enter_pwrlock(&pwrctrl->lock);
@@ -1296,7 +1386,7 @@ void rtw_unregister_rx_alive(PADAPTER padapter)
_func_enter_;
- pwrctrl = &padapter->pwrctrlpriv;
+ pwrctrl = adapter_to_pwrctl(padapter);
_enter_pwrlock(&pwrctrl->lock);
@@ -1317,7 +1407,7 @@ void rtw_unregister_evt_alive(PADAPTER padapter)
_func_enter_;
- pwrctrl = &padapter->pwrctrlpriv;
+ pwrctrl = adapter_to_pwrctl(padapter);
unregister_task_alive(pwrctrl, EVT_ALIVE);
@@ -1337,7 +1427,12 @@ static void resume_workitem_callback(struct work_struct *work);
void rtw_init_pwrctrl_priv(PADAPTER padapter)
{
- struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
+
+#if defined(CONFIG_CONCURRENT_MODE)
+ if (padapter->adapter_type != PRIMARY_ADAPTER)
+ return;
+#endif
_func_enter_;
@@ -1421,7 +1516,12 @@ _func_exit_;
void rtw_free_pwrctrl_priv(PADAPTER adapter)
{
- struct pwrctrl_priv *pwrctrlpriv = &adapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(adapter);
+
+#if defined(CONFIG_CONCURRENT_MODE)
+ if (adapter->adapter_type != PRIMARY_ADAPTER)
+ return;
+#endif
_func_enter_;
@@ -1452,7 +1552,8 @@ extern int rtw_resume_process(_adapter *padapter);
static void resume_workitem_callback(struct work_struct *work)
{
struct pwrctrl_priv *pwrpriv = container_of(work, struct pwrctrl_priv, resume_work);
- _adapter *adapter = container_of(pwrpriv, _adapter, pwrctrlpriv);
+ struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
+ _adapter *adapter = dvobj->if1;
DBG_871X("%s\n",__FUNCTION__);
@@ -1507,7 +1608,8 @@ static void rtw_early_suspend(struct early_suspend *h)
static void rtw_late_resume(struct early_suspend *h)
{
struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend);
- _adapter *adapter = container_of(pwrpriv, _adapter, pwrctrlpriv);
+ struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
+ _adapter *adapter = dvobj->if1;
DBG_871X("%s\n",__FUNCTION__);
if(pwrpriv->do_late_resume) {
@@ -1527,8 +1629,6 @@ void rtw_register_early_suspend(struct pwrctrl_priv *pwrpriv)
pwrpriv->early_suspend.suspend = rtw_early_suspend;
pwrpriv->early_suspend.resume = rtw_late_resume;
register_early_suspend(&pwrpriv->early_suspend);
-
-
}
void rtw_unregister_early_suspend(struct pwrctrl_priv *pwrpriv)
@@ -1560,7 +1660,8 @@ static void rtw_early_suspend(android_early_suspend_t *h)
static void rtw_late_resume(android_early_suspend_t *h)
{
struct pwrctrl_priv *pwrpriv = container_of(h, struct pwrctrl_priv, early_suspend);
- _adapter *adapter = container_of(pwrpriv, _adapter, pwrctrlpriv);
+ struct dvobj_priv *dvobj = pwrctl_to_dvobj(pwrpriv);
+ _adapter *adapter = dvobj->if1;
DBG_871X("%s\n",__FUNCTION__);
if(pwrpriv->do_late_resume) {
@@ -1607,7 +1708,7 @@ u8 rtw_interface_ps_func(_adapter *padapter,HAL_INTF_PS_FUNC efunc_id,u8* val)
inline void rtw_set_ips_deny(_adapter *padapter, u32 ms)
{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
pwrpriv->ips_deny_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
}
@@ -1620,7 +1721,7 @@ inline void rtw_set_ips_deny(_adapter *padapter, u32 ms)
int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller)
{
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
int ret = _SUCCESS;
u32 start = rtw_get_current_time();
@@ -1631,7 +1732,6 @@ int _rtw_pwr_wakeup(_adapter *padapter, u32 ips_deffer_ms, const char *caller)
if ((padapter->isprimary == _FALSE) && padapter->pbuddy_adapter){
padapter = padapter->pbuddy_adapter;
- pwrpriv = &padapter->pwrctrlpriv;
pmlmepriv = &padapter->mlmepriv;
}
#endif
@@ -1774,7 +1874,7 @@ exit:
int rtw_pm_set_lps(_adapter *padapter, u8 mode)
{
int ret = 0;
- struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
if ( mode < PS_MODE_NUM )
{
@@ -1802,7 +1902,7 @@ int rtw_pm_set_lps(_adapter *padapter, u8 mode)
int rtw_pm_set_ips(_adapter *padapter, u8 mode)
{
- struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv;
+ struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
if( mode == IPS_NORMAL || mode == IPS_LEVEL_2 ) {
rtw_ips_mode_req(pwrctrlpriv, mode);
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_recv.c b/drivers/net/wireless/rtl8723as/core/rtw_recv.c
index e7f8708c2028..05a514ea6926 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_recv.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_recv.c
@@ -31,6 +31,10 @@
#include <usb_ops.h>
#endif
+#ifdef CONFIG_BT_COEXIST
+#include <rtl8723a_hal.h>
+#endif
+
#if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
#error "Shall be Linux or Windows, but not both!\n"
@@ -279,7 +283,7 @@ _func_enter_;
#ifdef CONFIG_BSD_RX_USE_MBUF
m_freem(precvframe->u.hdr.pkt);
#else // CONFIG_BSD_RX_USE_MBUF
- dev_kfree_skb_any(precvframe->u.hdr.pkt);//free skb by driver
+ rtw_skb_free(precvframe->u.hdr.pkt);//free skb by driver
#endif // CONFIG_BSD_RX_USE_MBUF
precvframe->u.hdr.pkt = NULL;
}
@@ -737,6 +741,9 @@ _func_enter_;
return_packet = NULL;
}
+ else{
+ prxattrib->bdecrypted = _TRUE;
+ }
//recvframe_chkmic(adapter, precv_frame); //move to recvframme_defrag function
_func_exit_;
@@ -761,7 +768,6 @@ union recv_frame * portctrl(_adapter *adapter,union recv_frame * precv_frame)
_func_enter_;
pstapriv = &adapter->stapriv;
- psta = rtw_get_stainfo(pstapriv, psta_addr);
auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
@@ -772,6 +778,8 @@ _func_enter_;
prtnframe = NULL;
+ 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)
@@ -1739,7 +1747,7 @@ union recv_frame* recvframe_chk_defrag(PADAPTER padapter, union recv_frame *prec
sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame);
sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame)
{
- //struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ //struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("+validate_recv_mgnt_frame\n"));
@@ -2012,6 +2020,127 @@ _func_exit_;
return ret;
}
+#ifdef CONFIG_IEEE80211W
+static sint validate_80211w_mgmt(_adapter *adapter, union recv_frame *precv_frame)
+{
+ struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
+ struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ u8 type;
+ u8 subtype;
+
+ type = GetFrameType(ptr);
+ subtype = GetFrameSubType(ptr); //bit(7)~bit(2)
+
+ //only support station mode
+ if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED)
+ && adapter->securitypriv.binstallBIPkey == _TRUE)
+ {
+ //unicast management frame decrypt
+ if(pattrib->privacy && !(IS_MCAST(GetAddr1Ptr(ptr))) &&
+ (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || subtype == WIFI_ACTION))
+ {
+ u8 *ppp, *mgmt_DATA;
+ u32 data_len=0;
+ ppp = GetAddr2Ptr(ptr);
+
+ pattrib->bdecrypted = 0;
+ pattrib->encrypt = _AES_;
+ pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+ //set iv and icv length
+ SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
+ _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
+ _rtw_memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
+ //actual management data frame body
+ data_len = pattrib->pkt_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
+ mgmt_DATA = rtw_zmalloc(data_len);
+ if(mgmt_DATA == NULL)
+ {
+ DBG_871X("%s mgmt allocate fail !!!!!!!!!\n", __FUNCTION__);
+ goto validate_80211w_fail;
+ }
+ /*//dump the packet content before decrypt
+ {
+ int pp;
+ printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
+ for(pp=0;pp< pattrib->pkt_len; pp++)
+ printk(" %02x ", ptr[pp]);
+ printk("\n");
+ }*/
+
+ precv_frame = decryptor(adapter, precv_frame);
+ //save actual management data frame body
+ _rtw_memcpy(mgmt_DATA, ptr+pattrib->hdrlen+pattrib->iv_len, data_len);
+ //overwrite the iv field
+ _rtw_memcpy(ptr+pattrib->hdrlen, mgmt_DATA, data_len);
+ //remove the iv and icv length
+ pattrib->pkt_len = pattrib->pkt_len - pattrib->iv_len - pattrib->icv_len;
+ rtw_mfree(mgmt_DATA, data_len);
+ /*//print packet content after decryption
+ {
+ int pp;
+ printk("after decryption pattrib->pktlen = %d @@=>", pattrib->pkt_len);
+ for(pp=0;pp< pattrib->pkt_len; pp++)
+ printk(" %02x ", ptr[pp]);
+ printk("\n");
+ }*/
+ if(!precv_frame)
+ {
+ DBG_871X("%s mgmt descrypt fail !!!!!!!!!\n", __FUNCTION__);
+ goto validate_80211w_fail;
+ }
+ }
+ else if(IS_MCAST(GetAddr1Ptr(ptr)) &&
+ (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC))
+ {
+ sint BIP_ret = _SUCCESS;
+ //verify BIP MME IE of broadcast/multicast de-auth/disassoc packet
+ BIP_ret = rtw_BIP_verify(adapter, (u8 * )precv_frame);
+ if(BIP_ret == _FAIL)
+ {
+ //DBG_871X("802.11w BIP verify fail\n");
+ goto validate_80211w_fail;
+ }
+ else if(BIP_ret == RTW_RX_HANDLED)
+ {
+ //DBG_871X("802.11w recv none protected packet\n");
+ //issue sa query request
+ issue_action_SA_Query(adapter, NULL, 0, 0);
+ goto validate_80211w_fail;
+ }
+ }//802.11w protect
+ else
+ {
+ if(subtype == WIFI_ACTION)
+ {
+ //according 802.11-2012 standard, these five types are not robust types
+ if( ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_PUBLIC &&
+ ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_HT &&
+ ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_UNPROTECTED_WNM &&
+ ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_SELF_PROTECTED &&
+ ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_P2P)
+ {
+ DBG_871X("action frame category=%d should robust\n", ptr[WLAN_HDR_A3_LEN]);
+ goto validate_80211w_fail;
+ }
+ }
+ else if(subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC)
+ {
+ DBG_871X("802.11w recv none protected packet\n");
+ //issue sa query request
+ issue_action_SA_Query(adapter, NULL, 0, 0);
+ goto validate_80211w_fail;
+ }
+ }
+ }
+ return _SUCCESS;
+
+validate_80211w_fail:
+ return _FAIL;
+
+}
+#endif //CONFIG_IEEE80211W
+
sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame);
sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame)
{
@@ -2022,7 +2151,6 @@ sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame)
u8 type;
u8 subtype;
sint retval = _SUCCESS;
-
struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
u8 *ptr = precv_frame->u.hdr.rx_data;
@@ -2138,6 +2266,14 @@ _func_enter_;
switch (type)
{
case WIFI_MGT_TYPE: //mgnt
+#ifdef CONFIG_IEEE80211W
+ if(validate_80211w_mgmt(adapter, precv_frame) == _FAIL)
+ {
+ retval = _FAIL;
+ break;
+ }
+#endif //CONFIG_IEEE80211W
+
retval = validate_recv_mgnt_frame(adapter, precv_frame);
if (retval == _FAIL)
{
@@ -2454,12 +2590,8 @@ static void recvframe_expand_pkt(
//3 1. alloc new skb
// prepare extra space for 4 bytes alignment
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
- ppkt = dev_alloc_skb(alloc_sz);
- if (ppkt) ppkt->dev = padapter->pnetdev;
-#else
- ppkt = netdev_alloc_skb(padapter->pnetdev, alloc_sz);
-#endif
+ ppkt = rtw_skb_alloc(alloc_sz);
+
if (!ppkt) return; // no way to expand
//3 2. Prepare new skb to replace & release old skb
@@ -2471,7 +2603,7 @@ static void recvframe_expand_pkt(
// copy data to new pkt
_rtw_memcpy(skb_put(ppkt, pfhdr->len), pfhdr->rx_data, pfhdr->len);
- dev_kfree_skb_any(pfhdr->pkt);
+ rtw_skb_free(pfhdr->pkt);
// attach new pkt to recvframe
pfhdr->pkt = ppkt;
@@ -2770,7 +2902,7 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe)
/* Allocate new skb for releasing to upper layer */
#ifdef CONFIG_SKB_COPY
- sub_skb = dev_alloc_skb(nSubframe_Length + 12);
+ sub_skb = rtw_skb_alloc(nSubframe_Length + 12);
if(sub_skb)
{
skb_reserve(sub_skb, 12);
@@ -2780,7 +2912,7 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe)
else
#endif // CONFIG_SKB_COPY
{
- sub_skb = skb_clone(prframe->u.hdr.pkt, GFP_ATOMIC);
+ sub_skb = rtw_skb_clone(prframe->u.hdr.pkt);
if(sub_skb)
{
sub_skb->data = pdata;
@@ -2789,7 +2921,7 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe)
}
else
{
- DBG_871X("skb_clone() Fail!!! , nr_subframes = %d\n",nr_subframes);
+ DBG_871X("rtw_skb_clone() Fail!!! , nr_subframes = %d\n",nr_subframes);
break;
}
}
@@ -2890,7 +3022,7 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe)
#if 1
// bypass this frame to upper layer!!
#else
- dev_kfree_skb_any(sub_skb);
+ rtw_skb_free(sub_skb);
continue;
#endif
}
@@ -2910,7 +3042,7 @@ int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe)
sub_skb->ip_summed = CHECKSUM_NONE;
#endif //CONFIG_TCP_CSUM_OFFLOAD_RX
- netif_rx(sub_skb);
+ rtw_netif_rx(padapter->pnetdev, sub_skb);
}
#else //PLATFORM_FREEBSD
@@ -3151,11 +3283,8 @@ exit:
_rtw_init_listhead(&pnrframe_new->u.hdr.list);
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
- pskb_copy = dev_alloc_skb(copy_len+64);
- #else
- pskb_copy = netdev_alloc_skb(padapter->pnetdev, copy_len + 64);
- #endif
+ pskb_copy = rtw_skb_alloc(copy_len+64);
+
if(pskb_copy==NULL)
{
DBG_871X("amsdu_to_msdu:can not all(ocate memory for skb copy\n");
@@ -3230,7 +3359,7 @@ exit:
#ifdef PLATFORM_LINUX
if(pskb)
{
- pnrframe_new->u.hdr.pkt = skb_clone(pskb, GFP_ATOMIC);
+ pnrframe_new->u.hdr.pkt = rtw_skb_clone(pskb);
}
#endif //PLATFORM_LINUX
@@ -3597,8 +3726,9 @@ int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe)
//s1.
wlanhdr_to_ethhdr(prframe);
- if ((pattrib->qos!=1) /*|| pattrib->priority!=0 || IS_MCAST(pattrib->ra)*/
- || (pattrib->eth_type==0x0806) || (pattrib->ack_policy!=0))
+ //if ((pattrib->qos!=1) /*|| pattrib->priority!=0 || IS_MCAST(pattrib->ra)*/
+ // || (pattrib->eth_type==0x0806) || (pattrib->ack_policy!=0))
+ if (pattrib->qos!=1)
{
if ((padapter->bDriverStopped == _FALSE) &&
(padapter->bSurpriseRemoved == _FALSE))
@@ -3863,7 +3993,8 @@ int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe)
struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib;
struct recv_priv *precvpriv = &padapter->recvpriv;
_queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
-
+
+
#ifdef CONFIG_MP_INCLUDED
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
#endif //CONFIG_MP_INCLUDED
@@ -3871,20 +4002,20 @@ int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe)
#ifdef CONFIG_MP_INCLUDED
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 (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;
}
- }
}
#endif
@@ -4189,41 +4320,65 @@ void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS){
recvpriv->signal_qual_data.update_req = 1;
}
- //update value of signal_strength, rssi, signal_qual
- if(check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == _FALSE) {
- tmp_s = (avg_signal_strength+(_alpha-1)*recvpriv->signal_strength);
- if(tmp_s %_alpha)
- tmp_s = tmp_s/_alpha + 1;
- else
- tmp_s = tmp_s/_alpha;
- if(tmp_s>100)
- tmp_s = 100;
+ if (num_signal_strength == 0) {
+ if (rtw_get_on_cur_ch_time(adapter) == 0
+ || rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) < 2 * adapter->mlmeextpriv.mlmext_info.bcn_interval
+#ifdef CONFIG_BT_COEXIST
+ || ((BTDM_IsBtDisabled(adapter) == _FALSE) && (BT_IsBtInquiryPage(adapter) == _TRUE))
+#endif
+ ) {
+ goto set_timer;
+ }
+ }
- tmp_q = (avg_signal_qual+(_alpha-1)*recvpriv->signal_qual);
- if(tmp_q %_alpha)
- tmp_q = tmp_q/_alpha + 1;
- else
- tmp_q = tmp_q/_alpha;
- if(tmp_q>100)
- tmp_q = 100;
-
- recvpriv->signal_strength = tmp_s;
- recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
- recvpriv->signal_qual = tmp_q;
-
- #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
- DBG_871X("%s signal_strength:%3u, rssi:%3d, signal_qual:%3u"
- ", num_signal_strength:%u, num_signal_qual:%u"
- "\n"
- , __FUNCTION__
- , recvpriv->signal_strength
- , recvpriv->rssi
- , recvpriv->signal_qual
- , num_signal_strength, num_signal_qual
- );
- #endif
+ if(check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE
+ || check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _FALSE
+ ) {
+ goto set_timer;
}
+
+ #ifdef CONFIG_CONCURRENT_MODE
+ if (check_buddy_fwstate(adapter, _FW_UNDER_SURVEY) == _TRUE)
+ goto set_timer;
+ #endif
+
+ //update value of signal_strength, rssi, signal_qual
+ tmp_s = (avg_signal_strength+(_alpha-1)*recvpriv->signal_strength);
+ if(tmp_s %_alpha)
+ tmp_s = tmp_s/_alpha + 1;
+ else
+ tmp_s = tmp_s/_alpha;
+ if(tmp_s>100)
+ tmp_s = 100;
+
+ tmp_q = (avg_signal_qual+(_alpha-1)*recvpriv->signal_qual);
+ if(tmp_q %_alpha)
+ tmp_q = tmp_q/_alpha + 1;
+ else
+ tmp_q = tmp_q/_alpha;
+ if(tmp_q>100)
+ tmp_q = 100;
+
+ recvpriv->signal_strength = tmp_s;
+ recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
+ recvpriv->signal_qual = tmp_q;
+
+ #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
+ DBG_871X(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
+ ", num_signal_strength:%u, num_signal_qual:%u"
+ ", on_cur_ch_ms:%d"
+ "\n"
+ , FUNC_ADPT_ARG(adapter)
+ , recvpriv->signal_strength
+ , recvpriv->rssi
+ , recvpriv->signal_qual
+ , num_signal_strength, num_signal_qual
+ , rtw_get_on_cur_ch_time(adapter) ? rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) : 0
+ );
+ #endif
}
+
+set_timer:
rtw_set_signal_stat_timer(recvpriv);
}
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_security.c b/drivers/net/wireless/rtl8723as/core/rtw_security.c
index 4a3b20a9caed..68dfafb18de5 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_security.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_security.c
@@ -212,7 +212,7 @@ _func_enter_;
length=pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len- pattrib->icv_len;
- *((unsigned long *)crc)=cpu_to_le32(getcrc32(payload,length));
+ *((u32 *)crc)=cpu_to_le32(getcrc32(payload,length));
arcfour_init(&mycontext, wepkey,3+keylength);
arcfour_encrypt(&mycontext, payload, payload, length);
@@ -222,7 +222,7 @@ _func_enter_;
else
{
length=pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-pattrib->icv_len ;
- *((unsigned long *)crc)=cpu_to_le32(getcrc32(payload,length));
+ *((u32 *)crc)=cpu_to_le32(getcrc32(payload,length));
arcfour_init(&mycontext, wepkey,3+keylength);
arcfour_encrypt(&mycontext, payload, payload, length);
arcfour_encrypt(&mycontext, payload+length, crc, 4);
@@ -275,7 +275,7 @@ _func_enter_;
arcfour_encrypt(&mycontext, payload, payload, length);
//calculate icv and compare the icv
- *((unsigned long *)crc)=le32_to_cpu(getcrc32(payload,length-4));
+ *((u32 *)crc)=le32_to_cpu(getcrc32(payload,length-4));
if(crc[3]!=payload[length-1] || crc[2]!=payload[length-2] || crc[1]!=payload[length-3] || crc[0]!=payload[length-4])
{
@@ -801,12 +801,42 @@ _func_enter_;
if(IS_MCAST(prxattrib->ra))
{
+ static u32 start = 0;
+ static u32 no_gkey_bc_cnt = 0;
+ static u32 no_gkey_mc_cnt = 0;
+
if(psecuritypriv->binstallGrpkey==_FALSE)
{
- res=_FAIL;
- DBG_8192C("%s:rx bc/mc packets,but didn't install group key!!!!!!!!!!\n",__FUNCTION__);
+ res=_FAIL;
+
+ if (start == 0)
+ start = rtw_get_current_time();
+
+ if (is_broadcast_mac_addr(prxattrib->ra))
+ no_gkey_bc_cnt++;
+ else
+ no_gkey_mc_cnt++;
+
+ if (rtw_get_passing_time_ms(start) > 1000) {
+ if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
+ DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
+ FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
+ }
+ start = rtw_get_current_time();
+ no_gkey_bc_cnt = 0;
+ no_gkey_mc_cnt = 0;
+ }
goto exit;
}
+
+ if (no_gkey_bc_cnt || no_gkey_mc_cnt) {
+ DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" gkey installed. no_gkey_bc_cnt:%u, no_gkey_mc_cnt:%u\n",
+ FUNC_ADPT_ARG(padapter), no_gkey_bc_cnt, no_gkey_mc_cnt);
+ }
+ start = 0;
+ no_gkey_bc_cnt = 0;
+ no_gkey_mc_cnt = 0;
+
//DBG_871X("rx bc/mc packets, to perform sw rtw_tkip_decrypt\n");
//prwskey = psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey;
prwskey = psecuritypriv->dot118021XGrpKey[prxattrib->key_index].skey;
@@ -916,11 +946,13 @@ static void construct_mic_iv(
sint a4_exists,
u8 *mpdu,
uint payload_length,
- u8 * pn_vector);
+ u8 * pn_vector,
+ uint frtype);// add for CONFIG_IEEE80211W, none 11w also can use
static void construct_mic_header1(
u8 *mic_header1,
sint header_length,
- u8 *mpdu);
+ u8 *mpdu,
+ uint frtype);// add for CONFIG_IEEE80211W, none 11w also can use
static void construct_mic_header2(
u8 *mic_header2,
u8 *mpdu,
@@ -932,7 +964,8 @@ static void construct_ctr_preload(
sint qc_exists,
u8 *mpdu,
u8 *pn_vector,
- sint c);
+ sint c,
+ uint frtype);// add for CONFIG_IEEE80211W, none 11w also can use
static void xor_128(u8 *a, u8 *b, u8 *out);
static void xor_32(u8 *a, u8 *b, u8 *out);
static u8 sbox(u8 a);
@@ -1152,6 +1185,8 @@ _func_exit_;
/************************************************/
/* construct_mic_iv() */
/* Builds the MIC IV from header fields and PN */
+/* Baron think the function is construct CCM */
+/* nonce */
/************************************************/
static void construct_mic_iv(
u8 *mic_iv,
@@ -1159,7 +1194,8 @@ static void construct_mic_iv(
sint a4_exists,
u8 *mpdu,
uint payload_length,
- u8 *pn_vector
+ u8 *pn_vector,
+ uint frtype// add for CONFIG_IEEE80211W, none 11w also can use
)
{
sint i;
@@ -1168,6 +1204,11 @@ _func_enter_;
if (qc_exists && a4_exists) mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
if (qc_exists && !a4_exists) mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
if (!qc_exists) mic_iv[1] = 0x00;
+#ifdef CONFIG_IEEE80211W
+ //802.11w management frame should set management bit(4)
+ if(frtype == WIFI_MGT_TYPE)
+ mic_iv[1] |= BIT(4);
+#endif //CONFIG_IEEE80211W
for (i = 2; i < 8; i++)
mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
#ifdef CONSISTENT_PN_ORDER
@@ -1187,17 +1228,26 @@ _func_exit_;
/* construct_mic_header1() */
/* Builds the first MIC header block from */
/* header fields. */
+/* Build AAD SC,A1,A2 */
/************************************************/
static void construct_mic_header1(
u8 *mic_header1,
sint header_length,
- u8 *mpdu
+ u8 *mpdu,
+ uint frtype// add for CONFIG_IEEE80211W, none 11w also can use
)
{
_func_enter_;
mic_header1[0] = (u8)((header_length - 2) / 256);
mic_header1[1] = (u8)((header_length - 2) % 256);
- mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
+#ifdef CONFIG_IEEE80211W
+ //802.11w management frame don't AND subtype bits 4,5,6 of frame control field
+ if(frtype == WIFI_MGT_TYPE)
+ mic_header1[2] = mpdu[0]; /* Mute CF poll & CF ack bits */
+ else
+#endif //CONFIG_IEEE80211W
+ mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
+
mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
mic_header1[4] = mpdu[4]; /* A1 */
mic_header1[5] = mpdu[5];
@@ -1271,6 +1321,8 @@ _func_exit_;
/* construct_mic_header2() */
/* Builds the last MIC header block from */
/* header fields. */
+/* Baron think the function is construct CCM */
+/* nonce */
/************************************************/
static void construct_ctr_preload(
u8 *ctr_preload,
@@ -1278,20 +1330,25 @@ static void construct_ctr_preload(
sint qc_exists,
u8 *mpdu,
u8 *pn_vector,
- sint c
+ sint c,
+ uint frtype // add for CONFIG_IEEE80211W, none 11w also can use
)
{
sint i = 0;
_func_enter_;
for (i=0; i<16; i++) ctr_preload[i] = 0x00;
i = 0;
-
+
ctr_preload[0] = 0x01; /* flag */
if (qc_exists && a4_exists)
ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
if (qc_exists && !a4_exists)
ctr_preload[1] = mpdu[24] & 0x0f;
-
+#ifdef CONFIG_IEEE80211W
+ //802.11w management frame should set management bit(4)
+ if(frtype == WIFI_MGT_TYPE)
+ ctr_preload[1] |= BIT(4);
+#endif //CONFIG_IEEE80211W
for (i = 2; i < 8; i++)
ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
#ifdef CONSISTENT_PN_ORDER
@@ -1363,9 +1420,9 @@ _func_enter_;
a4_exists = 1;
if (
- (frtype == WIFI_DATA_CFACK) ||
- (frtype == WIFI_DATA_CFPOLL)||
- (frtype == WIFI_DATA_CFACKPOLL))
+ ((frtype|frsubtype) == WIFI_DATA_CFACK) ||
+ ((frtype|frsubtype) == WIFI_DATA_CFPOLL)||
+ ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL))
{
qc_exists = 1;
if(hdrlen != WLAN_HDR_A3_QOS_LEN){
@@ -1373,11 +1430,12 @@ _func_enter_;
hdrlen += 2;
}
}
- else if (
- (frsubtype == 0x08) ||
+ // add for CONFIG_IEEE80211W, none 11w also can use
+ else if ((frtype == WIFI_DATA) &&
+ ((frsubtype == 0x08) ||
(frsubtype == 0x09)||
(frsubtype == 0x0a)||
- (frsubtype == 0x0b))
+ (frsubtype == 0x0b)))
{
if(hdrlen != WLAN_HDR_A3_QOS_LEN){
@@ -1401,13 +1459,15 @@ _func_enter_;
a4_exists,
pframe, //message,
plen,
- pn_vector
+ pn_vector,
+ frtype // add for CONFIG_IEEE80211W, none 11w also can use
);
construct_mic_header1(
mic_header1,
hdrlen,
- pframe //message
+ pframe, //message
+ frtype // add for CONFIG_IEEE80211W, none 11w also can use
);
construct_mic_header2(
mic_header2,
@@ -1466,7 +1526,8 @@ _func_enter_;
qc_exists,
pframe, //message,
pn_vector,
- i+1);
+ i+1,
+ frtype); // add for CONFIG_IEEE80211W, none 11w also can use
aes128k128d(key, ctr_preload, aes_out);
bitwise_xor(aes_out, &pframe[payload_index], chain_buffer);//bitwise_xor(aes_out, &message[payload_index], chain_buffer);
for (j=0; j<16;j++) pframe[payload_index++] = chain_buffer[j];//for (j=0; j<16;j++) message[payload_index++] = chain_buffer[j];
@@ -1480,7 +1541,8 @@ _func_enter_;
qc_exists,
pframe, //message,
pn_vector,
- num_blocks+1);
+ num_blocks+1,
+ frtype); // add for CONFIG_IEEE80211W, none 11w also can use
for (j = 0; j < 16; j++) padded_buffer[j] = 0x00;
for (j = 0; j < payload_remainder; j++)
@@ -1499,7 +1561,8 @@ _func_enter_;
qc_exists,
pframe, //message,
pn_vector,
- 0);
+ 0,
+ frtype); // add for CONFIG_IEEE80211W, none 11w also can use
for (j = 0; j < 16; j++) padded_buffer[j] = 0x00;
for (j = 0; j < 8; j++)
@@ -1566,7 +1629,7 @@ _func_enter_;
{
DBG_871X("%s, call rtw_get_stainfo()\n", __func__);
stainfo=rtw_get_stainfo(&padapter->stapriv ,&pattrib->ra[0] );
- }
+ }
if (stainfo!=NULL){
@@ -1671,7 +1734,7 @@ _func_enter_;
//start to decrypt the payload
- num_blocks = (plen-8) / 16; //(plen including llc, payload_length and mic )
+ num_blocks = (plen-8) / 16; //(plen including LLC, payload_length and mic )
payload_remainder = (plen-8) % 16;
@@ -1688,21 +1751,21 @@ _func_enter_;
a4_exists = 1;
if (
- (frtype == WIFI_DATA_CFACK) ||
- (frtype == WIFI_DATA_CFPOLL)||
- (frtype == WIFI_DATA_CFACKPOLL))
+ ((frtype|frsubtype) == WIFI_DATA_CFACK) ||
+ ((frtype|frsubtype) == WIFI_DATA_CFPOLL)||
+ ((frtype|frsubtype) == WIFI_DATA_CFACKPOLL))
{
qc_exists = 1;
if(hdrlen != WLAN_HDR_A3_QOS_LEN){
hdrlen += 2;
}
- }
- else if (
- (frsubtype == 0x08) ||
+ }//only for data packet . add for CONFIG_IEEE80211W, none 11w also can use
+ else if ((frtype == WIFI_DATA) &&
+ ((frsubtype == 0x08) ||
(frsubtype == 0x09)||
(frsubtype == 0x0a)||
- (frsubtype == 0x0b))
+ (frsubtype == 0x0b)))
{
if(hdrlen != WLAN_HDR_A3_QOS_LEN){
@@ -1726,7 +1789,8 @@ _func_enter_;
qc_exists,
pframe,
pn_vector,
- i+1
+ i+1,
+ frtype
);
aes128k128d(key, ctr_preload, aes_out);
@@ -1743,7 +1807,8 @@ _func_enter_;
qc_exists,
pframe,
pn_vector,
- num_blocks+1
+ num_blocks+1,
+ frtype // add for CONFIG_IEEE80211W, none 11w also can use
);
for (j = 0; j < 16; j++) padded_buffer[j] = 0x00;
@@ -1776,13 +1841,15 @@ _func_enter_;
a4_exists,
message,
plen-8,
- pn_vector
+ pn_vector,
+ frtype // add for CONFIG_IEEE80211W, none 11w also can use
);
construct_mic_header1(
mic_header1,
hdrlen,
- message
+ message,
+ frtype // add for CONFIG_IEEE80211W, none 11w also can use
);
construct_mic_header2(
mic_header2,
@@ -1841,7 +1908,8 @@ _func_enter_;
qc_exists,
message,
pn_vector,
- i+1);
+ i+1,
+ frtype); // add for CONFIG_IEEE80211W, none 11w also can use
aes128k128d(key, ctr_preload, aes_out);
bitwise_xor(aes_out, &message[payload_index], chain_buffer);
for (j=0; j<16;j++) message[payload_index++] = chain_buffer[j];
@@ -1855,7 +1923,8 @@ _func_enter_;
qc_exists,
message,
pn_vector,
- num_blocks+1);
+ num_blocks+1,
+ frtype); // add for CONFIG_IEEE80211W, none 11w also can use
for (j = 0; j < 16; j++) padded_buffer[j] = 0x00;
for (j = 0; j < payload_remainder; j++)
@@ -1874,7 +1943,8 @@ _func_enter_;
qc_exists,
message,
pn_vector,
- 0);
+ 0,
+ frtype); // add for CONFIG_IEEE80211W, none 11w also can use
for (j = 0; j < 16; j++) padded_buffer[j] = 0x00;
for (j = 0; j < 8; j++)
@@ -1952,9 +2022,31 @@ _func_enter_;
{
prwskey=&stainfo->dot118021x_UncstKey.skey[0];
}
-
+
length= ((union recv_frame *)precvframe)->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len;
-
+ /*// add for CONFIG_IEEE80211W, debug
+ if(0)
+ printk("@@@@@@@@@@@@@@@@@@ length=%d, prxattrib->hdrlen=%d, prxattrib->pkt_len=%d \n"
+ , length, prxattrib->hdrlen, prxattrib->pkt_len);
+ if(0)
+ {
+ int no;
+ //test print PSK
+ printk("PSK key below:\n");
+ for(no=0;no<16;no++)
+ printk(" %02x ", prwskey[no]);
+ printk("\n");
+ }
+ if(0)
+ {
+ int no;
+ //test print PSK
+ printk("frame:\n");
+ for(no=0;no<prxattrib->pkt_len;no++)
+ printk(" %02x ", pframe[no]);
+ printk("\n");
+ }*/
+
res= aes_decipher(prwskey,prxattrib->hdrlen,pframe, length);
@@ -1969,6 +2061,109 @@ _func_exit_;
exit:
return res;
}
+
+#ifdef CONFIG_IEEE80211W
+u32 rtw_BIP_verify(_adapter *padapter, u8 *precvframe)
+{
+ struct rx_pkt_attrib *pattrib = &((union recv_frame *)precvframe)->u.hdr.attrib;
+ u8 *pframe;
+ u8 *BIP_AAD, *p;
+ u32 res=_FAIL;
+ uint len, ori_len;
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ u8 mic[16];
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ ori_len = pattrib->pkt_len-WLAN_HDR_A3_LEN+BIP_AAD_SIZE;
+ BIP_AAD = rtw_zmalloc(ori_len);
+
+ if(BIP_AAD == NULL)
+ {
+ DBG_871X("BIP AAD allocate fail\n");
+ return _FAIL;
+ }
+ //PKT start
+ pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data;
+ //mapping to wlan header
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ //save the frame body + MME
+ _rtw_memcpy(BIP_AAD+BIP_AAD_SIZE, pframe+WLAN_HDR_A3_LEN, pattrib->pkt_len-WLAN_HDR_A3_LEN);
+ //find MME IE pointer
+ p = rtw_get_ie(BIP_AAD+BIP_AAD_SIZE, _MME_IE_, &len, pattrib->pkt_len-WLAN_HDR_A3_LEN);
+ //Baron
+ if(p)
+ {
+ u16 keyid=0;
+ u64 temp_ipn=0;
+ //save packet number
+ _rtw_memcpy(&temp_ipn, p+4, 6);
+ temp_ipn = le64_to_cpu(temp_ipn);
+ //BIP packet number should bigger than previous BIP packet
+ if(temp_ipn <= pmlmeext->mgnt_80211w_IPN_rx)
+ {
+ DBG_871X("replay BIP packet\n");
+ goto BIP_exit;
+ }
+ //copy key index
+ _rtw_memcpy(&keyid, p+2, 2);
+ keyid = le16_to_cpu(keyid);
+ if(keyid != padapter->securitypriv.dot11wBIPKeyid)
+ {
+ DBG_871X("BIP key index error!\n");
+ goto BIP_exit;
+ }
+ //clear the MIC field of MME to zero
+ _rtw_memset(p+2+len-8, 0, 8);
+
+ //conscruct AAD, copy frame control field
+ _rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2);
+ ClearRetry(BIP_AAD);
+ ClearPwrMgt(BIP_AAD);
+ ClearMData(BIP_AAD);
+ //conscruct AAD, copy address 1 to address 3
+ _rtw_memcpy(BIP_AAD+2, pwlanhdr->addr1, 18);
+
+ if(omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey
+ , BIP_AAD, ori_len, mic))
+ goto BIP_exit;
+
+ /*//management packet content
+ {
+ int pp;
+ DBG_871X("pkt: ");
+ for(pp=0;pp< pattrib->pkt_len; pp++)
+ printk(" %02x ", pframe[pp]);
+ DBG_871X("\n");
+ //BIP AAD + management frame body + MME(MIC is zero)
+ DBG_871X("AAD+PKT: ");
+ for(pp=0;pp< ori_len; pp++)
+ DBG_871X(" %02x ", BIP_AAD[pp]);
+ DBG_871X("\n");
+ //show the MIC result
+ DBG_871X("mic: ");
+ for(pp=0;pp<16; pp++)
+ DBG_871X(" %02x ", mic[pp]);
+ DBG_871X("\n");
+ }
+ */
+ //MIC field should be last 8 bytes of packet (packet without FCS)
+ if(_rtw_memcmp(mic, pframe+pattrib->pkt_len-8, 8))
+ {
+ pmlmeext->mgnt_80211w_IPN_rx = temp_ipn;
+ res=_SUCCESS;
+ }
+ else
+ DBG_871X("BIP MIC error!\n");
+
+ }
+ else
+ res = RTW_RX_HANDLED;
+BIP_exit:
+
+ rtw_mfree(BIP_AAD, ori_len);
+ return res;
+}
+#endif //CONFIG_IEEE80211W
+
#ifndef PLATFORM_FREEBSD
/* compress 512-bits */
static int sha256_compress(struct sha256_state *md, unsigned char *buf)
@@ -2676,8 +2871,8 @@ static int omac1_aes_128_vector(u8 *key, size_t num_elem,
* This is a mode for using block cipher (AES in this case) for authentication.
* OMAC1 was standardized with the name CMAC by NIST in a Special Publication
* (SP) 800-38B.
- */
-static int omac1_aes_128(u8 *key, u8 *data, size_t data_len, u8 *mac)
+ */ //modify for CONFIG_IEEE80211W
+int omac1_aes_128(u8 *key, u8 *data, size_t data_len, u8 *mac)
{
return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
}
@@ -2891,3 +3086,43 @@ _func_exit_;
}
+/* Restore HW wep key setting according to key_mask */
+void rtw_sec_restore_wep_key(_adapter *adapter)
+{
+ struct security_priv* securitypriv=&(adapter->securitypriv);
+ sint keyid;
+
+ if((_WEP40_ == securitypriv->dot11PrivacyAlgrthm) ||(_WEP104_ == securitypriv->dot11PrivacyAlgrthm)) {
+ for(keyid=0;keyid<4;keyid++){
+ if(securitypriv->key_mask & BIT(keyid)){
+ if(keyid == securitypriv->dot11PrivacyKeyIndex)
+ rtw_set_key(adapter,securitypriv, keyid, 1, _TRUE);
+ else
+ rtw_set_key(adapter,securitypriv, keyid, 0, _TRUE);
+ }
+ }
+ }
+}
+
+u8 rtw_handle_tkip_countermeasure(_adapter* adapter, const char *caller)
+{
+ struct security_priv* securitypriv=&(adapter->securitypriv);
+ u8 status = _SUCCESS;
+
+ if (securitypriv->btkip_countermeasure == _TRUE) {
+ u32 passing_ms = rtw_get_passing_time_ms(securitypriv->btkip_countermeasure_time);
+ if (passing_ms > 60*1000) {
+ DBG_871X_LEVEL(_drv_always_, "%s("ADPT_FMT") countermeasure time:%ds > 60s \n",
+ caller, ADPT_ARG(adapter), passing_ms/1000);
+ securitypriv->btkip_countermeasure = _FALSE;
+ securitypriv->btkip_countermeasure_time = 0;
+ } else {
+ DBG_871X_LEVEL(_drv_always_, "%s("ADPT_FMT") countermeasure time:%ds < 60s \n",
+ caller, ADPT_ARG(adapter), passing_ms/1000);
+ status = _FAIL;
+ }
+ }
+
+ return status;
+}
+
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_sreset.c b/drivers/net/wireless/rtl8723as/core/rtw_sreset.c
index b700bbfe5958..bc34827b492b 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_sreset.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_sreset.c
@@ -1,350 +1,356 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-
-#include<rtw_sreset.h>
-
-void sreset_init_value(_adapter *padapter)
-{
-#if defined(DBG_CONFIG_ERROR_DETECT)
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
- _rtw_mutex_init(&psrtpriv->silentreset_mutex);
- psrtpriv->silent_reset_inprogress = _FALSE;
- psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
- psrtpriv->last_tx_time =0;
- psrtpriv->last_tx_complete_time =0;
-#endif
-}
-void sreset_reset_value(_adapter *padapter)
-{
-#if defined(DBG_CONFIG_ERROR_DETECT)
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
- psrtpriv->silent_reset_inprogress = _FALSE;
- psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
- psrtpriv->last_tx_time =0;
- psrtpriv->last_tx_complete_time =0;
-#endif
-}
-
-u8 sreset_get_wifi_status(_adapter *padapter)
-{
-#if defined(DBG_CONFIG_ERROR_DETECT)
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
-
- u8 status = WIFI_STATUS_SUCCESS;
- u32 val32 = 0;
- _irqL irqL;
- if(psrtpriv->silent_reset_inprogress == _TRUE)
- {
- return status;
- }
- val32 =rtw_read32(padapter,REG_TXDMA_STATUS);
- if(val32==0xeaeaeaea){
- psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
- }
- else if(val32!=0){
- DBG_8192C("txdmastatu(%x)\n",val32);
- psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR;
- }
-
- if(WIFI_STATUS_SUCCESS !=psrtpriv->Wifi_Error_Status)
- {
- DBG_8192C("==>%s error_status(0x%x) \n",__FUNCTION__,psrtpriv->Wifi_Error_Status);
- status = (psrtpriv->Wifi_Error_Status &( ~(USB_READ_PORT_FAIL|USB_WRITE_PORT_FAIL)));
- }
- DBG_8192C("==> %s wifi_status(0x%x)\n",__FUNCTION__,status);
-
- //status restore
- psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
-
- return status;
-#else
- return WIFI_STATUS_SUCCESS;
-#endif
-}
-
-void sreset_set_wifi_error_status(_adapter *padapter, u32 status)
-{
-#if defined(DBG_CONFIG_ERROR_DETECT)
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
- pHalData->srestpriv.Wifi_Error_Status = status;
-#endif
-}
-
-void sreset_set_trigger_point(_adapter *padapter, s32 tgp)
-{
-#if defined(DBG_CONFIG_ERROR_DETECT)
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
- pHalData->srestpriv.dbg_trigger_point = tgp;
-#endif
-}
-
-bool sreset_inprogress(_adapter *padapter)
-{
-#if defined(DBG_CONFIG_ERROR_RESET)
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
- return pHalData->srestpriv.silent_reset_inprogress;
-#else
- return _FALSE;
-#endif
-}
-
-void sreset_restore_security_station(_adapter *padapter)
-{
- u8 EntryId = 0;
- struct mlme_priv *mlmepriv = &padapter->mlmepriv;
- struct sta_priv * pstapriv = &padapter->stapriv;
- struct sta_info *psta;
- struct security_priv* psecuritypriv=&(padapter->securitypriv);
- struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info;
-
- {
- u8 val8;
-
- if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) {
- val8 = 0xcc;
- #ifdef CONFIG_WAPI_SUPPORT
- } else if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) {
- //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
- val8 = 0x4c;
- #endif
- } else {
- val8 = 0xcf;
- }
- rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
- }
-
- #if 0
- if ( ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP40_ ) ||
- ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP104_ ))
- {
-
- for(EntryId=0; EntryId<4; EntryId++)
- {
- if(EntryId == psecuritypriv->dot11PrivacyKeyIndex)
- rtw_set_key(padapter,&padapter->securitypriv, EntryId, 1);
- else
- rtw_set_key(padapter,&padapter->securitypriv, EntryId, 0);
- }
-
- }
- else
- #endif
- if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
- (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))
- {
- psta = rtw_get_stainfo(pstapriv, get_bssid(mlmepriv));
- if (psta == NULL) {
- //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
- }
- else
- {
- //pairwise key
- rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE);
- //group key
- rtw_set_key(padapter,&padapter->securitypriv,padapter->securitypriv.dot118021XGrpKeyid, 0);
- }
- }
-}
-
-void sreset_restore_network_station(_adapter *padapter)
-{
- struct mlme_priv *mlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
-
- #if 0
- {
- //=======================================================
- // reset related register of Beacon control
-
- //set MSR to nolink
- Set_MSR(padapter, _HW_STATE_NOLINK_);
- // reject all data frame
- rtw_write16(padapter, REG_RXFLTMAP2,0x00);
- //reset TSF
- rtw_write8(padapter, REG_DUAL_TSF_RST, (BIT(0)|BIT(1)));
-
- // disable update TSF
- SetBcnCtrlReg(padapter, BIT(4), 0);
-
- //=======================================================
- }
- #endif
-
- rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure);
-
- {
- u8 threshold;
- #ifdef CONFIG_USB_HCI
- // TH=1 => means that invalidate usb rx aggregation
- // TH=0 => means that validate usb rx aggregation, use init value.
- if(mlmepriv->htpriv.ht_option) {
- if(padapter->registrypriv.wifi_spec==1)
- threshold = 1;
- else
- threshold = 0;
- rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
- } else {
- threshold = 1;
- rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
- }
- #endif
- }
-
- set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
-
- //disable dynamic functions, such as high power, DIG
- //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
-
- rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
-
- {
- u8 join_type = 0;
- rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
- }
-
- Set_MSR(padapter, (pmlmeinfo->state & 0x3));
-
- mlmeext_joinbss_event_callback(padapter, 1);
- //restore Sequence No.
- rtw_write8(padapter,0x4dc,padapter->xmitpriv.nqos_ssn);
-
- sreset_restore_security_station(padapter);
-}
-
-void sreset_restore_network_status(_adapter *padapter)
-{
- struct mlme_priv *mlmepriv = &padapter->mlmepriv;
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
-
- if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) {
- DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
- sreset_restore_network_station(padapter);
- } else if (check_fwstate(mlmepriv, WIFI_AP_STATE)) {
- DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_AP_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
- rtw_ap_restore_network(padapter);
- } else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE)) {
- DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
- } else {
- DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
- }
-}
-
-void sreset_stop_adapter(_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- if (padapter == NULL)
- return;
-
- DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
-
- if (!rtw_netif_queue_stopped(padapter->pnetdev))
- rtw_netif_stop_queue(padapter->pnetdev);
-
- rtw_cancel_all_timer(padapter);
-
- /* TODO: OS and HCI independent */
- #if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI)
- tasklet_kill(&pxmitpriv->xmit_tasklet);
- #endif
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
- rtw_scan_abort(padapter);
-
- if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
- _rtw_join_timeout_handler(padapter);
-
-}
-
-void sreset_start_adapter(_adapter *padapter)
-{
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
-
- if (padapter == NULL)
- return;
-
- DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
-
- if (check_fwstate(pmlmepriv, _FW_LINKED)) {
- sreset_restore_network_status(padapter);
- }
-
- /* TODO: OS and HCI independent */
- #if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI)
- tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
- #endif
-
- _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000);
-
- if (rtw_netif_queue_stopped(padapter->pnetdev))
- rtw_netif_wake_queue(padapter->pnetdev);
-
-}
-
-void sreset_reset(_adapter *padapter)
-{
-#ifdef DBG_CONFIG_ERROR_RESET
- HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
- struct sreset_priv *psrtpriv = &pHalData->srestpriv;
- struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
- _irqL irqL;
- u32 start = rtw_get_current_time();
-
- DBG_871X("%s\n", __FUNCTION__);
-
- psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
-
- _enter_critical_mutex(&psrtpriv->silentreset_mutex, &irqL);
- psrtpriv->silent_reset_inprogress = _TRUE;
- pwrpriv->change_rfpwrstate = rf_off;
-
- sreset_stop_adapter(padapter);
- #ifdef CONFIG_CONCURRENT_MODE
- sreset_stop_adapter(padapter->pbuddy_adapter);
- #endif
-
- #ifdef CONFIG_IPS
- ips_enter(padapter);
- ips_leave(padapter);
- #endif
-
- sreset_start_adapter(padapter);
- #ifdef CONFIG_CONCURRENT_MODE
- sreset_start_adapter(padapter->pbuddy_adapter);
- #endif
-
- psrtpriv->silent_reset_inprogress = _FALSE;
- _exit_critical_mutex(&psrtpriv->silentreset_mutex, &irqL);
-
- DBG_871X("%s done in %d ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
-#endif
-}
-
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ *
+ ******************************************************************************/
+
+#include<rtw_sreset.h>
+
+void sreset_init_value(_adapter *padapter)
+{
+#if defined(DBG_CONFIG_ERROR_DETECT)
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct sreset_priv *psrtpriv = &pHalData->srestpriv;
+
+ _rtw_mutex_init(&psrtpriv->silentreset_mutex);
+ psrtpriv->silent_reset_inprogress = _FALSE;
+ psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
+ psrtpriv->last_tx_time =0;
+ psrtpriv->last_tx_complete_time =0;
+#endif
+}
+void sreset_reset_value(_adapter *padapter)
+{
+#if defined(DBG_CONFIG_ERROR_DETECT)
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct sreset_priv *psrtpriv = &pHalData->srestpriv;
+
+ //psrtpriv->silent_reset_inprogress = _FALSE;
+ psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
+ psrtpriv->last_tx_time =0;
+ psrtpriv->last_tx_complete_time =0;
+#endif
+}
+
+u8 sreset_get_wifi_status(_adapter *padapter)
+{
+#if defined(DBG_CONFIG_ERROR_DETECT)
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct sreset_priv *psrtpriv = &pHalData->srestpriv;
+
+ u8 status = WIFI_STATUS_SUCCESS;
+ u32 val32 = 0;
+ _irqL irqL;
+ if(psrtpriv->silent_reset_inprogress == _TRUE)
+ {
+ return status;
+ }
+ val32 =rtw_read32(padapter,REG_TXDMA_STATUS);
+ if(val32==0xeaeaeaea){
+ psrtpriv->Wifi_Error_Status = WIFI_IF_NOT_EXIST;
+ }
+ else if(val32!=0){
+ DBG_8192C("txdmastatu(%x)\n",val32);
+ psrtpriv->Wifi_Error_Status = WIFI_MAC_TXDMA_ERROR;
+ }
+
+ if(WIFI_STATUS_SUCCESS !=psrtpriv->Wifi_Error_Status)
+ {
+ DBG_8192C("==>%s error_status(0x%x) \n",__FUNCTION__,psrtpriv->Wifi_Error_Status);
+ status = (psrtpriv->Wifi_Error_Status &( ~(USB_READ_PORT_FAIL|USB_WRITE_PORT_FAIL)));
+ }
+ DBG_8192C("==> %s wifi_status(0x%x)\n",__FUNCTION__,status);
+
+ //status restore
+ psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
+
+ return status;
+#else
+ return WIFI_STATUS_SUCCESS;
+#endif
+}
+
+void sreset_set_wifi_error_status(_adapter *padapter, u32 status)
+{
+#if defined(DBG_CONFIG_ERROR_DETECT)
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ pHalData->srestpriv.Wifi_Error_Status = status;
+#endif
+}
+
+void sreset_set_trigger_point(_adapter *padapter, s32 tgp)
+{
+#if defined(DBG_CONFIG_ERROR_DETECT)
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ pHalData->srestpriv.dbg_trigger_point = tgp;
+#endif
+}
+
+bool sreset_inprogress(_adapter *padapter)
+{
+#if defined(DBG_CONFIG_ERROR_RESET)
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ return pHalData->srestpriv.silent_reset_inprogress;
+#else
+ return _FALSE;
+#endif
+}
+
+void sreset_restore_security_station(_adapter *padapter)
+{
+ u8 EntryId = 0;
+ struct mlme_priv *mlmepriv = &padapter->mlmepriv;
+ struct sta_priv * pstapriv = &padapter->stapriv;
+ struct sta_info *psta;
+ struct security_priv* psecuritypriv=&(padapter->securitypriv);
+ struct mlme_ext_info *pmlmeinfo = &padapter->mlmeextpriv.mlmext_info;
+
+ {
+ u8 val8;
+
+ if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) {
+ val8 = 0xcc;
+ #ifdef CONFIG_WAPI_SUPPORT
+ } else if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) {
+ //Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey.
+ val8 = 0x4c;
+ #endif
+ } else {
+ val8 = 0xcf;
+ }
+ rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
+ }
+
+ #if 0
+ if ( ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP40_ ) ||
+ ( padapter->securitypriv.dot11PrivacyAlgrthm == _WEP104_ ))
+ {
+
+ for(EntryId=0; EntryId<4; EntryId++)
+ {
+ if(EntryId == psecuritypriv->dot11PrivacyKeyIndex)
+ rtw_set_key(padapter,&padapter->securitypriv, EntryId, 1,_FALSE);
+ else
+ rtw_set_key(padapter,&padapter->securitypriv, EntryId, 0,_FALSE);
+ }
+
+ }
+ else
+ #endif
+ if((padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_) ||
+ (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_))
+ {
+ psta = rtw_get_stainfo(pstapriv, get_bssid(mlmepriv));
+ if (psta == NULL) {
+ //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
+ }
+ else
+ {
+ //pairwise key
+ rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE,_FALSE);
+ //group key
+ rtw_set_key(padapter,&padapter->securitypriv,padapter->securitypriv.dot118021XGrpKeyid, 0,_FALSE);
+ }
+ }
+}
+
+void sreset_restore_network_station(_adapter *padapter)
+{
+ struct mlme_priv *mlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ #if 0
+ {
+ //=======================================================
+ // reset related register of Beacon control
+
+ //set MSR to nolink
+ Set_MSR(padapter, _HW_STATE_NOLINK_);
+ // reject all data frame
+ rtw_write16(padapter, REG_RXFLTMAP2,0x00);
+ //reset TSF
+ rtw_write8(padapter, REG_DUAL_TSF_RST, (BIT(0)|BIT(1)));
+
+ // disable update TSF
+ SetBcnCtrlReg(padapter, BIT(4), 0);
+
+ //=======================================================
+ }
+ #endif
+
+ rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure,_FALSE);
+
+ {
+ u8 threshold;
+ #ifdef CONFIG_USB_HCI
+ // TH=1 => means that invalidate usb rx aggregation
+ // TH=0 => means that validate usb rx aggregation, use init value.
+ if(mlmepriv->htpriv.ht_option) {
+ if(padapter->registrypriv.wifi_spec==1)
+ threshold = 1;
+ else
+ threshold = 0;
+ rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
+ } else {
+ threshold = 1;
+ rtw_hal_set_hwreg(padapter, HW_VAR_RXDMA_AGG_PG_TH, (u8 *)(&threshold));
+ }
+ #endif
+ }
+
+ set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
+
+ //disable dynamic functions, such as high power, DIG
+ //Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
+
+ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
+
+ {
+ u8 join_type = 0;
+ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
+ }
+
+ Set_MSR(padapter, (pmlmeinfo->state & 0x3));
+
+ mlmeext_joinbss_event_callback(padapter, 1);
+ //restore Sequence No.
+ rtw_write8(padapter,0x4dc,padapter->xmitpriv.nqos_ssn);
+
+ sreset_restore_security_station(padapter);
+}
+
+
+void sreset_restore_network_status(_adapter *padapter)
+{
+ struct mlme_priv *mlmepriv = &padapter->mlmepriv;
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ if (check_fwstate(mlmepriv, WIFI_STATION_STATE)) {
+ DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_STATION_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
+ sreset_restore_network_station(padapter);
+ } else if (check_fwstate(mlmepriv, WIFI_AP_STATE)) {
+ DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_AP_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
+ rtw_ap_restore_network(padapter);
+ } else if (check_fwstate(mlmepriv, WIFI_ADHOC_STATE)) {
+ DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - WIFI_ADHOC_STATE\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
+ } else {
+ DBG_871X(FUNC_ADPT_FMT" fwstate:0x%08x - ???\n", FUNC_ADPT_ARG(padapter), get_fwstate(mlmepriv));
+ }
+}
+
+void sreset_stop_adapter(_adapter *padapter)
+{
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+
+ if (padapter == NULL)
+ return;
+
+ DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
+
+ if (!rtw_netif_queue_stopped(padapter->pnetdev))
+ rtw_netif_stop_queue(padapter->pnetdev);
+
+ rtw_cancel_all_timer(padapter);
+
+ /* TODO: OS and HCI independent */
+ #if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI)
+ tasklet_kill(&pxmitpriv->xmit_tasklet);
+ #endif
+
+ if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
+ rtw_scan_abort(padapter);
+
+ if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING))
+ {
+ rtw_set_roaming(padapter, 0);
+ _rtw_join_timeout_handler(padapter);
+ }
+
+}
+
+void sreset_start_adapter(_adapter *padapter)
+{
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+
+ if (padapter == NULL)
+ return;
+
+ DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
+
+ if (check_fwstate(pmlmepriv, _FW_LINKED)) {
+ sreset_restore_network_status(padapter);
+ }
+
+ /* TODO: OS and HCI independent */
+ #if defined(PLATFORM_LINUX) && defined(CONFIG_USB_HCI)
+ tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
+ #endif
+
+ _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 2000);
+
+ if (rtw_netif_queue_stopped(padapter->pnetdev))
+ rtw_netif_wake_queue(padapter->pnetdev);
+
+}
+
+void sreset_reset(_adapter *padapter)
+{
+#ifdef DBG_CONFIG_ERROR_RESET
+ HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
+ struct sreset_priv *psrtpriv = &pHalData->srestpriv;
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ _irqL irqL;
+ u32 start = rtw_get_current_time();
+
+ DBG_871X("%s\n", __FUNCTION__);
+
+ psrtpriv->Wifi_Error_Status = WIFI_STATUS_SUCCESS;
+
+ _enter_pwrlock(&pwrpriv->lock);
+
+ psrtpriv->silent_reset_inprogress = _TRUE;
+ pwrpriv->change_rfpwrstate = rf_off;
+
+ sreset_stop_adapter(padapter);
+ #ifdef CONFIG_CONCURRENT_MODE
+ sreset_stop_adapter(padapter->pbuddy_adapter);
+ #endif
+
+ #ifdef CONFIG_IPS
+ _ips_enter(padapter);
+ _ips_leave(padapter);
+ #endif
+
+ sreset_start_adapter(padapter);
+ #ifdef CONFIG_CONCURRENT_MODE
+ sreset_start_adapter(padapter->pbuddy_adapter);
+ #endif
+
+ psrtpriv->silent_reset_inprogress = _FALSE;
+
+ _exit_pwrlock(&pwrpriv->lock);
+
+ DBG_871X("%s done in %d ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
+#endif
+}
+
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_sta_mgt.c b/drivers/net/wireless/rtl8723as/core/rtw_sta_mgt.c
index 3c1e4c305dc3..3ba598f87371 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_sta_mgt.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_sta_mgt.c
@@ -87,7 +87,18 @@ _func_enter_;
psta->keep_alive_trycnt = 0;
#endif // CONFIG_AP_MODE
+
+#ifdef DBG_TRX_STA_PKTS
+ psta->tx_be_cnt = 0;
+ psta->tx_bk_cnt = 0;
+ psta->tx_vi_cnt = 0;
+ psta->tx_vo_cnt = 0;
+ psta->rx_be_cnt = 0;
+ psta->rx_bk_cnt = 0;
+ psta->rx_vi_cnt = 0;
+ psta->rx_vo_cnt = 0;
+#endif
_func_exit_;
}
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_tdls.c b/drivers/net/wireless/rtl8723as/core/rtw_tdls.c
index 231b240c89b7..f7ca24aab826 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_tdls.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_tdls.c
@@ -1,2941 +1,2941 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- *
- ******************************************************************************/
-#define _RTW_TDLS_C_
-
-#include <drv_types.h>
-#include <ethernet.h>
-#include <rtw_tdls.h>
-#include <wifi.h>
-
-#ifdef CONFIG_TDLS
-extern unsigned char MCS_rate_2R[16];
-extern unsigned char MCS_rate_1R[16];
-extern void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame);
-extern s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe);
-
-void rtw_reset_tdls_info(_adapter* padapter)
-{
- struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
-
- ptdlsinfo->ap_prohibited = _FALSE;
- ptdlsinfo->setup_state = TDLS_STATE_NONE;
- ptdlsinfo->sta_cnt = 0;
- ptdlsinfo->sta_maximum = _FALSE;
- ptdlsinfo->macid_index= 6;
- ptdlsinfo->clear_cam= 0;
- ptdlsinfo->ch_sensing = 0;
- ptdlsinfo->cur_channel = 0;
- ptdlsinfo->candidate_ch = 1; //when inplement channel switching, default candidate channel is 1
- ptdlsinfo->watchdog_count = 0;
- ptdlsinfo->dev_discovered = 0;
-
-#ifdef CONFIG_WFD
- ptdlsinfo->wfd_info = &padapter->wfd_info;
-#endif //CONFIG_WFD
-}
-
-int rtw_init_tdls_info(_adapter* padapter)
-{
- int res = _SUCCESS;
- struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
-
- ptdlsinfo->enable = 1;
- rtw_reset_tdls_info(padapter);
-
- _rtw_spinlock_init(&ptdlsinfo->cmd_lock);
- _rtw_spinlock_init(&ptdlsinfo->hdl_lock);
-
- return res;
-
-}
-
-void rtw_free_tdls_info(struct tdls_info *ptdlsinfo)
-{
- _rtw_spinlock_free(&ptdlsinfo->cmd_lock);
- _rtw_spinlock_free(&ptdlsinfo->hdl_lock);
-
- _rtw_memset(ptdlsinfo, 0, sizeof(struct tdls_info) );
-
-}
-
-void issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, struct sta_info *ptdls_sta, unsigned int power_mode)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-// SetToDs(fctrl);
- if (power_mode)
- {
- SetPwrMgt(fctrl);
- }
-
- _rtw_memcpy(pwlanhdr->addr1, ptdls_sta->hwaddr, ETH_ALEN);
- _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
-
- ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
- ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
- pattrib->seqnum = ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority];
- SetSeqNum(pwlanhdr, pattrib->seqnum);
-
- SetFrameSubType(pframe, WIFI_DATA_NULL);
-
- pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
-
- pattrib->last_txcmdsz = pattrib->pktlen;
- dump_mgntframe(padapter, pmgntframe);
-
- return;
-}
-
-s32 update_tdls_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
-{
-
- struct sta_info *psta = NULL;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct qos_priv *pqospriv= &pmlmepriv->qospriv;
-
- s32 res=_SUCCESS;
- sint bmcast;
-
- bmcast = IS_MCAST(pattrib->ra);
-
- psta = rtw_get_stainfo(pstapriv, pattrib->ra);
- if (psta == NULL) {
- res =_FAIL;
- goto exit;
- }
-
- pattrib->mac_id = psta->mac_id;
-
- pattrib->psta = psta;
-
- pattrib->ack_policy = 0;
- // get ether_hdr_len
- pattrib->pkt_hdrlen = ETH_HLEN;//(pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; //vlan tag
-
- if (pqospriv->qos_option && psta->qos_option) {
- pattrib->priority = 1; //tdls management frame should be AC_BK
- pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
- pattrib->subtype = WIFI_QOS_DATA_TYPE;
- } else {
- pattrib->hdrlen = WLAN_HDR_A3_LEN;
- pattrib->subtype = WIFI_DATA_TYPE;
- pattrib->priority = 0;
- }
-
- if (psta->ieee8021x_blocked == _TRUE)
- {
- pattrib->encrypt = 0;
- }
- else
- {
- GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
-
- switch(psecuritypriv->dot11AuthAlgrthm)
- {
- case dot11AuthAlgrthm_Open:
- case dot11AuthAlgrthm_Shared:
- case dot11AuthAlgrthm_Auto:
- pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
- break;
- case dot11AuthAlgrthm_8021X:
- pattrib->key_idx = 0;
- break;
- default:
- pattrib->key_idx = 0;
- break;
- }
- }
-
- switch (pattrib->encrypt)
- {
- case _WEP40_:
- case _WEP104_:
- pattrib->iv_len = 4;
- pattrib->icv_len = 4;
- break;
- case _TKIP_:
- pattrib->iv_len = 8;
- pattrib->icv_len = 4;
- if(padapter->securitypriv.busetkipkey==_FAIL)
- {
- res =_FAIL;
- goto exit;
- }
- break;
- case _AES_:
- pattrib->iv_len = 8;
- pattrib->icv_len = 8;
- break;
- default:
- pattrib->iv_len = 0;
- pattrib->icv_len = 0;
- break;
- }
-
- if (pattrib->encrypt &&
- ((padapter->securitypriv.sw_encrypt == _TRUE) || (psecuritypriv->hw_decrypted == _FALSE)))
- {
- pattrib->bswenc = _TRUE;
- } else {
- pattrib->bswenc = _FALSE;
- }
-
- //qos_en, ht_en, init rate, ,bw, ch_offset, sgi
- pattrib->qos_en = psta->qos_option;
- pattrib->ht_en = psta->htpriv.ht_option;
- pattrib->raid = psta->raid;
- pattrib->bwmode = psta->htpriv.bwmode;
- pattrib->ch_offset = psta->htpriv.ch_offset;
- pattrib->sgi= psta->htpriv.sgi;
- pattrib->ampdu_en = _FALSE;
-
- //if(pattrib->ht_en && psta->htpriv.ampdu_enable)
- //{
- // if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
- // pattrib->ampdu_en = _TRUE;
- //}
-
-exit:
-
- return res;
-}
-
-void free_tdls_sta(_adapter *padapter, struct sta_info *ptdls_sta)
-{
- struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
- struct sta_priv *pstapriv = &padapter->stapriv;
- _irqL irqL;
-
- //free peer sta_info
- _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
- if(ptdlsinfo->sta_cnt != 0)
- ptdlsinfo->sta_cnt--;
- _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
- if( ptdlsinfo->sta_cnt < (NUM_STA - 2) ) // -2: AP + BC/MC sta
- {
- ptdlsinfo->sta_maximum = _FALSE;
- _rtw_memset( &ptdlsinfo->ss_record, 0x00, sizeof(struct tdls_ss_record) );
- }
- //ready to clear cam
- if(ptdls_sta->mac_id!=0){
- ptdlsinfo->clear_cam=ptdls_sta->mac_id;
- rtw_setstakey_cmd(padapter, (u8 *)ptdls_sta, _TRUE);
- }
-
- if(ptdlsinfo->sta_cnt==0){
- rtw_tdls_cmd(padapter, myid(&(padapter->eeprompriv)), TDLS_RS_RCR);
- ptdlsinfo->setup_state=TDLS_STATE_NONE;
- }
- else
- DBG_871X("Remain tdls sta:%02x\n", ptdlsinfo->sta_cnt);
-
- rtw_free_stainfo(padapter, ptdls_sta);
-
-}
-
-// cam entry will be the same as mac_id
-void rtw_tdls_set_mac_id(struct tdls_info *ptdlsinfo, struct sta_info *ptdls_sta)
-{
- if(ptdls_sta->mac_id==0)
- {
- ptdls_sta->mac_id = ptdlsinfo->macid_index;
- if( (++ptdlsinfo->macid_index) > (NUM_STA -2) )
- ptdlsinfo->macid_index= TDLS_INI_MACID_ENTRY;
- }
-}
-
-//TDLS encryption(if needed) will always be CCMP
-void rtw_tdls_set_key(_adapter *adapter, struct rx_pkt_attrib *prx_pkt_attrib, struct sta_info *ptdls_sta)
-{
- if(prx_pkt_attrib->encrypt)
- {
- ptdls_sta->dot118021XPrivacy=_AES_;
- rtw_setstakey_cmd(adapter, (u8*)ptdls_sta, _TRUE);
- }
-}
-
-void rtw_tdls_process_ht_cap(_adapter *adapter, struct sta_info *ptdls_sta, u8 *data, u8 Length)
-{
- /* save HT capabilities in the sta object */
- _rtw_memset(&ptdls_sta->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
- if (data && Length >= sizeof(struct rtw_ieee80211_ht_cap) )
- {
- ptdls_sta->flags |= WLAN_STA_HT;
-
- ptdls_sta->flags |= WLAN_STA_WME;
-
- _rtw_memcpy(&ptdls_sta->htpriv.ht_cap, data, sizeof(struct rtw_ieee80211_ht_cap));
-
- } else
- ptdls_sta->flags &= ~WLAN_STA_HT;
-
- if(ptdls_sta->flags & WLAN_STA_HT)
- {
- if(adapter->registrypriv.ht_enable == _TRUE)
- {
- ptdls_sta->htpriv.ht_option = _TRUE;
- }
- else
- {
- ptdls_sta->htpriv.ht_option = _FALSE;
- ptdls_sta->stat_code = _STATS_FAILURE_;
- }
- }
-
- //HT related cap
- if(ptdls_sta->htpriv.ht_option)
- {
- //check if sta supports rx ampdu
- if(adapter->registrypriv.ampdu_enable==1)
- ptdls_sta->htpriv.ampdu_enable = _TRUE;
-
- //check if sta support s Short GI
- if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40))
- {
- ptdls_sta->htpriv.sgi = _TRUE;
- }
-
- // bwmode would still followed AP's setting
- if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
- {
- ptdls_sta->htpriv.bwmode = adapter->mlmeextpriv.cur_bwmode;
- ptdls_sta->htpriv.ch_offset = adapter->mlmeextpriv.cur_ch_offset;
- }
- }
-}
-
-u8 *rtw_tdls_set_ht_cap(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
-{
- struct rtw_ieee80211_ht_cap ht_capie;
- u8 rf_type;
-
- //HT capabilities
- _rtw_memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap));
-
- ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH |IEEE80211_HT_CAP_SGI_20 |IEEE80211_HT_CAP_SM_PS |
- IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_TX_STBC |IEEE80211_HT_CAP_DSSSCCK40;
-
- {
- u32 rx_packet_offset, max_recvbuf_sz;
- padapter->HalFunc.GetHalDefVarHandler(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
- padapter->HalFunc.GetHalDefVarHandler(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
- if(max_recvbuf_sz-rx_packet_offset>(8191-256))
- ht_capie.cap_info = ht_capie.cap_info |IEEE80211_HT_CAP_MAX_AMSDU;
- }
-
- ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR&0x03);
-
- padapter->HalFunc.GetHwRegHandler(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
- switch(rf_type)
- {
- case RF_1T1R:
- ht_capie.cap_info |= 0x0100;//RX STBC One spatial stream
- _rtw_memcpy(ht_capie.supp_mcs_set, MCS_rate_1R, 16);
- break;
-
- case RF_2T2R:
- case RF_1T2R:
- default:
- ht_capie.cap_info|= 0x0200;//RX STBC two spatial stream
- _rtw_memcpy(ht_capie.supp_mcs_set, MCS_rate_2R, 16);
- break;
- }
-
- return(rtw_set_ie(pframe, _HT_CAPABILITY_IE_,
- sizeof(struct rtw_ieee80211_ht_cap), (unsigned char*)&ht_capie, &(pattrib->pktlen)));
-}
-
-u8 *rtw_tdls_set_sup_ch(struct mlme_ext_priv *pmlmeext, u8 *pframe, struct pkt_attrib *pattrib)
-{
- u8 sup_ch[ 30 * 2 ] = { 0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel
- do{
- if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 )
- {
- sup_ch[0] = 1; //First channel number
- sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; //Number of channel
- }
- else
- {
- sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;
- sup_ch[idx_5g++] = 1;
- }
-
- sup_ch_idx++;
- }
- while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 );
- return(rtw_set_ie(pframe, _SUPPORTED_CH_IE_, idx_5g, sup_ch, &(pattrib->pktlen)));
-}
-
-#ifdef CONFIG_WFD
-void rtw_tdls_process_wfd_ie(struct tdls_info *ptdlsinfo, u8 *ptr, u8 length)
-{
- u8 wfd_ie[ 128 ] = { 0x00 };
- u32 wfd_ielen = 0;
- u32 wfd_offset = 0;
- // Try to get the TCP port information when receiving the negotiation response.
- //
-
- wfd_offset = 0;
- wfd_offset = rtw_get_wfd_ie( ptr + wfd_offset, length - wfd_offset, wfd_ie, &wfd_ielen );
- while( wfd_offset )
- {
- u8 attr_content[ 10 ] = { 0x00 };
- u32 attr_contentlen = 0;
- int i;
-
- DBG_871X( "[%s] WFD IE Found!!\n", __FUNCTION__ );
- rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
- if ( attr_contentlen )
- {
- ptdlsinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
- DBG_871X( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, ptdlsinfo->wfd_info->peer_rtsp_ctrlport );
- }
-
- _rtw_memset( attr_content, 0x00, 10);
- attr_contentlen = 0;
- rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_LOCAL_IP_ADDR, attr_content, &attr_contentlen);
- if ( attr_contentlen )
- {
- _rtw_memcpy(ptdlsinfo->wfd_info->peer_ip_address, ( attr_content + 1 ), 4);
- DBG_871X( "[%s] Peer IP = %02u.%02u.%02u.%02u \n", __FUNCTION__,
- ptdlsinfo->wfd_info->peer_ip_address[0], ptdlsinfo->wfd_info->peer_ip_address[1],
- ptdlsinfo->wfd_info->peer_ip_address[2], ptdlsinfo->wfd_info->peer_ip_address[3]
- );
- }
- wfd_offset = rtw_get_wfd_ie( ptr + wfd_offset, length - wfd_offset, wfd_ie, &wfd_ielen );
- }
-}
-
-void issue_tunneled_probe_req(_adapter *padapter)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- u8 baddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
- DBG_871X("[%s]\n", __FUNCTION__);
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
-
- pmgntframe->frame_tag = DATA_FRAMETAG;
- pattrib->ether_type = 0x890d;
- pattrib->pctrl =0;
-
- _rtw_memcpy(pattrib->dst, baddr, ETH_ALEN);
-
- _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
- _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- update_tdls_attrib(padapter, pattrib);
- pattrib->qsel=pattrib->priority;
- if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TUNNELED_PROBE_REQ) != _SUCCESS) {
- rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
- rtw_free_xmitframe(pxmitpriv, pmgntframe);
- goto exit;
- }
- rtw_dump_xframe(padapter, pmgntframe);
-
-exit:
-
- return;
-}
-
-void issue_tunneled_probe_rsp(_adapter *padapter, union recv_frame *precv_frame)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct rx_pkt_attrib *rx_pkt_pattrib = &precv_frame->u.hdr.attrib;
-
- DBG_871X("[%s]\n", __FUNCTION__);
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
-
- pmgntframe->frame_tag = DATA_FRAMETAG;
- pattrib->ether_type = 0x890d;
- pattrib->pctrl =0;
-
- _rtw_memcpy(pattrib->dst, rx_pkt_pattrib->src, ETH_ALEN);
-
- _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
- _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- update_tdls_attrib(padapter, pattrib);
- pattrib->qsel=pattrib->priority;
- if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TUNNELED_PROBE_RSP) != _SUCCESS) {
- rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
- rtw_free_xmitframe(pxmitpriv, pmgntframe);
- goto exit;
- }
- rtw_dump_xframe(padapter, pmgntframe);
-
-exit:
-
- return;
-}
-#endif //CONFIG_WFD
-
-void issue_tdls_setup_req(_adapter *padapter, u8 *mac_addr)
-{
- struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *ptdls_sta= NULL;
- _irqL irqL;
- static u8 dialogtoken = 0;
- u32 timeout_interval= TPK_RESEND_COUNT * 1000; //retry timer should set at least 301 sec, using TPK_count counting 301 times.
-
- if(ptdlsinfo->ap_prohibited == _TRUE)
- goto exit;
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
-
- pmgntframe->frame_tag = DATA_FRAMETAG;
- pattrib->ether_type = 0x890d;
- pattrib->pctrl =0;
-
- _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
- _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
- _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- update_tdls_attrib(padapter, pattrib);
-
- //init peer sta_info
- ptdls_sta = rtw_get_stainfo(pstapriv, mac_addr);
- if(ptdls_sta==NULL)
- {
- ptdls_sta = rtw_alloc_stainfo(pstapriv, mac_addr);
- if(ptdls_sta)
- {
- _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
- if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
- ptdlsinfo->sta_cnt++;
- _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
- if( ptdlsinfo->sta_cnt == (NUM_STA - 2) ) // -2: AP + BC/MC sta
- {
- ptdlsinfo->sta_maximum = _TRUE;
- }
- }
- else
- {
- rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
- rtw_free_xmitframe(pxmitpriv, pmgntframe);
- goto exit;
- }
- }
-
- if(ptdls_sta){
- ptdls_sta->tdls_sta_state |= TDLS_RESPONDER_STATE;
- //for tdls; ptdls_sta->aid is used to fill dialogtoken
- ptdls_sta->dialog = dialogtoken;
- dialogtoken = (dialogtoken+1)%256;
- ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval;
- _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME );
- }
-
- pattrib->qsel=pattrib->priority;
- if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_SETUP_REQUEST) !=_SUCCESS ){
- rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
- rtw_free_xmitframe(pxmitpriv, pmgntframe);
- goto exit;
- }
- rtw_dump_xframe(padapter, pmgntframe);
-
-exit:
-
- return;
-}
-
-void issue_tdls_teardown(_adapter *padapter, u8 *mac_addr)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *ptdls_sta=NULL;
- _irqL irqL;
-
- ptdls_sta = rtw_get_stainfo(pstapriv, mac_addr);
- if(ptdls_sta==NULL){
- DBG_871X("issue tdls teardown unsuccessful\n");
- return;
- }else{
- ptdls_sta->tdls_sta_state=TDLS_STATE_NONE;
- }
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
-
- pmgntframe->frame_tag = DATA_FRAMETAG;
- pattrib->ether_type = 0x890d;
- pattrib->pctrl =0;
-
- _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
- _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
- _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- update_tdls_attrib(padapter, pattrib);
- pattrib->qsel=pattrib->priority;
- if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_TEARDOWN) != _SUCCESS) {
- rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
- rtw_free_xmitframe(pxmitpriv, pmgntframe);
- goto exit;
- }
- rtw_dump_xframe(padapter, pmgntframe);
-
- if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE){
- rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
- }
-
- if( ptdls_sta->timer_flag == 1 )
- {
- _enter_critical_bh(&(padapter->tdlsinfo.hdl_lock), &irqL);
- ptdls_sta->timer_flag = 2;
- _exit_critical_bh(&(padapter->tdlsinfo.hdl_lock), &irqL);
- }
- else
- rtw_tdls_cmd(padapter, mac_addr, TDLS_FREE_STA );
-
-
-exit:
-
- return;
-}
-
-void issue_tdls_dis_req(_adapter *padapter, u8 *mac_addr)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- u8 baddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
-
- pmgntframe->frame_tag = DATA_FRAMETAG;
- pattrib->ether_type = 0x890d;
- pattrib->pctrl =0;
-
- if(mac_addr == NULL)
- _rtw_memcpy(pattrib->dst, baddr, ETH_ALEN);
- else
- _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
-
- _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
- _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- update_tdls_attrib(padapter, pattrib);
- pattrib->qsel=pattrib->priority;
- if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_DISCOVERY_REQUEST) != _SUCCESS) {
- rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
- rtw_free_xmitframe(pxmitpriv, pmgntframe);
- goto exit;
- }
- rtw_dump_xframe(padapter, pmgntframe);
- DBG_871X("issue tdls dis req\n");
-
-exit:
-
- return;
-}
-
-void issue_tdls_setup_rsp(_adapter *padapter, union recv_frame *precv_frame)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct rx_pkt_attrib *rx_pkt_pattrib = &precv_frame->u.hdr.attrib;
- _irqL irqL;
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
-
- pmgntframe->frame_tag = DATA_FRAMETAG;
- pattrib->ether_type = 0x890d;
- pattrib->pctrl =0;
-
- _rtw_memcpy(pattrib->dst, rx_pkt_pattrib->src, ETH_ALEN);
- _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- _rtw_memcpy(pattrib->ra, rx_pkt_pattrib->bssid, ETH_ALEN);
- _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- update_tdls_attrib(padapter, pattrib);
- pattrib->qsel=pattrib->priority;
- if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_SETUP_RESPONSE) != _SUCCESS) {
- rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
- rtw_free_xmitframe(pxmitpriv, pmgntframe);
- goto exit;
- }
- rtw_dump_xframe(padapter, pmgntframe);
-
-exit:
-
- return;
-
-}
-
-void issue_tdls_setup_cfm(_adapter *padapter, union recv_frame *precv_frame)
-{
- struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct sta_info *ptdls_sta=NULL;
- _irqL irqL;
-
- struct rx_pkt_attrib *rx_pkt_pattrib = & precv_frame->u.hdr.attrib;
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
-
- pmgntframe->frame_tag = DATA_FRAMETAG;
- pattrib->ether_type = 0x890d;
- pattrib->pctrl =0;
-
- _rtw_memcpy(pattrib->dst, rx_pkt_pattrib->src, ETH_ALEN);
- _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- _rtw_memcpy(pattrib->ra, rx_pkt_pattrib->bssid, ETH_ALEN);
- _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- update_tdls_attrib(padapter, pattrib);
- pattrib->qsel=pattrib->priority;
- if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_SETUP_CONFIRM) != _SUCCESS) {
- rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
- rtw_free_xmitframe(pxmitpriv, pmgntframe);
- goto exit;
- }
-
- rtw_dump_xframe(padapter, pmgntframe);
-
-exit:
-
- return;
-
-}
-
-//TDLS Discovery Response frame is a management action frame
-void issue_tdls_dis_rsp(_adapter *padapter, union recv_frame *precv_frame, u8 dialog)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- unsigned char *pframe;
- struct rtw_ieee80211_hdr *pwlanhdr;
- unsigned short *fctrl;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
-
- struct rx_pkt_attrib *rx_pkt_pattrib = &precv_frame->u.hdr.attrib;
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
- update_mgntframe_attrib(padapter, pattrib);
-
- _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
-
- pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
- pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
-
- fctrl = &(pwlanhdr->frame_ctl);
- *(fctrl) = 0;
-
- // unicast probe request frame
- _rtw_memcpy(pwlanhdr->addr1, rx_pkt_pattrib->src, ETH_ALEN);
- _rtw_memcpy(pattrib->dst, pwlanhdr->addr1, ETH_ALEN);
-
- _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
- _rtw_memcpy(pattrib->src, pwlanhdr->addr2, ETH_ALEN);
-
- _rtw_memcpy(pwlanhdr->addr3, rx_pkt_pattrib->bssid, ETH_ALEN);
- _rtw_memcpy(pattrib->ra, pwlanhdr->addr3, ETH_ALEN);
-
- SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
- pmlmeext->mgnt_seq++;
- SetFrameSubType(pframe, WIFI_ACTION);
-
- pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
- pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
-
- rtw_build_tdls_dis_rsp_ies(padapter, pmgntframe, pframe, dialog);
-
- pattrib->nr_frags = 1;
- pattrib->last_txcmdsz = pattrib->pktlen;
-
- dump_mgntframe(padapter, pmgntframe);
-
- return;
-}
-
-void issue_tdls_peer_traffic_indication(_adapter *padapter, struct sta_info *ptdls_sta)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
-
- static u8 dialogtoken=0;
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
-
- pmgntframe->frame_tag = DATA_FRAMETAG;
- pattrib->ether_type = 0x890d;
- pattrib->pctrl =0;
-
- _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN);
- _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
- _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- //for tdls; pattrib->nr_frags is used to fill dialogtoken
- ptdls_sta->dialog = dialogtoken;
- dialogtoken = (dialogtoken+1)%256;
- //PTI frame's priority should be AC_VO
- pattrib->priority = 7;
-
- update_tdls_attrib(padapter, pattrib);
- pattrib->qsel=pattrib->priority;
- if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_PEER_TRAFFIC_INDICATION) != _SUCCESS) {
- rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
- rtw_free_xmitframe(pxmitpriv, pmgntframe);
- goto exit;
- }
- rtw_dump_xframe(padapter, pmgntframe);
-
-exit:
-
- return;
-}
-
-void issue_tdls_ch_switch_req(_adapter *padapter, u8 *mac_addr)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
-
- pmgntframe->frame_tag = DATA_FRAMETAG;
- pattrib->ether_type = 0x890d;
- pattrib->pctrl =0;
-
- _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
- _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
- _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- update_tdls_attrib(padapter, pattrib);
-
- pattrib->qsel=pattrib->priority;
- if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_CHANNEL_SWITCH_REQUEST) !=_SUCCESS ){
- rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
- rtw_free_xmitframe(pxmitpriv, pmgntframe);
- goto exit;
- }
- rtw_dump_xframe(padapter, pmgntframe);
-
-exit:
-
- return;
-}
-
-void issue_tdls_ch_switch_rsp(_adapter *padapter, u8 *mac_addr)
-{
- struct xmit_frame *pmgntframe;
- struct pkt_attrib *pattrib;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
-
- _irqL irqL;
-
- if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
- {
- return;
- }
-
- //update attribute
- pattrib = &pmgntframe->attrib;
-
- pmgntframe->frame_tag = DATA_FRAMETAG;
- pattrib->ether_type = 0x890d;
- pattrib->pctrl =0;
-
- _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
- _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
-
- _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
- _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
-
- update_tdls_attrib(padapter, pattrib);
-
- pattrib->qsel=pattrib->priority;
-/*
- _enter_critical_bh(&pxmitpriv->lock, &irqL);
- if(xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pmgntframe)==_TRUE){
- _exit_critical_bh(&pxmitpriv->lock, &irqL);
- return _FALSE;
- }
-*/
- if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_CHANNEL_SWITCH_RESPONSE) !=_SUCCESS ){
- rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
- rtw_free_xmitframe(pxmitpriv, pmgntframe);
- goto exit;
- }
- rtw_dump_xframe(padapter, pmgntframe);
-
-exit:
-
- return;
-}
-
-sint On_TDLS_Dis_Rsp(_adapter *adapter, union recv_frame *precv_frame)
-{
- struct sta_info *ptdls_sta = NULL, *psta = rtw_get_stainfo(&(adapter->stapriv), get_bssid(&(adapter->mlmepriv)));
- struct recv_priv *precvpriv = &(adapter->recvpriv);
- u8 *ptr = precv_frame->u.hdr.rx_data, *psa;
- struct rx_pkt_attrib *pattrib = &(precv_frame->u.hdr.attrib);
- struct tdls_info *ptdlsinfo = &(adapter->tdlsinfo);
- u8 empty_addr[ETH_ALEN] = { 0x00 };
- int UndecoratedSmoothedPWDB;
-
-
- //WFDTDLS: for sigma test, not to setup direct link automatically
- ptdlsinfo->dev_discovered = 1;
-
-#ifdef CONFIG_TDLS_AUTOSETUP
- psa = get_sa(ptr);
- ptdls_sta = rtw_get_stainfo(&(adapter->stapriv), psa);
-
- if(ptdls_sta != NULL)
- {
- ptdls_sta->tdls_sta_state |= TDLS_ALIVE_STATE;
-
- //Record the tdls sta with lowest signal strength
- if( (ptdlsinfo->sta_maximum == _TRUE) && (ptdls_sta->alive_count >= 1) )
- {
- if( _rtw_memcmp(ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN) )
- {
- _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
- ptdlsinfo->ss_record.RxPWDBAll = pattrib->RxPWDBAll;
- }
- else
- {
- if( ptdlsinfo->ss_record.RxPWDBAll < pattrib->RxPWDBAll )
- {
- _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
- ptdlsinfo->ss_record.RxPWDBAll = pattrib->RxPWDBAll;
- }
- }
- }
-
- }
- else
- {
- if( ptdlsinfo->sta_maximum == _TRUE)
- {
- if( _rtw_memcmp( ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN ) )
- {
- //All traffics are busy, do not set up another direct link.
- return _FAIL;
- }
- else
- {
- if( pattrib->RxPWDBAll > ptdlsinfo->ss_record.RxPWDBAll )
- {
- issue_tdls_teardown(adapter, ptdlsinfo->ss_record.macaddr);
- }
- else
- {
- return _FAIL;
- }
- }
- }
-
- adapter->HalFunc.GetHalDefVarHandler(adapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
-
- if( pattrib->RxPWDBAll + TDLS_SIGNAL_THRESH >= UndecoratedSmoothedPWDB);
- {
- DBG_871X("pattrib->RxPWDBAll=%d, pdmpriv->UndecoratedSmoothedPWDB=%d\n", pattrib->RxPWDBAll, UndecoratedSmoothedPWDB);
- issue_tdls_setup_req(adapter, psa);
- }
- }
-#endif //CONFIG_TDLS_AUTOSETUP
-
- return _SUCCESS;
-}
-
-sint On_TDLS_Setup_Req(_adapter *adapter, union recv_frame *precv_frame)
-{
- struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
- u8 *psa, *pmyid;
- struct sta_info *ptdls_sta= NULL;
- struct sta_priv *pstapriv = &adapter->stapriv;
- u8 *ptr = precv_frame->u.hdr.rx_data;
- struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
- struct security_priv *psecuritypriv = &adapter->securitypriv;
- _irqL irqL;
- struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
- u8 *prsnie, *ppairwise_cipher;
- u8 i, k, pairwise_count;
- u8 ccmp_have=0, rsnie_have=0;
- u16 j;
- u8 SNonce[32];
- u32 *timeout_interval;
- sint parsing_length; //frame body length, without icv_len
- PNDIS_802_11_VARIABLE_IEs pIE;
- u8 FIXED_IE = 5;
- unsigned char supportRate[16];
- int supportRateNum = 0;
-
- psa = get_sa(ptr);
- ptdls_sta = rtw_get_stainfo(pstapriv, psa);
-
- pmyid=myid(&(adapter->eeprompriv));
- ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
- parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
- -prx_pkt_attrib->hdrlen
- -prx_pkt_attrib->iv_len
- -prx_pkt_attrib->icv_len
- -LLC_HEADER_SIZE
- -ETH_TYPE_LEN
- -PAYLOAD_TYPE_LEN
- -FIXED_IE;
-
- if(ptdlsinfo->ap_prohibited == _TRUE)
- {
- goto exit;
- }
-
- if(ptdls_sta==NULL){
- ptdls_sta = rtw_alloc_stainfo(pstapriv, psa);
- }else{
- if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE){
- //If the direct link is already set up
- //Process as re-setup after tear down
- DBG_871X("re-setup a direct link\n");
- }
- //already receiving TDLS setup request
- else if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
- DBG_871X("receive duplicated TDLS setup request frame in handshaking\n");
- goto exit;
- }
- //When receiving and sending setup_req to the same link at the same time, STA with higher MAC_addr would be initiator
- //following is to check out MAC_addr
- else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
- DBG_871X("receive setup_req after sending setup_req\n");
- for (i=0;i<6;i++){
- if(*(pmyid+i)==*(psa+i)){
- }
- else if(*(pmyid+i)>*(psa+i)){
- goto exit;
- }else if(*(pmyid+i)<*(psa+i)){
- ptdls_sta->tdls_sta_state=TDLS_INITIATOR_STATE;
- break;
- }
- }
- }
- }
-
- if(ptdls_sta)
- {
- ptdls_sta->dialog = *(ptr+2); //copy dialog token
- ptdls_sta->stat_code = 0;
-
- //parsing information element
- for(j=FIXED_IE; j<parsing_length;){
-
- pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
-
- switch (pIE->ElementID)
- {
- case _SUPPORTEDRATES_IE_:
- _rtw_memcpy(supportRate, pIE->data, pIE->Length);
- supportRateNum = pIE->Length;
- break;
- case _COUNTRY_IE_:
- break;
- case _EXT_SUPPORTEDRATES_IE_:
- if(supportRateNum<=sizeof(supportRate))
- {
- _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length);
- supportRateNum += pIE->Length;
- }
- break;
- case _SUPPORTED_CH_IE_:
- break;
- case _RSN_IE_2_:
- rsnie_have=1;
- if(prx_pkt_attrib->encrypt){
- prsnie=(u8*)pIE;
- //check whether initiator STA has CCMP pairwise_cipher.
- ppairwise_cipher=prsnie+10;
- _rtw_memcpy(&pairwise_count, (u16*)(ppairwise_cipher-2), 1);
- for(k=0;k<pairwise_count;k++){
- if(_rtw_memcmp( ppairwise_cipher+4*k, RSN_CIPHER_SUITE_CCMP, 4)==_TRUE)
- ccmp_have=1;
- }
- if(ccmp_have==0){
- //invalid contents of RSNIE
- ptdls_sta->stat_code=72;
- }
- }
- break;
- case _EXT_CAP_IE_:
- break;
- case _VENDOR_SPECIFIC_IE_:
- break;
- case _FTIE_:
- if(prx_pkt_attrib->encrypt)
- _rtw_memcpy(SNonce, (ptr+j+52), 32);
- break;
- case _TIMEOUT_ITVL_IE_:
- if(prx_pkt_attrib->encrypt)
- timeout_interval = (u32 *)(ptr+j+3);
- break;
- case _RIC_Descriptor_IE_:
- break;
- case _HT_CAPABILITY_IE_:
- rtw_tdls_process_ht_cap(adapter, ptdls_sta, pIE->data, pIE->Length);
- break;
- case EID_BSSCoexistence:
- break;
- case _LINK_ID_IE_:
- if(_rtw_memcmp(get_bssid(pmlmepriv), pIE->data, 6) == _FALSE)
- {
- //not in the same BSS
- ptdls_sta->stat_code=7;
- }
- break;
- default:
- break;
- }
-
- j += (pIE->Length + 2);
-
- }
-
- //update station supportRate
- ptdls_sta->bssratelen = supportRateNum;
- _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
-
- //check status code
- //if responder STA has/hasn't security on AP, but request hasn't/has RSNIE, it should reject
- if(ptdls_sta->stat_code == 0 )
- {
- if(rsnie_have && (prx_pkt_attrib->encrypt==0)){
- //security disabled
- ptdls_sta->stat_code = 5;
- }else if(rsnie_have==0 && (prx_pkt_attrib->encrypt)){
- //request haven't RSNIE
- ptdls_sta->stat_code = 38;
- }
-
-#ifdef CONFIG_WFD
- //WFD test plan version 0.18.2 test item 5.1.5
- //SoUT does not use TDLS if AP uses weak security
- if ( adapter->wdinfo.wfd_tdls_enable )
- {
- if(rsnie_have && (prx_pkt_attrib->encrypt != _AES_))
- {
- ptdls_sta->stat_code = 5;
- }
- }
-#endif //CONFIG_WFD
- }
-
- ptdls_sta->tdls_sta_state|= TDLS_INITIATOR_STATE;
- if(prx_pkt_attrib->encrypt){
- _rtw_memcpy(ptdls_sta->SNonce, SNonce, 32);
- _rtw_memcpy(&(ptdls_sta->TDLS_PeerKey_Lifetime), timeout_interval, 4);
- }
- _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
- if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
- ptdlsinfo->sta_cnt++;
- _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
- if( ptdlsinfo->sta_cnt == (NUM_STA - 2) ) // -2: AP + BC/MC sta
- {
- ptdlsinfo->sta_maximum = _TRUE;
- }
-
-#ifdef CONFIG_WFD
- rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length - FIXED_IE);
-#endif // CONFIG_WFD
-
- }
- else
- {
- goto exit;
- }
-
- issue_tdls_setup_rsp(adapter, precv_frame);
-
- if(ptdls_sta->stat_code==0)
- {
- _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME);
- }
- else //status code!=0 ; setup unsuccess
- {
- free_tdls_sta(adapter, ptdls_sta);
- }
-
-exit:
-
- return _FAIL;
-}
-
-sint On_TDLS_Setup_Rsp(_adapter *adapter, union recv_frame *precv_frame)
-{
- struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
- struct sta_info *ptdls_sta= NULL;
- struct sta_priv *pstapriv = &adapter->stapriv;
- u8 *ptr = precv_frame->u.hdr.rx_data;
- _irqL irqL;
- struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
- u8 *psa;
- u16 stat_code;
- sint parsing_length; //frame body length, without icv_len
- PNDIS_802_11_VARIABLE_IEs pIE;
- u8 FIXED_IE =7;
- u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic, *ppairwise_cipher;
- u16 pairwise_count, j, k;
- u8 verify_ccmp=0;
- unsigned char supportRate[16];
- int supportRateNum = 0;
-
- psa = get_sa(ptr);
- ptdls_sta = rtw_get_stainfo(pstapriv, psa);
-
- if ( NULL == ptdls_sta )
- {
- return _FAIL;
- }
-
- ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
- parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
- -prx_pkt_attrib->hdrlen
- -prx_pkt_attrib->iv_len
- -prx_pkt_attrib->icv_len
- -LLC_HEADER_SIZE
- -TYPE_LENGTH_FIELD_SIZE
- -1
- -FIXED_IE;
-
- _rtw_memcpy(&stat_code, ptr+2, 2);
-
- if(stat_code!=0)
- {
- DBG_871X( "[%s] status_code = %d, free_tdls_sta\n", __FUNCTION__, stat_code );
- free_tdls_sta(adapter, ptdls_sta);
- return _FAIL;
- }
-
- stat_code = 0;
-
- //parsing information element
- for(j=FIXED_IE; j<parsing_length;)
- {
- pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
-
- switch (pIE->ElementID)
- {
- case _SUPPORTEDRATES_IE_:
- _rtw_memcpy(supportRate, pIE->data, pIE->Length);
- supportRateNum = pIE->Length;
- break;
- case _COUNTRY_IE_:
- break;
- case _EXT_SUPPORTEDRATES_IE_:
- if(supportRateNum<=sizeof(supportRate))
- {
- _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length);
- supportRateNum += pIE->Length;
- }
- break;
- case _SUPPORTED_CH_IE_:
- break;
- case _RSN_IE_2_:
- prsnie=(u8*)pIE;
- //check whether responder STA has CCMP pairwise_cipher.
- ppairwise_cipher=prsnie+10;
- _rtw_memcpy(&pairwise_count, (u16*)(ppairwise_cipher-2), 2);
- for(k=0;k<pairwise_count;k++){
- if(_rtw_memcmp( ppairwise_cipher+4*k, RSN_CIPHER_SUITE_CCMP, 4)==_TRUE)
- verify_ccmp=1;
- }
- case _EXT_CAP_IE_:
- break;
- case _VENDOR_SPECIFIC_IE_:
- break;
- case _FTIE_:
- pftie=(u8*)pIE;
- _rtw_memcpy(ptdls_sta->ANonce, (ptr+j+20), 32);
- break;
- case _TIMEOUT_ITVL_IE_:
- ptimeout_ie=(u8*)pIE;
- break;
- case _RIC_Descriptor_IE_:
- break;
- case _HT_CAPABILITY_IE_:
- rtw_tdls_process_ht_cap(adapter, ptdls_sta, pIE->data, pIE->Length);
- break;
- case EID_BSSCoexistence:
- break;
- case _LINK_ID_IE_:
- plinkid_ie=(u8*)pIE;
- break;
- default:
- break;
- }
-
- j += (pIE->Length + 2);
-
- }
-
- //update station supportRate
- ptdls_sta->bssratelen = supportRateNum;
- _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
-
-#ifdef CONFIG_WFD
- rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length - FIXED_IE);
-#endif // CONFIG_WFD
-
- if(stat_code != 0)
- {
- ptdls_sta->stat_code = stat_code;
- }
- else
- {
- if(prx_pkt_attrib->encrypt)
- {
- if(verify_ccmp==1)
- {
- wpa_tdls_generate_tpk(adapter, ptdls_sta);
- ptdls_sta->stat_code=0;
- if(tdls_verify_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie)==0) //0: Invalid, 1: valid
- {
- free_tdls_sta(adapter, ptdls_sta);
- return _FAIL;
- }
- }
- else
- {
- ptdls_sta->stat_code=72; //invalide contents of RSNIE
- }
-
- }else{
- ptdls_sta->stat_code=0;
- }
- }
-
- DBG_871X("issue_tdls_setup_cfm\n");
- issue_tdls_setup_cfm(adapter, precv_frame);
-
- if(ptdls_sta->stat_code==0)
- {
- ptdlsinfo->setup_state = TDLS_LINKED_STATE;
-
- if( ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE )
- {
- ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
- _cancel_timer_ex( &ptdls_sta->handshake_timer);
-#ifdef CONFIG_TDLS_AUTOCHECKALIVE
- _set_timer( &ptdls_sta->alive_timer1, TDLS_ALIVE_TIMER_PH1);
-#endif //CONFIG_TDLS_AUTOSETUP
- }
-
- rtw_tdls_set_mac_id(ptdlsinfo, ptdls_sta);
- rtw_tdls_set_key(adapter, prx_pkt_attrib, ptdls_sta);
-
- rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_WRCR);
-
- }
- else //status code!=0 ; setup unsuccessful
- {
- free_tdls_sta(adapter, ptdls_sta);
- }
-
- return _FAIL;
-
-}
-
-sint On_TDLS_Setup_Cfm(_adapter *adapter, union recv_frame *precv_frame)
-{
- struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
- struct sta_info *ptdls_sta= NULL;
- struct sta_priv *pstapriv = &adapter->stapriv;
- u8 *ptr = precv_frame->u.hdr.rx_data;
- _irqL irqL;
- struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
- u8 *psa;
- u16 stat_code;
- sint parsing_length;
- PNDIS_802_11_VARIABLE_IEs pIE;
- u8 FIXED_IE =5;
- u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic, *ppairwise_cipher;
- u16 j, pairwise_count;
-
- psa = get_sa(ptr);
- ptdls_sta = rtw_get_stainfo(pstapriv, psa);
-
- ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
- parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
- -prx_pkt_attrib->hdrlen
- -prx_pkt_attrib->iv_len
- -prx_pkt_attrib->icv_len
- -LLC_HEADER_SIZE
- -ETH_TYPE_LEN
- -PAYLOAD_TYPE_LEN
- -FIXED_IE;
- _rtw_memcpy(&stat_code, ptr+2, 2);
-
- if(stat_code!=0){
- DBG_871X( "[%s] stat_code = %d\n, free_tdls_sta", __FUNCTION__, stat_code );
- free_tdls_sta(adapter, ptdls_sta);
- return _FAIL;
- }
-
- if(prx_pkt_attrib->encrypt){
- //parsing information element
- for(j=FIXED_IE; j<parsing_length;){
-
- pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
-
- switch (pIE->ElementID)
- {
- case _RSN_IE_2_:
- prsnie=(u8*)pIE;
- break;
- case _VENDOR_SPECIFIC_IE_:
- break;
- case _FTIE_:
- pftie=(u8*)pIE;
- break;
- case _TIMEOUT_ITVL_IE_:
- ptimeout_ie=(u8*)pIE;
- break;
- case _HT_EXTRA_INFO_IE_:
- break;
- case _LINK_ID_IE_:
- plinkid_ie=(u8*)pIE;
- break;
- default:
- break;
- }
-
- j += (pIE->Length + 2);
-
- }
-
- //verify mic in FTIE MIC field
- if(tdls_verify_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie)==0){ //0: Invalid, 1: Valid
- free_tdls_sta(adapter, ptdls_sta);
- return _FAIL;
- }
-
- }
-
- ptdlsinfo->setup_state = TDLS_LINKED_STATE;
- if( ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE )
- {
- ptdls_sta->tdls_sta_state|=TDLS_LINKED_STATE;
- _cancel_timer_ex( &ptdls_sta->handshake_timer);
-#ifdef CONFIG_TDLS_AUTOCHECKALIVE
- _set_timer( &ptdls_sta->alive_timer1, TDLS_ALIVE_TIMER_PH1);
-#endif //CONFIG_TDLS_AUTOCHECKALIVE
- }
-
- rtw_tdls_set_mac_id(ptdlsinfo, ptdls_sta);
- rtw_tdls_set_key(adapter, prx_pkt_attrib, ptdls_sta);
-
- rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_WRCR);
-
- return _FAIL;
-
-}
-
-sint On_TDLS_Dis_Req(_adapter *adapter, union recv_frame *precv_frame)
-{
- struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
- struct sta_priv *pstapriv = &adapter->stapriv;
- struct sta_info *psta_ap;
- u8 *ptr = precv_frame->u.hdr.rx_data;
- sint parsing_length; //frame body length, without icv_len
- PNDIS_802_11_VARIABLE_IEs pIE;
- u8 FIXED_IE = 3, *dst, *pdialog = NULL;
- u16 j;
-
- ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE + 1;
- pdialog=ptr+2;
-
- parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
- -prx_pkt_attrib->hdrlen
- -prx_pkt_attrib->iv_len
- -prx_pkt_attrib->icv_len
- -LLC_HEADER_SIZE
- -TYPE_LENGTH_FIELD_SIZE
- -1
- -FIXED_IE;
-
- //parsing information element
- for(j=FIXED_IE; j<parsing_length;){
-
- pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
-
- switch (pIE->ElementID)
- {
- case _LINK_ID_IE_:
- psta_ap = rtw_get_stainfo(pstapriv, pIE->data);
- if(psta_ap == NULL)
- {
- goto exit;
- }
- dst = pIE->data + 12;
- if( (MacAddr_isBcst(dst) == _FALSE) && (_rtw_memcmp(myid(&(adapter->eeprompriv)), dst, 6) == _FALSE) )
- {
- goto exit;
- }
- break;
- default:
- break;
- }
-
- j += (pIE->Length + 2);
-
- }
-
- //check frame contents
-
- issue_tdls_dis_rsp(adapter, precv_frame, *(pdialog) );
-
-exit:
-
- return _FAIL;
-
-}
-
-sint On_TDLS_Teardown(_adapter *adapter, union recv_frame *precv_frame)
-{
- u8 *psa;
- u8 *ptr = precv_frame->u.hdr.rx_data;
- struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
- struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct sta_priv *pstapriv = &adapter->stapriv;
- struct sta_info *ptdls_sta= NULL;
- _irqL irqL;
-
- psa = get_sa(ptr);
-
- ptdls_sta = rtw_get_stainfo(pstapriv, psa);
- if(ptdls_sta!=NULL){
- if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE){
- rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
- }
- free_tdls_sta(adapter, ptdls_sta);
- }
-
- return _FAIL;
-
-}
-
-u8 TDLS_check_ch_state(uint state){
- if( (state & TDLS_CH_SWITCH_ON_STATE) &&
- (state & TDLS_AT_OFF_CH_STATE) &&
- (state & TDLS_PEER_AT_OFF_STATE) ){
-
- if(state & TDLS_PEER_SLEEP_STATE)
- return 2; //U-APSD + ch. switch
- else
- return 1; //ch. switch
- }else
- return 0;
-}
-
-//we process buffered data for 1. U-APSD, 2. ch. switch, 3. U-APSD + ch. switch here
-sint On_TDLS_Peer_Traffic_Rsp(_adapter *adapter, union recv_frame *precv_frame)
-{
- struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
- struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
- struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
- struct sta_priv *pstapriv = &adapter->stapriv;
- //get peer sta infomation
- struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src);
- u8 wmmps_ac=0, state=TDLS_check_ch_state(ptdls_sta->tdls_sta_state);
- int i;
-
- ptdls_sta->sta_stats.rx_data_pkts++;
-
- //receive peer traffic response frame, sleeping STA wakes up
- //ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_SLEEP_STATE);
- process_wmmps_data( adapter, precv_frame);
-
- // if noticed peer STA wakes up by receiving peer traffic response
- // and we want to do channel swtiching, then we will transmit channel switch request first
- if(ptdls_sta->tdls_sta_state & TDLS_APSD_CHSW_STATE){
- issue_tdls_ch_switch_req(adapter, pattrib->src);
- ptdls_sta->tdls_sta_state &= ~(TDLS_APSD_CHSW_STATE);
- return _FAIL;
- }
-
- //check 4-AC queue bit
- if(ptdls_sta->uapsd_vo || ptdls_sta->uapsd_vi || ptdls_sta->uapsd_be || ptdls_sta->uapsd_bk)
- wmmps_ac=1;
-
- //if it's a direct link and have buffered frame
- if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE){
- if(wmmps_ac && state)
- {
- _irqL irqL;
- _list *xmitframe_plist, *xmitframe_phead;
- struct xmit_frame *pxmitframe=NULL;
-
- _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
-
- xmitframe_phead = get_list_head(&ptdls_sta->sleep_q);
- xmitframe_plist = get_next(xmitframe_phead);
-
- //transmit buffered frames
- while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
- {
- pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
- xmitframe_plist = get_next(xmitframe_plist);
- rtw_list_delete(&pxmitframe->list);
-
- ptdls_sta->sleepq_len--;
- if(ptdls_sta->sleepq_len>0){
- pxmitframe->attrib.mdata = 1;
- pxmitframe->attrib.eosp = 0;
- }else{
- pxmitframe->attrib.mdata = 0;
- pxmitframe->attrib.eosp = 1;
- }
- //pxmitframe->attrib.triggered = 1; //maybe doesn't need in TDLS
- if(adapter->HalFunc.hal_xmit(adapter, pxmitframe) == _TRUE)
- {
- rtw_os_xmit_complete(adapter, pxmitframe);
- }
-
- }
-
- if(ptdls_sta->sleepq_len==0)
- {
- DBG_871X("no buffered packets for tdls to xmit\n");
- //on U-APSD + CH. switch state, when there is no buffered date to xmit,
- // we should go back to base channel
- if(state==2){
- rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
- }else if(ptdls_sta->tdls_sta_state&TDLS_SW_OFF_STATE){
- ptdls_sta->tdls_sta_state &= ~(TDLS_SW_OFF_STATE);
- ptdlsinfo->candidate_ch= pmlmeext->cur_channel;
- issue_tdls_ch_switch_req(adapter, pattrib->src);
- DBG_871X("issue tdls ch switch req back to base channel\n");
- }
-
- }
- else
- {
- DBG_871X("error!psta->sleepq_len=%d\n", ptdls_sta->sleepq_len);
- ptdls_sta->sleepq_len=0;
- }
-
- _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
-
- }
-
- }
-
- return _FAIL;
-}
-
-sint On_TDLS_Ch_Switch_Req(_adapter *adapter, union recv_frame *precv_frame)
-{
- struct sta_info *ptdls_sta= NULL;
- struct sta_priv *pstapriv = &adapter->stapriv;
- u8 *ptr = precv_frame->u.hdr.rx_data;
- struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
- u8 *psa;
- sint parsing_length;
- PNDIS_802_11_VARIABLE_IEs pIE;
- u8 FIXED_IE =3;
- u16 j;
- struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
-
- psa = get_sa(ptr);
- ptdls_sta = rtw_get_stainfo(pstapriv, psa);
-
- ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
- parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
- -prx_pkt_attrib->hdrlen
- -prx_pkt_attrib->iv_len
- -prx_pkt_attrib->icv_len
- -LLC_HEADER_SIZE
- -ETH_TYPE_LEN
- -PAYLOAD_TYPE_LEN
- -FIXED_IE;
-
- ptdls_sta->off_ch = *(ptr+2);
-
- //parsing information element
- for(j=FIXED_IE; j<parsing_length;){
-
- pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
-
- switch (pIE->ElementID)
- {
- case _COUNTRY_IE_:
- break;
- case _CH_SWTICH_ANNOUNCE_:
- break;
- case _LINK_ID_IE_:
- break;
- case _CH_SWITCH_TIMING_:
- _rtw_memcpy(&ptdls_sta->ch_switch_time, pIE->data, 2);
- _rtw_memcpy(&ptdls_sta->ch_switch_timeout, pIE->data+2, 2);
- default:
- break;
- }
-
- j += (pIE->Length + 2);
-
- }
-
- //todo: check status
- ptdls_sta->stat_code=0;
- ptdls_sta->tdls_sta_state |= TDLS_CH_SWITCH_ON_STATE;
-
- issue_nulldata(adapter, NULL, 1, 0, 0);
-
- issue_tdls_ch_switch_rsp(adapter, psa);
-
- DBG_871X("issue tdls channel switch response\n");
-
- if((ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE) && ptdls_sta->off_ch==pmlmeext->cur_channel){
- DBG_871X("back to base channel %x\n", pmlmeext->cur_channel);
- ptdls_sta->option=7;
- rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_BASE_CH);
- }else{
- ptdls_sta->option=6;
- rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_OFF_CH);
- }
- return _FAIL;
-}
-
-sint On_TDLS_Ch_Switch_Rsp(_adapter *adapter, union recv_frame *precv_frame)
-{
- struct sta_info *ptdls_sta= NULL;
- struct sta_priv *pstapriv = &adapter->stapriv;
- u8 *ptr = precv_frame->u.hdr.rx_data;
- struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
- u8 *psa;
- sint parsing_length;
- PNDIS_802_11_VARIABLE_IEs pIE;
- u8 FIXED_IE =4;
- u16 stat_code, j, switch_time, switch_timeout;
- struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
-
- psa = get_sa(ptr);
- ptdls_sta = rtw_get_stainfo(pstapriv, psa);
-
- //if channel switch is running and receiving Unsolicited TDLS Channel Switch Response,
- //it will go back to base channel and terminate this channel switch procedure
- if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE ){
- if(pmlmeext->cur_channel==ptdls_sta->off_ch){
- DBG_871X("back to base channel %x\n", pmlmeext->cur_channel);
- ptdls_sta->option=7;
- rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_OFF_CH);
- }else{
- DBG_871X("receive unsolicited channel switch response \n");
- rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
- }
- return _FAIL;
- }
-
- //avoiding duplicated or unconditional ch. switch. rsp
- if((ptdls_sta->tdls_sta_state & TDLS_CH_SW_INITIATOR_STATE) != TDLS_CH_SW_INITIATOR_STATE)
- return _FAIL;
-
- ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
- parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
- -prx_pkt_attrib->hdrlen
- -prx_pkt_attrib->iv_len
- -prx_pkt_attrib->icv_len
- -LLC_HEADER_SIZE
- -ETH_TYPE_LEN
- -PAYLOAD_TYPE_LEN
- -FIXED_IE;
-
- _rtw_memcpy(&stat_code, ptr+2, 2);
-
- if(stat_code!=0){
- return _FAIL;
- }
-
- //parsing information element
- for(j=FIXED_IE; j<parsing_length;){
-
- pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
-
- switch (pIE->ElementID)
- {
- case _LINK_ID_IE_:
- break;
- case _CH_SWITCH_TIMING_:
- _rtw_memcpy(&switch_time, pIE->data, 2);
- if(switch_time > ptdls_sta->ch_switch_time)
- _rtw_memcpy(&ptdls_sta->ch_switch_time, &switch_time, 2);
-
- _rtw_memcpy(&switch_timeout, pIE->data+2, 2);
- if(switch_timeout > ptdls_sta->ch_switch_timeout)
- _rtw_memcpy(&ptdls_sta->ch_switch_timeout, &switch_timeout, 2);
-
- default:
- break;
- }
-
- j += (pIE->Length + 2);
-
- }
-
- ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SW_INITIATOR_STATE);
- ptdls_sta->tdls_sta_state |=TDLS_CH_SWITCH_ON_STATE;
-
- //goto set_channel_workitem_callback()
- ptdls_sta->option=6;
- rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_OFF_CH);
-
- return _FAIL;
-}
-
-#ifdef CONFIG_WFD
-void wfd_ie_tdls(_adapter * padapter, u8 *pframe, u32 *pktlen )
-{
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct wifi_display_info *pwfd_info = padapter->tdlsinfo.wfd_info;
- u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
- u32 wfdielen = 0;
-
- // WFD OUI
- wfdielen = 0;
- wfdie[ wfdielen++ ] = 0x50;
- wfdie[ wfdielen++ ] = 0x6F;
- wfdie[ wfdielen++ ] = 0x9A;
- wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
-
- // Commented by Albert 20110825
- // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
- // 1. WFD Device Information
- // 2. Associated BSSID ( Optional )
- // 3. Local IP Adress ( Optional )
-
- // WFD Device Information ATTR
- // Type:
- wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
-
- // Length:
- // Note: In the WFD specification, the size of length field is 2.
- RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
- wfdielen += 2;
-
- // Value1:
- // WFD device information
- // available for WFD session + Preferred TDLS + WSD ( WFD Service Discovery )
- RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL
- | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_WSD);
- wfdielen += 2;
-
- // Value2:
- // Session Management Control Port
- // Default TCP port for RTSP messages is 554
- RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
- wfdielen += 2;
-
- // Value3:
- // WFD Device Maximum Throughput
- // 300Mbps is the maximum throughput
- RTW_PUT_BE16(wfdie + wfdielen, 300);
- wfdielen += 2;
-
- // Associated BSSID ATTR
- // Type:
- wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
-
- // Length:
- // Note: In the WFD specification, the size of length field is 2.
- RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
- wfdielen += 2;
-
- // Value:
- // Associated BSSID
- if ( check_fwstate( pmlmepriv, _FW_LINKED) == _TRUE )
- {
- _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
- }
- else
- {
- _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
- }
-
- // Local IP Address ATTR
- wfdie[ wfdielen++ ] = WFD_ATTR_LOCAL_IP_ADDR;
-
- // Length:
- // Note: In the WFD specification, the size of length field is 2.
- RTW_PUT_BE16(wfdie + wfdielen, 0x0005);
- wfdielen += 2;
-
- // Version:
- // 0x01: Version1;IPv4
- wfdie[ wfdielen++ ] = 0x01;
-
- // IPv4 Address
- _rtw_memcpy( wfdie + wfdielen, pwfd_info->ip_address, 4 );
- wfdielen += 4;
-
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, pktlen);
-
-}
-#endif //CONFIG_WFD
-
-void rtw_build_tdls_setup_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
- struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst);
-
- u8 payload_type = 0x02;
- u8 category = RTW_WLAN_CATEGORY_TDLS;
- u8 action = TDLS_SETUP_REQUEST;
- u8 bssrate[NDIS_802_11_LENGTH_RATES_EX]; //Use NDIS_802_11_LENGTH_RATES_EX in order to call func.rtw_set_supported_rate
- int bssrate_len = 0, i = 0 ;
- u8 more_supportedrates = 0;
- unsigned int ie_len;
- u8 *p;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- u8 link_id_addr[18] = {0};
- u8 iedata=0;
- u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel
- u8 timeout_itvl[5]; //set timeout interval to maximum value
- u32 time;
-
- //SNonce
- if(pattrib->encrypt){
- for(i=0;i<8;i++){
- time=rtw_get_current_time();
- _rtw_memcpy(&ptdls_sta->SNonce[4*i], (u8 *)&time, 4);
- }
- }
-
- //payload type
- pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
- //category, action, dialog token
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
-
- //capability
- _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
-
- if(pattrib->encrypt)
- *pframe =*pframe | BIT(4);
- pframe += 2;
- pattrib->pktlen += 2;
-
- //supported rates
- rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
- bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
-
- if (bssrate_len > 8)
- {
- pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
- more_supportedrates = 1;
- }
- else
- {
- pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
- }
-
- //country(optional)
- //extended supported rates
- if(more_supportedrates==1){
- pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
- }
-
- //supported channels
- pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
-
- // SRC IE
- pframe = rtw_set_ie( pframe, _SRC_IE_, 16, TDLS_SRC, &(pattrib->pktlen));
-
- //RSNIE
- if(pattrib->encrypt)
- pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen));
-
- //extended capabilities
- pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , 5, TDLS_EXT_CAPIE, &(pattrib->pktlen));
-
- //QoS capability(WMM_IE)
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 7, TDLS_WMMIE, &(pattrib->pktlen));
-
-
- if(pattrib->encrypt){
- //FTIE
- _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
- _rtw_memset(pframe, _FTIE_, 1); //version
- _rtw_memset((pframe+1), 82, 1); //length
- _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
- pframe += 84;
- pattrib->pktlen += 84;
-
- //Timeout interval
- timeout_itvl[0]=0x02;
- _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
- pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
- }
-
- //Sup_reg_classes(optional)
- //HT capabilities
- pframe = rtw_tdls_set_ht_cap(padapter, pframe, pattrib);
-
- //20/40 BSS coexistence
- if(pmlmepriv->num_FortyMHzIntolerant>0)
- iedata |= BIT(2);//20 MHz BSS Width Request
- pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
-
- //Link identifier
- _rtw_memcpy(link_id_addr, pattrib->ra, 6);
- _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
- _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
- pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
-
-#ifdef CONFIG_WFD
- wfd_ie_tdls( padapter, pframe, &(pattrib->pktlen) );
-#endif //CONFIG_WFD
-
-}
-
-void rtw_build_tdls_setup_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
-{
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct sta_info *ptdls_sta;
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
-
- u8 payload_type = 0x02;
- unsigned char category = RTW_WLAN_CATEGORY_TDLS;
- unsigned char action = TDLS_SETUP_RESPONSE;
- unsigned char bssrate[NDIS_802_11_LENGTH_RATES_EX];
- int bssrate_len = 0;
- u8 more_supportedrates = 0;
- unsigned int ie_len;
- unsigned char *p;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- u8 link_id_addr[18] = {0};
- u8 iedata=0;
- u8 timeout_itvl[5]; //setup response timeout interval will copy from request
- u8 ANonce[32]; //maybe it can put in ontdls_req
- u8 k; //for random ANonce
- u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic;
- u32 time;
-
- ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst);
-
- if(ptdls_sta == NULL )
- {
- DBG_871X("[%s] %d\n", __FUNCTION__, __LINE__);
- return;
- }
-
- if(pattrib->encrypt){
- for(k=0;k<8;k++){
- time=rtw_get_current_time();
- _rtw_memcpy(&ptdls_sta->ANonce[4*k], (u8*)&time, 4);
- }
- }
-
- //payload type
- pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
- //category, action, status code
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
-
- if(ptdls_sta->stat_code!=0) //invalid setup request
- {
- DBG_871X("ptdls_sta->stat_code:%04x \n", ptdls_sta->stat_code);
- return;
- }
-
- //dialog token
- pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
-
- //capability
- _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
-
- if(pattrib->encrypt )
- *pframe =*pframe | BIT(4);
- pframe += 2;
- pattrib->pktlen += 2;
-
- //supported rates
- rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
- bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
-
- if (bssrate_len > 8)
- {
- pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
- more_supportedrates = 1;
- }
- else
- {
- pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
- }
-
- //country(optional)
- //extended supported rates
- if(more_supportedrates==1){
- pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
- }
-
- //supported channels
- pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
-
- // SRC IE
- pframe = rtw_set_ie(pframe, _SRC_IE_ , 16, TDLS_SRC, &(pattrib->pktlen));
-
- //RSNIE
- if(pattrib->encrypt){
- prsnie = pframe;
- pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen));
- }
-
- //extended capabilities
- pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , 5, TDLS_EXT_CAPIE, &(pattrib->pktlen));
-
- //QoS capability(WMM_IE)
- pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 7, TDLS_WMMIE, &(pattrib->pktlen));
-
- if(pattrib->encrypt){
- wpa_tdls_generate_tpk(padapter, ptdls_sta);
-
- //FTIE
- pftie = pframe;
- pftie_mic = pframe+4;
- _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
- _rtw_memset(pframe, _FTIE_, 1); //version
- _rtw_memset((pframe+1), 82, 1); //length
- _rtw_memcpy((pframe+20), ptdls_sta->ANonce, 32);
- _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
- pframe += 84;
- pattrib->pktlen += 84;
-
- //Timeout interval
- ptimeout_ie = pframe;
- timeout_itvl[0]=0x02;
- _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
- pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
- }
-
- //Sup_reg_classes(optional)
- //HT capabilities
- pframe = rtw_tdls_set_ht_cap(padapter, pframe, pattrib);
-
- //20/40 BSS coexistence
- if(pmlmepriv->num_FortyMHzIntolerant>0)
- iedata |= BIT(2);//20 MHz BSS Width Request
- pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
-
- //Link identifier
- plinkid_ie = pframe;
- _rtw_memcpy(link_id_addr, pattrib->ra, 6);
- _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
- _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
- pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
-
- //fill FTIE mic
- if(pattrib->encrypt)
- wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
-
-#ifdef CONFIG_WFD
- wfd_ie_tdls( padapter, pframe, &(pattrib->pktlen) );
-#endif //CONFIG_WFD
-
-}
-
-void rtw_build_tdls_setup_cfm_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
-{
-
- struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
- struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst);
-
- u8 payload_type = 0x02;
- unsigned char category = RTW_WLAN_CATEGORY_TDLS;
- unsigned char action = TDLS_SETUP_CONFIRM;
- u8 more_supportedrates = 0;
- unsigned int ie_len;
- unsigned char *p;
- u8 timeout_itvl[5]; //set timeout interval to maximum value
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- u8 link_id_addr[18] = {0};
- u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic;
-
- //payload type
- pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
- //category, action, status code, dialog token
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
-
- if(ptdls_sta->stat_code!=0) //invalid setup request
- return;
-
- //RSNIE
- if(pattrib->encrypt){
- prsnie = pframe;
- pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen));
- }
-
- //EDCA param set; WMM param ele.
- if(pattrib->encrypt){
- //FTIE
- pftie = pframe;
- pftie_mic = pframe+4;
- _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
- _rtw_memset(pframe, _FTIE_, 1); //version
- _rtw_memset((pframe+1), 82, 1); //length
- _rtw_memcpy((pframe+20), ptdls_sta->ANonce, 32);
- _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
- pframe += 84;
- pattrib->pktlen += 84;
-
- //Timeout interval
- ptimeout_ie = pframe;
- timeout_itvl[0]=0x02;
- _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
- ptdls_sta->TPK_count=0;
- _set_timer(&ptdls_sta->TPK_timer, ptdls_sta->TDLS_PeerKey_Lifetime/TPK_RESEND_COUNT);
- pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
- }
-
- //HT operation; todo
- //Link identifier
- plinkid_ie = pframe;
- _rtw_memcpy(link_id_addr, pattrib->ra, 6);
- _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
- _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
- pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
-
- //fill FTIE mic
- if(pattrib->encrypt)
- wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
-
-}
-
-void rtw_build_tdls_teardown_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
-{
-
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- u8 payload_type = 0x02;
- unsigned char category = RTW_WLAN_CATEGORY_TDLS;
- unsigned char action = TDLS_TEARDOWN;
- u8 link_id_addr[18] = {0};
-
- struct sta_info *ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst);
- struct sta_priv *pstapriv = &padapter->stapriv;
-
- //payload type
- pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
- //category, action, reason code
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
-
- //Link identifier
- if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
- _rtw_memcpy(link_id_addr, pattrib->ra, 6);
- _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
- _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
- }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
- _rtw_memcpy(link_id_addr, pattrib->ra, 6);
- _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
- _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
- }
- pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
-
-}
-
-void rtw_build_tdls_dis_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
-{
-
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- u8 payload_type = 0x02;
- u8 category = RTW_WLAN_CATEGORY_TDLS;
- u8 action = TDLS_DISCOVERY_REQUEST;
- u8 link_id_addr[18] = {0};
- static u8 dialogtoken=0;
-
- //payload type
- pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
- //category, action, reason code
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(dialogtoken), &(pattrib->pktlen));
- dialogtoken = (dialogtoken+1)%256;
-
- //Link identifier
- _rtw_memcpy(link_id_addr, pattrib->ra, 6);
- _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
- _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
- pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
-
-}
-
-void rtw_build_tdls_dis_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, u8 dialog)
-{
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct registry_priv *pregistrypriv = &padapter->registrypriv;
-
- u8 category = RTW_WLAN_CATEGORY_PUBLIC;
- u8 action = TDLS_DISCOVERY_RESPONSE;
- u8 bssrate[NDIS_802_11_LENGTH_RATES_EX];
- int bssrate_len = 0;
- u8 more_supportedrates = 0;
- u8 *p;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- u8 link_id_addr[18] = {0};
- u8 iedata=0;
- u8 timeout_itvl[5]; //set timeout interval to maximum value
- u32 timeout_interval= TPK_RESEND_COUNT * 1000;
-
- //category, action, dialog token
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(dialog), &(pattrib->pktlen));
-
- //capability
- _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
-
- if(pattrib->encrypt)
- *pframe =*pframe | BIT(4);
- pframe += 2;
- pattrib->pktlen += 2;
-
- //supported rates
- rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
- bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
-
- if (bssrate_len > 8)
- {
- pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
- more_supportedrates = 1;
- }
- else
- {
- pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
- }
-
- //extended supported rates
- if(more_supportedrates==1){
- pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
- }
-
- //supported channels
- pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
-
- //RSNIE
- if(pattrib->encrypt)
- pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen));
-
- //extended capability
- pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , 5, TDLS_EXT_CAPIE, &(pattrib->pktlen));
-
- if(pattrib->encrypt){
- //FTIE
- _rtw_memset(pframe, 0, 84); //All fields shall be set to 0
- _rtw_memset(pframe, _FTIE_, 1); //version
- _rtw_memset((pframe+1), 82, 1); //length
- pframe += 84;
- pattrib->pktlen += 84;
-
- //Timeout interval
- timeout_itvl[0]=0x02;
- _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4);
- pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
- }
-
- //Sup_reg_classes(optional)
- //HT capabilities
- pframe = rtw_tdls_set_ht_cap(padapter, pframe, pattrib);
-
- //20/40 BSS coexistence
- if(pmlmepriv->num_FortyMHzIntolerant>0)
- iedata |= BIT(2);//20 MHz BSS Width Request
- pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
-
- //Link identifier
- _rtw_memcpy(link_id_addr, pattrib->ra, 6);
- _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
- _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
- pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
-
-}
-
-void rtw_build_tdls_peer_traffic_indication_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
-{
-
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- u8 payload_type = 0x02;
- unsigned char category = RTW_WLAN_CATEGORY_TDLS;
- unsigned char action = TDLS_PEER_TRAFFIC_INDICATION;
-
- u8 link_id_addr[18] = {0};
- u8 AC_queue=0;
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
-
- //payload type
- pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
- //category, action, reason code
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
-
- //Link identifier
- _rtw_memcpy(link_id_addr, pattrib->ra, 6);
- _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
- _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
- pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
-
- //PTI control
- //PU buffer status
- if(ptdls_sta->uapsd_bk&BIT(1))
- AC_queue=BIT(0);
- if(ptdls_sta->uapsd_be&BIT(1))
- AC_queue=BIT(1);
- if(ptdls_sta->uapsd_vi&BIT(1))
- AC_queue=BIT(2);
- if(ptdls_sta->uapsd_vo&BIT(1))
- AC_queue=BIT(3);
- pframe = rtw_set_ie(pframe, _PTI_BUFFER_STATUS_, 1, &AC_queue, &(pattrib->pktlen));
-
-}
-
-void rtw_build_tdls_ch_switch_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
-{
-
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
- u8 payload_type = 0x02;
- unsigned char category = RTW_WLAN_CATEGORY_TDLS;
- unsigned char action = TDLS_CHANNEL_SWITCH_REQUEST;
- u8 link_id_addr[18] = {0};
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
- u8 ch_switch_timing[4] = {0};
- u16 switch_time= CH_SWITCH_TIME, switch_timeout=CH_SWITCH_TIMEOUT;
-
- //payload type
- pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
- //category, action, target_ch
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(ptdlsinfo->candidate_ch), &(pattrib->pktlen));
-
- //Link identifier
- _rtw_memcpy(link_id_addr, pattrib->ra, 6);
- _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
- _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
- pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
-
- //ch switch timing
- _rtw_memcpy(ch_switch_timing, &switch_time, 2);
- _rtw_memcpy(ch_switch_timing+2, &switch_timeout, 2);
- pframe = rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen));
-
- //update ch switch attrib to sta_info
- ptdls_sta->off_ch=ptdlsinfo->candidate_ch;
- ptdls_sta->ch_switch_time=switch_time;
- ptdls_sta->ch_switch_timeout=switch_timeout;
-
-}
-
-void rtw_build_tdls_ch_switch_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
-{
-
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- u8 payload_type = 0x02;
- unsigned char category = RTW_WLAN_CATEGORY_TDLS;
- unsigned char action = TDLS_CHANNEL_SWITCH_RESPONSE;
- u8 link_id_addr[18] = {0};
- struct sta_priv *pstapriv = &padapter->stapriv;
- struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
- struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
- struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
- u8 ch_switch_timing[4] = {0};
-
- //payload type
- pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
- //category, action, status_code
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
-
- //Link identifier
- _rtw_memcpy(link_id_addr, pattrib->ra, 6);
- _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
- _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
- pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
-
- //ch switch timing
- _rtw_memcpy(ch_switch_timing, &ptdls_sta->ch_switch_time, 2);
- _rtw_memcpy(ch_switch_timing+2, &ptdls_sta->ch_switch_timeout, 2);
- pframe = rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen));
-
-}
-
-#ifdef CONFIG_WFD
-void rtw_build_tunneled_probe_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
-{
-
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo;
- u8 payload_type = 0x02;
- u8 category = RTW_WLAN_CATEGORY_P2P;
- u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
- u8 probe_req = 4;
- u8 wfdielen = 0;
-
- //payload type
- pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
- //category, OUI, frame_body_type
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(probe_req), &(pattrib->pktlen));
-
- if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- {
- wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
- }
- else if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
- {
- wfdielen = build_probe_req_wfd_ie(pbuddy_wdinfo, pframe);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
- }
-
-}
-
-void rtw_build_tunneled_probe_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
-{
-
- struct pkt_attrib *pattrib = &pxmitframe->attrib;
- struct wifidirect_info *pwdinfo = &padapter->wdinfo;
- struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo;
- u8 payload_type = 0x02;
- u8 category = RTW_WLAN_CATEGORY_P2P;
- u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
- u8 probe_rsp = 5;
- u8 wfdielen = 0;
-
- //payload type
- pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
- //category, OUI, frame_body_type
- pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
- pframe = rtw_set_fixed_ie(pframe, 1, &(probe_rsp), &(pattrib->pktlen));
-
- if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
- {
- wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 1);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
- }
- else if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
- {
- wfdielen = build_probe_resp_wfd_ie(pbuddy_wdinfo, pframe, 1);
- pframe += wfdielen;
- pattrib->pktlen += wfdielen;
- }
-
-}
-#endif //CONFIG_WFD
-
-void _TPK_timer_hdl(void *FunctionContext)
-{
- struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
-
- ptdls_sta->TPK_count++;
- //TPK_timer set 1000 as default
- //retry timer should set at least 301 sec.
- if(ptdls_sta->TPK_count==TPK_RESEND_COUNT){
- ptdls_sta->TPK_count=0;
- issue_tdls_setup_req(ptdls_sta->padapter, ptdls_sta->hwaddr);
- }
-
- _set_timer(&ptdls_sta->TPK_timer, ptdls_sta->TDLS_PeerKey_Lifetime/TPK_RESEND_COUNT);
-}
-
-void init_TPK_timer(_adapter *padapter, struct sta_info *psta)
-{
- psta->padapter=padapter;
-
- _init_timer(&psta->TPK_timer, padapter->pnetdev, _TPK_timer_hdl, psta);
-}
-
-// TDLS_DONE_CH_SEN: channel sensing and report candidate channel
-// TDLS_OFF_CH: first time set channel to off channel
-// TDLS_BASE_CH: when go back to the channel linked with AP, send null data to peer STA as an indication
-void _ch_switch_timer_hdl(void *FunctionContext)
-{
-
- struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
- _adapter *padapter = ptdls_sta->padapter;
-
- if( ptdls_sta->option == TDLS_DONE_CH_SEN ){
- rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_DONE_CH_SEN);
- }else if( ptdls_sta->option == TDLS_OFF_CH ){
- issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta, 0);
- _set_timer(&ptdls_sta->base_ch_timer, 500);
- }else if( ptdls_sta->option == TDLS_BASE_CH){
- issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta, 0);
- }
-}
-
-void init_ch_switch_timer(_adapter *padapter, struct sta_info *psta)
-{
- psta->padapter=padapter;
- _init_timer(&psta->option_timer, padapter->pnetdev, _ch_switch_timer_hdl, psta);
-}
-
-void _base_ch_timer_hdl(void *FunctionContext)
-{
- struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
- rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_P_OFF_CH);
-}
-
-void init_base_ch_timer(_adapter *padapter, struct sta_info *psta)
-{
- psta->padapter=padapter;
- _init_timer(&psta->base_ch_timer, padapter->pnetdev, _base_ch_timer_hdl, psta);
-}
-
-void _off_ch_timer_hdl(void *FunctionContext)
-{
- struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
- rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_P_BASE_CH );
-}
-
-void init_off_ch_timer(_adapter *padapter, struct sta_info *psta)
-{
- psta->padapter=padapter;
- _init_timer(&psta->off_ch_timer, padapter->pnetdev, _off_ch_timer_hdl, psta);
-}
-
-void _tdls_handshake_timer_hdl(void *FunctionContext)
-{
- struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
-
- if(ptdls_sta != NULL)
- {
- if( !(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) )
- {
- DBG_871X("tdls handshake time out\n");
- free_tdls_sta(ptdls_sta->padapter, ptdls_sta);
- }
- }
-}
-
-void init_handshake_timer(_adapter *padapter, struct sta_info *psta)
-{
- psta->padapter=padapter;
- _init_timer(&psta->handshake_timer, padapter->pnetdev, _tdls_handshake_timer_hdl, psta);
-}
-
-//Check tdls peer sta alive.
-void _tdls_alive_timer_phase1_hdl(void *FunctionContext)
-{
- _irqL irqL;
- struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
- _adapter *padapter = ptdls_sta->padapter;
- struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
-
- _enter_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
- ptdls_sta->timer_flag = 1;
- _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
-
- ptdls_sta->tdls_sta_state &= (~TDLS_ALIVE_STATE);
-
- DBG_871X("issue_tdls_dis_req to check alive\n");
- issue_tdls_dis_req( padapter, ptdls_sta->hwaddr);
- rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CKALV_PH1);
- sta_update_last_rx_pkts(ptdls_sta);
-
- if ( ptdls_sta->timer_flag == 2 )
- rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_FREE_STA);
- else
- {
- _enter_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
- ptdls_sta->timer_flag = 0;
- _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
- }
-
-}
-
-void _tdls_alive_timer_phase2_hdl(void *FunctionContext)
-{
- _irqL irqL;
- struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
- _adapter *padapter = ptdls_sta->padapter;
- struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
-
- _enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
- ptdls_sta->timer_flag = 1;
- _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
-
- if( (ptdls_sta->tdls_sta_state & TDLS_ALIVE_STATE) &&
- (sta_last_rx_pkts(ptdls_sta) + 3 <= sta_rx_pkts(ptdls_sta)) )
- {
- DBG_871X("TDLS STA ALIVE, ptdls_sta->sta_stats.last_rx_pkts:%llu, ptdls_sta->sta_stats.rx_pkts:%llu\n",
- sta_last_rx_pkts(ptdls_sta), sta_rx_pkts(ptdls_sta));
-
- ptdls_sta->alive_count = 0;
- rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CKALV_PH2);
- }
- else
- {
- if( !(ptdls_sta->tdls_sta_state & TDLS_ALIVE_STATE) )
- DBG_871X("TDLS STA TOO FAR\n");
- if( !(sta_last_rx_pkts(ptdls_sta) + 3 <= sta_rx_pkts(ptdls_sta)))
- DBG_871X("TDLS LINK WITH LOW TRAFFIC, ptdls_sta->sta_stats.last_rx_pkts:%llu, ptdls_sta->sta_stats.rx_pkts:%llu\n",
- sta_last_rx_pkts(ptdls_sta), sta_rx_pkts(ptdls_sta));
-
- ptdls_sta->alive_count++;
- if( ptdls_sta->alive_count == TDLS_ALIVE_COUNT )
- {
- ptdls_sta->stat_code = _RSON_TDLS_TEAR_TOOFAR_;
- issue_tdls_teardown(padapter, ptdls_sta->hwaddr);
- }
- else
- {
- rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CKALV_PH2);
- }
- }
-
- if ( ptdls_sta->timer_flag == 2 )
- rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_FREE_STA);
- else
- {
- _enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
- ptdls_sta->timer_flag = 0;
- _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
-}
-
-}
-
-void init_tdls_alive_timer(_adapter *padapter, struct sta_info *psta)
-{
- psta->padapter=padapter;
- _init_timer(&psta->alive_timer1, padapter->pnetdev, _tdls_alive_timer_phase1_hdl, psta);
- _init_timer(&psta->alive_timer2, padapter->pnetdev, _tdls_alive_timer_phase2_hdl, psta);
-}
-
-int update_sgi_tdls(_adapter *padapter, struct sta_info *psta)
-{
- struct ht_priv *psta_ht = NULL;
- psta_ht = &psta->htpriv;
-
- if(psta_ht->ht_option)
- {
- return psta_ht->sgi;
- }
- else
- return _FALSE;
-}
-
-u32 update_mask_tdls(_adapter *padapter, struct sta_info *psta)
-{
- int i;
- u8 rf_type, id;
- unsigned char sta_band = 0;
- unsigned char limit;
- unsigned int tx_ra_bitmap=0;
- struct ht_priv *psta_ht = NULL;
- struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
- WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
-
- psta_ht = &psta->htpriv;
- //b/g mode ra_bitmap
- for (i=0; i<sizeof(psta->bssrateset); i++)
- {
- if (psta->bssrateset[i])
- tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
- }
-
- //n mode ra_bitmap
- if(psta_ht->ht_option)
- {
- padapter->HalFunc.GetHwRegHandler(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
- if(rf_type == RF_2T2R)
- limit=16;// 2R
- else
- limit=8;// 1R
-
- for (i=0; i<limit; i++) {
- if (psta_ht->ht_cap.supp_mcs_set[i/8] & BIT(i%8))
- tx_ra_bitmap |= BIT(i+12);
- }
- }
-
- if ( pcur_network->Configuration.DSConfig > 14 ) {
- // 5G band
- if (tx_ra_bitmap & 0xffff000)
- sta_band |= WIRELESS_11_5N | WIRELESS_11A;
- else
- sta_band |= WIRELESS_11A;
- } else {
- if (tx_ra_bitmap & 0xffff000)
- sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
- else if (tx_ra_bitmap & 0xff0)
- sta_band |= WIRELESS_11G |WIRELESS_11B;
- else
- sta_band |= WIRELESS_11B;
- }
-
- id = networktype_to_raid(sta_band);
- tx_ra_bitmap |= ((id<<28)&0xf0000000);
- return tx_ra_bitmap;
-}
-
-#endif //CONFIG_TDLS
-
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ *
+ ******************************************************************************/
+#define _RTW_TDLS_C_
+
+#include <drv_types.h>
+#include <ethernet.h>
+#include <rtw_tdls.h>
+#include <wifi.h>
+
+#ifdef CONFIG_TDLS
+extern unsigned char MCS_rate_2R[16];
+extern unsigned char MCS_rate_1R[16];
+extern void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame);
+extern s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe);
+
+void rtw_reset_tdls_info(_adapter* padapter)
+{
+ struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
+
+ ptdlsinfo->ap_prohibited = _FALSE;
+ ptdlsinfo->setup_state = TDLS_STATE_NONE;
+ ptdlsinfo->sta_cnt = 0;
+ ptdlsinfo->sta_maximum = _FALSE;
+ ptdlsinfo->macid_index= 6;
+ ptdlsinfo->clear_cam= 0;
+ ptdlsinfo->ch_sensing = 0;
+ ptdlsinfo->cur_channel = 0;
+ ptdlsinfo->candidate_ch = 1; //when inplement channel switching, default candidate channel is 1
+ ptdlsinfo->watchdog_count = 0;
+ ptdlsinfo->dev_discovered = 0;
+
+#ifdef CONFIG_WFD
+ ptdlsinfo->wfd_info = &padapter->wfd_info;
+#endif //CONFIG_WFD
+}
+
+int rtw_init_tdls_info(_adapter* padapter)
+{
+ int res = _SUCCESS;
+ struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
+
+ ptdlsinfo->enable = 1;
+ rtw_reset_tdls_info(padapter);
+
+ _rtw_spinlock_init(&ptdlsinfo->cmd_lock);
+ _rtw_spinlock_init(&ptdlsinfo->hdl_lock);
+
+ return res;
+
+}
+
+void rtw_free_tdls_info(struct tdls_info *ptdlsinfo)
+{
+ _rtw_spinlock_free(&ptdlsinfo->cmd_lock);
+ _rtw_spinlock_free(&ptdlsinfo->hdl_lock);
+
+ _rtw_memset(ptdlsinfo, 0, sizeof(struct tdls_info) );
+
+}
+
+void issue_nulldata_to_TDLS_peer_STA(_adapter *padapter, struct sta_info *ptdls_sta, unsigned int power_mode)
+{
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ unsigned char *pframe;
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ unsigned short *fctrl;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+ update_mgntframe_attrib(padapter, pattrib);
+
+ _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+
+ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+// SetToDs(fctrl);
+ if (power_mode)
+ {
+ SetPwrMgt(fctrl);
+ }
+
+ _rtw_memcpy(pwlanhdr->addr1, ptdls_sta->hwaddr, ETH_ALEN);
+ _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
+ _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
+
+ ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
+ ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
+ pattrib->seqnum = ptdls_sta->sta_xmitpriv.txseq_tid[pattrib->priority];
+ SetSeqNum(pwlanhdr, pattrib->seqnum);
+
+ SetFrameSubType(pframe, WIFI_DATA_NULL);
+
+ pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
+
+ pattrib->last_txcmdsz = pattrib->pktlen;
+ dump_mgntframe(padapter, pmgntframe);
+
+ return;
+}
+
+s32 update_tdls_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
+{
+
+ struct sta_info *psta = NULL;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct qos_priv *pqospriv= &pmlmepriv->qospriv;
+
+ s32 res=_SUCCESS;
+ sint bmcast;
+
+ bmcast = IS_MCAST(pattrib->ra);
+
+ psta = rtw_get_stainfo(pstapriv, pattrib->ra);
+ if (psta == NULL) {
+ res =_FAIL;
+ goto exit;
+ }
+
+ pattrib->mac_id = psta->mac_id;
+
+ pattrib->psta = psta;
+
+ pattrib->ack_policy = 0;
+ // get ether_hdr_len
+ pattrib->pkt_hdrlen = ETH_HLEN;//(pattrib->ether_type == 0x8100) ? (14 + 4 ): 14; //vlan tag
+
+ if (pqospriv->qos_option && psta->qos_option) {
+ pattrib->priority = 1; //tdls management frame should be AC_BK
+ pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
+ pattrib->subtype = WIFI_QOS_DATA_TYPE;
+ } else {
+ pattrib->hdrlen = WLAN_HDR_A3_LEN;
+ pattrib->subtype = WIFI_DATA_TYPE;
+ pattrib->priority = 0;
+ }
+
+ if (psta->ieee8021x_blocked == _TRUE)
+ {
+ pattrib->encrypt = 0;
+ }
+ else
+ {
+ GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
+
+ switch(psecuritypriv->dot11AuthAlgrthm)
+ {
+ case dot11AuthAlgrthm_Open:
+ case dot11AuthAlgrthm_Shared:
+ case dot11AuthAlgrthm_Auto:
+ pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
+ break;
+ case dot11AuthAlgrthm_8021X:
+ pattrib->key_idx = 0;
+ break;
+ default:
+ pattrib->key_idx = 0;
+ break;
+ }
+ }
+
+ switch (pattrib->encrypt)
+ {
+ case _WEP40_:
+ case _WEP104_:
+ pattrib->iv_len = 4;
+ pattrib->icv_len = 4;
+ break;
+ case _TKIP_:
+ pattrib->iv_len = 8;
+ pattrib->icv_len = 4;
+ if(padapter->securitypriv.busetkipkey==_FAIL)
+ {
+ res =_FAIL;
+ goto exit;
+ }
+ break;
+ case _AES_:
+ pattrib->iv_len = 8;
+ pattrib->icv_len = 8;
+ break;
+ default:
+ pattrib->iv_len = 0;
+ pattrib->icv_len = 0;
+ break;
+ }
+
+ if (pattrib->encrypt &&
+ ((padapter->securitypriv.sw_encrypt == _TRUE) || (psecuritypriv->hw_decrypted == _FALSE)))
+ {
+ pattrib->bswenc = _TRUE;
+ } else {
+ pattrib->bswenc = _FALSE;
+ }
+
+ //qos_en, ht_en, init rate, ,bw, ch_offset, sgi
+ pattrib->qos_en = psta->qos_option;
+ pattrib->ht_en = psta->htpriv.ht_option;
+ pattrib->raid = psta->raid;
+ pattrib->bwmode = psta->htpriv.bwmode;
+ pattrib->ch_offset = psta->htpriv.ch_offset;
+ pattrib->sgi= psta->htpriv.sgi;
+ pattrib->ampdu_en = _FALSE;
+
+ //if(pattrib->ht_en && psta->htpriv.ampdu_enable)
+ //{
+ // if(psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
+ // pattrib->ampdu_en = _TRUE;
+ //}
+
+exit:
+
+ return res;
+}
+
+void free_tdls_sta(_adapter *padapter, struct sta_info *ptdls_sta)
+{
+ struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ _irqL irqL;
+
+ //free peer sta_info
+ _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+ if(ptdlsinfo->sta_cnt != 0)
+ ptdlsinfo->sta_cnt--;
+ _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+ if( ptdlsinfo->sta_cnt < (NUM_STA - 2) ) // -2: AP + BC/MC sta
+ {
+ ptdlsinfo->sta_maximum = _FALSE;
+ _rtw_memset( &ptdlsinfo->ss_record, 0x00, sizeof(struct tdls_ss_record) );
+ }
+ //ready to clear cam
+ if(ptdls_sta->mac_id!=0){
+ ptdlsinfo->clear_cam=ptdls_sta->mac_id;
+ rtw_setstakey_cmd(padapter, (u8 *)ptdls_sta, _TRUE, _TRUE);
+ }
+
+ if(ptdlsinfo->sta_cnt==0){
+ rtw_tdls_cmd(padapter, myid(&(padapter->eeprompriv)), TDLS_RS_RCR);
+ ptdlsinfo->setup_state=TDLS_STATE_NONE;
+ }
+ else
+ DBG_871X("Remain tdls sta:%02x\n", ptdlsinfo->sta_cnt);
+
+ rtw_free_stainfo(padapter, ptdls_sta);
+
+}
+
+// cam entry will be the same as mac_id
+void rtw_tdls_set_mac_id(struct tdls_info *ptdlsinfo, struct sta_info *ptdls_sta)
+{
+ if(ptdls_sta->mac_id==0)
+ {
+ ptdls_sta->mac_id = ptdlsinfo->macid_index;
+ if( (++ptdlsinfo->macid_index) > (NUM_STA -2) )
+ ptdlsinfo->macid_index= TDLS_INI_MACID_ENTRY;
+ }
+}
+
+//TDLS encryption(if needed) will always be CCMP
+void rtw_tdls_set_key(_adapter *adapter, struct rx_pkt_attrib *prx_pkt_attrib, struct sta_info *ptdls_sta)
+{
+ if(prx_pkt_attrib->encrypt)
+ {
+ ptdls_sta->dot118021XPrivacy=_AES_;
+ rtw_setstakey_cmd(adapter, (u8*)ptdls_sta, _TRUE, _TRUE);
+ }
+}
+
+void rtw_tdls_process_ht_cap(_adapter *adapter, struct sta_info *ptdls_sta, u8 *data, u8 Length)
+{
+ /* save HT capabilities in the sta object */
+ _rtw_memset(&ptdls_sta->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
+ if (data && Length >= sizeof(struct rtw_ieee80211_ht_cap) )
+ {
+ ptdls_sta->flags |= WLAN_STA_HT;
+
+ ptdls_sta->flags |= WLAN_STA_WME;
+
+ _rtw_memcpy(&ptdls_sta->htpriv.ht_cap, data, sizeof(struct rtw_ieee80211_ht_cap));
+
+ } else
+ ptdls_sta->flags &= ~WLAN_STA_HT;
+
+ if(ptdls_sta->flags & WLAN_STA_HT)
+ {
+ if(adapter->registrypriv.ht_enable == _TRUE)
+ {
+ ptdls_sta->htpriv.ht_option = _TRUE;
+ }
+ else
+ {
+ ptdls_sta->htpriv.ht_option = _FALSE;
+ ptdls_sta->stat_code = _STATS_FAILURE_;
+ }
+ }
+
+ //HT related cap
+ if(ptdls_sta->htpriv.ht_option)
+ {
+ //check if sta supports rx ampdu
+ if(adapter->registrypriv.ampdu_enable==1)
+ ptdls_sta->htpriv.ampdu_enable = _TRUE;
+
+ //check if sta support s Short GI
+ if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SGI_20|IEEE80211_HT_CAP_SGI_40))
+ {
+ ptdls_sta->htpriv.sgi = _TRUE;
+ }
+
+ // bwmode would still followed AP's setting
+ if(ptdls_sta->htpriv.ht_cap.cap_info & cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH))
+ {
+ ptdls_sta->htpriv.bwmode = adapter->mlmeextpriv.cur_bwmode;
+ ptdls_sta->htpriv.ch_offset = adapter->mlmeextpriv.cur_ch_offset;
+ }
+ }
+}
+
+u8 *rtw_tdls_set_ht_cap(_adapter *padapter, u8 *pframe, struct pkt_attrib *pattrib)
+{
+ struct rtw_ieee80211_ht_cap ht_capie;
+ u8 rf_type;
+
+ //HT capabilities
+ _rtw_memset(&ht_capie, 0, sizeof(struct rtw_ieee80211_ht_cap));
+
+ ht_capie.cap_info = IEEE80211_HT_CAP_SUP_WIDTH |IEEE80211_HT_CAP_SGI_20 |IEEE80211_HT_CAP_SM_PS |
+ IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_TX_STBC |IEEE80211_HT_CAP_DSSSCCK40;
+
+ {
+ u32 rx_packet_offset, max_recvbuf_sz;
+ padapter->HalFunc.GetHalDefVarHandler(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset);
+ padapter->HalFunc.GetHalDefVarHandler(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz);
+ if(max_recvbuf_sz-rx_packet_offset>(8191-256))
+ ht_capie.cap_info = ht_capie.cap_info |IEEE80211_HT_CAP_MAX_AMSDU;
+ }
+
+ ht_capie.ampdu_params_info = (IEEE80211_HT_CAP_AMPDU_FACTOR&0x03);
+
+ padapter->HalFunc.GetHwRegHandler(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+ switch(rf_type)
+ {
+ case RF_1T1R:
+ ht_capie.cap_info |= 0x0100;//RX STBC One spatial stream
+ _rtw_memcpy(ht_capie.supp_mcs_set, MCS_rate_1R, 16);
+ break;
+
+ case RF_2T2R:
+ case RF_1T2R:
+ default:
+ ht_capie.cap_info|= 0x0200;//RX STBC two spatial stream
+ _rtw_memcpy(ht_capie.supp_mcs_set, MCS_rate_2R, 16);
+ break;
+ }
+
+ return(rtw_set_ie(pframe, _HT_CAPABILITY_IE_,
+ sizeof(struct rtw_ieee80211_ht_cap), (unsigned char*)&ht_capie, &(pattrib->pktlen)));
+}
+
+u8 *rtw_tdls_set_sup_ch(struct mlme_ext_priv *pmlmeext, u8 *pframe, struct pkt_attrib *pattrib)
+{
+ u8 sup_ch[ 30 * 2 ] = { 0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel
+ do{
+ if( pmlmeext->channel_set[sup_ch_idx].ChannelNum <= 14 )
+ {
+ sup_ch[0] = 1; //First channel number
+ sup_ch[1] = pmlmeext->channel_set[sup_ch_idx].ChannelNum; //Number of channel
+ }
+ else
+ {
+ sup_ch[idx_5g++] = pmlmeext->channel_set[sup_ch_idx].ChannelNum;
+ sup_ch[idx_5g++] = 1;
+ }
+
+ sup_ch_idx++;
+ }
+ while( pmlmeext->channel_set[sup_ch_idx].ChannelNum != 0 );
+ return(rtw_set_ie(pframe, _SUPPORTED_CH_IE_, idx_5g, sup_ch, &(pattrib->pktlen)));
+}
+
+#ifdef CONFIG_WFD
+void rtw_tdls_process_wfd_ie(struct tdls_info *ptdlsinfo, u8 *ptr, u8 length)
+{
+ u8 wfd_ie[ 128 ] = { 0x00 };
+ u32 wfd_ielen = 0;
+ u32 wfd_offset = 0;
+ // Try to get the TCP port information when receiving the negotiation response.
+ //
+
+ wfd_offset = 0;
+ wfd_offset = rtw_get_wfd_ie( ptr + wfd_offset, length - wfd_offset, wfd_ie, &wfd_ielen );
+ while( wfd_offset )
+ {
+ u8 attr_content[ 10 ] = { 0x00 };
+ u32 attr_contentlen = 0;
+ int i;
+
+ DBG_871X( "[%s] WFD IE Found!!\n", __FUNCTION__ );
+ rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
+ if ( attr_contentlen )
+ {
+ ptdlsinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
+ DBG_871X( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, ptdlsinfo->wfd_info->peer_rtsp_ctrlport );
+ }
+
+ _rtw_memset( attr_content, 0x00, 10);
+ attr_contentlen = 0;
+ rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_LOCAL_IP_ADDR, attr_content, &attr_contentlen);
+ if ( attr_contentlen )
+ {
+ _rtw_memcpy(ptdlsinfo->wfd_info->peer_ip_address, ( attr_content + 1 ), 4);
+ DBG_871X( "[%s] Peer IP = %02u.%02u.%02u.%02u \n", __FUNCTION__,
+ ptdlsinfo->wfd_info->peer_ip_address[0], ptdlsinfo->wfd_info->peer_ip_address[1],
+ ptdlsinfo->wfd_info->peer_ip_address[2], ptdlsinfo->wfd_info->peer_ip_address[3]
+ );
+ }
+ wfd_offset = rtw_get_wfd_ie( ptr + wfd_offset, length - wfd_offset, wfd_ie, &wfd_ielen );
+ }
+}
+
+void issue_tunneled_probe_req(_adapter *padapter)
+{
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ u8 baddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ DBG_871X("[%s]\n", __FUNCTION__);
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+
+ pmgntframe->frame_tag = DATA_FRAMETAG;
+ pattrib->ether_type = 0x890d;
+ pattrib->pctrl =0;
+
+ _rtw_memcpy(pattrib->dst, baddr, ETH_ALEN);
+
+ _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
+
+ _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
+ _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+
+ update_tdls_attrib(padapter, pattrib);
+ pattrib->qsel=pattrib->priority;
+ if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TUNNELED_PROBE_REQ) != _SUCCESS) {
+ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ goto exit;
+ }
+ rtw_dump_xframe(padapter, pmgntframe);
+
+exit:
+
+ return;
+}
+
+void issue_tunneled_probe_rsp(_adapter *padapter, union recv_frame *precv_frame)
+{
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct rx_pkt_attrib *rx_pkt_pattrib = &precv_frame->u.hdr.attrib;
+
+ DBG_871X("[%s]\n", __FUNCTION__);
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+
+ pmgntframe->frame_tag = DATA_FRAMETAG;
+ pattrib->ether_type = 0x890d;
+ pattrib->pctrl =0;
+
+ _rtw_memcpy(pattrib->dst, rx_pkt_pattrib->src, ETH_ALEN);
+
+ _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
+
+ _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
+ _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+
+ update_tdls_attrib(padapter, pattrib);
+ pattrib->qsel=pattrib->priority;
+ if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TUNNELED_PROBE_RSP) != _SUCCESS) {
+ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ goto exit;
+ }
+ rtw_dump_xframe(padapter, pmgntframe);
+
+exit:
+
+ return;
+}
+#endif //CONFIG_WFD
+
+void issue_tdls_setup_req(_adapter *padapter, u8 *mac_addr)
+{
+ struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct sta_info *ptdls_sta= NULL;
+ _irqL irqL;
+ static u8 dialogtoken = 0;
+ u32 timeout_interval= TPK_RESEND_COUNT * 1000; //retry timer should set at least 301 sec, using TPK_count counting 301 times.
+
+ if(ptdlsinfo->ap_prohibited == _TRUE)
+ goto exit;
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+
+ pmgntframe->frame_tag = DATA_FRAMETAG;
+ pattrib->ether_type = 0x890d;
+ pattrib->pctrl =0;
+
+ _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
+ _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
+
+ _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
+ _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+
+ update_tdls_attrib(padapter, pattrib);
+
+ //init peer sta_info
+ ptdls_sta = rtw_get_stainfo(pstapriv, mac_addr);
+ if(ptdls_sta==NULL)
+ {
+ ptdls_sta = rtw_alloc_stainfo(pstapriv, mac_addr);
+ if(ptdls_sta)
+ {
+ _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+ if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
+ ptdlsinfo->sta_cnt++;
+ _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+ if( ptdlsinfo->sta_cnt == (NUM_STA - 2) ) // -2: AP + BC/MC sta
+ {
+ ptdlsinfo->sta_maximum = _TRUE;
+ }
+ }
+ else
+ {
+ rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ goto exit;
+ }
+ }
+
+ if(ptdls_sta){
+ ptdls_sta->tdls_sta_state |= TDLS_RESPONDER_STATE;
+ //for tdls; ptdls_sta->aid is used to fill dialogtoken
+ ptdls_sta->dialog = dialogtoken;
+ dialogtoken = (dialogtoken+1)%256;
+ ptdls_sta->TDLS_PeerKey_Lifetime = timeout_interval;
+ _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME );
+ }
+
+ pattrib->qsel=pattrib->priority;
+ if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_SETUP_REQUEST) !=_SUCCESS ){
+ rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ goto exit;
+ }
+ rtw_dump_xframe(padapter, pmgntframe);
+
+exit:
+
+ return;
+}
+
+void issue_tdls_teardown(_adapter *padapter, u8 *mac_addr)
+{
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct sta_info *ptdls_sta=NULL;
+ _irqL irqL;
+
+ ptdls_sta = rtw_get_stainfo(pstapriv, mac_addr);
+ if(ptdls_sta==NULL){
+ DBG_871X("issue tdls teardown unsuccessful\n");
+ return;
+ }else{
+ ptdls_sta->tdls_sta_state=TDLS_STATE_NONE;
+ }
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+
+ pmgntframe->frame_tag = DATA_FRAMETAG;
+ pattrib->ether_type = 0x890d;
+ pattrib->pctrl =0;
+
+ _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
+ _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
+
+ _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
+ _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+
+ update_tdls_attrib(padapter, pattrib);
+ pattrib->qsel=pattrib->priority;
+ if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_TEARDOWN) != _SUCCESS) {
+ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ goto exit;
+ }
+ rtw_dump_xframe(padapter, pmgntframe);
+
+ if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE){
+ rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
+ }
+
+ if( ptdls_sta->timer_flag == 1 )
+ {
+ _enter_critical_bh(&(padapter->tdlsinfo.hdl_lock), &irqL);
+ ptdls_sta->timer_flag = 2;
+ _exit_critical_bh(&(padapter->tdlsinfo.hdl_lock), &irqL);
+ }
+ else
+ rtw_tdls_cmd(padapter, mac_addr, TDLS_FREE_STA );
+
+
+exit:
+
+ return;
+}
+
+void issue_tdls_dis_req(_adapter *padapter, u8 *mac_addr)
+{
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ u8 baddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+
+ pmgntframe->frame_tag = DATA_FRAMETAG;
+ pattrib->ether_type = 0x890d;
+ pattrib->pctrl =0;
+
+ if(mac_addr == NULL)
+ _rtw_memcpy(pattrib->dst, baddr, ETH_ALEN);
+ else
+ _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
+
+ _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
+
+ _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
+ _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+
+ update_tdls_attrib(padapter, pattrib);
+ pattrib->qsel=pattrib->priority;
+ if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_DISCOVERY_REQUEST) != _SUCCESS) {
+ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ goto exit;
+ }
+ rtw_dump_xframe(padapter, pmgntframe);
+ DBG_871X("issue tdls dis req\n");
+
+exit:
+
+ return;
+}
+
+void issue_tdls_setup_rsp(_adapter *padapter, union recv_frame *precv_frame)
+{
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct rx_pkt_attrib *rx_pkt_pattrib = &precv_frame->u.hdr.attrib;
+ _irqL irqL;
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+
+ pmgntframe->frame_tag = DATA_FRAMETAG;
+ pattrib->ether_type = 0x890d;
+ pattrib->pctrl =0;
+
+ _rtw_memcpy(pattrib->dst, rx_pkt_pattrib->src, ETH_ALEN);
+ _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
+
+ _rtw_memcpy(pattrib->ra, rx_pkt_pattrib->bssid, ETH_ALEN);
+ _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+
+ update_tdls_attrib(padapter, pattrib);
+ pattrib->qsel=pattrib->priority;
+ if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_SETUP_RESPONSE) != _SUCCESS) {
+ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ goto exit;
+ }
+ rtw_dump_xframe(padapter, pmgntframe);
+
+exit:
+
+ return;
+
+}
+
+void issue_tdls_setup_cfm(_adapter *padapter, union recv_frame *precv_frame)
+{
+ struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct sta_info *ptdls_sta=NULL;
+ _irqL irqL;
+
+ struct rx_pkt_attrib *rx_pkt_pattrib = & precv_frame->u.hdr.attrib;
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+
+ pmgntframe->frame_tag = DATA_FRAMETAG;
+ pattrib->ether_type = 0x890d;
+ pattrib->pctrl =0;
+
+ _rtw_memcpy(pattrib->dst, rx_pkt_pattrib->src, ETH_ALEN);
+ _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
+
+ _rtw_memcpy(pattrib->ra, rx_pkt_pattrib->bssid, ETH_ALEN);
+ _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+
+ update_tdls_attrib(padapter, pattrib);
+ pattrib->qsel=pattrib->priority;
+ if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_SETUP_CONFIRM) != _SUCCESS) {
+ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ goto exit;
+ }
+
+ rtw_dump_xframe(padapter, pmgntframe);
+
+exit:
+
+ return;
+
+}
+
+//TDLS Discovery Response frame is a management action frame
+void issue_tdls_dis_rsp(_adapter *padapter, union recv_frame *precv_frame, u8 dialog)
+{
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ unsigned char *pframe;
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ unsigned short *fctrl;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+
+ struct rx_pkt_attrib *rx_pkt_pattrib = &precv_frame->u.hdr.attrib;
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+ update_mgntframe_attrib(padapter, pattrib);
+
+ _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
+
+ pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+
+ fctrl = &(pwlanhdr->frame_ctl);
+ *(fctrl) = 0;
+
+ // unicast probe request frame
+ _rtw_memcpy(pwlanhdr->addr1, rx_pkt_pattrib->src, ETH_ALEN);
+ _rtw_memcpy(pattrib->dst, pwlanhdr->addr1, ETH_ALEN);
+
+ _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
+ _rtw_memcpy(pattrib->src, pwlanhdr->addr2, ETH_ALEN);
+
+ _rtw_memcpy(pwlanhdr->addr3, rx_pkt_pattrib->bssid, ETH_ALEN);
+ _rtw_memcpy(pattrib->ra, pwlanhdr->addr3, ETH_ALEN);
+
+ SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
+ pmlmeext->mgnt_seq++;
+ SetFrameSubType(pframe, WIFI_ACTION);
+
+ pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
+ pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
+
+ rtw_build_tdls_dis_rsp_ies(padapter, pmgntframe, pframe, dialog);
+
+ pattrib->nr_frags = 1;
+ pattrib->last_txcmdsz = pattrib->pktlen;
+
+ dump_mgntframe(padapter, pmgntframe);
+
+ return;
+}
+
+void issue_tdls_peer_traffic_indication(_adapter *padapter, struct sta_info *ptdls_sta)
+{
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+
+ static u8 dialogtoken=0;
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+
+ pmgntframe->frame_tag = DATA_FRAMETAG;
+ pattrib->ether_type = 0x890d;
+ pattrib->pctrl =0;
+
+ _rtw_memcpy(pattrib->dst, ptdls_sta->hwaddr, ETH_ALEN);
+ _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
+
+ _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
+ _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+
+ //for tdls; pattrib->nr_frags is used to fill dialogtoken
+ ptdls_sta->dialog = dialogtoken;
+ dialogtoken = (dialogtoken+1)%256;
+ //PTI frame's priority should be AC_VO
+ pattrib->priority = 7;
+
+ update_tdls_attrib(padapter, pattrib);
+ pattrib->qsel=pattrib->priority;
+ if (rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_PEER_TRAFFIC_INDICATION) != _SUCCESS) {
+ rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ goto exit;
+ }
+ rtw_dump_xframe(padapter, pmgntframe);
+
+exit:
+
+ return;
+}
+
+void issue_tdls_ch_switch_req(_adapter *padapter, u8 *mac_addr)
+{
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+
+ pmgntframe->frame_tag = DATA_FRAMETAG;
+ pattrib->ether_type = 0x890d;
+ pattrib->pctrl =0;
+
+ _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
+ _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
+
+ _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
+ _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+
+ update_tdls_attrib(padapter, pattrib);
+
+ pattrib->qsel=pattrib->priority;
+ if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_CHANNEL_SWITCH_REQUEST) !=_SUCCESS ){
+ rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ goto exit;
+ }
+ rtw_dump_xframe(padapter, pmgntframe);
+
+exit:
+
+ return;
+}
+
+void issue_tdls_ch_switch_rsp(_adapter *padapter, u8 *mac_addr)
+{
+ struct xmit_frame *pmgntframe;
+ struct pkt_attrib *pattrib;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
+
+ _irqL irqL;
+
+ if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
+ {
+ return;
+ }
+
+ //update attribute
+ pattrib = &pmgntframe->attrib;
+
+ pmgntframe->frame_tag = DATA_FRAMETAG;
+ pattrib->ether_type = 0x890d;
+ pattrib->pctrl =0;
+
+ _rtw_memcpy(pattrib->dst, mac_addr, ETH_ALEN);
+ _rtw_memcpy(pattrib->src, myid(&(padapter->eeprompriv)), ETH_ALEN);
+
+ _rtw_memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
+ _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
+
+ update_tdls_attrib(padapter, pattrib);
+
+ pattrib->qsel=pattrib->priority;
+/*
+ _enter_critical_bh(&pxmitpriv->lock, &irqL);
+ if(xmitframe_enqueue_for_tdls_sleeping_sta(padapter, pmgntframe)==_TRUE){
+ _exit_critical_bh(&pxmitpriv->lock, &irqL);
+ return _FALSE;
+ }
+*/
+ if(rtw_xmit_tdls_coalesce(padapter, pmgntframe, TDLS_CHANNEL_SWITCH_RESPONSE) !=_SUCCESS ){
+ rtw_free_xmitbuf(pxmitpriv,pmgntframe->pxmitbuf);
+ rtw_free_xmitframe(pxmitpriv, pmgntframe);
+ goto exit;
+ }
+ rtw_dump_xframe(padapter, pmgntframe);
+
+exit:
+
+ return;
+}
+
+sint On_TDLS_Dis_Rsp(_adapter *adapter, union recv_frame *precv_frame)
+{
+ struct sta_info *ptdls_sta = NULL, *psta = rtw_get_stainfo(&(adapter->stapriv), get_bssid(&(adapter->mlmepriv)));
+ struct recv_priv *precvpriv = &(adapter->recvpriv);
+ u8 *ptr = precv_frame->u.hdr.rx_data, *psa;
+ struct rx_pkt_attrib *pattrib = &(precv_frame->u.hdr.attrib);
+ struct tdls_info *ptdlsinfo = &(adapter->tdlsinfo);
+ u8 empty_addr[ETH_ALEN] = { 0x00 };
+ int UndecoratedSmoothedPWDB;
+
+
+ //WFDTDLS: for sigma test, not to setup direct link automatically
+ ptdlsinfo->dev_discovered = 1;
+
+#ifdef CONFIG_TDLS_AUTOSETUP
+ psa = get_sa(ptr);
+ ptdls_sta = rtw_get_stainfo(&(adapter->stapriv), psa);
+
+ if(ptdls_sta != NULL)
+ {
+ ptdls_sta->tdls_sta_state |= TDLS_ALIVE_STATE;
+
+ //Record the tdls sta with lowest signal strength
+ if( (ptdlsinfo->sta_maximum == _TRUE) && (ptdls_sta->alive_count >= 1) )
+ {
+ if( _rtw_memcmp(ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN) )
+ {
+ _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
+ ptdlsinfo->ss_record.RxPWDBAll = pattrib->RxPWDBAll;
+ }
+ else
+ {
+ if( ptdlsinfo->ss_record.RxPWDBAll < pattrib->RxPWDBAll )
+ {
+ _rtw_memcpy(ptdlsinfo->ss_record.macaddr, psa, ETH_ALEN);
+ ptdlsinfo->ss_record.RxPWDBAll = pattrib->RxPWDBAll;
+ }
+ }
+ }
+
+ }
+ else
+ {
+ if( ptdlsinfo->sta_maximum == _TRUE)
+ {
+ if( _rtw_memcmp( ptdlsinfo->ss_record.macaddr, empty_addr, ETH_ALEN ) )
+ {
+ //All traffics are busy, do not set up another direct link.
+ return _FAIL;
+ }
+ else
+ {
+ if( pattrib->RxPWDBAll > ptdlsinfo->ss_record.RxPWDBAll )
+ {
+ issue_tdls_teardown(adapter, ptdlsinfo->ss_record.macaddr);
+ }
+ else
+ {
+ return _FAIL;
+ }
+ }
+ }
+
+ adapter->HalFunc.GetHalDefVarHandler(adapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
+
+ if( pattrib->RxPWDBAll + TDLS_SIGNAL_THRESH >= UndecoratedSmoothedPWDB);
+ {
+ DBG_871X("pattrib->RxPWDBAll=%d, pdmpriv->UndecoratedSmoothedPWDB=%d\n", pattrib->RxPWDBAll, UndecoratedSmoothedPWDB);
+ issue_tdls_setup_req(adapter, psa);
+ }
+ }
+#endif //CONFIG_TDLS_AUTOSETUP
+
+ return _SUCCESS;
+}
+
+sint On_TDLS_Setup_Req(_adapter *adapter, union recv_frame *precv_frame)
+{
+ struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
+ u8 *psa, *pmyid;
+ struct sta_info *ptdls_sta= NULL;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
+ struct security_priv *psecuritypriv = &adapter->securitypriv;
+ _irqL irqL;
+ struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
+ u8 *prsnie, *ppairwise_cipher;
+ u8 i, k, pairwise_count;
+ u8 ccmp_have=0, rsnie_have=0;
+ u16 j;
+ u8 SNonce[32];
+ u32 *timeout_interval;
+ sint parsing_length; //frame body length, without icv_len
+ PNDIS_802_11_VARIABLE_IEs pIE;
+ u8 FIXED_IE = 5;
+ unsigned char supportRate[16];
+ int supportRateNum = 0;
+
+ psa = get_sa(ptr);
+ ptdls_sta = rtw_get_stainfo(pstapriv, psa);
+
+ pmyid=myid(&(adapter->eeprompriv));
+ ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
+ parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
+ -prx_pkt_attrib->hdrlen
+ -prx_pkt_attrib->iv_len
+ -prx_pkt_attrib->icv_len
+ -LLC_HEADER_SIZE
+ -ETH_TYPE_LEN
+ -PAYLOAD_TYPE_LEN
+ -FIXED_IE;
+
+ if(ptdlsinfo->ap_prohibited == _TRUE)
+ {
+ goto exit;
+ }
+
+ if(ptdls_sta==NULL){
+ ptdls_sta = rtw_alloc_stainfo(pstapriv, psa);
+ }else{
+ if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE){
+ //If the direct link is already set up
+ //Process as re-setup after tear down
+ DBG_871X("re-setup a direct link\n");
+ }
+ //already receiving TDLS setup request
+ else if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
+ DBG_871X("receive duplicated TDLS setup request frame in handshaking\n");
+ goto exit;
+ }
+ //When receiving and sending setup_req to the same link at the same time, STA with higher MAC_addr would be initiator
+ //following is to check out MAC_addr
+ else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
+ DBG_871X("receive setup_req after sending setup_req\n");
+ for (i=0;i<6;i++){
+ if(*(pmyid+i)==*(psa+i)){
+ }
+ else if(*(pmyid+i)>*(psa+i)){
+ goto exit;
+ }else if(*(pmyid+i)<*(psa+i)){
+ ptdls_sta->tdls_sta_state=TDLS_INITIATOR_STATE;
+ break;
+ }
+ }
+ }
+ }
+
+ if(ptdls_sta)
+ {
+ ptdls_sta->dialog = *(ptr+2); //copy dialog token
+ ptdls_sta->stat_code = 0;
+
+ //parsing information element
+ for(j=FIXED_IE; j<parsing_length;){
+
+ pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
+
+ switch (pIE->ElementID)
+ {
+ case _SUPPORTEDRATES_IE_:
+ _rtw_memcpy(supportRate, pIE->data, pIE->Length);
+ supportRateNum = pIE->Length;
+ break;
+ case _COUNTRY_IE_:
+ break;
+ case _EXT_SUPPORTEDRATES_IE_:
+ if(supportRateNum<=sizeof(supportRate))
+ {
+ _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length);
+ supportRateNum += pIE->Length;
+ }
+ break;
+ case _SUPPORTED_CH_IE_:
+ break;
+ case _RSN_IE_2_:
+ rsnie_have=1;
+ if(prx_pkt_attrib->encrypt){
+ prsnie=(u8*)pIE;
+ //check whether initiator STA has CCMP pairwise_cipher.
+ ppairwise_cipher=prsnie+10;
+ _rtw_memcpy(&pairwise_count, (u16*)(ppairwise_cipher-2), 1);
+ for(k=0;k<pairwise_count;k++){
+ if(_rtw_memcmp( ppairwise_cipher+4*k, RSN_CIPHER_SUITE_CCMP, 4)==_TRUE)
+ ccmp_have=1;
+ }
+ if(ccmp_have==0){
+ //invalid contents of RSNIE
+ ptdls_sta->stat_code=72;
+ }
+ }
+ break;
+ case _EXT_CAP_IE_:
+ break;
+ case _VENDOR_SPECIFIC_IE_:
+ break;
+ case _FTIE_:
+ if(prx_pkt_attrib->encrypt)
+ _rtw_memcpy(SNonce, (ptr+j+52), 32);
+ break;
+ case _TIMEOUT_ITVL_IE_:
+ if(prx_pkt_attrib->encrypt)
+ timeout_interval = (u32 *)(ptr+j+3);
+ break;
+ case _RIC_Descriptor_IE_:
+ break;
+ case _HT_CAPABILITY_IE_:
+ rtw_tdls_process_ht_cap(adapter, ptdls_sta, pIE->data, pIE->Length);
+ break;
+ case EID_BSSCoexistence:
+ break;
+ case _LINK_ID_IE_:
+ if(_rtw_memcmp(get_bssid(pmlmepriv), pIE->data, 6) == _FALSE)
+ {
+ //not in the same BSS
+ ptdls_sta->stat_code=7;
+ }
+ break;
+ default:
+ break;
+ }
+
+ j += (pIE->Length + 2);
+
+ }
+
+ //update station supportRate
+ ptdls_sta->bssratelen = supportRateNum;
+ _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
+
+ //check status code
+ //if responder STA has/hasn't security on AP, but request hasn't/has RSNIE, it should reject
+ if(ptdls_sta->stat_code == 0 )
+ {
+ if(rsnie_have && (prx_pkt_attrib->encrypt==0)){
+ //security disabled
+ ptdls_sta->stat_code = 5;
+ }else if(rsnie_have==0 && (prx_pkt_attrib->encrypt)){
+ //request haven't RSNIE
+ ptdls_sta->stat_code = 38;
+ }
+
+#ifdef CONFIG_WFD
+ //WFD test plan version 0.18.2 test item 5.1.5
+ //SoUT does not use TDLS if AP uses weak security
+ if ( adapter->wdinfo.wfd_tdls_enable )
+ {
+ if(rsnie_have && (prx_pkt_attrib->encrypt != _AES_))
+ {
+ ptdls_sta->stat_code = 5;
+ }
+ }
+#endif //CONFIG_WFD
+ }
+
+ ptdls_sta->tdls_sta_state|= TDLS_INITIATOR_STATE;
+ if(prx_pkt_attrib->encrypt){
+ _rtw_memcpy(ptdls_sta->SNonce, SNonce, 32);
+ _rtw_memcpy(&(ptdls_sta->TDLS_PeerKey_Lifetime), timeout_interval, 4);
+ }
+ _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+ if(!(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
+ ptdlsinfo->sta_cnt++;
+ _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL);
+ if( ptdlsinfo->sta_cnt == (NUM_STA - 2) ) // -2: AP + BC/MC sta
+ {
+ ptdlsinfo->sta_maximum = _TRUE;
+ }
+
+#ifdef CONFIG_WFD
+ rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length - FIXED_IE);
+#endif // CONFIG_WFD
+
+ }
+ else
+ {
+ goto exit;
+ }
+
+ issue_tdls_setup_rsp(adapter, precv_frame);
+
+ if(ptdls_sta->stat_code==0)
+ {
+ _set_timer( &ptdls_sta->handshake_timer, TDLS_HANDSHAKE_TIME);
+ }
+ else //status code!=0 ; setup unsuccess
+ {
+ free_tdls_sta(adapter, ptdls_sta);
+ }
+
+exit:
+
+ return _FAIL;
+}
+
+sint On_TDLS_Setup_Rsp(_adapter *adapter, union recv_frame *precv_frame)
+{
+ struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
+ struct sta_info *ptdls_sta= NULL;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ _irqL irqL;
+ struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
+ u8 *psa;
+ u16 stat_code;
+ sint parsing_length; //frame body length, without icv_len
+ PNDIS_802_11_VARIABLE_IEs pIE;
+ u8 FIXED_IE =7;
+ u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic, *ppairwise_cipher;
+ u16 pairwise_count, j, k;
+ u8 verify_ccmp=0;
+ unsigned char supportRate[16];
+ int supportRateNum = 0;
+
+ psa = get_sa(ptr);
+ ptdls_sta = rtw_get_stainfo(pstapriv, psa);
+
+ if ( NULL == ptdls_sta )
+ {
+ return _FAIL;
+ }
+
+ ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
+ parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
+ -prx_pkt_attrib->hdrlen
+ -prx_pkt_attrib->iv_len
+ -prx_pkt_attrib->icv_len
+ -LLC_HEADER_SIZE
+ -TYPE_LENGTH_FIELD_SIZE
+ -1
+ -FIXED_IE;
+
+ _rtw_memcpy(&stat_code, ptr+2, 2);
+
+ if(stat_code!=0)
+ {
+ DBG_871X( "[%s] status_code = %d, free_tdls_sta\n", __FUNCTION__, stat_code );
+ free_tdls_sta(adapter, ptdls_sta);
+ return _FAIL;
+ }
+
+ stat_code = 0;
+
+ //parsing information element
+ for(j=FIXED_IE; j<parsing_length;)
+ {
+ pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
+
+ switch (pIE->ElementID)
+ {
+ case _SUPPORTEDRATES_IE_:
+ _rtw_memcpy(supportRate, pIE->data, pIE->Length);
+ supportRateNum = pIE->Length;
+ break;
+ case _COUNTRY_IE_:
+ break;
+ case _EXT_SUPPORTEDRATES_IE_:
+ if(supportRateNum<=sizeof(supportRate))
+ {
+ _rtw_memcpy(supportRate+supportRateNum, pIE->data, pIE->Length);
+ supportRateNum += pIE->Length;
+ }
+ break;
+ case _SUPPORTED_CH_IE_:
+ break;
+ case _RSN_IE_2_:
+ prsnie=(u8*)pIE;
+ //check whether responder STA has CCMP pairwise_cipher.
+ ppairwise_cipher=prsnie+10;
+ _rtw_memcpy(&pairwise_count, (u16*)(ppairwise_cipher-2), 2);
+ for(k=0;k<pairwise_count;k++){
+ if(_rtw_memcmp( ppairwise_cipher+4*k, RSN_CIPHER_SUITE_CCMP, 4)==_TRUE)
+ verify_ccmp=1;
+ }
+ case _EXT_CAP_IE_:
+ break;
+ case _VENDOR_SPECIFIC_IE_:
+ break;
+ case _FTIE_:
+ pftie=(u8*)pIE;
+ _rtw_memcpy(ptdls_sta->ANonce, (ptr+j+20), 32);
+ break;
+ case _TIMEOUT_ITVL_IE_:
+ ptimeout_ie=(u8*)pIE;
+ break;
+ case _RIC_Descriptor_IE_:
+ break;
+ case _HT_CAPABILITY_IE_:
+ rtw_tdls_process_ht_cap(adapter, ptdls_sta, pIE->data, pIE->Length);
+ break;
+ case EID_BSSCoexistence:
+ break;
+ case _LINK_ID_IE_:
+ plinkid_ie=(u8*)pIE;
+ break;
+ default:
+ break;
+ }
+
+ j += (pIE->Length + 2);
+
+ }
+
+ //update station supportRate
+ ptdls_sta->bssratelen = supportRateNum;
+ _rtw_memcpy(ptdls_sta->bssrateset, supportRate, supportRateNum);
+
+#ifdef CONFIG_WFD
+ rtw_tdls_process_wfd_ie(ptdlsinfo, ptr + FIXED_IE, parsing_length - FIXED_IE);
+#endif // CONFIG_WFD
+
+ if(stat_code != 0)
+ {
+ ptdls_sta->stat_code = stat_code;
+ }
+ else
+ {
+ if(prx_pkt_attrib->encrypt)
+ {
+ if(verify_ccmp==1)
+ {
+ wpa_tdls_generate_tpk(adapter, ptdls_sta);
+ ptdls_sta->stat_code=0;
+ if(tdls_verify_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie)==0) //0: Invalid, 1: valid
+ {
+ free_tdls_sta(adapter, ptdls_sta);
+ return _FAIL;
+ }
+ }
+ else
+ {
+ ptdls_sta->stat_code=72; //invalide contents of RSNIE
+ }
+
+ }else{
+ ptdls_sta->stat_code=0;
+ }
+ }
+
+ DBG_871X("issue_tdls_setup_cfm\n");
+ issue_tdls_setup_cfm(adapter, precv_frame);
+
+ if(ptdls_sta->stat_code==0)
+ {
+ ptdlsinfo->setup_state = TDLS_LINKED_STATE;
+
+ if( ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE )
+ {
+ ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
+ _cancel_timer_ex( &ptdls_sta->handshake_timer);
+#ifdef CONFIG_TDLS_AUTOCHECKALIVE
+ _set_timer( &ptdls_sta->alive_timer1, TDLS_ALIVE_TIMER_PH1);
+#endif //CONFIG_TDLS_AUTOSETUP
+ }
+
+ rtw_tdls_set_mac_id(ptdlsinfo, ptdls_sta);
+ rtw_tdls_set_key(adapter, prx_pkt_attrib, ptdls_sta);
+
+ rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_WRCR);
+
+ }
+ else //status code!=0 ; setup unsuccessful
+ {
+ free_tdls_sta(adapter, ptdls_sta);
+ }
+
+ return _FAIL;
+
+}
+
+sint On_TDLS_Setup_Cfm(_adapter *adapter, union recv_frame *precv_frame)
+{
+ struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
+ struct sta_info *ptdls_sta= NULL;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ _irqL irqL;
+ struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
+ u8 *psa;
+ u16 stat_code;
+ sint parsing_length;
+ PNDIS_802_11_VARIABLE_IEs pIE;
+ u8 FIXED_IE =5;
+ u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic, *ppairwise_cipher;
+ u16 j, pairwise_count;
+
+ psa = get_sa(ptr);
+ ptdls_sta = rtw_get_stainfo(pstapriv, psa);
+
+ ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
+ parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
+ -prx_pkt_attrib->hdrlen
+ -prx_pkt_attrib->iv_len
+ -prx_pkt_attrib->icv_len
+ -LLC_HEADER_SIZE
+ -ETH_TYPE_LEN
+ -PAYLOAD_TYPE_LEN
+ -FIXED_IE;
+ _rtw_memcpy(&stat_code, ptr+2, 2);
+
+ if(stat_code!=0){
+ DBG_871X( "[%s] stat_code = %d\n, free_tdls_sta", __FUNCTION__, stat_code );
+ free_tdls_sta(adapter, ptdls_sta);
+ return _FAIL;
+ }
+
+ if(prx_pkt_attrib->encrypt){
+ //parsing information element
+ for(j=FIXED_IE; j<parsing_length;){
+
+ pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
+
+ switch (pIE->ElementID)
+ {
+ case _RSN_IE_2_:
+ prsnie=(u8*)pIE;
+ break;
+ case _VENDOR_SPECIFIC_IE_:
+ break;
+ case _FTIE_:
+ pftie=(u8*)pIE;
+ break;
+ case _TIMEOUT_ITVL_IE_:
+ ptimeout_ie=(u8*)pIE;
+ break;
+ case _HT_EXTRA_INFO_IE_:
+ break;
+ case _LINK_ID_IE_:
+ plinkid_ie=(u8*)pIE;
+ break;
+ default:
+ break;
+ }
+
+ j += (pIE->Length + 2);
+
+ }
+
+ //verify mic in FTIE MIC field
+ if(tdls_verify_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie)==0){ //0: Invalid, 1: Valid
+ free_tdls_sta(adapter, ptdls_sta);
+ return _FAIL;
+ }
+
+ }
+
+ ptdlsinfo->setup_state = TDLS_LINKED_STATE;
+ if( ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE )
+ {
+ ptdls_sta->tdls_sta_state|=TDLS_LINKED_STATE;
+ _cancel_timer_ex( &ptdls_sta->handshake_timer);
+#ifdef CONFIG_TDLS_AUTOCHECKALIVE
+ _set_timer( &ptdls_sta->alive_timer1, TDLS_ALIVE_TIMER_PH1);
+#endif //CONFIG_TDLS_AUTOCHECKALIVE
+ }
+
+ rtw_tdls_set_mac_id(ptdlsinfo, ptdls_sta);
+ rtw_tdls_set_key(adapter, prx_pkt_attrib, ptdls_sta);
+
+ rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_WRCR);
+
+ return _FAIL;
+
+}
+
+sint On_TDLS_Dis_Req(_adapter *adapter, union recv_frame *precv_frame)
+{
+ struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ struct sta_info *psta_ap;
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ sint parsing_length; //frame body length, without icv_len
+ PNDIS_802_11_VARIABLE_IEs pIE;
+ u8 FIXED_IE = 3, *dst, *pdialog = NULL;
+ u16 j;
+
+ ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len + LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE + 1;
+ pdialog=ptr+2;
+
+ parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
+ -prx_pkt_attrib->hdrlen
+ -prx_pkt_attrib->iv_len
+ -prx_pkt_attrib->icv_len
+ -LLC_HEADER_SIZE
+ -TYPE_LENGTH_FIELD_SIZE
+ -1
+ -FIXED_IE;
+
+ //parsing information element
+ for(j=FIXED_IE; j<parsing_length;){
+
+ pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
+
+ switch (pIE->ElementID)
+ {
+ case _LINK_ID_IE_:
+ psta_ap = rtw_get_stainfo(pstapriv, pIE->data);
+ if(psta_ap == NULL)
+ {
+ goto exit;
+ }
+ dst = pIE->data + 12;
+ if( (MacAddr_isBcst(dst) == _FALSE) && (_rtw_memcmp(myid(&(adapter->eeprompriv)), dst, 6) == _FALSE) )
+ {
+ goto exit;
+ }
+ break;
+ default:
+ break;
+ }
+
+ j += (pIE->Length + 2);
+
+ }
+
+ //check frame contents
+
+ issue_tdls_dis_rsp(adapter, precv_frame, *(pdialog) );
+
+exit:
+
+ return _FAIL;
+
+}
+
+sint On_TDLS_Teardown(_adapter *adapter, union recv_frame *precv_frame)
+{
+ u8 *psa;
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
+ struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ struct sta_info *ptdls_sta= NULL;
+ _irqL irqL;
+
+ psa = get_sa(ptr);
+
+ ptdls_sta = rtw_get_stainfo(pstapriv, psa);
+ if(ptdls_sta!=NULL){
+ if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE){
+ rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
+ }
+ free_tdls_sta(adapter, ptdls_sta);
+ }
+
+ return _FAIL;
+
+}
+
+u8 TDLS_check_ch_state(uint state){
+ if( (state & TDLS_CH_SWITCH_ON_STATE) &&
+ (state & TDLS_AT_OFF_CH_STATE) &&
+ (state & TDLS_PEER_AT_OFF_STATE) ){
+
+ if(state & TDLS_PEER_SLEEP_STATE)
+ return 2; //U-APSD + ch. switch
+ else
+ return 1; //ch. switch
+ }else
+ return 0;
+}
+
+//we process buffered data for 1. U-APSD, 2. ch. switch, 3. U-APSD + ch. switch here
+sint On_TDLS_Peer_Traffic_Rsp(_adapter *adapter, union recv_frame *precv_frame)
+{
+ struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
+ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+ struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ //get peer sta infomation
+ struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src);
+ u8 wmmps_ac=0, state=TDLS_check_ch_state(ptdls_sta->tdls_sta_state);
+ int i;
+
+ ptdls_sta->sta_stats.rx_data_pkts++;
+
+ //receive peer traffic response frame, sleeping STA wakes up
+ //ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_SLEEP_STATE);
+ process_wmmps_data( adapter, precv_frame);
+
+ // if noticed peer STA wakes up by receiving peer traffic response
+ // and we want to do channel swtiching, then we will transmit channel switch request first
+ if(ptdls_sta->tdls_sta_state & TDLS_APSD_CHSW_STATE){
+ issue_tdls_ch_switch_req(adapter, pattrib->src);
+ ptdls_sta->tdls_sta_state &= ~(TDLS_APSD_CHSW_STATE);
+ return _FAIL;
+ }
+
+ //check 4-AC queue bit
+ if(ptdls_sta->uapsd_vo || ptdls_sta->uapsd_vi || ptdls_sta->uapsd_be || ptdls_sta->uapsd_bk)
+ wmmps_ac=1;
+
+ //if it's a direct link and have buffered frame
+ if(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE){
+ if(wmmps_ac && state)
+ {
+ _irqL irqL;
+ _list *xmitframe_plist, *xmitframe_phead;
+ struct xmit_frame *pxmitframe=NULL;
+
+ _enter_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
+
+ xmitframe_phead = get_list_head(&ptdls_sta->sleep_q);
+ xmitframe_plist = get_next(xmitframe_phead);
+
+ //transmit buffered frames
+ while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
+ {
+ pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
+ xmitframe_plist = get_next(xmitframe_plist);
+ rtw_list_delete(&pxmitframe->list);
+
+ ptdls_sta->sleepq_len--;
+ if(ptdls_sta->sleepq_len>0){
+ pxmitframe->attrib.mdata = 1;
+ pxmitframe->attrib.eosp = 0;
+ }else{
+ pxmitframe->attrib.mdata = 0;
+ pxmitframe->attrib.eosp = 1;
+ }
+ //pxmitframe->attrib.triggered = 1; //maybe doesn't need in TDLS
+ if(adapter->HalFunc.hal_xmit(adapter, pxmitframe) == _TRUE)
+ {
+ rtw_os_xmit_complete(adapter, pxmitframe);
+ }
+
+ }
+
+ if(ptdls_sta->sleepq_len==0)
+ {
+ DBG_871X("no buffered packets for tdls to xmit\n");
+ //on U-APSD + CH. switch state, when there is no buffered date to xmit,
+ // we should go back to base channel
+ if(state==2){
+ rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
+ }else if(ptdls_sta->tdls_sta_state&TDLS_SW_OFF_STATE){
+ ptdls_sta->tdls_sta_state &= ~(TDLS_SW_OFF_STATE);
+ ptdlsinfo->candidate_ch= pmlmeext->cur_channel;
+ issue_tdls_ch_switch_req(adapter, pattrib->src);
+ DBG_871X("issue tdls ch switch req back to base channel\n");
+ }
+
+ }
+ else
+ {
+ DBG_871X("error!psta->sleepq_len=%d\n", ptdls_sta->sleepq_len);
+ ptdls_sta->sleepq_len=0;
+ }
+
+ _exit_critical_bh(&ptdls_sta->sleep_q.lock, &irqL);
+
+ }
+
+ }
+
+ return _FAIL;
+}
+
+sint On_TDLS_Ch_Switch_Req(_adapter *adapter, union recv_frame *precv_frame)
+{
+ struct sta_info *ptdls_sta= NULL;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
+ u8 *psa;
+ sint parsing_length;
+ PNDIS_802_11_VARIABLE_IEs pIE;
+ u8 FIXED_IE =3;
+ u16 j;
+ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+
+ psa = get_sa(ptr);
+ ptdls_sta = rtw_get_stainfo(pstapriv, psa);
+
+ ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
+ parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
+ -prx_pkt_attrib->hdrlen
+ -prx_pkt_attrib->iv_len
+ -prx_pkt_attrib->icv_len
+ -LLC_HEADER_SIZE
+ -ETH_TYPE_LEN
+ -PAYLOAD_TYPE_LEN
+ -FIXED_IE;
+
+ ptdls_sta->off_ch = *(ptr+2);
+
+ //parsing information element
+ for(j=FIXED_IE; j<parsing_length;){
+
+ pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
+
+ switch (pIE->ElementID)
+ {
+ case _COUNTRY_IE_:
+ break;
+ case _CH_SWTICH_ANNOUNCE_:
+ break;
+ case _LINK_ID_IE_:
+ break;
+ case _CH_SWITCH_TIMING_:
+ _rtw_memcpy(&ptdls_sta->ch_switch_time, pIE->data, 2);
+ _rtw_memcpy(&ptdls_sta->ch_switch_timeout, pIE->data+2, 2);
+ default:
+ break;
+ }
+
+ j += (pIE->Length + 2);
+
+ }
+
+ //todo: check status
+ ptdls_sta->stat_code=0;
+ ptdls_sta->tdls_sta_state |= TDLS_CH_SWITCH_ON_STATE;
+
+ issue_nulldata(adapter, NULL, 1, 0, 0);
+
+ issue_tdls_ch_switch_rsp(adapter, psa);
+
+ DBG_871X("issue tdls channel switch response\n");
+
+ if((ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE) && ptdls_sta->off_ch==pmlmeext->cur_channel){
+ DBG_871X("back to base channel %x\n", pmlmeext->cur_channel);
+ ptdls_sta->option=7;
+ rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_BASE_CH);
+ }else{
+ ptdls_sta->option=6;
+ rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_OFF_CH);
+ }
+ return _FAIL;
+}
+
+sint On_TDLS_Ch_Switch_Rsp(_adapter *adapter, union recv_frame *precv_frame)
+{
+ struct sta_info *ptdls_sta= NULL;
+ struct sta_priv *pstapriv = &adapter->stapriv;
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ struct rx_pkt_attrib *prx_pkt_attrib = &precv_frame->u.hdr.attrib;
+ u8 *psa;
+ sint parsing_length;
+ PNDIS_802_11_VARIABLE_IEs pIE;
+ u8 FIXED_IE =4;
+ u16 stat_code, j, switch_time, switch_timeout;
+ struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
+
+ psa = get_sa(ptr);
+ ptdls_sta = rtw_get_stainfo(pstapriv, psa);
+
+ //if channel switch is running and receiving Unsolicited TDLS Channel Switch Response,
+ //it will go back to base channel and terminate this channel switch procedure
+ if(ptdls_sta->tdls_sta_state & TDLS_CH_SWITCH_ON_STATE ){
+ if(pmlmeext->cur_channel==ptdls_sta->off_ch){
+ DBG_871X("back to base channel %x\n", pmlmeext->cur_channel);
+ ptdls_sta->option=7;
+ rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_OFF_CH);
+ }else{
+ DBG_871X("receive unsolicited channel switch response \n");
+ rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_CS_OFF);
+ }
+ return _FAIL;
+ }
+
+ //avoiding duplicated or unconditional ch. switch. rsp
+ if((ptdls_sta->tdls_sta_state & TDLS_CH_SW_INITIATOR_STATE) != TDLS_CH_SW_INITIATOR_STATE)
+ return _FAIL;
+
+ ptr +=prx_pkt_attrib->hdrlen + prx_pkt_attrib->iv_len+LLC_HEADER_SIZE+TYPE_LENGTH_FIELD_SIZE+1;
+ parsing_length= ((union recv_frame *)precv_frame)->u.hdr.len
+ -prx_pkt_attrib->hdrlen
+ -prx_pkt_attrib->iv_len
+ -prx_pkt_attrib->icv_len
+ -LLC_HEADER_SIZE
+ -ETH_TYPE_LEN
+ -PAYLOAD_TYPE_LEN
+ -FIXED_IE;
+
+ _rtw_memcpy(&stat_code, ptr+2, 2);
+
+ if(stat_code!=0){
+ return _FAIL;
+ }
+
+ //parsing information element
+ for(j=FIXED_IE; j<parsing_length;){
+
+ pIE = (PNDIS_802_11_VARIABLE_IEs)(ptr+ j);
+
+ switch (pIE->ElementID)
+ {
+ case _LINK_ID_IE_:
+ break;
+ case _CH_SWITCH_TIMING_:
+ _rtw_memcpy(&switch_time, pIE->data, 2);
+ if(switch_time > ptdls_sta->ch_switch_time)
+ _rtw_memcpy(&ptdls_sta->ch_switch_time, &switch_time, 2);
+
+ _rtw_memcpy(&switch_timeout, pIE->data+2, 2);
+ if(switch_timeout > ptdls_sta->ch_switch_timeout)
+ _rtw_memcpy(&ptdls_sta->ch_switch_timeout, &switch_timeout, 2);
+
+ default:
+ break;
+ }
+
+ j += (pIE->Length + 2);
+
+ }
+
+ ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SW_INITIATOR_STATE);
+ ptdls_sta->tdls_sta_state |=TDLS_CH_SWITCH_ON_STATE;
+
+ //goto set_channel_workitem_callback()
+ ptdls_sta->option=6;
+ rtw_tdls_cmd(adapter, ptdls_sta->hwaddr, TDLS_OFF_CH);
+
+ return _FAIL;
+}
+
+#ifdef CONFIG_WFD
+void wfd_ie_tdls(_adapter * padapter, u8 *pframe, u32 *pktlen )
+{
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct wifi_display_info *pwfd_info = padapter->tdlsinfo.wfd_info;
+ u8 wfdie[ MAX_WFD_IE_LEN] = { 0x00 };
+ u32 wfdielen = 0;
+
+ // WFD OUI
+ wfdielen = 0;
+ wfdie[ wfdielen++ ] = 0x50;
+ wfdie[ wfdielen++ ] = 0x6F;
+ wfdie[ wfdielen++ ] = 0x9A;
+ wfdie[ wfdielen++ ] = 0x0A; // WFA WFD v1.0
+
+ // Commented by Albert 20110825
+ // According to the WFD Specification, the negotiation request frame should contain 3 WFD attributes
+ // 1. WFD Device Information
+ // 2. Associated BSSID ( Optional )
+ // 3. Local IP Adress ( Optional )
+
+ // WFD Device Information ATTR
+ // Type:
+ wfdie[ wfdielen++ ] = WFD_ATTR_DEVICE_INFO;
+
+ // Length:
+ // Note: In the WFD specification, the size of length field is 2.
+ RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
+ wfdielen += 2;
+
+ // Value1:
+ // WFD device information
+ // available for WFD session + Preferred TDLS + WSD ( WFD Service Discovery )
+ RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->wfd_device_type | WFD_DEVINFO_SESSION_AVAIL
+ | WFD_DEVINFO_PC_TDLS | WFD_DEVINFO_WSD);
+ wfdielen += 2;
+
+ // Value2:
+ // Session Management Control Port
+ // Default TCP port for RTSP messages is 554
+ RTW_PUT_BE16(wfdie + wfdielen, pwfd_info->rtsp_ctrlport );
+ wfdielen += 2;
+
+ // Value3:
+ // WFD Device Maximum Throughput
+ // 300Mbps is the maximum throughput
+ RTW_PUT_BE16(wfdie + wfdielen, 300);
+ wfdielen += 2;
+
+ // Associated BSSID ATTR
+ // Type:
+ wfdie[ wfdielen++ ] = WFD_ATTR_ASSOC_BSSID;
+
+ // Length:
+ // Note: In the WFD specification, the size of length field is 2.
+ RTW_PUT_BE16(wfdie + wfdielen, 0x0006);
+ wfdielen += 2;
+
+ // Value:
+ // Associated BSSID
+ if ( check_fwstate( pmlmepriv, _FW_LINKED) == _TRUE )
+ {
+ _rtw_memcpy( wfdie + wfdielen, &pmlmepriv->assoc_bssid[ 0 ], ETH_ALEN );
+ }
+ else
+ {
+ _rtw_memset( wfdie + wfdielen, 0x00, ETH_ALEN );
+ }
+
+ // Local IP Address ATTR
+ wfdie[ wfdielen++ ] = WFD_ATTR_LOCAL_IP_ADDR;
+
+ // Length:
+ // Note: In the WFD specification, the size of length field is 2.
+ RTW_PUT_BE16(wfdie + wfdielen, 0x0005);
+ wfdielen += 2;
+
+ // Version:
+ // 0x01: Version1;IPv4
+ wfdie[ wfdielen++ ] = 0x01;
+
+ // IPv4 Address
+ _rtw_memcpy( wfdie + wfdielen, pwfd_info->ip_address, 4 );
+ wfdielen += 4;
+
+ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wfdielen, (unsigned char *) wfdie, pktlen);
+
+}
+#endif //CONFIG_WFD
+
+void rtw_build_tdls_setup_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
+{
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+ struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst);
+
+ u8 payload_type = 0x02;
+ u8 category = RTW_WLAN_CATEGORY_TDLS;
+ u8 action = TDLS_SETUP_REQUEST;
+ u8 bssrate[NDIS_802_11_LENGTH_RATES_EX]; //Use NDIS_802_11_LENGTH_RATES_EX in order to call func.rtw_set_supported_rate
+ int bssrate_len = 0, i = 0 ;
+ u8 more_supportedrates = 0;
+ unsigned int ie_len;
+ u8 *p;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ u8 link_id_addr[18] = {0};
+ u8 iedata=0;
+ u8 sup_ch[ 30 * 2 ] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; //For supported channel
+ u8 timeout_itvl[5]; //set timeout interval to maximum value
+ u32 time;
+
+ //SNonce
+ if(pattrib->encrypt){
+ for(i=0;i<8;i++){
+ time=rtw_get_current_time();
+ _rtw_memcpy(&ptdls_sta->SNonce[4*i], (u8 *)&time, 4);
+ }
+ }
+
+ //payload type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
+ //category, action, dialog token
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
+
+ //capability
+ _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
+
+ if(pattrib->encrypt)
+ *pframe =*pframe | BIT(4);
+ pframe += 2;
+ pattrib->pktlen += 2;
+
+ //supported rates
+ rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
+ bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
+
+ if (bssrate_len > 8)
+ {
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
+ more_supportedrates = 1;
+ }
+ else
+ {
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
+ }
+
+ //country(optional)
+ //extended supported rates
+ if(more_supportedrates==1){
+ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
+ }
+
+ //supported channels
+ pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
+
+ // SRC IE
+ pframe = rtw_set_ie( pframe, _SRC_IE_, 16, TDLS_SRC, &(pattrib->pktlen));
+
+ //RSNIE
+ if(pattrib->encrypt)
+ pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen));
+
+ //extended capabilities
+ pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , 5, TDLS_EXT_CAPIE, &(pattrib->pktlen));
+
+ //QoS capability(WMM_IE)
+ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 7, TDLS_WMMIE, &(pattrib->pktlen));
+
+
+ if(pattrib->encrypt){
+ //FTIE
+ _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
+ _rtw_memset(pframe, _FTIE_, 1); //version
+ _rtw_memset((pframe+1), 82, 1); //length
+ _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
+ pframe += 84;
+ pattrib->pktlen += 84;
+
+ //Timeout interval
+ timeout_itvl[0]=0x02;
+ _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
+ pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
+ }
+
+ //Sup_reg_classes(optional)
+ //HT capabilities
+ pframe = rtw_tdls_set_ht_cap(padapter, pframe, pattrib);
+
+ //20/40 BSS coexistence
+ if(pmlmepriv->num_FortyMHzIntolerant>0)
+ iedata |= BIT(2);//20 MHz BSS Width Request
+ pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
+
+ //Link identifier
+ _rtw_memcpy(link_id_addr, pattrib->ra, 6);
+ _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
+ _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
+ pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
+
+#ifdef CONFIG_WFD
+ wfd_ie_tdls( padapter, pframe, &(pattrib->pktlen) );
+#endif //CONFIG_WFD
+
+}
+
+void rtw_build_tdls_setup_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
+{
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct sta_info *ptdls_sta;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+
+ u8 payload_type = 0x02;
+ unsigned char category = RTW_WLAN_CATEGORY_TDLS;
+ unsigned char action = TDLS_SETUP_RESPONSE;
+ unsigned char bssrate[NDIS_802_11_LENGTH_RATES_EX];
+ int bssrate_len = 0;
+ u8 more_supportedrates = 0;
+ unsigned int ie_len;
+ unsigned char *p;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ u8 link_id_addr[18] = {0};
+ u8 iedata=0;
+ u8 timeout_itvl[5]; //setup response timeout interval will copy from request
+ u8 ANonce[32]; //maybe it can put in ontdls_req
+ u8 k; //for random ANonce
+ u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic;
+ u32 time;
+
+ ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst);
+
+ if(ptdls_sta == NULL )
+ {
+ DBG_871X("[%s] %d\n", __FUNCTION__, __LINE__);
+ return;
+ }
+
+ if(pattrib->encrypt){
+ for(k=0;k<8;k++){
+ time=rtw_get_current_time();
+ _rtw_memcpy(&ptdls_sta->ANonce[4*k], (u8*)&time, 4);
+ }
+ }
+
+ //payload type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
+ //category, action, status code
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
+
+ if(ptdls_sta->stat_code!=0) //invalid setup request
+ {
+ DBG_871X("ptdls_sta->stat_code:%04x \n", ptdls_sta->stat_code);
+ return;
+ }
+
+ //dialog token
+ pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
+
+ //capability
+ _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
+
+ if(pattrib->encrypt )
+ *pframe =*pframe | BIT(4);
+ pframe += 2;
+ pattrib->pktlen += 2;
+
+ //supported rates
+ rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
+ bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
+
+ if (bssrate_len > 8)
+ {
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
+ more_supportedrates = 1;
+ }
+ else
+ {
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
+ }
+
+ //country(optional)
+ //extended supported rates
+ if(more_supportedrates==1){
+ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
+ }
+
+ //supported channels
+ pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
+
+ // SRC IE
+ pframe = rtw_set_ie(pframe, _SRC_IE_ , 16, TDLS_SRC, &(pattrib->pktlen));
+
+ //RSNIE
+ if(pattrib->encrypt){
+ prsnie = pframe;
+ pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen));
+ }
+
+ //extended capabilities
+ pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , 5, TDLS_EXT_CAPIE, &(pattrib->pktlen));
+
+ //QoS capability(WMM_IE)
+ pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 7, TDLS_WMMIE, &(pattrib->pktlen));
+
+ if(pattrib->encrypt){
+ wpa_tdls_generate_tpk(padapter, ptdls_sta);
+
+ //FTIE
+ pftie = pframe;
+ pftie_mic = pframe+4;
+ _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
+ _rtw_memset(pframe, _FTIE_, 1); //version
+ _rtw_memset((pframe+1), 82, 1); //length
+ _rtw_memcpy((pframe+20), ptdls_sta->ANonce, 32);
+ _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
+ pframe += 84;
+ pattrib->pktlen += 84;
+
+ //Timeout interval
+ ptimeout_ie = pframe;
+ timeout_itvl[0]=0x02;
+ _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
+ pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
+ }
+
+ //Sup_reg_classes(optional)
+ //HT capabilities
+ pframe = rtw_tdls_set_ht_cap(padapter, pframe, pattrib);
+
+ //20/40 BSS coexistence
+ if(pmlmepriv->num_FortyMHzIntolerant>0)
+ iedata |= BIT(2);//20 MHz BSS Width Request
+ pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
+
+ //Link identifier
+ plinkid_ie = pframe;
+ _rtw_memcpy(link_id_addr, pattrib->ra, 6);
+ _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
+ _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
+ pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
+
+ //fill FTIE mic
+ if(pattrib->encrypt)
+ wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 2, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
+
+#ifdef CONFIG_WFD
+ wfd_ie_tdls( padapter, pframe, &(pattrib->pktlen) );
+#endif //CONFIG_WFD
+
+}
+
+void rtw_build_tdls_setup_cfm_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
+{
+
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct sta_info *ptdls_sta=rtw_get_stainfo( (&padapter->stapriv) , pattrib->dst);
+
+ u8 payload_type = 0x02;
+ unsigned char category = RTW_WLAN_CATEGORY_TDLS;
+ unsigned char action = TDLS_SETUP_CONFIRM;
+ u8 more_supportedrates = 0;
+ unsigned int ie_len;
+ unsigned char *p;
+ u8 timeout_itvl[5]; //set timeout interval to maximum value
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ u8 link_id_addr[18] = {0};
+ u8 *pftie, *ptimeout_ie, *plinkid_ie, *prsnie, *pftie_mic;
+
+ //payload type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
+ //category, action, status code, dialog token
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
+
+ if(ptdls_sta->stat_code!=0) //invalid setup request
+ return;
+
+ //RSNIE
+ if(pattrib->encrypt){
+ prsnie = pframe;
+ pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen));
+ }
+
+ //EDCA param set; WMM param ele.
+ if(pattrib->encrypt){
+ //FTIE
+ pftie = pframe;
+ pftie_mic = pframe+4;
+ _rtw_memset(pframe, 0, 84); //All fields except SNonce shall be set to 0
+ _rtw_memset(pframe, _FTIE_, 1); //version
+ _rtw_memset((pframe+1), 82, 1); //length
+ _rtw_memcpy((pframe+20), ptdls_sta->ANonce, 32);
+ _rtw_memcpy((pframe+52), ptdls_sta->SNonce, 32);
+ pframe += 84;
+ pattrib->pktlen += 84;
+
+ //Timeout interval
+ ptimeout_ie = pframe;
+ timeout_itvl[0]=0x02;
+ _rtw_memcpy(timeout_itvl+1, (u8 *)(&ptdls_sta->TDLS_PeerKey_Lifetime), 4);
+ ptdls_sta->TPK_count=0;
+ _set_timer(&ptdls_sta->TPK_timer, ptdls_sta->TDLS_PeerKey_Lifetime/TPK_RESEND_COUNT);
+ pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
+ }
+
+ //HT operation; todo
+ //Link identifier
+ plinkid_ie = pframe;
+ _rtw_memcpy(link_id_addr, pattrib->ra, 6);
+ _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
+ _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
+ pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
+
+ //fill FTIE mic
+ if(pattrib->encrypt)
+ wpa_tdls_ftie_mic(ptdls_sta->tpk.kck, 3, plinkid_ie, prsnie, ptimeout_ie, pftie, pftie_mic);
+
+}
+
+void rtw_build_tdls_teardown_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
+{
+
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ u8 payload_type = 0x02;
+ unsigned char category = RTW_WLAN_CATEGORY_TDLS;
+ unsigned char action = TDLS_TEARDOWN;
+ u8 link_id_addr[18] = {0};
+
+ struct sta_info *ptdls_sta = rtw_get_stainfo( &(padapter->stapriv) , pattrib->dst);
+ struct sta_priv *pstapriv = &padapter->stapriv;
+
+ //payload type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
+ //category, action, reason code
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
+
+ //Link identifier
+ if(ptdls_sta->tdls_sta_state & TDLS_INITIATOR_STATE){
+ _rtw_memcpy(link_id_addr, pattrib->ra, 6);
+ _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
+ _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
+ }else if(ptdls_sta->tdls_sta_state & TDLS_RESPONDER_STATE){
+ _rtw_memcpy(link_id_addr, pattrib->ra, 6);
+ _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
+ _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
+ }
+ pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
+
+}
+
+void rtw_build_tdls_dis_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
+{
+
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ u8 payload_type = 0x02;
+ u8 category = RTW_WLAN_CATEGORY_TDLS;
+ u8 action = TDLS_DISCOVERY_REQUEST;
+ u8 link_id_addr[18] = {0};
+ static u8 dialogtoken=0;
+
+ //payload type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
+ //category, action, reason code
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(dialogtoken), &(pattrib->pktlen));
+ dialogtoken = (dialogtoken+1)%256;
+
+ //Link identifier
+ _rtw_memcpy(link_id_addr, pattrib->ra, 6);
+ _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
+ _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
+ pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
+
+}
+
+void rtw_build_tdls_dis_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe, u8 dialog)
+{
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct registry_priv *pregistrypriv = &padapter->registrypriv;
+
+ u8 category = RTW_WLAN_CATEGORY_PUBLIC;
+ u8 action = TDLS_DISCOVERY_RESPONSE;
+ u8 bssrate[NDIS_802_11_LENGTH_RATES_EX];
+ int bssrate_len = 0;
+ u8 more_supportedrates = 0;
+ u8 *p;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ u8 link_id_addr[18] = {0};
+ u8 iedata=0;
+ u8 timeout_itvl[5]; //set timeout interval to maximum value
+ u32 timeout_interval= TPK_RESEND_COUNT * 1000;
+
+ //category, action, dialog token
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(dialog), &(pattrib->pktlen));
+
+ //capability
+ _rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
+
+ if(pattrib->encrypt)
+ *pframe =*pframe | BIT(4);
+ pframe += 2;
+ pattrib->pktlen += 2;
+
+ //supported rates
+ rtw_set_supported_rate(bssrate, WIRELESS_11BG_24N);
+ bssrate_len = IEEE80211_CCK_RATE_LEN + IEEE80211_NUM_OFDM_RATESLEN;
+
+ if (bssrate_len > 8)
+ {
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
+ more_supportedrates = 1;
+ }
+ else
+ {
+ pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
+ }
+
+ //extended supported rates
+ if(more_supportedrates==1){
+ pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
+ }
+
+ //supported channels
+ pframe = rtw_tdls_set_sup_ch(pmlmeext, pframe, pattrib);
+
+ //RSNIE
+ if(pattrib->encrypt)
+ pframe = rtw_set_ie(pframe, _RSN_IE_2_, 20, TDLS_RSNIE, &(pattrib->pktlen));
+
+ //extended capability
+ pframe = rtw_set_ie(pframe, _EXT_CAP_IE_ , 5, TDLS_EXT_CAPIE, &(pattrib->pktlen));
+
+ if(pattrib->encrypt){
+ //FTIE
+ _rtw_memset(pframe, 0, 84); //All fields shall be set to 0
+ _rtw_memset(pframe, _FTIE_, 1); //version
+ _rtw_memset((pframe+1), 82, 1); //length
+ pframe += 84;
+ pattrib->pktlen += 84;
+
+ //Timeout interval
+ timeout_itvl[0]=0x02;
+ _rtw_memcpy(timeout_itvl+1, &timeout_interval, 4);
+ pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
+ }
+
+ //Sup_reg_classes(optional)
+ //HT capabilities
+ pframe = rtw_tdls_set_ht_cap(padapter, pframe, pattrib);
+
+ //20/40 BSS coexistence
+ if(pmlmepriv->num_FortyMHzIntolerant>0)
+ iedata |= BIT(2);//20 MHz BSS Width Request
+ pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
+
+ //Link identifier
+ _rtw_memcpy(link_id_addr, pattrib->ra, 6);
+ _rtw_memcpy((link_id_addr+6), pattrib->dst, 6);
+ _rtw_memcpy((link_id_addr+12), pattrib->src, 6);
+ pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
+
+}
+
+void rtw_build_tdls_peer_traffic_indication_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
+{
+
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ u8 payload_type = 0x02;
+ unsigned char category = RTW_WLAN_CATEGORY_TDLS;
+ unsigned char action = TDLS_PEER_TRAFFIC_INDICATION;
+
+ u8 link_id_addr[18] = {0};
+ u8 AC_queue=0;
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
+
+ //payload type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
+ //category, action, reason code
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(ptdls_sta->dialog), &(pattrib->pktlen));
+
+ //Link identifier
+ _rtw_memcpy(link_id_addr, pattrib->ra, 6);
+ _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
+ _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
+ pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
+
+ //PTI control
+ //PU buffer status
+ if(ptdls_sta->uapsd_bk&BIT(1))
+ AC_queue=BIT(0);
+ if(ptdls_sta->uapsd_be&BIT(1))
+ AC_queue=BIT(1);
+ if(ptdls_sta->uapsd_vi&BIT(1))
+ AC_queue=BIT(2);
+ if(ptdls_sta->uapsd_vo&BIT(1))
+ AC_queue=BIT(3);
+ pframe = rtw_set_ie(pframe, _PTI_BUFFER_STATUS_, 1, &AC_queue, &(pattrib->pktlen));
+
+}
+
+void rtw_build_tdls_ch_switch_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
+{
+
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
+ u8 payload_type = 0x02;
+ unsigned char category = RTW_WLAN_CATEGORY_TDLS;
+ unsigned char action = TDLS_CHANNEL_SWITCH_REQUEST;
+ u8 link_id_addr[18] = {0};
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
+ u8 ch_switch_timing[4] = {0};
+ u16 switch_time= CH_SWITCH_TIME, switch_timeout=CH_SWITCH_TIMEOUT;
+
+ //payload type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
+ //category, action, target_ch
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(ptdlsinfo->candidate_ch), &(pattrib->pktlen));
+
+ //Link identifier
+ _rtw_memcpy(link_id_addr, pattrib->ra, 6);
+ _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
+ _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
+ pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
+
+ //ch switch timing
+ _rtw_memcpy(ch_switch_timing, &switch_time, 2);
+ _rtw_memcpy(ch_switch_timing+2, &switch_timeout, 2);
+ pframe = rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen));
+
+ //update ch switch attrib to sta_info
+ ptdls_sta->off_ch=ptdlsinfo->candidate_ch;
+ ptdls_sta->ch_switch_time=switch_time;
+ ptdls_sta->ch_switch_timeout=switch_timeout;
+
+}
+
+void rtw_build_tdls_ch_switch_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
+{
+
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ u8 payload_type = 0x02;
+ unsigned char category = RTW_WLAN_CATEGORY_TDLS;
+ unsigned char action = TDLS_CHANNEL_SWITCH_RESPONSE;
+ u8 link_id_addr[18] = {0};
+ struct sta_priv *pstapriv = &padapter->stapriv;
+ struct sta_info *ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
+ u8 ch_switch_timing[4] = {0};
+
+ //payload type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
+ //category, action, status_code
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 2, (u8 *)&ptdls_sta->stat_code, &(pattrib->pktlen));
+
+ //Link identifier
+ _rtw_memcpy(link_id_addr, pattrib->ra, 6);
+ _rtw_memcpy((link_id_addr+6), pattrib->src, 6);
+ _rtw_memcpy((link_id_addr+12), pattrib->dst, 6);
+ pframe = rtw_set_ie(pframe, _LINK_ID_IE_, 18, link_id_addr, &(pattrib->pktlen));
+
+ //ch switch timing
+ _rtw_memcpy(ch_switch_timing, &ptdls_sta->ch_switch_time, 2);
+ _rtw_memcpy(ch_switch_timing+2, &ptdls_sta->ch_switch_timeout, 2);
+ pframe = rtw_set_ie(pframe, _CH_SWITCH_TIMING_, 4, ch_switch_timing, &(pattrib->pktlen));
+
+}
+
+#ifdef CONFIG_WFD
+void rtw_build_tunneled_probe_req_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
+{
+
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct wifidirect_info *pwdinfo = &padapter->wdinfo;
+ struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo;
+ u8 payload_type = 0x02;
+ u8 category = RTW_WLAN_CATEGORY_P2P;
+ u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
+ u8 probe_req = 4;
+ u8 wfdielen = 0;
+
+ //payload type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
+ //category, OUI, frame_body_type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(probe_req), &(pattrib->pktlen));
+
+ if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
+ {
+ wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
+ pframe += wfdielen;
+ pattrib->pktlen += wfdielen;
+ }
+ else if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
+ {
+ wfdielen = build_probe_req_wfd_ie(pbuddy_wdinfo, pframe);
+ pframe += wfdielen;
+ pattrib->pktlen += wfdielen;
+ }
+
+}
+
+void rtw_build_tunneled_probe_rsp_ies(_adapter * padapter, struct xmit_frame * pxmitframe, u8 *pframe)
+{
+
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ struct wifidirect_info *pwdinfo = &padapter->wdinfo;
+ struct wifidirect_info *pbuddy_wdinfo = &padapter->pbuddy_adapter->wdinfo;
+ u8 payload_type = 0x02;
+ u8 category = RTW_WLAN_CATEGORY_P2P;
+ u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a};
+ u8 probe_rsp = 5;
+ u8 wfdielen = 0;
+
+ //payload type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(payload_type), &(pattrib->pktlen));
+ //category, OUI, frame_body_type
+ pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 3, WFA_OUI, &(pattrib->pktlen));
+ pframe = rtw_set_fixed_ie(pframe, 1, &(probe_rsp), &(pattrib->pktlen));
+
+ if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
+ {
+ wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 1);
+ pframe += wfdielen;
+ pattrib->pktlen += wfdielen;
+ }
+ else if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
+ {
+ wfdielen = build_probe_resp_wfd_ie(pbuddy_wdinfo, pframe, 1);
+ pframe += wfdielen;
+ pattrib->pktlen += wfdielen;
+ }
+
+}
+#endif //CONFIG_WFD
+
+void _TPK_timer_hdl(void *FunctionContext)
+{
+ struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
+
+ ptdls_sta->TPK_count++;
+ //TPK_timer set 1000 as default
+ //retry timer should set at least 301 sec.
+ if(ptdls_sta->TPK_count==TPK_RESEND_COUNT){
+ ptdls_sta->TPK_count=0;
+ issue_tdls_setup_req(ptdls_sta->padapter, ptdls_sta->hwaddr);
+ }
+
+ _set_timer(&ptdls_sta->TPK_timer, ptdls_sta->TDLS_PeerKey_Lifetime/TPK_RESEND_COUNT);
+}
+
+void init_TPK_timer(_adapter *padapter, struct sta_info *psta)
+{
+ psta->padapter=padapter;
+
+ _init_timer(&psta->TPK_timer, padapter->pnetdev, _TPK_timer_hdl, psta);
+}
+
+// TDLS_DONE_CH_SEN: channel sensing and report candidate channel
+// TDLS_OFF_CH: first time set channel to off channel
+// TDLS_BASE_CH: when go back to the channel linked with AP, send null data to peer STA as an indication
+void _ch_switch_timer_hdl(void *FunctionContext)
+{
+
+ struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
+ _adapter *padapter = ptdls_sta->padapter;
+
+ if( ptdls_sta->option == TDLS_DONE_CH_SEN ){
+ rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_DONE_CH_SEN);
+ }else if( ptdls_sta->option == TDLS_OFF_CH ){
+ issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta, 0);
+ _set_timer(&ptdls_sta->base_ch_timer, 500);
+ }else if( ptdls_sta->option == TDLS_BASE_CH){
+ issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta, 0);
+ }
+}
+
+void init_ch_switch_timer(_adapter *padapter, struct sta_info *psta)
+{
+ psta->padapter=padapter;
+ _init_timer(&psta->option_timer, padapter->pnetdev, _ch_switch_timer_hdl, psta);
+}
+
+void _base_ch_timer_hdl(void *FunctionContext)
+{
+ struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
+ rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_P_OFF_CH);
+}
+
+void init_base_ch_timer(_adapter *padapter, struct sta_info *psta)
+{
+ psta->padapter=padapter;
+ _init_timer(&psta->base_ch_timer, padapter->pnetdev, _base_ch_timer_hdl, psta);
+}
+
+void _off_ch_timer_hdl(void *FunctionContext)
+{
+ struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
+ rtw_tdls_cmd(ptdls_sta->padapter, ptdls_sta->hwaddr, TDLS_P_BASE_CH );
+}
+
+void init_off_ch_timer(_adapter *padapter, struct sta_info *psta)
+{
+ psta->padapter=padapter;
+ _init_timer(&psta->off_ch_timer, padapter->pnetdev, _off_ch_timer_hdl, psta);
+}
+
+void _tdls_handshake_timer_hdl(void *FunctionContext)
+{
+ struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
+
+ if(ptdls_sta != NULL)
+ {
+ if( !(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) )
+ {
+ DBG_871X("tdls handshake time out\n");
+ free_tdls_sta(ptdls_sta->padapter, ptdls_sta);
+ }
+ }
+}
+
+void init_handshake_timer(_adapter *padapter, struct sta_info *psta)
+{
+ psta->padapter=padapter;
+ _init_timer(&psta->handshake_timer, padapter->pnetdev, _tdls_handshake_timer_hdl, psta);
+}
+
+//Check tdls peer sta alive.
+void _tdls_alive_timer_phase1_hdl(void *FunctionContext)
+{
+ _irqL irqL;
+ struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
+ _adapter *padapter = ptdls_sta->padapter;
+ struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
+
+ _enter_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
+ ptdls_sta->timer_flag = 1;
+ _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
+
+ ptdls_sta->tdls_sta_state &= (~TDLS_ALIVE_STATE);
+
+ DBG_871X("issue_tdls_dis_req to check alive\n");
+ issue_tdls_dis_req( padapter, ptdls_sta->hwaddr);
+ rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CKALV_PH1);
+ sta_update_last_rx_pkts(ptdls_sta);
+
+ if ( ptdls_sta->timer_flag == 2 )
+ rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_FREE_STA);
+ else
+ {
+ _enter_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
+ ptdls_sta->timer_flag = 0;
+ _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
+ }
+
+}
+
+void _tdls_alive_timer_phase2_hdl(void *FunctionContext)
+{
+ _irqL irqL;
+ struct sta_info *ptdls_sta = (struct sta_info *)FunctionContext;
+ _adapter *padapter = ptdls_sta->padapter;
+ struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
+
+ _enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
+ ptdls_sta->timer_flag = 1;
+ _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
+
+ if( (ptdls_sta->tdls_sta_state & TDLS_ALIVE_STATE) &&
+ (sta_last_rx_pkts(ptdls_sta) + 3 <= sta_rx_pkts(ptdls_sta)) )
+ {
+ DBG_871X("TDLS STA ALIVE, ptdls_sta->sta_stats.last_rx_pkts:%llu, ptdls_sta->sta_stats.rx_pkts:%llu\n",
+ sta_last_rx_pkts(ptdls_sta), sta_rx_pkts(ptdls_sta));
+
+ ptdls_sta->alive_count = 0;
+ rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CKALV_PH2);
+ }
+ else
+ {
+ if( !(ptdls_sta->tdls_sta_state & TDLS_ALIVE_STATE) )
+ DBG_871X("TDLS STA TOO FAR\n");
+ if( !(sta_last_rx_pkts(ptdls_sta) + 3 <= sta_rx_pkts(ptdls_sta)))
+ DBG_871X("TDLS LINK WITH LOW TRAFFIC, ptdls_sta->sta_stats.last_rx_pkts:%llu, ptdls_sta->sta_stats.rx_pkts:%llu\n",
+ sta_last_rx_pkts(ptdls_sta), sta_rx_pkts(ptdls_sta));
+
+ ptdls_sta->alive_count++;
+ if( ptdls_sta->alive_count == TDLS_ALIVE_COUNT )
+ {
+ ptdls_sta->stat_code = _RSON_TDLS_TEAR_TOOFAR_;
+ issue_tdls_teardown(padapter, ptdls_sta->hwaddr);
+ }
+ else
+ {
+ rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_CKALV_PH2);
+ }
+ }
+
+ if ( ptdls_sta->timer_flag == 2 )
+ rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_FREE_STA);
+ else
+ {
+ _enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL);
+ ptdls_sta->timer_flag = 0;
+ _exit_critical_bh(&ptdlsinfo->hdl_lock, &irqL);
+}
+
+}
+
+void init_tdls_alive_timer(_adapter *padapter, struct sta_info *psta)
+{
+ psta->padapter=padapter;
+ _init_timer(&psta->alive_timer1, padapter->pnetdev, _tdls_alive_timer_phase1_hdl, psta);
+ _init_timer(&psta->alive_timer2, padapter->pnetdev, _tdls_alive_timer_phase2_hdl, psta);
+}
+
+int update_sgi_tdls(_adapter *padapter, struct sta_info *psta)
+{
+ struct ht_priv *psta_ht = NULL;
+ psta_ht = &psta->htpriv;
+
+ if(psta_ht->ht_option)
+ {
+ return psta_ht->sgi;
+ }
+ else
+ return _FALSE;
+}
+
+u32 update_mask_tdls(_adapter *padapter, struct sta_info *psta)
+{
+ int i;
+ u8 rf_type, id;
+ unsigned char sta_band = 0;
+ unsigned char limit;
+ unsigned int tx_ra_bitmap=0;
+ struct ht_priv *psta_ht = NULL;
+ struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
+ WLAN_BSSID_EX *pcur_network = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
+
+ psta_ht = &psta->htpriv;
+ //b/g mode ra_bitmap
+ for (i=0; i<sizeof(psta->bssrateset); i++)
+ {
+ if (psta->bssrateset[i])
+ tx_ra_bitmap |= rtw_get_bit_value_from_ieee_value(psta->bssrateset[i]&0x7f);
+ }
+
+ //n mode ra_bitmap
+ if(psta_ht->ht_option)
+ {
+ padapter->HalFunc.GetHwRegHandler(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
+ if(rf_type == RF_2T2R)
+ limit=16;// 2R
+ else
+ limit=8;// 1R
+
+ for (i=0; i<limit; i++) {
+ if (psta_ht->ht_cap.supp_mcs_set[i/8] & BIT(i%8))
+ tx_ra_bitmap |= BIT(i+12);
+ }
+ }
+
+ if ( pcur_network->Configuration.DSConfig > 14 ) {
+ // 5G band
+ if (tx_ra_bitmap & 0xffff000)
+ sta_band |= WIRELESS_11_5N | WIRELESS_11A;
+ else
+ sta_band |= WIRELESS_11A;
+ } else {
+ if (tx_ra_bitmap & 0xffff000)
+ sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B;
+ else if (tx_ra_bitmap & 0xff0)
+ sta_band |= WIRELESS_11G |WIRELESS_11B;
+ else
+ sta_band |= WIRELESS_11B;
+ }
+
+ id = networktype_to_raid(sta_band);
+ tx_ra_bitmap |= ((id<<28)&0xf0000000);
+ return tx_ra_bitmap;
+}
+
+#endif //CONFIG_TDLS
+
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_wapi.c b/drivers/net/wireless/rtl8723as/core/rtw_wapi.c
index 1d4e197a85db..6c6268c0a56f 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_wapi.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_wapi.c
@@ -1,1326 +1,1326 @@
-#ifdef CONFIG_WAPI_SUPPORT
-
-#include <linux/unistd.h>
-#include <linux/etherdevice.h>
-#include <drv_types.h>
-#include <rtw_wapi.h>
-
-
-u32 wapi_debug_component =
-// WAPI_INIT |
-// WAPI_API |
-// WAPI_TX |
-// WAPI_RX |
- WAPI_ERR ; //always open err flags on
-
-void WapiFreeAllStaInfo(_adapter *padapter)
-{
- PRT_WAPI_T pWapiInfo;
- PRT_WAPI_STA_INFO pWapiStaInfo;
- PRT_WAPI_BKID pWapiBkid;
-
- WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
- pWapiInfo = &padapter->wapiInfo;
-
- //Pust to Idle List
- rtw_wapi_return_all_sta_info(padapter);
-
- //Sta Info List
- while(!list_empty(&(pWapiInfo->wapiSTAIdleList)))
- {
- pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAIdleList.next, RT_WAPI_STA_INFO, list);
- list_del_init(&pWapiStaInfo->list);
- }
-
- //BKID List
- while(!list_empty(&(pWapiInfo->wapiBKIDIdleList)))
- {
- pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDIdleList.next, RT_WAPI_BKID, list);
- list_del_init(&pWapiBkid->list);
- }
- WAPI_TRACE(WAPI_INIT, "<=========== %s\n", __FUNCTION__);
- return;
-}
-
-void WapiSetIE(_adapter *padapter)
-{
- PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
- //PRT_WAPI_BKID pWapiBkid;
- u16 protocolVer = 1;
- u16 akmCnt = 1;
- u16 suiteCnt = 1;
- u16 capability = 0;
- u8 OUI[3];
-
- OUI[0] = 0x00;
- OUI[1] = 0x14;
- OUI[2] = 0x72;
-
- pWapiInfo->wapiIELength = 0;
-//protocol version
- memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &protocolVer, 2);
- pWapiInfo->wapiIELength +=2;
-//akm
- memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &akmCnt, 2);
- pWapiInfo->wapiIELength +=2;
-
- if(pWapiInfo->bWapiPSK){
- memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3);
- pWapiInfo->wapiIELength +=3;
- pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x2;
- pWapiInfo->wapiIELength +=1;
- }else{
- memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3);
- pWapiInfo->wapiIELength +=3;
- pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1;
- pWapiInfo->wapiIELength +=1;
- }
-
-//usk
- memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &suiteCnt, 2);
- pWapiInfo->wapiIELength +=2;
- memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3);
- pWapiInfo->wapiIELength +=3;
- pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1;
- pWapiInfo->wapiIELength +=1;
-
-//msk
- memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3);
- pWapiInfo->wapiIELength +=3;
- pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1;
- pWapiInfo->wapiIELength +=1;
-
-//Capbility
- memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &capability, 2);
- pWapiInfo->wapiIELength +=2;
-}
-
-
-/* PN1 > PN2, return 1,
- * else return 0.
- */
-u32 WapiComparePN(u8 *PN1, u8 *PN2)
-{
- char i;
-
- if ((NULL == PN1) || (NULL == PN2))
- return 1;
-
- // overflow case
- if ((PN2[15] - PN1[15]) & 0x80)
- return 1;
-
- for (i=16; i>0; i--)
- {
- if(PN1[i-1] == PN2[i-1])
- continue;
- else if(PN1[i-1] > PN2[i-1])
- return 1;
- else
- return 0;
- }
-
- return 0;
-}
-
-u8
-WapiGetEntryForCamWrite(_adapter *padapter,u8 *pMacAddr,u8 KID,BOOLEAN IsMsk)
-{
- PRT_WAPI_T pWapiInfo=NULL;
- //PRT_WAPI_CAM_ENTRY pEntry=NULL;
- u8 i=0;
- u8 ret = 0xff;
-
- WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
-
- pWapiInfo = &padapter->wapiInfo;
-
- //exist?
- for(i=0;i<WAPI_CAM_ENTRY_NUM;i++)
- {
- if(pWapiInfo->wapiCamEntry[i].IsUsed
- && (_rtw_memcmp(pMacAddr, pWapiInfo->wapiCamEntry[i].PeerMacAddr, ETH_ALEN) == _TRUE)
- && pWapiInfo->wapiCamEntry[i].keyidx == KID
- && pWapiInfo->wapiCamEntry[i].type == IsMsk)
- {
- ret = pWapiInfo->wapiCamEntry[i].entry_idx; //cover it
- break;
- }
- }
-
- if(i == WAPI_CAM_ENTRY_NUM) //not found
- {
- for(i=0;i<WAPI_CAM_ENTRY_NUM;i++)
- {
- if(pWapiInfo->wapiCamEntry[i].IsUsed == 0)
- {
- pWapiInfo->wapiCamEntry[i].IsUsed = 1;
- pWapiInfo->wapiCamEntry[i].type = IsMsk;
- pWapiInfo->wapiCamEntry[i].keyidx = KID;
- _rtw_memcpy(pWapiInfo->wapiCamEntry[i].PeerMacAddr, pMacAddr,ETH_ALEN);
- ret = pWapiInfo->wapiCamEntry[i].entry_idx;
- break;
- }
- }
- }
-
- WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
- return ret;
-
-/*
- if(RTIsListEmpty(&pWapiInfo->wapiCamIdleList)){
- RT_TRACE(COMP_SEC,DBG_LOUD,("No Entry for wapi!!!\n"));
- return 0;
- }
-
- pEntry = (PRT_WAPI_CAM_ENTRY)RTRemoveHeadList(&pWapiInfo->wapiCamIdleList);
- RTInsertTailList(&pWapiInfo->wapiCamUsedList, &pEntry->list);
-
- RT_TRACE(COMP_SEC,DBG_LOUD,("<====WapiGetCamEntry(),Get Entry Idx:%d.but we just return 4 for test\n",pEntry->entry_idx));
-
- return pEntry->entry_idx;*/
-}
-
-u8 WapiGetEntryForCamClear(_adapter *padapter,u8 *pPeerMac,u8 keyid,u8 IsMsk)
-{
- PRT_WAPI_T pWapiInfo=NULL;
- u8 i=0;
-
- WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
-
- pWapiInfo = &padapter->wapiInfo;
-
- for(i=0;i<WAPI_CAM_ENTRY_NUM;i++)
- {
- if(pWapiInfo->wapiCamEntry[i].IsUsed
- && (_rtw_memcmp(pPeerMac, pWapiInfo->wapiCamEntry[i].PeerMacAddr, ETH_ALEN) == _TRUE)
- && pWapiInfo->wapiCamEntry[i].keyidx == keyid
- && pWapiInfo->wapiCamEntry[i].type == IsMsk)
- {
- pWapiInfo->wapiCamEntry[i].IsUsed = 0;
- pWapiInfo->wapiCamEntry[i].keyidx = 2;
- _rtw_memset(pWapiInfo->wapiCamEntry[i].PeerMacAddr,0,ETH_ALEN);
-
- WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
- return pWapiInfo->wapiCamEntry[i].entry_idx;
- }
- }
-
- WAPI_TRACE(WAPI_API,"<====WapiGetReturnCamEntry(), No this cam entry.\n");
- return 0xff;
-/*
- if(RTIsListEmpty(&pWapiInfo->wapiCamUsedList)){
- RT_TRACE(COMP_SEC,DBG_LOUD,("No Entry for wapi!!!\n"));
- return FALSE;
- }
-
- pList = &pWapiInfo->wapiCamUsedList;
- while(pList->Flink != &pWapiInfo->wapiCamUsedList)
- {
- pEntry = (PRT_WAPI_CAM_ENTRY)pList->Flink;
- if(PlatformCompareMemory(pPeerMac,pEntry->PeerMacAddr, ETHER_ADDRLEN)== 0
- && keyid == pEntry->keyidx)
- {
- RTRemoveEntryList(pList);
- RTInsertHeadList(&pWapiInfo->wapiCamIdleList, pList);
- return pEntry->entry_idx;
- }
- pList = pList->Flink;
- }
-
- return 0;
-*/
-}
-
-void
-WapiResetAllCamEntry(_adapter *padapter)
-{
- PRT_WAPI_T pWapiInfo;
- int i;
-
- WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
-
- pWapiInfo = &padapter->wapiInfo;
-
- for (i=0;i<WAPI_CAM_ENTRY_NUM;i++)
- {
- _rtw_memset(pWapiInfo->wapiCamEntry[i].PeerMacAddr, 0, ETH_ALEN);
- pWapiInfo->wapiCamEntry[i].IsUsed = 0;
- pWapiInfo->wapiCamEntry[i].keyidx = 2; //invalid
- pWapiInfo->wapiCamEntry[i].entry_idx = 4+i*2;
- }
-
- WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
-
- return;
-}
-
-u8 WapiWriteOneCamEntry(
- _adapter *padapter,
- u8 *pMacAddr,
- u8 KeyId,
- u8 EntryId,
- u8 EncAlg,
- u8 bGroupKey,
- u8 *pKey
-)
-{
- u8 retVal = 0;
- u16 usConfig = 0;
-
- WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
-
- if(EntryId >= 32)
- {
- WAPI_TRACE(WAPI_ERR, "<=== CamAddOneEntry(): ulKeyId exceed!\n");
- return retVal;
- }
-
- usConfig=usConfig|(0x01<<15)|((u16)(EncAlg)<<2)|(KeyId);
-
- if(EncAlg == _SMS4_ )
- {
- if(bGroupKey == 1)
- usConfig |= (0x01<<6);
- if((EntryId % 2)==1) // ==0 sec key; == 1mic key
- usConfig |= (0x01<<5);
- }
-
- write_cam(padapter, EntryId, usConfig, pMacAddr, pKey);
-
- WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
- return 1;
-}
-
-void rtw_wapi_init(_adapter *padapter)
-{
- PRT_WAPI_T pWapiInfo;
- int i;
-
- WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
- RT_ASSERT_RET(padapter);
-
- if (!padapter->WapiSupport)
- {
- WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__);
- return;
- }
-
- pWapiInfo = &padapter->wapiInfo;
- pWapiInfo->bWapiEnable = false;
-
- //Init BKID List
- INIT_LIST_HEAD(&pWapiInfo->wapiBKIDIdleList);
- INIT_LIST_HEAD(&pWapiInfo->wapiBKIDStoreList);
- for(i=0;i<WAPI_MAX_BKID_NUM;i++)
- {
- list_add_tail(&pWapiInfo->wapiBKID[i].list, &pWapiInfo->wapiBKIDIdleList);
- }
-
- //Init STA List
- INIT_LIST_HEAD(&pWapiInfo->wapiSTAIdleList);
- INIT_LIST_HEAD(&pWapiInfo->wapiSTAUsedList);
- for(i=0;i<WAPI_MAX_STAINFO_NUM;i++)
- {
- list_add_tail(&pWapiInfo->wapiSta[i].list, &pWapiInfo->wapiSTAIdleList);
- }
-
- for (i=0;i<WAPI_CAM_ENTRY_NUM;i++)
- {
- pWapiInfo->wapiCamEntry[i].IsUsed = 0;
- pWapiInfo->wapiCamEntry[i].keyidx = 2; //invalid
- pWapiInfo->wapiCamEntry[i].entry_idx = 4+i*2;
- }
-
- WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__);
-}
-
-void rtw_wapi_free(_adapter *padapter)
-{
- WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
- RT_ASSERT_RET(padapter);
-
- if (!padapter->WapiSupport)
- {
- WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__);
- return;
- }
-
- WapiFreeAllStaInfo(padapter);
-
- WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__);
-}
-
-void rtw_wapi_disable_tx(_adapter *padapter)
-{
- WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
- RT_ASSERT_RET(padapter);
-
- if (!padapter->WapiSupport)
- {
- WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__);
- return;
- }
-
- padapter->wapiInfo.wapiTxMsk.bTxEnable = false;
- padapter->wapiInfo.wapiTxMsk.bSet = false;
-
- WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__);
-}
-
-u8 rtw_wapi_is_wai_packet(_adapter* padapter,u8 *pkt_data)
-{
- PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
- PRT_WAPI_STA_INFO pWapiSta = NULL;
- u8 WaiPkt = 0, *pTaddr, bFind = false;
- u8 Offset_TypeWAI = 0 ; // (mac header len + llc length)
-
- WAPI_TRACE(WAPI_TX|WAPI_RX, "===========> %s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
- {
- WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
- return 0;
- }
-
- Offset_TypeWAI = 24 + 6 ;
-
- //YJ,add,091103. Data frame may also have skb->data[30]=0x88 and skb->data[31]=0xb4.
- if ((pkt_data[1]&0x40) !=0)
- {
- DBG_871X("data is privacy \n");
- return 0;
- }
-
- pTaddr = GetAddr2Ptr(pkt_data);
- if(list_empty(&pWapiInfo->wapiSTAUsedList)){
- bFind = false;
- }else{
- list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list){
- if (_rtw_memcmp(pTaddr, pWapiSta->PeerMacAddr, 6) == _TRUE) {
- bFind = true;
- break;
- }
- }
- }
-
- WAPI_TRACE(WAPI_TX|WAPI_RX, "%s: bFind=%d pTaddr="MAC_FMT"\n", __FUNCTION__, bFind, MAC_ARG(pTaddr));
-
- if (pkt_data[0] == WIFI_QOS_DATA_TYPE)
- {
- Offset_TypeWAI += 2;
- }
-
- // 88b4?
- if( (pkt_data[Offset_TypeWAI]==0x88) && (pkt_data[Offset_TypeWAI+1]==0xb4) ){
- WaiPkt = pkt_data[Offset_TypeWAI+5];
-
- psecuritypriv->hw_decrypted = _TRUE;
- }else{
- WAPI_TRACE(WAPI_TX|WAPI_RX, "%s(): non wai packet\n",__FUNCTION__);
- }
-
- WAPI_TRACE(WAPI_TX|WAPI_RX, "%s(): Recvd WAI frame. IsWAIPkt(%d)\n",__FUNCTION__, WaiPkt);
-
- return WaiPkt;
-}
-
-
-void rtw_wapi_update_info(_adapter *padapter, union recv_frame *precv_frame)
-{
- PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
- struct recv_frame_hdr *precv_hdr;
- u8 *ptr;
- u8 *pTA;
- u8 *pRecvPN;
-
-
- WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
- {
- WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
- return;
- }
-
- precv_hdr = &precv_frame->u.hdr;
- ptr = precv_hdr->rx_data;
-
- if (precv_hdr->attrib.qos == 1)
- {
- precv_hdr->UserPriority = GetTid(ptr);
- }
- else
- {
- precv_hdr->UserPriority = 0;
- }
-
- pTA = GetAddr2Ptr(ptr);
- _rtw_memcpy((u8 *)precv_hdr->WapiSrcAddr, pTA, 6);
- pRecvPN = ptr + precv_hdr->attrib.hdrlen + 2;
- _rtw_memcpy((u8 *)precv_hdr->WapiTempPN, pRecvPN, 16);
-
- WAPI_TRACE(WAPI_RX, "<========== %s\n", __FUNCTION__);
-}
-
-/****************************************************************************
-TRUE-----------------Drop
-FALSE---------------- handle
-add to support WAPI to N-mode
-*****************************************************************************/
-u8 rtw_wapi_check_for_drop(
- _adapter *padapter,
- union recv_frame *precv_frame
-)
-{
- PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
- u8 *pLastRecvPN = NULL;
- u8 bFind = false;
- PRT_WAPI_STA_INFO pWapiSta = NULL;
- u8 bDrop = false;
- struct recv_frame_hdr *precv_hdr = &precv_frame->u.hdr;
- u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
- u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
- u8 *ptr = precv_frame->u.hdr.rx_data;
- int i;
-
- WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
- {
- WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
- return false;
- }
-
- if(precv_hdr->bIsWaiPacket !=0)
- {
- if(precv_hdr->bIsWaiPacket== 0x8)
- {
-
- DBG_871X("rtw_wapi_check_for_drop: dump packet \n");
- for(i=0;i<50;i++)
- {
- DBG_871X("%02X ",ptr[i]);
- if((i+1) %8 ==0)
- DBG_871X("\n");
- }
- DBG_871X("\n rtw_wapi_check_for_drop: dump packet \n");
-
- for(i=0;i<16;i++)
- {
- if(ptr[i+27] !=0)
- break;
- }
-
- if(i== 16)
- {
- WAPI_TRACE(WAPI_RX,"rtw_wapi_check_for_drop: drop with zero BKID \n");
- return true;
- }
- else
- {
- return false;
- }
- }
- else
- return false;
- }
-
- if(list_empty(&pWapiInfo->wapiSTAUsedList)){
- bFind = false;
- }else{
- list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
- if (_rtw_memcmp(precv_hdr->WapiSrcAddr, pWapiSta->PeerMacAddr, ETH_ALEN) == _TRUE) {
- bFind = true;
- break;
- }
- }
- }
- WAPI_TRACE(WAPI_RX, "%s: bFind=%d prxb->WapiSrcAddr="MAC_FMT"\n", __FUNCTION__, bFind, MAC_ARG(precv_hdr->WapiSrcAddr));
-
- if(bFind)
- {
- if(IS_MCAST(precv_hdr->attrib.ra))
- {
- WAPI_TRACE(WAPI_RX,"rtw_wapi_check_for_drop: multicast case \n");
- pLastRecvPN = pWapiSta->lastRxMulticastPN;
- }
- else
- {
- WAPI_TRACE(WAPI_RX,"rtw_wapi_check_for_drop: unicast case \n");
- switch(precv_hdr->UserPriority)
- {
- case 0:
- case 3:
- pLastRecvPN = pWapiSta->lastRxUnicastPNBEQueue;
- break;
- case 1:
- case 2:
- pLastRecvPN = pWapiSta->lastRxUnicastPNBKQueue;
- break;
- case 4:
- case 5:
- pLastRecvPN = pWapiSta->lastRxUnicastPNVIQueue;
- break;
- case 6:
- case 7:
- pLastRecvPN = pWapiSta->lastRxUnicastPNVOQueue;
- break;
- default:
- WAPI_TRACE(WAPI_ERR,"%s: Unknown TID \n",__FUNCTION__);
- break;
- }
- }
-
- if(!WapiComparePN(precv_hdr->WapiTempPN,pLastRecvPN))
- {
- WAPI_TRACE(WAPI_RX,"%s: Equal PN!!\n",__FUNCTION__);
- if(IS_MCAST(precv_hdr->attrib.ra))
- _rtw_memcpy(pLastRecvPN,WapiAEMultiCastPNInitialValueSrc,16);
- else
- _rtw_memcpy(pLastRecvPN,WapiAEPNInitialValueSrc,16);
- bDrop = true;
- }
- else
- {
- _rtw_memcpy(pLastRecvPN,precv_hdr->WapiTempPN,16);
- }
- }
-
- WAPI_TRACE(WAPI_RX, "<========== %s\n", __FUNCTION__);
- return bDrop;
-}
-
-void rtw_build_probe_resp_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib)
-{
- PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
- u8 WapiIELength = 0;
-
- WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
- {
- WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__);
- return;
- }
-
- WapiSetIE(padapter);
- WapiIELength = pWapiInfo->wapiIELength;
- pframe[0] = _WAPI_IE_;
- pframe[1] = WapiIELength;
- _rtw_memcpy(pframe+2, pWapiInfo->wapiIE, WapiIELength);
- pframe += WapiIELength+2;
- pattrib->pktlen += WapiIELength+2;
-
- WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
-}
-
-void rtw_build_beacon_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib)
-{
- PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
- u8 WapiIELength = 0;
- WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
- {
- WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__);
- return;
- }
-
- WapiSetIE(padapter);
- WapiIELength = pWapiInfo->wapiIELength;
- pframe[0] = _WAPI_IE_;
- pframe[1] = WapiIELength;
- _rtw_memcpy(pframe+2, pWapiInfo->wapiIE, WapiIELength);
- pframe += WapiIELength+2;
- pattrib->pktlen += WapiIELength+2;
-
- WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
-}
-
-void rtw_build_assoc_req_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib)
-{
- PRT_WAPI_BKID pWapiBKID;
- u16 bkidNum;
- PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
- u8 WapiIELength = 0;
-
- WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
- {
- WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__);
- return;
- }
-
- WapiSetIE(padapter);
- WapiIELength = pWapiInfo->wapiIELength;
- bkidNum = 0;
- if(!list_empty(&(pWapiInfo->wapiBKIDStoreList))){
- list_for_each_entry(pWapiBKID, &pWapiInfo->wapiBKIDStoreList, list) {
- bkidNum ++;
- _rtw_memcpy(pWapiInfo->wapiIE+WapiIELength+2, pWapiBKID->bkid,16);
- WapiIELength += 16;
- }
- }
- _rtw_memcpy(pWapiInfo->wapiIE+WapiIELength, &bkidNum, 2);
- WapiIELength += 2;
-
- pframe[0] = _WAPI_IE_;
- pframe[1] = WapiIELength;
- _rtw_memcpy(pframe+2, pWapiInfo->wapiIE, WapiIELength);
- pframe += WapiIELength+2;
- pattrib->pktlen += WapiIELength+2;
- WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
-}
-
-void rtw_wapi_on_assoc_ok(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
-{
- PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
- PRT_WAPI_STA_INFO pWapiSta;
- u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
- //u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
- u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
-
- WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
- {
- WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
- return;
- }
-
- pWapiSta =(PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAIdleList.next, RT_WAPI_STA_INFO, list);
- list_del_init(&pWapiSta->list);
- list_add_tail(&pWapiSta->list, &pWapiInfo->wapiSTAUsedList);
- _rtw_memcpy(pWapiSta->PeerMacAddr,padapter->mlmeextpriv.mlmext_info.network.MacAddress,6);
- _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
- _rtw_memcpy(pWapiSta->lastRxUnicastPN, WapiAEPNInitialValueSrc, 16);
-
- //For chenk PN error with Qos Data after s3: add by ylb 20111114
- _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
- _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
- _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
- _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
-
- WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
-}
-
-
-void rtw_wapi_return_one_sta_info(_adapter *padapter, u8 *MacAddr)
-{
- PRT_WAPI_T pWapiInfo;
- PRT_WAPI_STA_INFO pWapiStaInfo = NULL;
- PRT_WAPI_BKID pWapiBkid = NULL;
- struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
-
- pWapiInfo = &padapter->wapiInfo;
-
- WAPI_TRACE(WAPI_API, "==========> %s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
- {
- WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
- return;
- }
-
- if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
- {
- while(!list_empty(&(pWapiInfo->wapiBKIDStoreList)))
- {
- pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDStoreList.next, RT_WAPI_BKID, list);
- list_del_init(&pWapiBkid->list);
- _rtw_memset(pWapiBkid->bkid,0,16);
- list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDIdleList);
- }
- }
-
-
- WAPI_TRACE(WAPI_API, " %s: after clear bkid \n", __FUNCTION__);
-
-
- //Remove STA info
- if(list_empty(&(pWapiInfo->wapiSTAUsedList))){
- WAPI_TRACE(WAPI_API, " %s: wapiSTAUsedList is null \n", __FUNCTION__);
- return;
- }else{
-
- WAPI_TRACE(WAPI_API, " %s: wapiSTAUsedList is not null \n", __FUNCTION__);
-#if 0
- pWapiStaInfo=(PRT_WAPI_STA_INFO)list_entry((pWapiInfo->wapiSTAUsedList.next),RT_WAPI_STA_INFO,list);
-
- list_for_each_entry(pWapiStaInfo, &(pWapiInfo->wapiSTAUsedList), list) {
-
- DBG_871X("MAC Addr %02x-%02x-%02x-%02x-%02x-%02x \n",MacAddr[0],MacAddr[1],MacAddr[2],MacAddr[3],MacAddr[4],MacAddr[5]);
-
-
- DBG_871X("peer Addr %02x-%02x-%02x-%02x-%02x-%02x \n",pWapiStaInfo->PeerMacAddr[0],pWapiStaInfo->PeerMacAddr[1],pWapiStaInfo->PeerMacAddr[2],pWapiStaInfo->PeerMacAddr[3],pWapiStaInfo->PeerMacAddr[4],pWapiStaInfo->PeerMacAddr[5]);
-
- if(pWapiStaInfo == NULL)
- {
- WAPI_TRACE(WAPI_API, " %s: pWapiStaInfo == NULL Case \n", __FUNCTION__);
- return;
- }
-
- if(pWapiStaInfo->PeerMacAddr == NULL)
- {
- WAPI_TRACE(WAPI_API, " %s: pWapiStaInfo->PeerMacAddr == NULL Case \n", __FUNCTION__);
- return;
- }
-
- if(MacAddr == NULL)
- {
- WAPI_TRACE(WAPI_API, " %s: MacAddr == NULL Case \n", __FUNCTION__);
- return;
- }
-
- if (_rtw_memcmp(pWapiStaInfo->PeerMacAddr, MacAddr, ETH_ALEN) == _TRUE) {
- pWapiStaInfo->bAuthenticateInProgress = false;
- pWapiStaInfo->bSetkeyOk = false;
- _rtw_memset(pWapiStaInfo->PeerMacAddr,0,ETH_ALEN);
- list_del_init(&pWapiStaInfo->list);
- list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList);
- break;
- }
-
- }
-#endif
-
- while(!list_empty(&(pWapiInfo->wapiSTAUsedList)))
- {
- pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAUsedList.next, RT_WAPI_STA_INFO, list);
-
- DBG_871X("peer Addr %02x-%02x-%02x-%02x-%02x-%02x \n",pWapiStaInfo->PeerMacAddr[0],pWapiStaInfo->PeerMacAddr[1],pWapiStaInfo->PeerMacAddr[2],pWapiStaInfo->PeerMacAddr[3],pWapiStaInfo->PeerMacAddr[4],pWapiStaInfo->PeerMacAddr[5]);
-
- list_del_init(&pWapiStaInfo->list);
- memset(pWapiStaInfo->PeerMacAddr,0,ETH_ALEN);
- pWapiStaInfo->bSetkeyOk = 0;
- list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList);
- }
-
- }
-
- WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
- return;
-}
-
-void rtw_wapi_return_all_sta_info(_adapter *padapter)
-{
- PRT_WAPI_T pWapiInfo;
- PRT_WAPI_STA_INFO pWapiStaInfo;
- PRT_WAPI_BKID pWapiBkid;
- WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
-
- pWapiInfo = &padapter->wapiInfo;
-
- if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
- {
- WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
- return;
- }
-
- //Sta Info List
- while(!list_empty(&(pWapiInfo->wapiSTAUsedList)))
- {
- pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAUsedList.next, RT_WAPI_STA_INFO, list);
- list_del_init(&pWapiStaInfo->list);
- memset(pWapiStaInfo->PeerMacAddr,0,ETH_ALEN);
- pWapiStaInfo->bSetkeyOk = 0;
- list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList);
- }
-
- //BKID List
- while(!list_empty(&(pWapiInfo->wapiBKIDStoreList)))
- {
- pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDStoreList.next, RT_WAPI_BKID, list);
- list_del_init(&pWapiBkid->list);
- memset(pWapiBkid->bkid,0,16);
- list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDIdleList);
- }
- WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
-}
-
-void rtw_wapi_clear_cam_entry(_adapter *padapter, u8 *pMacAddr)
-{
- u8 UcIndex = 0;
-
- WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable))
- {
- WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
- return;
- }
-
- UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 0, 0);
- if(UcIndex != 0xff){
- //CAM_mark_invalid(Adapter, UcIndex);
- CAM_empty_entry(padapter, UcIndex);
- }
-
- UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 1, 0);
- if(UcIndex != 0xff){
- //CAM_mark_invalid(Adapter, UcIndex);
- CAM_empty_entry(padapter, UcIndex);
- }
-
- UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 0, 1);
- if(UcIndex != 0xff){
- //CAM_mark_invalid(Adapter, UcIndex);
- CAM_empty_entry(padapter, UcIndex);
- }
-
- UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 1, 1);
- if(UcIndex != 0xff){
- //CAM_mark_invalid(padapter, UcIndex);
- CAM_empty_entry(padapter, UcIndex);
- }
-
- WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
-}
-
-void rtw_wapi_clear_all_cam_entry(_adapter *padapter)
-{
- WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable))
- {
- WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
- return;
- }
-
- invalidate_cam_all(padapter); // is this ok?
- WapiResetAllCamEntry(padapter);
-
- WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
-}
-
-void rtw_wapi_set_key(_adapter *padapter, RT_WAPI_KEY *pWapiKey, RT_WAPI_STA_INFO *pWapiSta, u8 bGroupKey, u8 bUseDefaultKey)
-{
- PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
- u8 *pMacAddr = pWapiSta->PeerMacAddr;
- u32 EntryId = 0;
- BOOLEAN IsPairWise = false ;
- u8 EncAlgo;
-
- WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable))
- {
- WAPI_TRACE(WAPI_API, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
- return;
- }
-
- EncAlgo = _SMS4_;
-
- //For Tx bc/mc pkt,use defualt key entry
- if(bUseDefaultKey)
- {
- // when WAPI update key, keyid will be 0 or 1 by turns.
- if (pWapiKey->keyId == 0)
- EntryId = 0;
- else
- EntryId = 2;
- }
- else
- {
- // tx/rx unicast pkt, or rx broadcast, find the key entry by peer's MacAddr
- EntryId = WapiGetEntryForCamWrite(padapter,pMacAddr,pWapiKey->keyId,bGroupKey);
- }
-
- if(EntryId == 0xff){
- WAPI_TRACE(WAPI_API, "===>No entry for WAPI setkey! !!\n");
- return;
- }
-
- //EntryId is also used to diff Sec key and Mic key
- //Sec Key
- WapiWriteOneCamEntry(padapter,
- pMacAddr,
- pWapiKey->keyId, //keyid
- EntryId, //entry
- EncAlgo, //type
- bGroupKey, //pairwise or group key
- pWapiKey->dataKey);
- //MIC key
- WapiWriteOneCamEntry(padapter,
- pMacAddr,
- pWapiKey->keyId, //keyid
- EntryId+1, //entry
- EncAlgo, //type
- bGroupKey, //pairwise or group key
- pWapiKey->micKey);
-
- WAPI_TRACE(WAPI_API, "Set Wapi Key :KeyId:%d,EntryId:%d,PairwiseKey:%d.\n",pWapiKey->keyId,EntryId,!bGroupKey);
- WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
-
-}
-
-#if 0
-//YJ,test,091013
-void wapi_test_set_key(struct _adapter *padapter, u8* buf)
-{ /*Data: keyType(1) + bTxEnable(1) + bAuthenticator(1) + bUpdate(1) + PeerAddr(6) + DataKey(16) + MicKey(16) + KeyId(1)*/
- PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
- PRT_WAPI_BKID pWapiBkid;
- PRT_WAPI_STA_INFO pWapiSta;
- u8 data[43];
- bool bTxEnable;
- bool bUpdate;
- bool bAuthenticator;
- u8 PeerAddr[6];
- u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
- u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
- u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
-
- WAPI_TRACE(WAPI_INIT, "===========>%s\n", __FUNCTION__);
-
- if (!padapter->WapiSupport){
- return;
- }
-
- copy_from_user(data, buf, 43);
- bTxEnable = data[1];
- bAuthenticator = data[2];
- bUpdate = data[3];
- memcpy(PeerAddr,data+4,6);
-
- if(data[0] == 0x3){
- if(!list_empty(&(pWapiInfo->wapiBKIDIdleList))){
- pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDIdleList.next, RT_WAPI_BKID, list);
- list_del_init(&pWapiBkid->list);
- memcpy(pWapiBkid->bkid, data+10, 16);
- WAPI_DATA(WAPI_INIT, "SetKey - BKID", pWapiBkid->bkid, 16);
- list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDStoreList);
- }
- }else{
- list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
- if(!memcmp(pWapiSta->PeerMacAddr,PeerAddr,6)){
- pWapiSta->bAuthenticatorInUpdata = false;
- switch(data[0]){
- case 1: //usk
- if(bAuthenticator){ //authenticator
- memcpy(pWapiSta->lastTxUnicastPN,WapiAEPNInitialValueSrc,16);
- if(!bUpdate) { //first
- WAPI_TRACE(WAPI_INIT,"AE fisrt set usk \n");
- pWapiSta->wapiUsk.bSet = true;
- memcpy(pWapiSta->wapiUsk.dataKey,data+10,16);
- memcpy(pWapiSta->wapiUsk.micKey,data+26,16);
- pWapiSta->wapiUsk.keyId = *(data+42);
- pWapiSta->wapiUsk.bTxEnable = true;
- WAPI_DATA(WAPI_INIT, "SetKey - AE USK Data Key", pWapiSta->wapiUsk.dataKey, 16);
- WAPI_DATA(WAPI_INIT, "SetKey - AE USK Mic Key", pWapiSta->wapiUsk.micKey, 16);
- }
- else //update
- {
- WAPI_TRACE(WAPI_INIT, "AE update usk \n");
- pWapiSta->wapiUskUpdate.bSet = true;
- pWapiSta->bAuthenticatorInUpdata = true;
- memcpy(pWapiSta->wapiUskUpdate.dataKey,data+10,16);
- memcpy(pWapiSta->wapiUskUpdate.micKey,data+26,16);
- memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiASUEPNInitialValueSrc,16);
- memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiASUEPNInitialValueSrc,16);
- memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiASUEPNInitialValueSrc,16);
- memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiASUEPNInitialValueSrc,16);
- memcpy(pWapiSta->lastRxUnicastPN,WapiASUEPNInitialValueSrc,16);
- pWapiSta->wapiUskUpdate.keyId = *(data+42);
- pWapiSta->wapiUskUpdate.bTxEnable = true;
- }
- }
- else{
- if(!bUpdate){
- WAPI_TRACE(WAPI_INIT,"ASUE fisrt set usk \n");
- if(bTxEnable){
- pWapiSta->wapiUsk.bTxEnable = true;
- memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
- }else{
- pWapiSta->wapiUsk.bSet = true;
- memcpy(pWapiSta->wapiUsk.dataKey,data+10,16);
- memcpy(pWapiSta->wapiUsk.micKey,data+26,16);
- pWapiSta->wapiUsk.keyId = *(data+42);
- pWapiSta->wapiUsk.bTxEnable = false;
- }
- }else{
- WAPI_TRACE(WAPI_INIT,"ASUE update usk \n");
- if(bTxEnable){
- pWapiSta->wapiUskUpdate.bTxEnable = true;
- if(pWapiSta->wapiUskUpdate.bSet){
- memcpy(pWapiSta->wapiUsk.dataKey,pWapiSta->wapiUskUpdate.dataKey,16);
- memcpy(pWapiSta->wapiUsk.micKey,pWapiSta->wapiUskUpdate.micKey,16);
- pWapiSta->wapiUsk.keyId=pWapiSta->wapiUskUpdate.keyId;
- memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiASUEPNInitialValueSrc,16);
- memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiASUEPNInitialValueSrc,16);
- memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiASUEPNInitialValueSrc,16);
- memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiASUEPNInitialValueSrc,16);
- memcpy(pWapiSta->lastRxUnicastPN,WapiASUEPNInitialValueSrc,16);
- pWapiSta->wapiUskUpdate.bTxEnable = false;
- pWapiSta->wapiUskUpdate.bSet = false;
- }
- memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
- }else{
- pWapiSta->wapiUskUpdate.bSet = true;
- memcpy(pWapiSta->wapiUskUpdate.dataKey,data+10,16);
- memcpy(pWapiSta->wapiUskUpdate.micKey,data+26,16);
- pWapiSta->wapiUskUpdate.keyId = *(data+42);
- pWapiSta->wapiUskUpdate.bTxEnable = false;
- }
- }
- }
- break;
- case 2: //msk
- if(bAuthenticator){ //authenticator
- pWapiInfo->wapiTxMsk.bSet = true;
- memcpy(pWapiInfo->wapiTxMsk.dataKey,data+10,16);
- memcpy(pWapiInfo->wapiTxMsk.micKey,data+26,16);
- pWapiInfo->wapiTxMsk.keyId = *(data+42);
- pWapiInfo->wapiTxMsk.bTxEnable = true;
- memcpy(pWapiInfo->lastTxMulticastPN,WapiAEMultiCastPNInitialValueSrc,16);
-
- if(!bUpdate){ //first
- WAPI_TRACE(WAPI_INIT, "AE fisrt set msk \n");
- if(!pWapiSta->bSetkeyOk)
- pWapiSta->bSetkeyOk = true;
- pWapiInfo->bFirstAuthentiateInProgress= false;
- }else{ //update
- WAPI_TRACE(WAPI_INIT,"AE update msk \n");
- }
-
- WAPI_DATA(WAPI_INIT, "SetKey - AE MSK Data Key", pWapiInfo->wapiTxMsk.dataKey, 16);
- WAPI_DATA(WAPI_INIT, "SetKey - AE MSK Mic Key", pWapiInfo->wapiTxMsk.micKey, 16);
- }
- else{
- if(!bUpdate){
- WAPI_TRACE(WAPI_INIT,"ASUE fisrt set msk \n");
- pWapiSta->wapiMsk.bSet = true;
- memcpy(pWapiSta->wapiMsk.dataKey,data+10,16);
- memcpy(pWapiSta->wapiMsk.micKey,data+26,16);
- pWapiSta->wapiMsk.keyId = *(data+42);
- pWapiSta->wapiMsk.bTxEnable = false;
- if(!pWapiSta->bSetkeyOk)
- pWapiSta->bSetkeyOk = true;
- pWapiInfo->bFirstAuthentiateInProgress= false;
- WAPI_DATA(WAPI_INIT, "SetKey - ASUE MSK Data Key", pWapiSta->wapiMsk.dataKey, 16);
- WAPI_DATA(WAPI_INIT, "SetKey - ASUE MSK Mic Key", pWapiSta->wapiMsk.micKey, 16);
- }else{
- WAPI_TRACE(WAPI_INIT,"ASUE update msk \n");
- pWapiSta->wapiMskUpdate.bSet = true;
- memcpy(pWapiSta->wapiMskUpdate.dataKey,data+10,16);
- memcpy(pWapiSta->wapiMskUpdate.micKey,data+26,16);
- pWapiSta->wapiMskUpdate.keyId = *(data+42);
- pWapiSta->wapiMskUpdate.bTxEnable = false;
- }
- }
- break;
- default:
- WAPI_TRACE(WAPI_ERR,"Unknown Flag \n");
- break;
- }
- }
- }
- }
- WAPI_TRACE(WAPI_INIT, "<===========%s\n", __FUNCTION__);
-}
-
-
-void wapi_test_init(struct _adapter *padapter)
-{
- u8 keybuf[100];
- u8 mac_addr[6]={0x00,0xe0,0x4c,0x72,0x04,0x70};
- u8 UskDataKey[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
- u8 UskMicKey[16]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f};
- u8 UskId = 0;
- u8 MskDataKey[16]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f};
- u8 MskMicKey[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f};
- u8 MskId = 0;
-
- WAPI_TRACE(WAPI_INIT, "===========>%s\n", __FUNCTION__);
-
- //Enable Wapi
- WAPI_TRACE(WAPI_INIT, "%s: Enable wapi!!!!\n", __FUNCTION__);
- padapter->wapiInfo.bWapiEnable = true;
- padapter->pairwise_key_type = KEY_TYPE_SMS4;
- ieee->group_key_type = KEY_TYPE_SMS4;
- padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
- padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
-
- //set usk
- WAPI_TRACE(WAPI_INIT, "%s: Set USK!!!!\n", __FUNCTION__);
- memset(keybuf,0,100);
- keybuf[0] = 1; //set usk
- keybuf[1] = 1; //enable tx
- keybuf[2] = 1; //AE
- keybuf[3] = 0; //not update
-
- memcpy(keybuf+4,mac_addr,6);
- memcpy(keybuf+10,UskDataKey,16);
- memcpy(keybuf+26,UskMicKey,16);
- keybuf[42]=UskId;
- wapi_test_set_key(padapter, keybuf);
-
- memset(keybuf,0,100);
- keybuf[0] = 1; //set usk
- keybuf[1] = 1; //enable tx
- keybuf[2] = 0; //AE
- keybuf[3] = 0; //not update
-
- memcpy(keybuf+4,mac_addr,6);
- memcpy(keybuf+10,UskDataKey,16);
- memcpy(keybuf+26,UskMicKey,16);
- keybuf[42]=UskId;
- wapi_test_set_key(padapter, keybuf);
-
- //set msk
- WAPI_TRACE(WAPI_INIT, "%s: Set MSK!!!!\n", __FUNCTION__);
- memset(keybuf,0,100);
- keybuf[0] = 2; //set msk
- keybuf[1] = 1; //Enable TX
- keybuf[2] = 1; //AE
- keybuf[3] = 0; //not update
- memcpy(keybuf+4,mac_addr,6);
- memcpy(keybuf+10,MskDataKey,16);
- memcpy(keybuf+26,MskMicKey,16);
- keybuf[42] = MskId;
- wapi_test_set_key(padapter, keybuf);
-
- memset(keybuf,0,100);
- keybuf[0] = 2; //set msk
- keybuf[1] = 1; //Enable TX
- keybuf[2] = 0; //AE
- keybuf[3] = 0; //not update
- memcpy(keybuf+4,mac_addr,6);
- memcpy(keybuf+10,MskDataKey,16);
- memcpy(keybuf+26,MskMicKey,16);
- keybuf[42] = MskId;
- wapi_test_set_key(padapter, keybuf);
- WAPI_TRACE(WAPI_INIT, "<===========%s\n", __FUNCTION__);
-}
-#endif
-
-void rtw_wapi_get_iv(_adapter *padapter,u8 *pRA, u8*IV)
-{
- PWLAN_HEADER_WAPI_EXTENSION pWapiExt = NULL;
- PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
- bool bPNOverflow = false;
- bool bFindMatchPeer = false;
- PRT_WAPI_STA_INFO pWapiSta = NULL;
-
- pWapiExt = (PWLAN_HEADER_WAPI_EXTENSION)IV;
-
- WAPI_DATA(WAPI_RX,"wapi_get_iv: pra",pRA,6);
-
- if(IS_MCAST(pRA)){
- if(!pWapiInfo->wapiTxMsk.bTxEnable){
- WAPI_TRACE(WAPI_ERR,"%s: bTxEnable = 0!!\n",__FUNCTION__);
- return;
- }
-
- if(pWapiInfo->wapiTxMsk.keyId <= 1){
- pWapiExt->KeyIdx = pWapiInfo->wapiTxMsk.keyId;
- pWapiExt->Reserved = 0;
- bPNOverflow = WapiIncreasePN(pWapiInfo->lastTxMulticastPN, 1);
- memcpy(pWapiExt->PN, pWapiInfo->lastTxMulticastPN, 16);
- }
- }
- else
- {
- if(list_empty(&pWapiInfo->wapiSTAUsedList)){
- WAPI_TRACE(WAPI_RX,"rtw_wapi_get_iv: list is empty \n");
- _rtw_memset(IV,10,18);
- return;
- }
- else{
- list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list){
- WAPI_DATA(WAPI_RX,"rtw_wapi_get_iv: peermacaddr ",pWapiSta->PeerMacAddr,6);
- if (_rtw_memcmp((u8*)pWapiSta->PeerMacAddr, pRA, 6) == _TRUE) {
- bFindMatchPeer = true;
- break;
- }
- }
-
- WAPI_TRACE(WAPI_RX,"bFindMatchPeer: %d \n",bFindMatchPeer);
- WAPI_DATA(WAPI_RX,"Addr",pRA,6);
-
- if (bFindMatchPeer){
- if((!pWapiSta->wapiUskUpdate.bTxEnable) && (!pWapiSta->wapiUsk.bTxEnable))
- return;
-
- if (pWapiSta->wapiUsk.keyId <= 1){
- if(pWapiSta->wapiUskUpdate.bTxEnable)
- pWapiExt->KeyIdx = pWapiSta->wapiUskUpdate.keyId;
- else
- pWapiExt->KeyIdx = pWapiSta->wapiUsk.keyId;
-
- pWapiExt->Reserved = 0;
- bPNOverflow = WapiIncreasePN(pWapiSta->lastTxUnicastPN, 2);
- _rtw_memcpy(pWapiExt->PN, pWapiSta->lastTxUnicastPN, 16);
-
- }
- }
- }
-
- }
-
-}
-
-bool rtw_wapi_drop_for_key_absent(_adapter *padapter,u8 *pRA)
-{
- PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
- bool bFindMatchPeer = false;
- bool bDrop = false;
- PRT_WAPI_STA_INFO pWapiSta = NULL;
- struct security_priv *psecuritypriv = &padapter->securitypriv;
-
- WAPI_DATA(WAPI_RX,"rtw_wapi_drop_for_key_absent: ra ",pRA,6);
-
- if(psecuritypriv->dot11PrivacyAlgrthm == _SMS4_)
- {
- if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
- return true;
-
- if(IS_MCAST(pRA)){
- if(!pWapiInfo->wapiTxMsk.bTxEnable){
- bDrop = true;
- WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: multicast key is absent \n");
- return bDrop;
- }
- }
- else{
- if(!list_empty(&pWapiInfo->wapiSTAUsedList)){
- list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list){
- WAPI_DATA(WAPI_RX,"rtw_wapi_drop_for_key_absent: pWapiSta->PeerMacAddr ",pWapiSta->PeerMacAddr,6);
- if (_rtw_memcmp(pRA, pWapiSta->PeerMacAddr, 6) == _TRUE){
- bFindMatchPeer = true;
- break;
- }
- }
- if (bFindMatchPeer) {
- if (!pWapiSta->wapiUsk.bTxEnable){
- bDrop = true;
- WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: unicast key is absent \n");
- return bDrop;
- }
- }
- else{
- bDrop = true;
- WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: no peer find \n");
- return bDrop;
- }
-
- }
- else{
- bDrop = true;
- WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: no sta exist \n");
- return bDrop;
- }
- }
- }
- else
- {
- return bDrop;
- }
-
- return bDrop;
-}
-
-#endif
+#ifdef CONFIG_WAPI_SUPPORT
+
+#include <linux/unistd.h>
+#include <linux/etherdevice.h>
+#include <drv_types.h>
+#include <rtw_wapi.h>
+
+
+u32 wapi_debug_component =
+// WAPI_INIT |
+// WAPI_API |
+// WAPI_TX |
+// WAPI_RX |
+ WAPI_ERR ; //always open err flags on
+
+void WapiFreeAllStaInfo(_adapter *padapter)
+{
+ PRT_WAPI_T pWapiInfo;
+ PRT_WAPI_STA_INFO pWapiStaInfo;
+ PRT_WAPI_BKID pWapiBkid;
+
+ WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
+ pWapiInfo = &padapter->wapiInfo;
+
+ //Pust to Idle List
+ rtw_wapi_return_all_sta_info(padapter);
+
+ //Sta Info List
+ while(!list_empty(&(pWapiInfo->wapiSTAIdleList)))
+ {
+ pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAIdleList.next, RT_WAPI_STA_INFO, list);
+ list_del_init(&pWapiStaInfo->list);
+ }
+
+ //BKID List
+ while(!list_empty(&(pWapiInfo->wapiBKIDIdleList)))
+ {
+ pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDIdleList.next, RT_WAPI_BKID, list);
+ list_del_init(&pWapiBkid->list);
+ }
+ WAPI_TRACE(WAPI_INIT, "<=========== %s\n", __FUNCTION__);
+ return;
+}
+
+void WapiSetIE(_adapter *padapter)
+{
+ PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
+ //PRT_WAPI_BKID pWapiBkid;
+ u16 protocolVer = 1;
+ u16 akmCnt = 1;
+ u16 suiteCnt = 1;
+ u16 capability = 0;
+ u8 OUI[3];
+
+ OUI[0] = 0x00;
+ OUI[1] = 0x14;
+ OUI[2] = 0x72;
+
+ pWapiInfo->wapiIELength = 0;
+//protocol version
+ memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &protocolVer, 2);
+ pWapiInfo->wapiIELength +=2;
+//akm
+ memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &akmCnt, 2);
+ pWapiInfo->wapiIELength +=2;
+
+ if(pWapiInfo->bWapiPSK){
+ memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3);
+ pWapiInfo->wapiIELength +=3;
+ pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x2;
+ pWapiInfo->wapiIELength +=1;
+ }else{
+ memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3);
+ pWapiInfo->wapiIELength +=3;
+ pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1;
+ pWapiInfo->wapiIELength +=1;
+ }
+
+//usk
+ memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &suiteCnt, 2);
+ pWapiInfo->wapiIELength +=2;
+ memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3);
+ pWapiInfo->wapiIELength +=3;
+ pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1;
+ pWapiInfo->wapiIELength +=1;
+
+//msk
+ memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength,OUI, 3);
+ pWapiInfo->wapiIELength +=3;
+ pWapiInfo->wapiIE[pWapiInfo->wapiIELength] = 0x1;
+ pWapiInfo->wapiIELength +=1;
+
+//Capbility
+ memcpy(pWapiInfo->wapiIE+pWapiInfo->wapiIELength, &capability, 2);
+ pWapiInfo->wapiIELength +=2;
+}
+
+
+/* PN1 > PN2, return 1,
+ * else return 0.
+ */
+u32 WapiComparePN(u8 *PN1, u8 *PN2)
+{
+ char i;
+
+ if ((NULL == PN1) || (NULL == PN2))
+ return 1;
+
+ // overflow case
+ if ((PN2[15] - PN1[15]) & 0x80)
+ return 1;
+
+ for (i=16; i>0; i--)
+ {
+ if(PN1[i-1] == PN2[i-1])
+ continue;
+ else if(PN1[i-1] > PN2[i-1])
+ return 1;
+ else
+ return 0;
+ }
+
+ return 0;
+}
+
+u8
+WapiGetEntryForCamWrite(_adapter *padapter,u8 *pMacAddr,u8 KID,BOOLEAN IsMsk)
+{
+ PRT_WAPI_T pWapiInfo=NULL;
+ //PRT_WAPI_CAM_ENTRY pEntry=NULL;
+ u8 i=0;
+ u8 ret = 0xff;
+
+ WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
+
+ pWapiInfo = &padapter->wapiInfo;
+
+ //exist?
+ for(i=0;i<WAPI_CAM_ENTRY_NUM;i++)
+ {
+ if(pWapiInfo->wapiCamEntry[i].IsUsed
+ && (_rtw_memcmp(pMacAddr, pWapiInfo->wapiCamEntry[i].PeerMacAddr, ETH_ALEN) == _TRUE)
+ && pWapiInfo->wapiCamEntry[i].keyidx == KID
+ && pWapiInfo->wapiCamEntry[i].type == IsMsk)
+ {
+ ret = pWapiInfo->wapiCamEntry[i].entry_idx; //cover it
+ break;
+ }
+ }
+
+ if(i == WAPI_CAM_ENTRY_NUM) //not found
+ {
+ for(i=0;i<WAPI_CAM_ENTRY_NUM;i++)
+ {
+ if(pWapiInfo->wapiCamEntry[i].IsUsed == 0)
+ {
+ pWapiInfo->wapiCamEntry[i].IsUsed = 1;
+ pWapiInfo->wapiCamEntry[i].type = IsMsk;
+ pWapiInfo->wapiCamEntry[i].keyidx = KID;
+ _rtw_memcpy(pWapiInfo->wapiCamEntry[i].PeerMacAddr, pMacAddr,ETH_ALEN);
+ ret = pWapiInfo->wapiCamEntry[i].entry_idx;
+ break;
+ }
+ }
+ }
+
+ WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
+ return ret;
+
+/*
+ if(RTIsListEmpty(&pWapiInfo->wapiCamIdleList)){
+ RT_TRACE(COMP_SEC,DBG_LOUD,("No Entry for wapi!!!\n"));
+ return 0;
+ }
+
+ pEntry = (PRT_WAPI_CAM_ENTRY)RTRemoveHeadList(&pWapiInfo->wapiCamIdleList);
+ RTInsertTailList(&pWapiInfo->wapiCamUsedList, &pEntry->list);
+
+ RT_TRACE(COMP_SEC,DBG_LOUD,("<====WapiGetCamEntry(),Get Entry Idx:%d.but we just return 4 for test\n",pEntry->entry_idx));
+
+ return pEntry->entry_idx;*/
+}
+
+u8 WapiGetEntryForCamClear(_adapter *padapter,u8 *pPeerMac,u8 keyid,u8 IsMsk)
+{
+ PRT_WAPI_T pWapiInfo=NULL;
+ u8 i=0;
+
+ WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
+
+ pWapiInfo = &padapter->wapiInfo;
+
+ for(i=0;i<WAPI_CAM_ENTRY_NUM;i++)
+ {
+ if(pWapiInfo->wapiCamEntry[i].IsUsed
+ && (_rtw_memcmp(pPeerMac, pWapiInfo->wapiCamEntry[i].PeerMacAddr, ETH_ALEN) == _TRUE)
+ && pWapiInfo->wapiCamEntry[i].keyidx == keyid
+ && pWapiInfo->wapiCamEntry[i].type == IsMsk)
+ {
+ pWapiInfo->wapiCamEntry[i].IsUsed = 0;
+ pWapiInfo->wapiCamEntry[i].keyidx = 2;
+ _rtw_memset(pWapiInfo->wapiCamEntry[i].PeerMacAddr,0,ETH_ALEN);
+
+ WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
+ return pWapiInfo->wapiCamEntry[i].entry_idx;
+ }
+ }
+
+ WAPI_TRACE(WAPI_API,"<====WapiGetReturnCamEntry(), No this cam entry.\n");
+ return 0xff;
+/*
+ if(RTIsListEmpty(&pWapiInfo->wapiCamUsedList)){
+ RT_TRACE(COMP_SEC,DBG_LOUD,("No Entry for wapi!!!\n"));
+ return FALSE;
+ }
+
+ pList = &pWapiInfo->wapiCamUsedList;
+ while(pList->Flink != &pWapiInfo->wapiCamUsedList)
+ {
+ pEntry = (PRT_WAPI_CAM_ENTRY)pList->Flink;
+ if(PlatformCompareMemory(pPeerMac,pEntry->PeerMacAddr, ETHER_ADDRLEN)== 0
+ && keyid == pEntry->keyidx)
+ {
+ RTRemoveEntryList(pList);
+ RTInsertHeadList(&pWapiInfo->wapiCamIdleList, pList);
+ return pEntry->entry_idx;
+ }
+ pList = pList->Flink;
+ }
+
+ return 0;
+*/
+}
+
+void
+WapiResetAllCamEntry(_adapter *padapter)
+{
+ PRT_WAPI_T pWapiInfo;
+ int i;
+
+ WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
+
+ pWapiInfo = &padapter->wapiInfo;
+
+ for (i=0;i<WAPI_CAM_ENTRY_NUM;i++)
+ {
+ _rtw_memset(pWapiInfo->wapiCamEntry[i].PeerMacAddr, 0, ETH_ALEN);
+ pWapiInfo->wapiCamEntry[i].IsUsed = 0;
+ pWapiInfo->wapiCamEntry[i].keyidx = 2; //invalid
+ pWapiInfo->wapiCamEntry[i].entry_idx = 4+i*2;
+ }
+
+ WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
+
+ return;
+}
+
+u8 WapiWriteOneCamEntry(
+ _adapter *padapter,
+ u8 *pMacAddr,
+ u8 KeyId,
+ u8 EntryId,
+ u8 EncAlg,
+ u8 bGroupKey,
+ u8 *pKey
+)
+{
+ u8 retVal = 0;
+ u16 usConfig = 0;
+
+ WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
+
+ if(EntryId >= 32)
+ {
+ WAPI_TRACE(WAPI_ERR, "<=== CamAddOneEntry(): ulKeyId exceed!\n");
+ return retVal;
+ }
+
+ usConfig=usConfig|(0x01<<15)|((u16)(EncAlg)<<2)|(KeyId);
+
+ if(EncAlg == _SMS4_ )
+ {
+ if(bGroupKey == 1)
+ usConfig |= (0x01<<6);
+ if((EntryId % 2)==1) // ==0 sec key; == 1mic key
+ usConfig |= (0x01<<5);
+ }
+
+ write_cam(padapter, EntryId, usConfig, pMacAddr, pKey);
+
+ WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
+ return 1;
+}
+
+void rtw_wapi_init(_adapter *padapter)
+{
+ PRT_WAPI_T pWapiInfo;
+ int i;
+
+ WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
+ RT_ASSERT_RET(padapter);
+
+ if (!padapter->WapiSupport)
+ {
+ WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__);
+ return;
+ }
+
+ pWapiInfo = &padapter->wapiInfo;
+ pWapiInfo->bWapiEnable = false;
+
+ //Init BKID List
+ INIT_LIST_HEAD(&pWapiInfo->wapiBKIDIdleList);
+ INIT_LIST_HEAD(&pWapiInfo->wapiBKIDStoreList);
+ for(i=0;i<WAPI_MAX_BKID_NUM;i++)
+ {
+ list_add_tail(&pWapiInfo->wapiBKID[i].list, &pWapiInfo->wapiBKIDIdleList);
+ }
+
+ //Init STA List
+ INIT_LIST_HEAD(&pWapiInfo->wapiSTAIdleList);
+ INIT_LIST_HEAD(&pWapiInfo->wapiSTAUsedList);
+ for(i=0;i<WAPI_MAX_STAINFO_NUM;i++)
+ {
+ list_add_tail(&pWapiInfo->wapiSta[i].list, &pWapiInfo->wapiSTAIdleList);
+ }
+
+ for (i=0;i<WAPI_CAM_ENTRY_NUM;i++)
+ {
+ pWapiInfo->wapiCamEntry[i].IsUsed = 0;
+ pWapiInfo->wapiCamEntry[i].keyidx = 2; //invalid
+ pWapiInfo->wapiCamEntry[i].entry_idx = 4+i*2;
+ }
+
+ WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__);
+}
+
+void rtw_wapi_free(_adapter *padapter)
+{
+ WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
+ RT_ASSERT_RET(padapter);
+
+ if (!padapter->WapiSupport)
+ {
+ WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__);
+ return;
+ }
+
+ WapiFreeAllStaInfo(padapter);
+
+ WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__);
+}
+
+void rtw_wapi_disable_tx(_adapter *padapter)
+{
+ WAPI_TRACE(WAPI_INIT, "===========> %s\n", __FUNCTION__);
+ RT_ASSERT_RET(padapter);
+
+ if (!padapter->WapiSupport)
+ {
+ WAPI_TRACE(WAPI_INIT, "<========== %s, WAPI not supported!\n", __FUNCTION__);
+ return;
+ }
+
+ padapter->wapiInfo.wapiTxMsk.bTxEnable = false;
+ padapter->wapiInfo.wapiTxMsk.bSet = false;
+
+ WAPI_TRACE(WAPI_INIT, "<========== %s\n", __FUNCTION__);
+}
+
+u8 rtw_wapi_is_wai_packet(_adapter* padapter,u8 *pkt_data)
+{
+ PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+ PRT_WAPI_STA_INFO pWapiSta = NULL;
+ u8 WaiPkt = 0, *pTaddr, bFind = false;
+ u8 Offset_TypeWAI = 0 ; // (mac header len + llc length)
+
+ WAPI_TRACE(WAPI_TX|WAPI_RX, "===========> %s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
+ return 0;
+ }
+
+ Offset_TypeWAI = 24 + 6 ;
+
+ //YJ,add,091103. Data frame may also have skb->data[30]=0x88 and skb->data[31]=0xb4.
+ if ((pkt_data[1]&0x40) !=0)
+ {
+ DBG_871X("data is privacy \n");
+ return 0;
+ }
+
+ pTaddr = GetAddr2Ptr(pkt_data);
+ if(list_empty(&pWapiInfo->wapiSTAUsedList)){
+ bFind = false;
+ }else{
+ list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list){
+ if (_rtw_memcmp(pTaddr, pWapiSta->PeerMacAddr, 6) == _TRUE) {
+ bFind = true;
+ break;
+ }
+ }
+ }
+
+ WAPI_TRACE(WAPI_TX|WAPI_RX, "%s: bFind=%d pTaddr="MAC_FMT"\n", __FUNCTION__, bFind, MAC_ARG(pTaddr));
+
+ if (pkt_data[0] == WIFI_QOS_DATA_TYPE)
+ {
+ Offset_TypeWAI += 2;
+ }
+
+ // 88b4?
+ if( (pkt_data[Offset_TypeWAI]==0x88) && (pkt_data[Offset_TypeWAI+1]==0xb4) ){
+ WaiPkt = pkt_data[Offset_TypeWAI+5];
+
+ psecuritypriv->hw_decrypted = _TRUE;
+ }else{
+ WAPI_TRACE(WAPI_TX|WAPI_RX, "%s(): non wai packet\n",__FUNCTION__);
+ }
+
+ WAPI_TRACE(WAPI_TX|WAPI_RX, "%s(): Recvd WAI frame. IsWAIPkt(%d)\n",__FUNCTION__, WaiPkt);
+
+ return WaiPkt;
+}
+
+
+void rtw_wapi_update_info(_adapter *padapter, union recv_frame *precv_frame)
+{
+ PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
+ struct recv_frame_hdr *precv_hdr;
+ u8 *ptr;
+ u8 *pTA;
+ u8 *pRecvPN;
+
+
+ WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
+ return;
+ }
+
+ precv_hdr = &precv_frame->u.hdr;
+ ptr = precv_hdr->rx_data;
+
+ if (precv_hdr->attrib.qos == 1)
+ {
+ precv_hdr->UserPriority = GetTid(ptr);
+ }
+ else
+ {
+ precv_hdr->UserPriority = 0;
+ }
+
+ pTA = GetAddr2Ptr(ptr);
+ _rtw_memcpy((u8 *)precv_hdr->WapiSrcAddr, pTA, 6);
+ pRecvPN = ptr + precv_hdr->attrib.hdrlen + 2;
+ _rtw_memcpy((u8 *)precv_hdr->WapiTempPN, pRecvPN, 16);
+
+ WAPI_TRACE(WAPI_RX, "<========== %s\n", __FUNCTION__);
+}
+
+/****************************************************************************
+TRUE-----------------Drop
+FALSE---------------- handle
+add to support WAPI to N-mode
+*****************************************************************************/
+u8 rtw_wapi_check_for_drop(
+ _adapter *padapter,
+ union recv_frame *precv_frame
+)
+{
+ PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
+ u8 *pLastRecvPN = NULL;
+ u8 bFind = false;
+ PRT_WAPI_STA_INFO pWapiSta = NULL;
+ u8 bDrop = false;
+ struct recv_frame_hdr *precv_hdr = &precv_frame->u.hdr;
+ u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
+ u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
+ u8 *ptr = precv_frame->u.hdr.rx_data;
+ int i;
+
+ WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
+ return false;
+ }
+
+ if(precv_hdr->bIsWaiPacket !=0)
+ {
+ if(precv_hdr->bIsWaiPacket== 0x8)
+ {
+
+ DBG_871X("rtw_wapi_check_for_drop: dump packet \n");
+ for(i=0;i<50;i++)
+ {
+ DBG_871X("%02X ",ptr[i]);
+ if((i+1) %8 ==0)
+ DBG_871X("\n");
+ }
+ DBG_871X("\n rtw_wapi_check_for_drop: dump packet \n");
+
+ for(i=0;i<16;i++)
+ {
+ if(ptr[i+27] !=0)
+ break;
+ }
+
+ if(i== 16)
+ {
+ WAPI_TRACE(WAPI_RX,"rtw_wapi_check_for_drop: drop with zero BKID \n");
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ return false;
+ }
+
+ if(list_empty(&pWapiInfo->wapiSTAUsedList)){
+ bFind = false;
+ }else{
+ list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
+ if (_rtw_memcmp(precv_hdr->WapiSrcAddr, pWapiSta->PeerMacAddr, ETH_ALEN) == _TRUE) {
+ bFind = true;
+ break;
+ }
+ }
+ }
+ WAPI_TRACE(WAPI_RX, "%s: bFind=%d prxb->WapiSrcAddr="MAC_FMT"\n", __FUNCTION__, bFind, MAC_ARG(precv_hdr->WapiSrcAddr));
+
+ if(bFind)
+ {
+ if(IS_MCAST(precv_hdr->attrib.ra))
+ {
+ WAPI_TRACE(WAPI_RX,"rtw_wapi_check_for_drop: multicast case \n");
+ pLastRecvPN = pWapiSta->lastRxMulticastPN;
+ }
+ else
+ {
+ WAPI_TRACE(WAPI_RX,"rtw_wapi_check_for_drop: unicast case \n");
+ switch(precv_hdr->UserPriority)
+ {
+ case 0:
+ case 3:
+ pLastRecvPN = pWapiSta->lastRxUnicastPNBEQueue;
+ break;
+ case 1:
+ case 2:
+ pLastRecvPN = pWapiSta->lastRxUnicastPNBKQueue;
+ break;
+ case 4:
+ case 5:
+ pLastRecvPN = pWapiSta->lastRxUnicastPNVIQueue;
+ break;
+ case 6:
+ case 7:
+ pLastRecvPN = pWapiSta->lastRxUnicastPNVOQueue;
+ break;
+ default:
+ WAPI_TRACE(WAPI_ERR,"%s: Unknown TID \n",__FUNCTION__);
+ break;
+ }
+ }
+
+ if(!WapiComparePN(precv_hdr->WapiTempPN,pLastRecvPN))
+ {
+ WAPI_TRACE(WAPI_RX,"%s: Equal PN!!\n",__FUNCTION__);
+ if(IS_MCAST(precv_hdr->attrib.ra))
+ _rtw_memcpy(pLastRecvPN,WapiAEMultiCastPNInitialValueSrc,16);
+ else
+ _rtw_memcpy(pLastRecvPN,WapiAEPNInitialValueSrc,16);
+ bDrop = true;
+ }
+ else
+ {
+ _rtw_memcpy(pLastRecvPN,precv_hdr->WapiTempPN,16);
+ }
+ }
+
+ WAPI_TRACE(WAPI_RX, "<========== %s\n", __FUNCTION__);
+ return bDrop;
+}
+
+void rtw_build_probe_resp_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib)
+{
+ PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
+ u8 WapiIELength = 0;
+
+ WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__);
+ return;
+ }
+
+ WapiSetIE(padapter);
+ WapiIELength = pWapiInfo->wapiIELength;
+ pframe[0] = _WAPI_IE_;
+ pframe[1] = WapiIELength;
+ _rtw_memcpy(pframe+2, pWapiInfo->wapiIE, WapiIELength);
+ pframe += WapiIELength+2;
+ pattrib->pktlen += WapiIELength+2;
+
+ WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
+}
+
+void rtw_build_beacon_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib)
+{
+ PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
+ u8 WapiIELength = 0;
+ WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__);
+ return;
+ }
+
+ WapiSetIE(padapter);
+ WapiIELength = pWapiInfo->wapiIELength;
+ pframe[0] = _WAPI_IE_;
+ pframe[1] = WapiIELength;
+ _rtw_memcpy(pframe+2, pWapiInfo->wapiIE, WapiIELength);
+ pframe += WapiIELength+2;
+ pattrib->pktlen += WapiIELength+2;
+
+ WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
+}
+
+void rtw_build_assoc_req_wapi_ie(_adapter *padapter, unsigned char *pframe, struct pkt_attrib *pattrib)
+{
+ PRT_WAPI_BKID pWapiBKID;
+ u16 bkidNum;
+ PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
+ u8 WapiIELength = 0;
+
+ WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported!\n", __FUNCTION__);
+ return;
+ }
+
+ WapiSetIE(padapter);
+ WapiIELength = pWapiInfo->wapiIELength;
+ bkidNum = 0;
+ if(!list_empty(&(pWapiInfo->wapiBKIDStoreList))){
+ list_for_each_entry(pWapiBKID, &pWapiInfo->wapiBKIDStoreList, list) {
+ bkidNum ++;
+ _rtw_memcpy(pWapiInfo->wapiIE+WapiIELength+2, pWapiBKID->bkid,16);
+ WapiIELength += 16;
+ }
+ }
+ _rtw_memcpy(pWapiInfo->wapiIE+WapiIELength, &bkidNum, 2);
+ WapiIELength += 2;
+
+ pframe[0] = _WAPI_IE_;
+ pframe[1] = WapiIELength;
+ _rtw_memcpy(pframe+2, pWapiInfo->wapiIE, WapiIELength);
+ pframe += WapiIELength+2;
+ pattrib->pktlen += WapiIELength+2;
+ WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
+}
+
+void rtw_wapi_on_assoc_ok(_adapter *padapter, PNDIS_802_11_VARIABLE_IEs pIE)
+{
+ PRT_WAPI_T pWapiInfo = &(padapter->wapiInfo);
+ PRT_WAPI_STA_INFO pWapiSta;
+ u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
+ //u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
+ u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
+
+ WAPI_TRACE(WAPI_MLME, "===========> %s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
+ return;
+ }
+
+ pWapiSta =(PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAIdleList.next, RT_WAPI_STA_INFO, list);
+ list_del_init(&pWapiSta->list);
+ list_add_tail(&pWapiSta->list, &pWapiInfo->wapiSTAUsedList);
+ _rtw_memcpy(pWapiSta->PeerMacAddr,padapter->mlmeextpriv.mlmext_info.network.MacAddress,6);
+ _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
+ _rtw_memcpy(pWapiSta->lastRxUnicastPN, WapiAEPNInitialValueSrc, 16);
+
+ //For chenk PN error with Qos Data after s3: add by ylb 20111114
+ _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
+ _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
+ _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
+ _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
+
+ WAPI_TRACE(WAPI_MLME, "<========== %s\n", __FUNCTION__);
+}
+
+
+void rtw_wapi_return_one_sta_info(_adapter *padapter, u8 *MacAddr)
+{
+ PRT_WAPI_T pWapiInfo;
+ PRT_WAPI_STA_INFO pWapiStaInfo = NULL;
+ PRT_WAPI_BKID pWapiBkid = NULL;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+
+ pWapiInfo = &padapter->wapiInfo;
+
+ WAPI_TRACE(WAPI_API, "==========> %s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
+ return;
+ }
+
+ if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
+ {
+ while(!list_empty(&(pWapiInfo->wapiBKIDStoreList)))
+ {
+ pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDStoreList.next, RT_WAPI_BKID, list);
+ list_del_init(&pWapiBkid->list);
+ _rtw_memset(pWapiBkid->bkid,0,16);
+ list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDIdleList);
+ }
+ }
+
+
+ WAPI_TRACE(WAPI_API, " %s: after clear bkid \n", __FUNCTION__);
+
+
+ //Remove STA info
+ if(list_empty(&(pWapiInfo->wapiSTAUsedList))){
+ WAPI_TRACE(WAPI_API, " %s: wapiSTAUsedList is null \n", __FUNCTION__);
+ return;
+ }else{
+
+ WAPI_TRACE(WAPI_API, " %s: wapiSTAUsedList is not null \n", __FUNCTION__);
+#if 0
+ pWapiStaInfo=(PRT_WAPI_STA_INFO)list_entry((pWapiInfo->wapiSTAUsedList.next),RT_WAPI_STA_INFO,list);
+
+ list_for_each_entry(pWapiStaInfo, &(pWapiInfo->wapiSTAUsedList), list) {
+
+ DBG_871X("MAC Addr %02x-%02x-%02x-%02x-%02x-%02x \n",MacAddr[0],MacAddr[1],MacAddr[2],MacAddr[3],MacAddr[4],MacAddr[5]);
+
+
+ DBG_871X("peer Addr %02x-%02x-%02x-%02x-%02x-%02x \n",pWapiStaInfo->PeerMacAddr[0],pWapiStaInfo->PeerMacAddr[1],pWapiStaInfo->PeerMacAddr[2],pWapiStaInfo->PeerMacAddr[3],pWapiStaInfo->PeerMacAddr[4],pWapiStaInfo->PeerMacAddr[5]);
+
+ if(pWapiStaInfo == NULL)
+ {
+ WAPI_TRACE(WAPI_API, " %s: pWapiStaInfo == NULL Case \n", __FUNCTION__);
+ return;
+ }
+
+ if(pWapiStaInfo->PeerMacAddr == NULL)
+ {
+ WAPI_TRACE(WAPI_API, " %s: pWapiStaInfo->PeerMacAddr == NULL Case \n", __FUNCTION__);
+ return;
+ }
+
+ if(MacAddr == NULL)
+ {
+ WAPI_TRACE(WAPI_API, " %s: MacAddr == NULL Case \n", __FUNCTION__);
+ return;
+ }
+
+ if (_rtw_memcmp(pWapiStaInfo->PeerMacAddr, MacAddr, ETH_ALEN) == _TRUE) {
+ pWapiStaInfo->bAuthenticateInProgress = false;
+ pWapiStaInfo->bSetkeyOk = false;
+ _rtw_memset(pWapiStaInfo->PeerMacAddr,0,ETH_ALEN);
+ list_del_init(&pWapiStaInfo->list);
+ list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList);
+ break;
+ }
+
+ }
+#endif
+
+ while(!list_empty(&(pWapiInfo->wapiSTAUsedList)))
+ {
+ pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAUsedList.next, RT_WAPI_STA_INFO, list);
+
+ DBG_871X("peer Addr %02x-%02x-%02x-%02x-%02x-%02x \n",pWapiStaInfo->PeerMacAddr[0],pWapiStaInfo->PeerMacAddr[1],pWapiStaInfo->PeerMacAddr[2],pWapiStaInfo->PeerMacAddr[3],pWapiStaInfo->PeerMacAddr[4],pWapiStaInfo->PeerMacAddr[5]);
+
+ list_del_init(&pWapiStaInfo->list);
+ memset(pWapiStaInfo->PeerMacAddr,0,ETH_ALEN);
+ pWapiStaInfo->bSetkeyOk = 0;
+ list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList);
+ }
+
+ }
+
+ WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
+ return;
+}
+
+void rtw_wapi_return_all_sta_info(_adapter *padapter)
+{
+ PRT_WAPI_T pWapiInfo;
+ PRT_WAPI_STA_INFO pWapiStaInfo;
+ PRT_WAPI_BKID pWapiBkid;
+ WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
+
+ pWapiInfo = &padapter->wapiInfo;
+
+ if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
+ return;
+ }
+
+ //Sta Info List
+ while(!list_empty(&(pWapiInfo->wapiSTAUsedList)))
+ {
+ pWapiStaInfo = (PRT_WAPI_STA_INFO)list_entry(pWapiInfo->wapiSTAUsedList.next, RT_WAPI_STA_INFO, list);
+ list_del_init(&pWapiStaInfo->list);
+ memset(pWapiStaInfo->PeerMacAddr,0,ETH_ALEN);
+ pWapiStaInfo->bSetkeyOk = 0;
+ list_add_tail(&pWapiStaInfo->list, &pWapiInfo->wapiSTAIdleList);
+ }
+
+ //BKID List
+ while(!list_empty(&(pWapiInfo->wapiBKIDStoreList)))
+ {
+ pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDStoreList.next, RT_WAPI_BKID, list);
+ list_del_init(&pWapiBkid->list);
+ memset(pWapiBkid->bkid,0,16);
+ list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDIdleList);
+ }
+ WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
+}
+
+void rtw_wapi_clear_cam_entry(_adapter *padapter, u8 *pMacAddr)
+{
+ u8 UcIndex = 0;
+
+ WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
+ return;
+ }
+
+ UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 0, 0);
+ if(UcIndex != 0xff){
+ //CAM_mark_invalid(Adapter, UcIndex);
+ CAM_empty_entry(padapter, UcIndex);
+ }
+
+ UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 1, 0);
+ if(UcIndex != 0xff){
+ //CAM_mark_invalid(Adapter, UcIndex);
+ CAM_empty_entry(padapter, UcIndex);
+ }
+
+ UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 0, 1);
+ if(UcIndex != 0xff){
+ //CAM_mark_invalid(Adapter, UcIndex);
+ CAM_empty_entry(padapter, UcIndex);
+ }
+
+ UcIndex = WapiGetEntryForCamClear(padapter, pMacAddr, 1, 1);
+ if(UcIndex != 0xff){
+ //CAM_mark_invalid(padapter, UcIndex);
+ CAM_empty_entry(padapter, UcIndex);
+ }
+
+ WAPI_TRACE(WAPI_API, "<========== %s\n", __FUNCTION__);
+}
+
+void rtw_wapi_clear_all_cam_entry(_adapter *padapter)
+{
+ WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_MLME, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
+ return;
+ }
+
+ invalidate_cam_all(padapter); // is this ok?
+ WapiResetAllCamEntry(padapter);
+
+ WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
+}
+
+void rtw_wapi_set_key(_adapter *padapter, RT_WAPI_KEY *pWapiKey, RT_WAPI_STA_INFO *pWapiSta, u8 bGroupKey, u8 bUseDefaultKey)
+{
+ PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
+ u8 *pMacAddr = pWapiSta->PeerMacAddr;
+ u32 EntryId = 0;
+ BOOLEAN IsPairWise = false ;
+ u8 EncAlgo;
+
+ WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_API, "<========== %s, WAPI not supported or not enabled!\n", __FUNCTION__);
+ return;
+ }
+
+ EncAlgo = _SMS4_;
+
+ //For Tx bc/mc pkt,use defualt key entry
+ if(bUseDefaultKey)
+ {
+ // when WAPI update key, keyid will be 0 or 1 by turns.
+ if (pWapiKey->keyId == 0)
+ EntryId = 0;
+ else
+ EntryId = 2;
+ }
+ else
+ {
+ // tx/rx unicast pkt, or rx broadcast, find the key entry by peer's MacAddr
+ EntryId = WapiGetEntryForCamWrite(padapter,pMacAddr,pWapiKey->keyId,bGroupKey);
+ }
+
+ if(EntryId == 0xff){
+ WAPI_TRACE(WAPI_API, "===>No entry for WAPI setkey! !!\n");
+ return;
+ }
+
+ //EntryId is also used to diff Sec key and Mic key
+ //Sec Key
+ WapiWriteOneCamEntry(padapter,
+ pMacAddr,
+ pWapiKey->keyId, //keyid
+ EntryId, //entry
+ EncAlgo, //type
+ bGroupKey, //pairwise or group key
+ pWapiKey->dataKey);
+ //MIC key
+ WapiWriteOneCamEntry(padapter,
+ pMacAddr,
+ pWapiKey->keyId, //keyid
+ EntryId+1, //entry
+ EncAlgo, //type
+ bGroupKey, //pairwise or group key
+ pWapiKey->micKey);
+
+ WAPI_TRACE(WAPI_API, "Set Wapi Key :KeyId:%d,EntryId:%d,PairwiseKey:%d.\n",pWapiKey->keyId,EntryId,!bGroupKey);
+ WAPI_TRACE(WAPI_API, "===========> %s\n", __FUNCTION__);
+
+}
+
+#if 0
+//YJ,test,091013
+void wapi_test_set_key(struct _adapter *padapter, u8* buf)
+{ /*Data: keyType(1) + bTxEnable(1) + bAuthenticator(1) + bUpdate(1) + PeerAddr(6) + DataKey(16) + MicKey(16) + KeyId(1)*/
+ PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
+ PRT_WAPI_BKID pWapiBkid;
+ PRT_WAPI_STA_INFO pWapiSta;
+ u8 data[43];
+ bool bTxEnable;
+ bool bUpdate;
+ bool bAuthenticator;
+ u8 PeerAddr[6];
+ u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
+ u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
+ u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
+
+ WAPI_TRACE(WAPI_INIT, "===========>%s\n", __FUNCTION__);
+
+ if (!padapter->WapiSupport){
+ return;
+ }
+
+ copy_from_user(data, buf, 43);
+ bTxEnable = data[1];
+ bAuthenticator = data[2];
+ bUpdate = data[3];
+ memcpy(PeerAddr,data+4,6);
+
+ if(data[0] == 0x3){
+ if(!list_empty(&(pWapiInfo->wapiBKIDIdleList))){
+ pWapiBkid = (PRT_WAPI_BKID)list_entry(pWapiInfo->wapiBKIDIdleList.next, RT_WAPI_BKID, list);
+ list_del_init(&pWapiBkid->list);
+ memcpy(pWapiBkid->bkid, data+10, 16);
+ WAPI_DATA(WAPI_INIT, "SetKey - BKID", pWapiBkid->bkid, 16);
+ list_add_tail(&pWapiBkid->list, &pWapiInfo->wapiBKIDStoreList);
+ }
+ }else{
+ list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
+ if(!memcmp(pWapiSta->PeerMacAddr,PeerAddr,6)){
+ pWapiSta->bAuthenticatorInUpdata = false;
+ switch(data[0]){
+ case 1: //usk
+ if(bAuthenticator){ //authenticator
+ memcpy(pWapiSta->lastTxUnicastPN,WapiAEPNInitialValueSrc,16);
+ if(!bUpdate) { //first
+ WAPI_TRACE(WAPI_INIT,"AE fisrt set usk \n");
+ pWapiSta->wapiUsk.bSet = true;
+ memcpy(pWapiSta->wapiUsk.dataKey,data+10,16);
+ memcpy(pWapiSta->wapiUsk.micKey,data+26,16);
+ pWapiSta->wapiUsk.keyId = *(data+42);
+ pWapiSta->wapiUsk.bTxEnable = true;
+ WAPI_DATA(WAPI_INIT, "SetKey - AE USK Data Key", pWapiSta->wapiUsk.dataKey, 16);
+ WAPI_DATA(WAPI_INIT, "SetKey - AE USK Mic Key", pWapiSta->wapiUsk.micKey, 16);
+ }
+ else //update
+ {
+ WAPI_TRACE(WAPI_INIT, "AE update usk \n");
+ pWapiSta->wapiUskUpdate.bSet = true;
+ pWapiSta->bAuthenticatorInUpdata = true;
+ memcpy(pWapiSta->wapiUskUpdate.dataKey,data+10,16);
+ memcpy(pWapiSta->wapiUskUpdate.micKey,data+26,16);
+ memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiASUEPNInitialValueSrc,16);
+ memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiASUEPNInitialValueSrc,16);
+ memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiASUEPNInitialValueSrc,16);
+ memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiASUEPNInitialValueSrc,16);
+ memcpy(pWapiSta->lastRxUnicastPN,WapiASUEPNInitialValueSrc,16);
+ pWapiSta->wapiUskUpdate.keyId = *(data+42);
+ pWapiSta->wapiUskUpdate.bTxEnable = true;
+ }
+ }
+ else{
+ if(!bUpdate){
+ WAPI_TRACE(WAPI_INIT,"ASUE fisrt set usk \n");
+ if(bTxEnable){
+ pWapiSta->wapiUsk.bTxEnable = true;
+ memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
+ }else{
+ pWapiSta->wapiUsk.bSet = true;
+ memcpy(pWapiSta->wapiUsk.dataKey,data+10,16);
+ memcpy(pWapiSta->wapiUsk.micKey,data+26,16);
+ pWapiSta->wapiUsk.keyId = *(data+42);
+ pWapiSta->wapiUsk.bTxEnable = false;
+ }
+ }else{
+ WAPI_TRACE(WAPI_INIT,"ASUE update usk \n");
+ if(bTxEnable){
+ pWapiSta->wapiUskUpdate.bTxEnable = true;
+ if(pWapiSta->wapiUskUpdate.bSet){
+ memcpy(pWapiSta->wapiUsk.dataKey,pWapiSta->wapiUskUpdate.dataKey,16);
+ memcpy(pWapiSta->wapiUsk.micKey,pWapiSta->wapiUskUpdate.micKey,16);
+ pWapiSta->wapiUsk.keyId=pWapiSta->wapiUskUpdate.keyId;
+ memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiASUEPNInitialValueSrc,16);
+ memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiASUEPNInitialValueSrc,16);
+ memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiASUEPNInitialValueSrc,16);
+ memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiASUEPNInitialValueSrc,16);
+ memcpy(pWapiSta->lastRxUnicastPN,WapiASUEPNInitialValueSrc,16);
+ pWapiSta->wapiUskUpdate.bTxEnable = false;
+ pWapiSta->wapiUskUpdate.bSet = false;
+ }
+ memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
+ }else{
+ pWapiSta->wapiUskUpdate.bSet = true;
+ memcpy(pWapiSta->wapiUskUpdate.dataKey,data+10,16);
+ memcpy(pWapiSta->wapiUskUpdate.micKey,data+26,16);
+ pWapiSta->wapiUskUpdate.keyId = *(data+42);
+ pWapiSta->wapiUskUpdate.bTxEnable = false;
+ }
+ }
+ }
+ break;
+ case 2: //msk
+ if(bAuthenticator){ //authenticator
+ pWapiInfo->wapiTxMsk.bSet = true;
+ memcpy(pWapiInfo->wapiTxMsk.dataKey,data+10,16);
+ memcpy(pWapiInfo->wapiTxMsk.micKey,data+26,16);
+ pWapiInfo->wapiTxMsk.keyId = *(data+42);
+ pWapiInfo->wapiTxMsk.bTxEnable = true;
+ memcpy(pWapiInfo->lastTxMulticastPN,WapiAEMultiCastPNInitialValueSrc,16);
+
+ if(!bUpdate){ //first
+ WAPI_TRACE(WAPI_INIT, "AE fisrt set msk \n");
+ if(!pWapiSta->bSetkeyOk)
+ pWapiSta->bSetkeyOk = true;
+ pWapiInfo->bFirstAuthentiateInProgress= false;
+ }else{ //update
+ WAPI_TRACE(WAPI_INIT,"AE update msk \n");
+ }
+
+ WAPI_DATA(WAPI_INIT, "SetKey - AE MSK Data Key", pWapiInfo->wapiTxMsk.dataKey, 16);
+ WAPI_DATA(WAPI_INIT, "SetKey - AE MSK Mic Key", pWapiInfo->wapiTxMsk.micKey, 16);
+ }
+ else{
+ if(!bUpdate){
+ WAPI_TRACE(WAPI_INIT,"ASUE fisrt set msk \n");
+ pWapiSta->wapiMsk.bSet = true;
+ memcpy(pWapiSta->wapiMsk.dataKey,data+10,16);
+ memcpy(pWapiSta->wapiMsk.micKey,data+26,16);
+ pWapiSta->wapiMsk.keyId = *(data+42);
+ pWapiSta->wapiMsk.bTxEnable = false;
+ if(!pWapiSta->bSetkeyOk)
+ pWapiSta->bSetkeyOk = true;
+ pWapiInfo->bFirstAuthentiateInProgress= false;
+ WAPI_DATA(WAPI_INIT, "SetKey - ASUE MSK Data Key", pWapiSta->wapiMsk.dataKey, 16);
+ WAPI_DATA(WAPI_INIT, "SetKey - ASUE MSK Mic Key", pWapiSta->wapiMsk.micKey, 16);
+ }else{
+ WAPI_TRACE(WAPI_INIT,"ASUE update msk \n");
+ pWapiSta->wapiMskUpdate.bSet = true;
+ memcpy(pWapiSta->wapiMskUpdate.dataKey,data+10,16);
+ memcpy(pWapiSta->wapiMskUpdate.micKey,data+26,16);
+ pWapiSta->wapiMskUpdate.keyId = *(data+42);
+ pWapiSta->wapiMskUpdate.bTxEnable = false;
+ }
+ }
+ break;
+ default:
+ WAPI_TRACE(WAPI_ERR,"Unknown Flag \n");
+ break;
+ }
+ }
+ }
+ }
+ WAPI_TRACE(WAPI_INIT, "<===========%s\n", __FUNCTION__);
+}
+
+
+void wapi_test_init(struct _adapter *padapter)
+{
+ u8 keybuf[100];
+ u8 mac_addr[6]={0x00,0xe0,0x4c,0x72,0x04,0x70};
+ u8 UskDataKey[16]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
+ u8 UskMicKey[16]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f};
+ u8 UskId = 0;
+ u8 MskDataKey[16]={0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f};
+ u8 MskMicKey[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f};
+ u8 MskId = 0;
+
+ WAPI_TRACE(WAPI_INIT, "===========>%s\n", __FUNCTION__);
+
+ //Enable Wapi
+ WAPI_TRACE(WAPI_INIT, "%s: Enable wapi!!!!\n", __FUNCTION__);
+ padapter->wapiInfo.bWapiEnable = true;
+ padapter->pairwise_key_type = KEY_TYPE_SMS4;
+ ieee->group_key_type = KEY_TYPE_SMS4;
+ padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
+ padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
+
+ //set usk
+ WAPI_TRACE(WAPI_INIT, "%s: Set USK!!!!\n", __FUNCTION__);
+ memset(keybuf,0,100);
+ keybuf[0] = 1; //set usk
+ keybuf[1] = 1; //enable tx
+ keybuf[2] = 1; //AE
+ keybuf[3] = 0; //not update
+
+ memcpy(keybuf+4,mac_addr,6);
+ memcpy(keybuf+10,UskDataKey,16);
+ memcpy(keybuf+26,UskMicKey,16);
+ keybuf[42]=UskId;
+ wapi_test_set_key(padapter, keybuf);
+
+ memset(keybuf,0,100);
+ keybuf[0] = 1; //set usk
+ keybuf[1] = 1; //enable tx
+ keybuf[2] = 0; //AE
+ keybuf[3] = 0; //not update
+
+ memcpy(keybuf+4,mac_addr,6);
+ memcpy(keybuf+10,UskDataKey,16);
+ memcpy(keybuf+26,UskMicKey,16);
+ keybuf[42]=UskId;
+ wapi_test_set_key(padapter, keybuf);
+
+ //set msk
+ WAPI_TRACE(WAPI_INIT, "%s: Set MSK!!!!\n", __FUNCTION__);
+ memset(keybuf,0,100);
+ keybuf[0] = 2; //set msk
+ keybuf[1] = 1; //Enable TX
+ keybuf[2] = 1; //AE
+ keybuf[3] = 0; //not update
+ memcpy(keybuf+4,mac_addr,6);
+ memcpy(keybuf+10,MskDataKey,16);
+ memcpy(keybuf+26,MskMicKey,16);
+ keybuf[42] = MskId;
+ wapi_test_set_key(padapter, keybuf);
+
+ memset(keybuf,0,100);
+ keybuf[0] = 2; //set msk
+ keybuf[1] = 1; //Enable TX
+ keybuf[2] = 0; //AE
+ keybuf[3] = 0; //not update
+ memcpy(keybuf+4,mac_addr,6);
+ memcpy(keybuf+10,MskDataKey,16);
+ memcpy(keybuf+26,MskMicKey,16);
+ keybuf[42] = MskId;
+ wapi_test_set_key(padapter, keybuf);
+ WAPI_TRACE(WAPI_INIT, "<===========%s\n", __FUNCTION__);
+}
+#endif
+
+void rtw_wapi_get_iv(_adapter *padapter,u8 *pRA, u8*IV)
+{
+ PWLAN_HEADER_WAPI_EXTENSION pWapiExt = NULL;
+ PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
+ bool bPNOverflow = false;
+ bool bFindMatchPeer = false;
+ PRT_WAPI_STA_INFO pWapiSta = NULL;
+
+ pWapiExt = (PWLAN_HEADER_WAPI_EXTENSION)IV;
+
+ WAPI_DATA(WAPI_RX,"wapi_get_iv: pra",pRA,6);
+
+ if(IS_MCAST(pRA)){
+ if(!pWapiInfo->wapiTxMsk.bTxEnable){
+ WAPI_TRACE(WAPI_ERR,"%s: bTxEnable = 0!!\n",__FUNCTION__);
+ return;
+ }
+
+ if(pWapiInfo->wapiTxMsk.keyId <= 1){
+ pWapiExt->KeyIdx = pWapiInfo->wapiTxMsk.keyId;
+ pWapiExt->Reserved = 0;
+ bPNOverflow = WapiIncreasePN(pWapiInfo->lastTxMulticastPN, 1);
+ memcpy(pWapiExt->PN, pWapiInfo->lastTxMulticastPN, 16);
+ }
+ }
+ else
+ {
+ if(list_empty(&pWapiInfo->wapiSTAUsedList)){
+ WAPI_TRACE(WAPI_RX,"rtw_wapi_get_iv: list is empty \n");
+ _rtw_memset(IV,10,18);
+ return;
+ }
+ else{
+ list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list){
+ WAPI_DATA(WAPI_RX,"rtw_wapi_get_iv: peermacaddr ",pWapiSta->PeerMacAddr,6);
+ if (_rtw_memcmp((u8*)pWapiSta->PeerMacAddr, pRA, 6) == _TRUE) {
+ bFindMatchPeer = true;
+ break;
+ }
+ }
+
+ WAPI_TRACE(WAPI_RX,"bFindMatchPeer: %d \n",bFindMatchPeer);
+ WAPI_DATA(WAPI_RX,"Addr",pRA,6);
+
+ if (bFindMatchPeer){
+ if((!pWapiSta->wapiUskUpdate.bTxEnable) && (!pWapiSta->wapiUsk.bTxEnable))
+ return;
+
+ if (pWapiSta->wapiUsk.keyId <= 1){
+ if(pWapiSta->wapiUskUpdate.bTxEnable)
+ pWapiExt->KeyIdx = pWapiSta->wapiUskUpdate.keyId;
+ else
+ pWapiExt->KeyIdx = pWapiSta->wapiUsk.keyId;
+
+ pWapiExt->Reserved = 0;
+ bPNOverflow = WapiIncreasePN(pWapiSta->lastTxUnicastPN, 2);
+ _rtw_memcpy(pWapiExt->PN, pWapiSta->lastTxUnicastPN, 16);
+
+ }
+ }
+ }
+
+ }
+
+}
+
+bool rtw_wapi_drop_for_key_absent(_adapter *padapter,u8 *pRA)
+{
+ PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
+ bool bFindMatchPeer = false;
+ bool bDrop = false;
+ PRT_WAPI_STA_INFO pWapiSta = NULL;
+ struct security_priv *psecuritypriv = &padapter->securitypriv;
+
+ WAPI_DATA(WAPI_RX,"rtw_wapi_drop_for_key_absent: ra ",pRA,6);
+
+ if(psecuritypriv->dot11PrivacyAlgrthm == _SMS4_)
+ {
+ if ((!padapter->WapiSupport) || (!pWapiInfo->bWapiEnable))
+ return true;
+
+ if(IS_MCAST(pRA)){
+ if(!pWapiInfo->wapiTxMsk.bTxEnable){
+ bDrop = true;
+ WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: multicast key is absent \n");
+ return bDrop;
+ }
+ }
+ else{
+ if(!list_empty(&pWapiInfo->wapiSTAUsedList)){
+ list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list){
+ WAPI_DATA(WAPI_RX,"rtw_wapi_drop_for_key_absent: pWapiSta->PeerMacAddr ",pWapiSta->PeerMacAddr,6);
+ if (_rtw_memcmp(pRA, pWapiSta->PeerMacAddr, 6) == _TRUE){
+ bFindMatchPeer = true;
+ break;
+ }
+ }
+ if (bFindMatchPeer) {
+ if (!pWapiSta->wapiUsk.bTxEnable){
+ bDrop = true;
+ WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: unicast key is absent \n");
+ return bDrop;
+ }
+ }
+ else{
+ bDrop = true;
+ WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: no peer find \n");
+ return bDrop;
+ }
+
+ }
+ else{
+ bDrop = true;
+ WAPI_TRACE(WAPI_RX,"rtw_wapi_drop_for_key_absent: no sta exist \n");
+ return bDrop;
+ }
+ }
+ }
+ else
+ {
+ return bDrop;
+ }
+
+ return bDrop;
+}
+
+#endif
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_wapi_sms4.c b/drivers/net/wireless/rtl8723as/core/rtw_wapi_sms4.c
index aa6419390673..6126ed9a00c6 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_wapi_sms4.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_wapi_sms4.c
@@ -1,923 +1,923 @@
-#ifdef CONFIG_WAPI_SUPPORT
-
-#include <linux/unistd.h>
-#include <linux/etherdevice.h>
-#include <drv_types.h>
-#include <rtw_wapi.h>
-
-
-#ifdef CONFIG_WAPI_SW_SMS4
-
-#define WAPI_LITTLE_ENDIAN
-//#define BIG_ENDIAN
-#define ENCRYPT 0
-#define DECRYPT 1
-
-
-/**********************************************************
- **********************************************************/
-const u8 Sbox[256] = {
-0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05,
-0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99,
-0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62,
-0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6,
-0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8,
-0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35,
-0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87,
-0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e,
-0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1,
-0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3,
-0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f,
-0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51,
-0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8,
-0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0,
-0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84,
-0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48
-};
-
-const u32 CK[32] = {
- 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
- 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
- 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
- 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
- 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
- 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
- 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
- 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 };
-
-#define Rotl(_x, _y) (((_x) << (_y)) | ((_x) >> (32 - (_y))))
-
-#define ByteSub(_A) (Sbox[(_A) >> 24 & 0xFF] << 24 | \
- Sbox[(_A) >> 16 & 0xFF] << 16 | \
- Sbox[(_A) >> 8 & 0xFF] << 8 | \
- Sbox[(_A) & 0xFF])
-
-#define L1(_B) ((_B) ^ Rotl(_B, 2) ^ Rotl(_B, 10) ^ Rotl(_B, 18) ^ Rotl(_B, 24))
-#define L2(_B) ((_B) ^ Rotl(_B, 13) ^ Rotl(_B, 23))
-
-static void
-xor_block(void *dst, void *src1, void *src2)
-/* 128-bit xor: *dst = *src1 xor *src2. Pointers must be 32-bit aligned */
-{
- ((u32 *)dst)[0] = ((u32 *)src1)[0] ^ ((u32 *)src2)[0];
- ((u32 *)dst)[1] = ((u32 *)src1)[1] ^ ((u32 *)src2)[1];
- ((u32 *)dst)[2] = ((u32 *)src1)[2] ^ ((u32 *)src2)[2];
- ((u32 *)dst)[3] = ((u32 *)src1)[3] ^ ((u32 *)src2)[3];
-}
-
-
-void SMS4Crypt(u8 *Input, u8 *Output, u32 *rk)
-{
- u32 r, mid, x0, x1, x2, x3, *p;
- p = (u32 *)Input;
- x0 = p[0];
- x1 = p[1];
- x2 = p[2];
- x3 = p[3];
-#ifdef WAPI_LITTLE_ENDIAN
- x0 = Rotl(x0, 16); x0 = ((x0 & 0x00FF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
- x1 = Rotl(x1, 16); x1 = ((x1 & 0x00FF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
- x2 = Rotl(x2, 16); x2 = ((x2 & 0x00FF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
- x3 = Rotl(x3, 16); x3 = ((x3 & 0x00FF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
-#endif
- for (r = 0; r < 32; r += 4)
- {
- mid = x1 ^ x2 ^ x3 ^ rk[r + 0];
- mid = ByteSub(mid);
- x0 ^= L1(mid);
- mid = x2 ^ x3 ^ x0 ^ rk[r + 1];
- mid = ByteSub(mid);
- x1 ^= L1(mid);
- mid = x3 ^ x0 ^ x1 ^ rk[r + 2];
- mid = ByteSub(mid);
- x2 ^= L1(mid);
- mid = x0 ^ x1 ^ x2 ^ rk[r + 3];
- mid = ByteSub(mid);
- x3 ^= L1(mid);
- }
-#ifdef WAPI_LITTLE_ENDIAN
- x0 = Rotl(x0, 16); x0 = ((x0 & 0x00FF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
- x1 = Rotl(x1, 16); x1 = ((x1 & 0x00FF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
- x2 = Rotl(x2, 16); x2 = ((x2 & 0x00FF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
- x3 = Rotl(x3, 16); x3 = ((x3 & 0x00FF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
-#endif
- p = (u32 *)Output;
- p[0] = x3;
- p[1] = x2;
- p[2] = x1;
- p[3] = x0;
-}
-
-
-
-void SMS4KeyExt(u8 *Key, u32 *rk, u32 CryptFlag)
-{
- u32 r, mid, x0, x1, x2, x3, *p;
-
- p = (u32 *)Key;
- x0 = p[0];
- x1 = p[1];
- x2 = p[2];
- x3 = p[3];
-#ifdef WAPI_LITTLE_ENDIAN
- x0 = Rotl(x0, 16); x0 = ((x0 & 0xFF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
- x1 = Rotl(x1, 16); x1 = ((x1 & 0xFF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
- x2 = Rotl(x2, 16); x2 = ((x2 & 0xFF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
- x3 = Rotl(x3, 16); x3 = ((x3 & 0xFF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
-#endif
-
- x0 ^= 0xa3b1bac6;
- x1 ^= 0x56aa3350;
- x2 ^= 0x677d9197;
- x3 ^= 0xb27022dc;
- for (r = 0; r < 32; r += 4)
- {
- mid = x1 ^ x2 ^ x3 ^ CK[r + 0];
- mid = ByteSub(mid);
- rk[r + 0] = x0 ^= L2(mid);
- mid = x2 ^ x3 ^ x0 ^ CK[r + 1];
- mid = ByteSub(mid);
- rk[r + 1] = x1 ^= L2(mid);
- mid = x3 ^ x0 ^ x1 ^ CK[r + 2];
- mid = ByteSub(mid);
- rk[r + 2] = x2 ^= L2(mid);
- mid = x0 ^ x1 ^ x2 ^ CK[r + 3];
- mid = ByteSub(mid);
- rk[r + 3] = x3 ^= L2(mid);
- }
- if (CryptFlag == DECRYPT)
- {
- for (r = 0; r < 16; r++)
- mid = rk[r], rk[r] = rk[31 - r], rk[31 - r] = mid;
- }
-}
-
-
-void WapiSMS4Cryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
- u8 *Output, u16 *OutputLength, u32 CryptFlag)
-{
- u32 blockNum,i,j, rk[32];
- u16 remainder;
- u8 blockIn[16],blockOut[16], tempIV[16], k;
-
- *OutputLength = 0;
- remainder = InputLength & 0x0F;
- blockNum = InputLength >> 4;
- if(remainder !=0)
- blockNum++;
- else
- remainder = 16;
-
- for(k=0;k<16;k++)
- tempIV[k] = IV[15-k];
-
- memcpy(blockIn, tempIV, 16);
-
- SMS4KeyExt((u8 *)Key, rk,CryptFlag);
-
- for(i=0; i<blockNum-1; i++)
- {
- SMS4Crypt((u8 *)blockIn, blockOut, rk);
- xor_block(&Output[i*16], &Input[i*16], blockOut);
- memcpy(blockIn,blockOut,16);
- }
-
- *OutputLength = i*16;
-
- SMS4Crypt((u8 *)blockIn, blockOut, rk);
-
- for(j=0; j<remainder; j++)
- {
- Output[i*16+j] = Input[i*16+j] ^ blockOut[j];
- }
- *OutputLength += remainder;
-
-}
-
-void WapiSMS4Encryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
- u8 *Output, u16 *OutputLength)
-{
-
- WapiSMS4Cryption(Key, IV, Input, InputLength, Output, OutputLength, ENCRYPT);
-}
-
-void WapiSMS4Decryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
- u8 *Output, u16 *OutputLength)
-{
- // OFB mode: is also ENCRYPT flag
- WapiSMS4Cryption(Key, IV, Input, InputLength, Output, OutputLength, ENCRYPT);
-}
-
-void WapiSMS4CalculateMic(u8 *Key, u8 *IV, u8 *Input1, u8 Input1Length,
- u8 *Input2, u16 Input2Length, u8 *Output, u8 *OutputLength)
-{
- u32 blockNum, i, remainder, rk[32];
- u8 BlockIn[16], BlockOut[16], TempBlock[16], tempIV[16], k;
-
- *OutputLength = 0;
- remainder = Input1Length & 0x0F;
- blockNum = Input1Length >> 4;
-
- for(k=0;k<16;k++)
- tempIV[k] = IV[15-k];
-
- memcpy(BlockIn, tempIV, 16);
-
- SMS4KeyExt((u8 *)Key, rk, ENCRYPT);
-
- SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
-
- for(i=0; i<blockNum; i++){
- xor_block(BlockIn, (Input1+i*16), BlockOut);
- SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
- }
-
- if(remainder !=0){
- memset(TempBlock, 0, 16);
- memcpy(TempBlock, (Input1+blockNum*16), remainder);
-
- xor_block(BlockIn, TempBlock, BlockOut);
- SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
- }
-
- remainder = Input2Length & 0x0F;
- blockNum = Input2Length >> 4;
-
- for(i=0; i<blockNum; i++){
- xor_block(BlockIn, (Input2+i*16), BlockOut);
- SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
- }
-
- if(remainder !=0){
- memset(TempBlock, 0, 16);
- memcpy(TempBlock, (Input2+blockNum*16), remainder);
-
- xor_block(BlockIn, TempBlock, BlockOut);
- SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
- }
-
- memcpy(Output, BlockOut, 16);
- *OutputLength = 16;
-}
-
-void SecCalculateMicSMS4(
- u8 KeyIdx,
- u8 *MicKey,
- u8 *pHeader,
- u8 *pData,
- u16 DataLen,
- u8 *MicBuffer
- )
-{
-#if 0
- struct ieee80211_hdr_3addr_qos *header;
- u8 TempBuf[34], TempLen = 32, MicLen, QosOffset, *IV;
- u16 *pTemp, fc;
-
- WAPI_TRACE(WAPI_TX|WAPI_RX, "=========>%s\n", __FUNCTION__);
-
- header = (struct ieee80211_hdr_3addr_qos *)pHeader;
- memset(TempBuf, 0, 34);
- memcpy(TempBuf, pHeader, 2); //FrameCtrl
- pTemp = (u16*)TempBuf;
- *pTemp &= 0xc78f; //bit4,5,6,11,12,13
-
- memcpy((TempBuf+2), (pHeader+4), 12); //Addr1, Addr2
- memcpy((TempBuf+14), (pHeader+22), 2); // SeqCtrl
- pTemp = (u16*)(TempBuf + 14);
- *pTemp &= 0x000f;
-
- memcpy((TempBuf+16), (pHeader+16), 6); //Addr3
-
- fc = le16_to_cpu(header->frame_ctl);
-
-
-
- if (GetFrDs((u16*)&fc) && GetToDs((u16 *)&fc))
- {
- memcpy((TempBuf+22), (pHeader+24), 6);
- QosOffset = 30;
- }else{
- memset((TempBuf+22), 0, 6);
- QosOffset = 24;
- }
-
- if((fc & 0x0088) == 0x0088){
- memcpy((TempBuf+28), (pHeader+QosOffset), 2);
- TempLen += 2;
- //IV = pHeader + QosOffset + 2 + SNAP_SIZE + sizeof(u16) + 2;
- IV = pHeader + QosOffset + 2 + 2;
- }else{
- IV = pHeader + QosOffset + 2;
- //IV = pHeader + QosOffset + SNAP_SIZE + sizeof(u16) + 2;
- }
-
- TempBuf[TempLen-1] = (u8)(DataLen & 0xff);
- TempBuf[TempLen-2] = (u8)((DataLen & 0xff00)>>8);
- TempBuf[TempLen-4] = KeyIdx;
-
- WAPI_DATA(WAPI_TX, "CalculateMic - KEY", MicKey, 16);
- WAPI_DATA(WAPI_TX, "CalculateMic - IV", IV, 16);
- WAPI_DATA(WAPI_TX, "CalculateMic - TempBuf", TempBuf, TempLen);
- WAPI_DATA(WAPI_TX, "CalculateMic - pData", pData, DataLen);
-
- WapiSMS4CalculateMic(MicKey, IV, TempBuf, TempLen,
- pData, DataLen, MicBuffer, &MicLen);
-
- if (MicLen != 16)
- WAPI_TRACE(WAPI_ERR,"%s: MIC Length Error!!\n",__FUNCTION__);
-
- WAPI_TRACE(WAPI_TX|WAPI_RX, "<=========%s\n", __FUNCTION__);
-#endif
-}
-
-/* AddCount: 1 or 2.
- * If overflow, return 1,
- * else return 0.
- */
-u8 WapiIncreasePN(u8 *PN, u8 AddCount)
-{
- u8 i;
-
- if (NULL == PN)
- return 1;
- //YJ,test,091102
- /*
- if(AddCount == 2){
- DBG_8192C("############################%s(): PN[0]=0x%x\n", __FUNCTION__, PN[0]);
- if(PN[0] == 0x48){
- PN[0] += AddCount;
- return 1;
- }else{
- PN[0] += AddCount;
- return 0;
- }
- }
- */
- //YJ,test,091102,end
-
- for (i=0; i<16; i++)
- {
- if (PN[i] + AddCount <= 0xff)
- {
- PN[i] += AddCount;
- return 0;
- }
- else
- {
- PN[i] += AddCount;
- AddCount = 1;
- }
- }
- return 1;
-}
-
-
-void WapiGetLastRxUnicastPNForQoSData(
- u8 UserPriority,
- PRT_WAPI_STA_INFO pWapiStaInfo,
- u8 *PNOut
-)
-{
- WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
- switch(UserPriority)
- {
- case 0:
- case 3:
- memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNBEQueue,16);
- break;
- case 1:
- case 2:
- memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNBKQueue,16);
- break;
- case 4:
- case 5:
- memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNVIQueue,16);
- break;
- case 6:
- case 7:
- memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNVOQueue,16);
- break;
- default:
- WAPI_TRACE(WAPI_ERR, "%s: Unknown TID \n", __FUNCTION__);
- break;
- }
- WAPI_TRACE(WAPI_RX, "<=========== %s\n", __FUNCTION__);
-}
-
-
-void WapiSetLastRxUnicastPNForQoSData(
- u8 UserPriority,
- u8 *PNIn,
- PRT_WAPI_STA_INFO pWapiStaInfo
-)
-{
- WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
- switch(UserPriority)
- {
- case 0:
- case 3:
- memcpy(pWapiStaInfo->lastRxUnicastPNBEQueue,PNIn,16);
- break;
- case 1:
- case 2:
- memcpy(pWapiStaInfo->lastRxUnicastPNBKQueue,PNIn,16);
- break;
- case 4:
- case 5:
- memcpy(pWapiStaInfo->lastRxUnicastPNVIQueue,PNIn,16);
- break;
- case 6:
- case 7:
- memcpy(pWapiStaInfo->lastRxUnicastPNVOQueue,PNIn,16);
- break;
- default:
- WAPI_TRACE(WAPI_ERR, "%s: Unknown TID \n", __FUNCTION__);
- break;
- }
- WAPI_TRACE(WAPI_RX, "<=========== %s\n", __FUNCTION__);
-}
-
-
-/****************************************************************************
- FALSE not RX-Reorder
- TRUE do RX Reorder
-add to support WAPI to N-mode
-*****************************************************************************/
-u8 WapiCheckPnInSwDecrypt(
- _adapter *padapter,
- struct sk_buff *pskb
-)
-{
- u8 ret = false;
-
-#if 0
- struct ieee80211_hdr_3addr_qos *header;
- u16 fc;
- u8 *pDaddr, *pTaddr, *pRaddr;
-
- header = (struct ieee80211_hdr_3addr_qos *)pskb->data;
- pTaddr = header->addr2;
- pRaddr = header->addr1;
- fc = le16_to_cpu(header->frame_ctl);
-
- if(GetToDs(&fc))
- pDaddr = header->addr3;
- else
- pDaddr = header->addr1;
-
- if ((_rtw_memcmp(pRaddr, padapter->pnetdev->dev_addr, ETH_ALEN) == 0)
- && ! (pDaddr)
- && (GetFrameType(&fc) == WIFI_QOS_DATA_TYPE))
- //&& ieee->pHTInfo->bCurrentHTSupport &&
- //ieee->pHTInfo->bCurRxReorderEnable)
- ret = false;
- else
- ret = true;
-#endif
- WAPI_TRACE(WAPI_RX, "%s: return %d\n", __FUNCTION__, ret);
- return ret;
-}
-
-int SecSMS4HeaderFillIV(_adapter *padapter, u8 *pxmitframe)
-{
- struct pkt_attrib *pattrib = &((struct xmit_frame*)pxmitframe)->attrib;
- u8 * frame = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET;
- u8 *pSecHeader = NULL, *pos = NULL, *pRA = NULL;
- u8 bPNOverflow = false, bFindMatchPeer = false, hdr_len = 0;
- PWLAN_HEADER_WAPI_EXTENSION pWapiExt = NULL;
- PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
- PRT_WAPI_STA_INFO pWapiSta = NULL;
- int ret = 0;
-
- WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
-
- return ret;
-#if 0
- hdr_len = sMacHdrLng;
- if (GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE)
- {
- hdr_len += 2;
- }
- //hdr_len += SNAP_SIZE + sizeof(u16);
-
- pos = skb_push(pskb, padapter->wapiInfo.extra_prefix_len);
- memmove(pos, pos+padapter->wapiInfo.extra_prefix_len, hdr_len);
-
- pSecHeader = pskb->data + hdr_len;
- pWapiExt = (PWLAN_HEADER_WAPI_EXTENSION)pSecHeader;
- pRA = pskb->data + 4;
-
- WAPI_DATA(WAPI_TX, "FillIV - Before Fill IV", pskb->data, pskb->len);
-
- //Address 1 is always receiver's address
- if( IS_MCAST(pRA) ){
- if(!pWapiInfo->wapiTxMsk.bTxEnable){
- WAPI_TRACE(WAPI_ERR,"%s: bTxEnable = 0!!\n",__FUNCTION__);
- return -2;
- }
- if(pWapiInfo->wapiTxMsk.keyId <= 1){
- pWapiExt->KeyIdx = pWapiInfo->wapiTxMsk.keyId;
- pWapiExt->Reserved = 0;
- bPNOverflow = WapiIncreasePN(pWapiInfo->lastTxMulticastPN, 1);
- memcpy(pWapiExt->PN, pWapiInfo->lastTxMulticastPN, 16);
- if (bPNOverflow){
- // Update MSK Notification.
- WAPI_TRACE(WAPI_ERR,"===============>%s():multicast PN overflow\n",__FUNCTION__);
- rtw_wapi_app_event_handler(padapter,NULL,0,pRA, false, false, true, 0, false);
- }
- }else{
- WAPI_TRACE(WAPI_ERR,"%s: Invalid Wapi Multicast KeyIdx!!\n",__FUNCTION__);
- ret = -3;
- }
- }
- else{
- list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
- if(!memcmp(pWapiSta->PeerMacAddr,pRA,6)){
- bFindMatchPeer = true;
- break;
- }
- }
- if (bFindMatchPeer){
- if((!pWapiSta->wapiUskUpdate.bTxEnable) && (!pWapiSta->wapiUsk.bTxEnable)){
- WAPI_TRACE(WAPI_ERR,"%s: bTxEnable = 0!!\n",__FUNCTION__);
- return -4;
- }
- if (pWapiSta->wapiUsk.keyId <= 1){
- if(pWapiSta->wapiUskUpdate.bTxEnable)
- pWapiExt->KeyIdx = pWapiSta->wapiUskUpdate.keyId;
- else
- pWapiExt->KeyIdx = pWapiSta->wapiUsk.keyId;
-
- pWapiExt->Reserved = 0;
- bPNOverflow = WapiIncreasePN(pWapiSta->lastTxUnicastPN, 2);
- memcpy(pWapiExt->PN, pWapiSta->lastTxUnicastPN, 16);
- if (bPNOverflow){
- // Update USK Notification.
- WAPI_TRACE(WAPI_ERR,"===============>%s():unicast PN overflow\n",__FUNCTION__);
- rtw_wapi_app_event_handler(padapter,NULL,0,pWapiSta->PeerMacAddr, false, true, false, 0, false);
- }
- }else{
- WAPI_TRACE(WAPI_ERR,"%s: Invalid Wapi Unicast KeyIdx!!\n",__FUNCTION__);
- ret = -5;
- }
- }
- else{
- WAPI_TRACE(WAPI_ERR,"%s: Can not find Peer Sta "MAC_FMT"!!\n",__FUNCTION__, MAC_ARG(pRA));
- ret = -6;
- }
- }
-
- WAPI_DATA(WAPI_TX, "FillIV - After Fill IV", pskb->data, pskb->len);
- WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
- return ret;
-#endif
-}
-
-// WAPI SW Enc: must have done Coalesce!
-void SecSWSMS4Encryption(
- _adapter *padapter,
- u8 * pxmitframe
- )
-{
- PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
- PRT_WAPI_STA_INFO pWapiSta = NULL;
- u8 *pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_SIZE;
- struct pkt_attrib *pattrib = &((struct xmit_frame*)pxmitframe)->attrib;
-
- u8 *SecPtr = NULL, *pRA, *pMicKey = NULL, *pDataKey = NULL, *pIV = NULL;
- u8 IVOffset, DataOffset, bFindMatchPeer = false, KeyIdx = 0, MicBuffer[16];
- u16 OutputLength;
-
- WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
-
- WAPI_TRACE(WAPI_TX,"hdrlen: %d \n",pattrib->hdrlen);
-
- return;
-
- DataOffset = pattrib->hdrlen + pattrib->iv_len;
-
- pRA = pframe + 4;
-
-
- if( IS_MCAST(pRA) ){
- KeyIdx = pWapiInfo->wapiTxMsk.keyId;
- pIV = pWapiInfo->lastTxMulticastPN;
- pMicKey = pWapiInfo->wapiTxMsk.micKey;
- pDataKey = pWapiInfo->wapiTxMsk.dataKey;
- }else{
- if (!list_empty(&(pWapiInfo->wapiSTAUsedList))){
- list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
- if (0 == memcmp(pWapiSta->PeerMacAddr, pRA, 6)){
- bFindMatchPeer = true;
- break;
- }
- }
-
- if (bFindMatchPeer){
- if (pWapiSta->wapiUskUpdate.bTxEnable){
- KeyIdx = pWapiSta->wapiUskUpdate.keyId;
- WAPI_TRACE(WAPI_TX, "%s(): Use update USK!! KeyIdx=%d\n", __FUNCTION__, KeyIdx);
- pIV = pWapiSta->lastTxUnicastPN;
- pMicKey = pWapiSta->wapiUskUpdate.micKey;
- pDataKey = pWapiSta->wapiUskUpdate.dataKey;
- }else{
- KeyIdx = pWapiSta->wapiUsk.keyId;
- WAPI_TRACE(WAPI_TX, "%s(): Use USK!! KeyIdx=%d\n", __FUNCTION__, KeyIdx);
- pIV = pWapiSta->lastTxUnicastPN;
- pMicKey = pWapiSta->wapiUsk.micKey;
- pDataKey = pWapiSta->wapiUsk.dataKey;
- }
- }else{
- WAPI_TRACE(WAPI_ERR,"%s: Can not find Peer Sta!!\n",__FUNCTION__);
- return;
- }
- }else{
- WAPI_TRACE(WAPI_ERR,"%s: wapiSTAUsedList is empty!!\n",__FUNCTION__);
- return;
- }
- }
-
- SecPtr = pframe;
- SecCalculateMicSMS4(KeyIdx, pMicKey, SecPtr, (SecPtr+DataOffset), pattrib->pktlen, MicBuffer);
-
- WAPI_DATA(WAPI_TX, "Encryption - MIC", MicBuffer, padapter->wapiInfo.extra_postfix_len);
-
- memcpy(pframe+pattrib->hdrlen+pattrib->iv_len+pattrib->pktlen-pattrib->icv_len,
- (u8 *)MicBuffer,
- padapter->wapiInfo.extra_postfix_len
- );
-
-
- WapiSMS4Encryption(pDataKey, pIV, (SecPtr+DataOffset),pattrib->pktlen+pattrib->icv_len, (SecPtr+DataOffset), &OutputLength);
-
- WAPI_DATA(WAPI_TX, "Encryption - After SMS4 encryption",pframe,pattrib->hdrlen+pattrib->iv_len+pattrib->pktlen);
-
- WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
-}
-
-u8 SecSWSMS4Decryption(
- _adapter *padapter,
- u8 *precv_frame,
- struct recv_priv *precv_priv
- )
-{
- PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
- struct recv_frame_hdr *precv_hdr;
- PRT_WAPI_STA_INFO pWapiSta = NULL;
- u8 IVOffset, DataOffset, bFindMatchPeer = false, bUseUpdatedKey = false;
- u8 KeyIdx, MicBuffer[16], lastRxPNforQoS[16];
- u8 *pRA, *pTA, *pMicKey, *pDataKey, *pLastRxPN, *pRecvPN, *pSecData, *pRecvMic, *pos;
- u8 TID = 0;
- u16 OutputLength, DataLen;
- u8 bQosData;
- struct sk_buff * pskb;
-
- WAPI_TRACE(WAPI_RX, "=========>%s\n", __FUNCTION__);
-
- return 0;
-
- precv_hdr = &((union recv_frame*)precv_frame)->u.hdr;
- pskb = (struct sk_buff *)(precv_hdr->rx_data);
- precv_hdr->bWapiCheckPNInDecrypt = WapiCheckPnInSwDecrypt(padapter, pskb);
- WAPI_TRACE(WAPI_RX, "=========>%s: check PN %d\n", __FUNCTION__,precv_hdr->bWapiCheckPNInDecrypt);
- WAPI_DATA(WAPI_RX, "Decryption - Before decryption", pskb->data, pskb->len);
-
- IVOffset = sMacHdrLng;
- bQosData = GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE;
- if (bQosData){
- IVOffset += 2;
- }
-
- //if(GetHTC())
- // IVOffset += 4;
-
- //IVOffset += SNAP_SIZE + sizeof(u16);
-
- DataOffset = IVOffset + padapter->wapiInfo.extra_prefix_len;
-
- pRA = pskb->data + 4;
- pTA = pskb->data + 10;
- KeyIdx = *(pskb->data + IVOffset);
- pRecvPN = pskb->data + IVOffset + 2;
- pSecData = pskb->data + DataOffset;
- DataLen = pskb->len - DataOffset;
- pRecvMic = pskb->data + pskb->len - padapter->wapiInfo.extra_postfix_len;
- TID = GetTid(pskb->data);
-
- if (!list_empty(&(pWapiInfo->wapiSTAUsedList))){
- list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
- if (0 == memcmp(pWapiSta->PeerMacAddr, pTA, 6)){
- bFindMatchPeer = true;
- break;
- }
- }
- }
-
- if (!bFindMatchPeer){
- WAPI_TRACE(WAPI_ERR, "%s: Can not find Peer Sta "MAC_FMT" for Key Info!!!\n", __FUNCTION__, MAC_ARG(pTA));
- return false;
- }
-
- if( IS_MCAST(pRA) ){
- WAPI_TRACE(WAPI_RX, "%s: Multicast decryption !!!\n", __FUNCTION__);
- if (pWapiSta->wapiMsk.keyId == KeyIdx && pWapiSta->wapiMsk.bSet){
- pLastRxPN = pWapiSta->lastRxMulticastPN;
- if (!WapiComparePN(pRecvPN, pLastRxPN)){
- WAPI_TRACE(WAPI_ERR, "%s: MSK PN is not larger than last, Dropped!!!\n", __FUNCTION__);
- WAPI_DATA(WAPI_ERR, "pRecvPN:", pRecvPN, 16);
- WAPI_DATA(WAPI_ERR, "pLastRxPN:", pLastRxPN, 16);
- return false;
- }
-
- memcpy(pLastRxPN, pRecvPN, 16);
- pMicKey = pWapiSta->wapiMsk.micKey;
- pDataKey = pWapiSta->wapiMsk.dataKey;
- }else if (pWapiSta->wapiMskUpdate.keyId == KeyIdx && pWapiSta->wapiMskUpdate.bSet){
- WAPI_TRACE(WAPI_RX, "%s: Use Updated MSK for Decryption !!!\n", __FUNCTION__);
- bUseUpdatedKey = true;
- memcpy(pWapiSta->lastRxMulticastPN, pRecvPN, 16);
- pMicKey = pWapiSta->wapiMskUpdate.micKey;
- pDataKey = pWapiSta->wapiMskUpdate.dataKey;
- }else{
- WAPI_TRACE(WAPI_ERR, "%s: Can not find MSK with matched KeyIdx(%d), Dropped !!!\n", __FUNCTION__,KeyIdx);
- return false;
- }
- }
- else{
- WAPI_TRACE(WAPI_RX, "%s: Unicast decryption !!!\n", __FUNCTION__);
- if (pWapiSta->wapiUsk.keyId == KeyIdx && pWapiSta->wapiUsk.bSet){
- WAPI_TRACE(WAPI_RX, "%s: Use USK for Decryption!!!\n", __FUNCTION__);
- if(precv_hdr->bWapiCheckPNInDecrypt){
- if(GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE){
- WapiGetLastRxUnicastPNForQoSData(TID, pWapiSta, lastRxPNforQoS);
- pLastRxPN = lastRxPNforQoS;
- }else{
- pLastRxPN = pWapiSta->lastRxUnicastPN;
- }
- if (!WapiComparePN(pRecvPN, pLastRxPN)){
- return false;
- }
- if(bQosData){
- WapiSetLastRxUnicastPNForQoSData(TID, pRecvPN, pWapiSta);
- }else{
- memcpy(pWapiSta->lastRxUnicastPN, pRecvPN, 16);
- }
- }else{
- memcpy(precv_hdr->WapiTempPN,pRecvPN,16);
- }
-
- if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE))
- {
- if ((pRecvPN[0] & 0x1) == 0){
- WAPI_TRACE(WAPI_ERR, "%s: Rx USK PN is not odd when Infra STA mode, Dropped !!!\n", __FUNCTION__);
- return false;
- }
- }
-
- pMicKey = pWapiSta->wapiUsk.micKey;
- pDataKey = pWapiSta->wapiUsk.dataKey;
- }
- else if (pWapiSta->wapiUskUpdate.keyId == KeyIdx && pWapiSta->wapiUskUpdate.bSet ){
- WAPI_TRACE(WAPI_RX, "%s: Use Updated USK for Decryption!!!\n", __FUNCTION__);
- if(pWapiSta->bAuthenticatorInUpdata)
- bUseUpdatedKey = true;
- else
- bUseUpdatedKey = false;
-
- if(bQosData){
- WapiSetLastRxUnicastPNForQoSData(TID, pRecvPN, pWapiSta);
- }else{
- memcpy(pWapiSta->lastRxUnicastPN, pRecvPN, 16);
- }
- pMicKey = pWapiSta->wapiUskUpdate.micKey;
- pDataKey = pWapiSta->wapiUskUpdate.dataKey;
- }else{
- WAPI_TRACE(WAPI_ERR, "%s: No valid USK!!!KeyIdx=%d pWapiSta->wapiUsk.keyId=%d pWapiSta->wapiUskUpdate.keyId=%d\n", __FUNCTION__, KeyIdx, pWapiSta->wapiUsk.keyId, pWapiSta->wapiUskUpdate.keyId);
- //dump_buf(pskb->data,pskb->len);
- return false;
- }
- }
-
- WAPI_DATA(WAPI_RX, "Decryption - DataKey", pDataKey, 16);
- WAPI_DATA(WAPI_RX, "Decryption - IV", pRecvPN, 16);
- WapiSMS4Decryption(pDataKey, pRecvPN, pSecData, DataLen, pSecData, &OutputLength);
-
- if (OutputLength != DataLen)
- WAPI_TRACE(WAPI_ERR, "%s: Output Length Error!!!!\n", __FUNCTION__);
-
- WAPI_DATA(WAPI_RX, "Decryption - After decryption", pskb->data, pskb->len);
-
- DataLen -= padapter->wapiInfo.extra_postfix_len;
-
- SecCalculateMicSMS4(KeyIdx, pMicKey, pskb->data, pSecData, DataLen, MicBuffer);
-
- WAPI_DATA(WAPI_RX, "Decryption - MIC received", pRecvMic, SMS4_MIC_LEN);
- WAPI_DATA(WAPI_RX, "Decryption - MIC calculated", MicBuffer, SMS4_MIC_LEN);
-
- if (0 == memcmp(MicBuffer, pRecvMic, padapter->wapiInfo.extra_postfix_len)){
- WAPI_TRACE(WAPI_RX, "%s: Check MIC OK!!\n", __FUNCTION__);
- if (bUseUpdatedKey){
- // delete the old key
- if ( IS_MCAST(pRA) ){
- WAPI_TRACE(WAPI_API, "%s(): AE use new update MSK!!\n", __FUNCTION__);
- pWapiSta->wapiMsk.keyId = pWapiSta->wapiMskUpdate.keyId;
- memcpy(pWapiSta->wapiMsk.dataKey, pWapiSta->wapiMskUpdate.dataKey, 16);
- memcpy(pWapiSta->wapiMsk.micKey, pWapiSta->wapiMskUpdate.micKey, 16);
- pWapiSta->wapiMskUpdate.bTxEnable = pWapiSta->wapiMskUpdate.bSet = false;
- }else{
- WAPI_TRACE(WAPI_API, "%s(): AE use new update USK!!\n", __FUNCTION__);
- pWapiSta->wapiUsk.keyId = pWapiSta->wapiUskUpdate.keyId;
- memcpy(pWapiSta->wapiUsk.dataKey, pWapiSta->wapiUskUpdate.dataKey, 16);
- memcpy(pWapiSta->wapiUsk.micKey, pWapiSta->wapiUskUpdate.micKey, 16);
- pWapiSta->wapiUskUpdate.bTxEnable = pWapiSta->wapiUskUpdate.bSet = false;
- }
- }
- }else{
- WAPI_TRACE(WAPI_ERR, "%s: Check MIC Error, Dropped !!!!\n", __FUNCTION__);
- return false;
- }
-
- pos = pskb->data;
- memmove(pos+padapter->wapiInfo.extra_prefix_len, pos, IVOffset);
- skb_pull(pskb, padapter->wapiInfo.extra_prefix_len);
-
- WAPI_TRACE(WAPI_RX, "<=========%s\n", __FUNCTION__);
-
- return true;
-}
-
-u32 rtw_sms4_encrypt(_adapter *padapter, u8 *pxmitframe)
-{
-
- u8 *pframe;
- u32 res = _SUCCESS;
-
- WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable))
- {
- WAPI_TRACE(WAPI_TX, "<========== %s, WAPI not supported or enabled!\n", __FUNCTION__);
- return _FAIL;
- }
-
- if(((struct xmit_frame*)pxmitframe)->buf_addr==NULL)
- return _FAIL;
-
- pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_OFFSET;
-
- SecSWSMS4Encryption(padapter, pxmitframe);
-
- WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
- return res;
-}
-
-u32 rtw_sms4_decrypt(_adapter *padapter, u8 *precvframe)
-{
- u8 *pframe;
- u32 res = _SUCCESS;
-
- WAPI_TRACE(WAPI_RX, "=========>%s\n", __FUNCTION__);
-
- if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable))
- {
- WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or enabled!\n", __FUNCTION__);
- return _FAIL;
- }
-
-
- //drop packet when hw decrypt fail
- //return tempraily
- return _FAIL;
-
- //pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data;
-
- if (false == SecSWSMS4Decryption(padapter, precvframe, &padapter->recvpriv))
- {
- WAPI_TRACE(WAPI_ERR, "%s():SMS4 decrypt frame error\n",__FUNCTION__);
- return _FAIL;
- }
-
- WAPI_TRACE(WAPI_RX, "<=========%s\n", __FUNCTION__);
- return res;
-}
-
-#else
-
-u32 rtw_sms4_encrypt(_adapter *padapter, u8 *pxmitframe)
-{
- WAPI_TRACE(WAPI_TX, "=========>Dummy %s\n", __FUNCTION__);
- WAPI_TRACE(WAPI_TX, "<=========Dummy %s\n", __FUNCTION__);
- return _SUCCESS;
-}
-
-u32 rtw_sms4_decrypt(_adapter *padapter, u8 *precvframe)
-{
- WAPI_TRACE(WAPI_RX, "=========>Dummy %s\n", __FUNCTION__);
- WAPI_TRACE(WAPI_RX, "<=========Dummy %s\n", __FUNCTION__);
- return _SUCCESS;
-}
-
-#endif
-
-#endif
+#ifdef CONFIG_WAPI_SUPPORT
+
+#include <linux/unistd.h>
+#include <linux/etherdevice.h>
+#include <drv_types.h>
+#include <rtw_wapi.h>
+
+
+#ifdef CONFIG_WAPI_SW_SMS4
+
+#define WAPI_LITTLE_ENDIAN
+//#define BIG_ENDIAN
+#define ENCRYPT 0
+#define DECRYPT 1
+
+
+/**********************************************************
+ **********************************************************/
+const u8 Sbox[256] = {
+0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05,
+0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99,
+0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62,
+0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6,
+0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8,
+0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35,
+0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87,
+0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e,
+0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1,
+0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3,
+0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f,
+0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51,
+0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8,
+0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0,
+0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84,
+0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48
+};
+
+const u32 CK[32] = {
+ 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
+ 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
+ 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
+ 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
+ 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
+ 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
+ 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
+ 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 };
+
+#define Rotl(_x, _y) (((_x) << (_y)) | ((_x) >> (32 - (_y))))
+
+#define ByteSub(_A) (Sbox[(_A) >> 24 & 0xFF] << 24 | \
+ Sbox[(_A) >> 16 & 0xFF] << 16 | \
+ Sbox[(_A) >> 8 & 0xFF] << 8 | \
+ Sbox[(_A) & 0xFF])
+
+#define L1(_B) ((_B) ^ Rotl(_B, 2) ^ Rotl(_B, 10) ^ Rotl(_B, 18) ^ Rotl(_B, 24))
+#define L2(_B) ((_B) ^ Rotl(_B, 13) ^ Rotl(_B, 23))
+
+static void
+xor_block(void *dst, void *src1, void *src2)
+/* 128-bit xor: *dst = *src1 xor *src2. Pointers must be 32-bit aligned */
+{
+ ((u32 *)dst)[0] = ((u32 *)src1)[0] ^ ((u32 *)src2)[0];
+ ((u32 *)dst)[1] = ((u32 *)src1)[1] ^ ((u32 *)src2)[1];
+ ((u32 *)dst)[2] = ((u32 *)src1)[2] ^ ((u32 *)src2)[2];
+ ((u32 *)dst)[3] = ((u32 *)src1)[3] ^ ((u32 *)src2)[3];
+}
+
+
+void SMS4Crypt(u8 *Input, u8 *Output, u32 *rk)
+{
+ u32 r, mid, x0, x1, x2, x3, *p;
+ p = (u32 *)Input;
+ x0 = p[0];
+ x1 = p[1];
+ x2 = p[2];
+ x3 = p[3];
+#ifdef WAPI_LITTLE_ENDIAN
+ x0 = Rotl(x0, 16); x0 = ((x0 & 0x00FF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
+ x1 = Rotl(x1, 16); x1 = ((x1 & 0x00FF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
+ x2 = Rotl(x2, 16); x2 = ((x2 & 0x00FF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
+ x3 = Rotl(x3, 16); x3 = ((x3 & 0x00FF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
+#endif
+ for (r = 0; r < 32; r += 4)
+ {
+ mid = x1 ^ x2 ^ x3 ^ rk[r + 0];
+ mid = ByteSub(mid);
+ x0 ^= L1(mid);
+ mid = x2 ^ x3 ^ x0 ^ rk[r + 1];
+ mid = ByteSub(mid);
+ x1 ^= L1(mid);
+ mid = x3 ^ x0 ^ x1 ^ rk[r + 2];
+ mid = ByteSub(mid);
+ x2 ^= L1(mid);
+ mid = x0 ^ x1 ^ x2 ^ rk[r + 3];
+ mid = ByteSub(mid);
+ x3 ^= L1(mid);
+ }
+#ifdef WAPI_LITTLE_ENDIAN
+ x0 = Rotl(x0, 16); x0 = ((x0 & 0x00FF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
+ x1 = Rotl(x1, 16); x1 = ((x1 & 0x00FF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
+ x2 = Rotl(x2, 16); x2 = ((x2 & 0x00FF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
+ x3 = Rotl(x3, 16); x3 = ((x3 & 0x00FF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
+#endif
+ p = (u32 *)Output;
+ p[0] = x3;
+ p[1] = x2;
+ p[2] = x1;
+ p[3] = x0;
+}
+
+
+
+void SMS4KeyExt(u8 *Key, u32 *rk, u32 CryptFlag)
+{
+ u32 r, mid, x0, x1, x2, x3, *p;
+
+ p = (u32 *)Key;
+ x0 = p[0];
+ x1 = p[1];
+ x2 = p[2];
+ x3 = p[3];
+#ifdef WAPI_LITTLE_ENDIAN
+ x0 = Rotl(x0, 16); x0 = ((x0 & 0xFF00FF) << 8) | ((x0 & 0xFF00FF00) >> 8);
+ x1 = Rotl(x1, 16); x1 = ((x1 & 0xFF00FF) << 8) | ((x1 & 0xFF00FF00) >> 8);
+ x2 = Rotl(x2, 16); x2 = ((x2 & 0xFF00FF) << 8) | ((x2 & 0xFF00FF00) >> 8);
+ x3 = Rotl(x3, 16); x3 = ((x3 & 0xFF00FF) << 8) | ((x3 & 0xFF00FF00) >> 8);
+#endif
+
+ x0 ^= 0xa3b1bac6;
+ x1 ^= 0x56aa3350;
+ x2 ^= 0x677d9197;
+ x3 ^= 0xb27022dc;
+ for (r = 0; r < 32; r += 4)
+ {
+ mid = x1 ^ x2 ^ x3 ^ CK[r + 0];
+ mid = ByteSub(mid);
+ rk[r + 0] = x0 ^= L2(mid);
+ mid = x2 ^ x3 ^ x0 ^ CK[r + 1];
+ mid = ByteSub(mid);
+ rk[r + 1] = x1 ^= L2(mid);
+ mid = x3 ^ x0 ^ x1 ^ CK[r + 2];
+ mid = ByteSub(mid);
+ rk[r + 2] = x2 ^= L2(mid);
+ mid = x0 ^ x1 ^ x2 ^ CK[r + 3];
+ mid = ByteSub(mid);
+ rk[r + 3] = x3 ^= L2(mid);
+ }
+ if (CryptFlag == DECRYPT)
+ {
+ for (r = 0; r < 16; r++)
+ mid = rk[r], rk[r] = rk[31 - r], rk[31 - r] = mid;
+ }
+}
+
+
+void WapiSMS4Cryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
+ u8 *Output, u16 *OutputLength, u32 CryptFlag)
+{
+ u32 blockNum,i,j, rk[32];
+ u16 remainder;
+ u8 blockIn[16],blockOut[16], tempIV[16], k;
+
+ *OutputLength = 0;
+ remainder = InputLength & 0x0F;
+ blockNum = InputLength >> 4;
+ if(remainder !=0)
+ blockNum++;
+ else
+ remainder = 16;
+
+ for(k=0;k<16;k++)
+ tempIV[k] = IV[15-k];
+
+ memcpy(blockIn, tempIV, 16);
+
+ SMS4KeyExt((u8 *)Key, rk,CryptFlag);
+
+ for(i=0; i<blockNum-1; i++)
+ {
+ SMS4Crypt((u8 *)blockIn, blockOut, rk);
+ xor_block(&Output[i*16], &Input[i*16], blockOut);
+ memcpy(blockIn,blockOut,16);
+ }
+
+ *OutputLength = i*16;
+
+ SMS4Crypt((u8 *)blockIn, blockOut, rk);
+
+ for(j=0; j<remainder; j++)
+ {
+ Output[i*16+j] = Input[i*16+j] ^ blockOut[j];
+ }
+ *OutputLength += remainder;
+
+}
+
+void WapiSMS4Encryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
+ u8 *Output, u16 *OutputLength)
+{
+
+ WapiSMS4Cryption(Key, IV, Input, InputLength, Output, OutputLength, ENCRYPT);
+}
+
+void WapiSMS4Decryption(u8 *Key, u8 *IV, u8 *Input, u16 InputLength,
+ u8 *Output, u16 *OutputLength)
+{
+ // OFB mode: is also ENCRYPT flag
+ WapiSMS4Cryption(Key, IV, Input, InputLength, Output, OutputLength, ENCRYPT);
+}
+
+void WapiSMS4CalculateMic(u8 *Key, u8 *IV, u8 *Input1, u8 Input1Length,
+ u8 *Input2, u16 Input2Length, u8 *Output, u8 *OutputLength)
+{
+ u32 blockNum, i, remainder, rk[32];
+ u8 BlockIn[16], BlockOut[16], TempBlock[16], tempIV[16], k;
+
+ *OutputLength = 0;
+ remainder = Input1Length & 0x0F;
+ blockNum = Input1Length >> 4;
+
+ for(k=0;k<16;k++)
+ tempIV[k] = IV[15-k];
+
+ memcpy(BlockIn, tempIV, 16);
+
+ SMS4KeyExt((u8 *)Key, rk, ENCRYPT);
+
+ SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
+
+ for(i=0; i<blockNum; i++){
+ xor_block(BlockIn, (Input1+i*16), BlockOut);
+ SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
+ }
+
+ if(remainder !=0){
+ memset(TempBlock, 0, 16);
+ memcpy(TempBlock, (Input1+blockNum*16), remainder);
+
+ xor_block(BlockIn, TempBlock, BlockOut);
+ SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
+ }
+
+ remainder = Input2Length & 0x0F;
+ blockNum = Input2Length >> 4;
+
+ for(i=0; i<blockNum; i++){
+ xor_block(BlockIn, (Input2+i*16), BlockOut);
+ SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
+ }
+
+ if(remainder !=0){
+ memset(TempBlock, 0, 16);
+ memcpy(TempBlock, (Input2+blockNum*16), remainder);
+
+ xor_block(BlockIn, TempBlock, BlockOut);
+ SMS4Crypt((u8 *)BlockIn, BlockOut, rk);
+ }
+
+ memcpy(Output, BlockOut, 16);
+ *OutputLength = 16;
+}
+
+void SecCalculateMicSMS4(
+ u8 KeyIdx,
+ u8 *MicKey,
+ u8 *pHeader,
+ u8 *pData,
+ u16 DataLen,
+ u8 *MicBuffer
+ )
+{
+#if 0
+ struct ieee80211_hdr_3addr_qos *header;
+ u8 TempBuf[34], TempLen = 32, MicLen, QosOffset, *IV;
+ u16 *pTemp, fc;
+
+ WAPI_TRACE(WAPI_TX|WAPI_RX, "=========>%s\n", __FUNCTION__);
+
+ header = (struct ieee80211_hdr_3addr_qos *)pHeader;
+ memset(TempBuf, 0, 34);
+ memcpy(TempBuf, pHeader, 2); //FrameCtrl
+ pTemp = (u16*)TempBuf;
+ *pTemp &= 0xc78f; //bit4,5,6,11,12,13
+
+ memcpy((TempBuf+2), (pHeader+4), 12); //Addr1, Addr2
+ memcpy((TempBuf+14), (pHeader+22), 2); // SeqCtrl
+ pTemp = (u16*)(TempBuf + 14);
+ *pTemp &= 0x000f;
+
+ memcpy((TempBuf+16), (pHeader+16), 6); //Addr3
+
+ fc = le16_to_cpu(header->frame_ctl);
+
+
+
+ if (GetFrDs((u16*)&fc) && GetToDs((u16 *)&fc))
+ {
+ memcpy((TempBuf+22), (pHeader+24), 6);
+ QosOffset = 30;
+ }else{
+ memset((TempBuf+22), 0, 6);
+ QosOffset = 24;
+ }
+
+ if((fc & 0x0088) == 0x0088){
+ memcpy((TempBuf+28), (pHeader+QosOffset), 2);
+ TempLen += 2;
+ //IV = pHeader + QosOffset + 2 + SNAP_SIZE + sizeof(u16) + 2;
+ IV = pHeader + QosOffset + 2 + 2;
+ }else{
+ IV = pHeader + QosOffset + 2;
+ //IV = pHeader + QosOffset + SNAP_SIZE + sizeof(u16) + 2;
+ }
+
+ TempBuf[TempLen-1] = (u8)(DataLen & 0xff);
+ TempBuf[TempLen-2] = (u8)((DataLen & 0xff00)>>8);
+ TempBuf[TempLen-4] = KeyIdx;
+
+ WAPI_DATA(WAPI_TX, "CalculateMic - KEY", MicKey, 16);
+ WAPI_DATA(WAPI_TX, "CalculateMic - IV", IV, 16);
+ WAPI_DATA(WAPI_TX, "CalculateMic - TempBuf", TempBuf, TempLen);
+ WAPI_DATA(WAPI_TX, "CalculateMic - pData", pData, DataLen);
+
+ WapiSMS4CalculateMic(MicKey, IV, TempBuf, TempLen,
+ pData, DataLen, MicBuffer, &MicLen);
+
+ if (MicLen != 16)
+ WAPI_TRACE(WAPI_ERR,"%s: MIC Length Error!!\n",__FUNCTION__);
+
+ WAPI_TRACE(WAPI_TX|WAPI_RX, "<=========%s\n", __FUNCTION__);
+#endif
+}
+
+/* AddCount: 1 or 2.
+ * If overflow, return 1,
+ * else return 0.
+ */
+u8 WapiIncreasePN(u8 *PN, u8 AddCount)
+{
+ u8 i;
+
+ if (NULL == PN)
+ return 1;
+ //YJ,test,091102
+ /*
+ if(AddCount == 2){
+ DBG_8192C("############################%s(): PN[0]=0x%x\n", __FUNCTION__, PN[0]);
+ if(PN[0] == 0x48){
+ PN[0] += AddCount;
+ return 1;
+ }else{
+ PN[0] += AddCount;
+ return 0;
+ }
+ }
+ */
+ //YJ,test,091102,end
+
+ for (i=0; i<16; i++)
+ {
+ if (PN[i] + AddCount <= 0xff)
+ {
+ PN[i] += AddCount;
+ return 0;
+ }
+ else
+ {
+ PN[i] += AddCount;
+ AddCount = 1;
+ }
+ }
+ return 1;
+}
+
+
+void WapiGetLastRxUnicastPNForQoSData(
+ u8 UserPriority,
+ PRT_WAPI_STA_INFO pWapiStaInfo,
+ u8 *PNOut
+)
+{
+ WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
+ switch(UserPriority)
+ {
+ case 0:
+ case 3:
+ memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNBEQueue,16);
+ break;
+ case 1:
+ case 2:
+ memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNBKQueue,16);
+ break;
+ case 4:
+ case 5:
+ memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNVIQueue,16);
+ break;
+ case 6:
+ case 7:
+ memcpy(PNOut,pWapiStaInfo->lastRxUnicastPNVOQueue,16);
+ break;
+ default:
+ WAPI_TRACE(WAPI_ERR, "%s: Unknown TID \n", __FUNCTION__);
+ break;
+ }
+ WAPI_TRACE(WAPI_RX, "<=========== %s\n", __FUNCTION__);
+}
+
+
+void WapiSetLastRxUnicastPNForQoSData(
+ u8 UserPriority,
+ u8 *PNIn,
+ PRT_WAPI_STA_INFO pWapiStaInfo
+)
+{
+ WAPI_TRACE(WAPI_RX, "===========> %s\n", __FUNCTION__);
+ switch(UserPriority)
+ {
+ case 0:
+ case 3:
+ memcpy(pWapiStaInfo->lastRxUnicastPNBEQueue,PNIn,16);
+ break;
+ case 1:
+ case 2:
+ memcpy(pWapiStaInfo->lastRxUnicastPNBKQueue,PNIn,16);
+ break;
+ case 4:
+ case 5:
+ memcpy(pWapiStaInfo->lastRxUnicastPNVIQueue,PNIn,16);
+ break;
+ case 6:
+ case 7:
+ memcpy(pWapiStaInfo->lastRxUnicastPNVOQueue,PNIn,16);
+ break;
+ default:
+ WAPI_TRACE(WAPI_ERR, "%s: Unknown TID \n", __FUNCTION__);
+ break;
+ }
+ WAPI_TRACE(WAPI_RX, "<=========== %s\n", __FUNCTION__);
+}
+
+
+/****************************************************************************
+ FALSE not RX-Reorder
+ TRUE do RX Reorder
+add to support WAPI to N-mode
+*****************************************************************************/
+u8 WapiCheckPnInSwDecrypt(
+ _adapter *padapter,
+ struct sk_buff *pskb
+)
+{
+ u8 ret = false;
+
+#if 0
+ struct ieee80211_hdr_3addr_qos *header;
+ u16 fc;
+ u8 *pDaddr, *pTaddr, *pRaddr;
+
+ header = (struct ieee80211_hdr_3addr_qos *)pskb->data;
+ pTaddr = header->addr2;
+ pRaddr = header->addr1;
+ fc = le16_to_cpu(header->frame_ctl);
+
+ if(GetToDs(&fc))
+ pDaddr = header->addr3;
+ else
+ pDaddr = header->addr1;
+
+ if ((_rtw_memcmp(pRaddr, padapter->pnetdev->dev_addr, ETH_ALEN) == 0)
+ && ! (pDaddr)
+ && (GetFrameType(&fc) == WIFI_QOS_DATA_TYPE))
+ //&& ieee->pHTInfo->bCurrentHTSupport &&
+ //ieee->pHTInfo->bCurRxReorderEnable)
+ ret = false;
+ else
+ ret = true;
+#endif
+ WAPI_TRACE(WAPI_RX, "%s: return %d\n", __FUNCTION__, ret);
+ return ret;
+}
+
+int SecSMS4HeaderFillIV(_adapter *padapter, u8 *pxmitframe)
+{
+ struct pkt_attrib *pattrib = &((struct xmit_frame*)pxmitframe)->attrib;
+ u8 * frame = ((struct xmit_frame *)pxmitframe)->buf_addr + TXDESC_OFFSET;
+ u8 *pSecHeader = NULL, *pos = NULL, *pRA = NULL;
+ u8 bPNOverflow = false, bFindMatchPeer = false, hdr_len = 0;
+ PWLAN_HEADER_WAPI_EXTENSION pWapiExt = NULL;
+ PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
+ PRT_WAPI_STA_INFO pWapiSta = NULL;
+ int ret = 0;
+
+ WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
+
+ return ret;
+#if 0
+ hdr_len = sMacHdrLng;
+ if (GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE)
+ {
+ hdr_len += 2;
+ }
+ //hdr_len += SNAP_SIZE + sizeof(u16);
+
+ pos = skb_push(pskb, padapter->wapiInfo.extra_prefix_len);
+ memmove(pos, pos+padapter->wapiInfo.extra_prefix_len, hdr_len);
+
+ pSecHeader = pskb->data + hdr_len;
+ pWapiExt = (PWLAN_HEADER_WAPI_EXTENSION)pSecHeader;
+ pRA = pskb->data + 4;
+
+ WAPI_DATA(WAPI_TX, "FillIV - Before Fill IV", pskb->data, pskb->len);
+
+ //Address 1 is always receiver's address
+ if( IS_MCAST(pRA) ){
+ if(!pWapiInfo->wapiTxMsk.bTxEnable){
+ WAPI_TRACE(WAPI_ERR,"%s: bTxEnable = 0!!\n",__FUNCTION__);
+ return -2;
+ }
+ if(pWapiInfo->wapiTxMsk.keyId <= 1){
+ pWapiExt->KeyIdx = pWapiInfo->wapiTxMsk.keyId;
+ pWapiExt->Reserved = 0;
+ bPNOverflow = WapiIncreasePN(pWapiInfo->lastTxMulticastPN, 1);
+ memcpy(pWapiExt->PN, pWapiInfo->lastTxMulticastPN, 16);
+ if (bPNOverflow){
+ // Update MSK Notification.
+ WAPI_TRACE(WAPI_ERR,"===============>%s():multicast PN overflow\n",__FUNCTION__);
+ rtw_wapi_app_event_handler(padapter,NULL,0,pRA, false, false, true, 0, false);
+ }
+ }else{
+ WAPI_TRACE(WAPI_ERR,"%s: Invalid Wapi Multicast KeyIdx!!\n",__FUNCTION__);
+ ret = -3;
+ }
+ }
+ else{
+ list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
+ if(!memcmp(pWapiSta->PeerMacAddr,pRA,6)){
+ bFindMatchPeer = true;
+ break;
+ }
+ }
+ if (bFindMatchPeer){
+ if((!pWapiSta->wapiUskUpdate.bTxEnable) && (!pWapiSta->wapiUsk.bTxEnable)){
+ WAPI_TRACE(WAPI_ERR,"%s: bTxEnable = 0!!\n",__FUNCTION__);
+ return -4;
+ }
+ if (pWapiSta->wapiUsk.keyId <= 1){
+ if(pWapiSta->wapiUskUpdate.bTxEnable)
+ pWapiExt->KeyIdx = pWapiSta->wapiUskUpdate.keyId;
+ else
+ pWapiExt->KeyIdx = pWapiSta->wapiUsk.keyId;
+
+ pWapiExt->Reserved = 0;
+ bPNOverflow = WapiIncreasePN(pWapiSta->lastTxUnicastPN, 2);
+ memcpy(pWapiExt->PN, pWapiSta->lastTxUnicastPN, 16);
+ if (bPNOverflow){
+ // Update USK Notification.
+ WAPI_TRACE(WAPI_ERR,"===============>%s():unicast PN overflow\n",__FUNCTION__);
+ rtw_wapi_app_event_handler(padapter,NULL,0,pWapiSta->PeerMacAddr, false, true, false, 0, false);
+ }
+ }else{
+ WAPI_TRACE(WAPI_ERR,"%s: Invalid Wapi Unicast KeyIdx!!\n",__FUNCTION__);
+ ret = -5;
+ }
+ }
+ else{
+ WAPI_TRACE(WAPI_ERR,"%s: Can not find Peer Sta "MAC_FMT"!!\n",__FUNCTION__, MAC_ARG(pRA));
+ ret = -6;
+ }
+ }
+
+ WAPI_DATA(WAPI_TX, "FillIV - After Fill IV", pskb->data, pskb->len);
+ WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
+ return ret;
+#endif
+}
+
+// WAPI SW Enc: must have done Coalesce!
+void SecSWSMS4Encryption(
+ _adapter *padapter,
+ u8 * pxmitframe
+ )
+{
+ PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
+ PRT_WAPI_STA_INFO pWapiSta = NULL;
+ u8 *pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_SIZE;
+ struct pkt_attrib *pattrib = &((struct xmit_frame*)pxmitframe)->attrib;
+
+ u8 *SecPtr = NULL, *pRA, *pMicKey = NULL, *pDataKey = NULL, *pIV = NULL;
+ u8 IVOffset, DataOffset, bFindMatchPeer = false, KeyIdx = 0, MicBuffer[16];
+ u16 OutputLength;
+
+ WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
+
+ WAPI_TRACE(WAPI_TX,"hdrlen: %d \n",pattrib->hdrlen);
+
+ return;
+
+ DataOffset = pattrib->hdrlen + pattrib->iv_len;
+
+ pRA = pframe + 4;
+
+
+ if( IS_MCAST(pRA) ){
+ KeyIdx = pWapiInfo->wapiTxMsk.keyId;
+ pIV = pWapiInfo->lastTxMulticastPN;
+ pMicKey = pWapiInfo->wapiTxMsk.micKey;
+ pDataKey = pWapiInfo->wapiTxMsk.dataKey;
+ }else{
+ if (!list_empty(&(pWapiInfo->wapiSTAUsedList))){
+ list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
+ if (0 == memcmp(pWapiSta->PeerMacAddr, pRA, 6)){
+ bFindMatchPeer = true;
+ break;
+ }
+ }
+
+ if (bFindMatchPeer){
+ if (pWapiSta->wapiUskUpdate.bTxEnable){
+ KeyIdx = pWapiSta->wapiUskUpdate.keyId;
+ WAPI_TRACE(WAPI_TX, "%s(): Use update USK!! KeyIdx=%d\n", __FUNCTION__, KeyIdx);
+ pIV = pWapiSta->lastTxUnicastPN;
+ pMicKey = pWapiSta->wapiUskUpdate.micKey;
+ pDataKey = pWapiSta->wapiUskUpdate.dataKey;
+ }else{
+ KeyIdx = pWapiSta->wapiUsk.keyId;
+ WAPI_TRACE(WAPI_TX, "%s(): Use USK!! KeyIdx=%d\n", __FUNCTION__, KeyIdx);
+ pIV = pWapiSta->lastTxUnicastPN;
+ pMicKey = pWapiSta->wapiUsk.micKey;
+ pDataKey = pWapiSta->wapiUsk.dataKey;
+ }
+ }else{
+ WAPI_TRACE(WAPI_ERR,"%s: Can not find Peer Sta!!\n",__FUNCTION__);
+ return;
+ }
+ }else{
+ WAPI_TRACE(WAPI_ERR,"%s: wapiSTAUsedList is empty!!\n",__FUNCTION__);
+ return;
+ }
+ }
+
+ SecPtr = pframe;
+ SecCalculateMicSMS4(KeyIdx, pMicKey, SecPtr, (SecPtr+DataOffset), pattrib->pktlen, MicBuffer);
+
+ WAPI_DATA(WAPI_TX, "Encryption - MIC", MicBuffer, padapter->wapiInfo.extra_postfix_len);
+
+ memcpy(pframe+pattrib->hdrlen+pattrib->iv_len+pattrib->pktlen-pattrib->icv_len,
+ (u8 *)MicBuffer,
+ padapter->wapiInfo.extra_postfix_len
+ );
+
+
+ WapiSMS4Encryption(pDataKey, pIV, (SecPtr+DataOffset),pattrib->pktlen+pattrib->icv_len, (SecPtr+DataOffset), &OutputLength);
+
+ WAPI_DATA(WAPI_TX, "Encryption - After SMS4 encryption",pframe,pattrib->hdrlen+pattrib->iv_len+pattrib->pktlen);
+
+ WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
+}
+
+u8 SecSWSMS4Decryption(
+ _adapter *padapter,
+ u8 *precv_frame,
+ struct recv_priv *precv_priv
+ )
+{
+ PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
+ struct recv_frame_hdr *precv_hdr;
+ PRT_WAPI_STA_INFO pWapiSta = NULL;
+ u8 IVOffset, DataOffset, bFindMatchPeer = false, bUseUpdatedKey = false;
+ u8 KeyIdx, MicBuffer[16], lastRxPNforQoS[16];
+ u8 *pRA, *pTA, *pMicKey, *pDataKey, *pLastRxPN, *pRecvPN, *pSecData, *pRecvMic, *pos;
+ u8 TID = 0;
+ u16 OutputLength, DataLen;
+ u8 bQosData;
+ struct sk_buff * pskb;
+
+ WAPI_TRACE(WAPI_RX, "=========>%s\n", __FUNCTION__);
+
+ return 0;
+
+ precv_hdr = &((union recv_frame*)precv_frame)->u.hdr;
+ pskb = (struct sk_buff *)(precv_hdr->rx_data);
+ precv_hdr->bWapiCheckPNInDecrypt = WapiCheckPnInSwDecrypt(padapter, pskb);
+ WAPI_TRACE(WAPI_RX, "=========>%s: check PN %d\n", __FUNCTION__,precv_hdr->bWapiCheckPNInDecrypt);
+ WAPI_DATA(WAPI_RX, "Decryption - Before decryption", pskb->data, pskb->len);
+
+ IVOffset = sMacHdrLng;
+ bQosData = GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE;
+ if (bQosData){
+ IVOffset += 2;
+ }
+
+ //if(GetHTC())
+ // IVOffset += 4;
+
+ //IVOffset += SNAP_SIZE + sizeof(u16);
+
+ DataOffset = IVOffset + padapter->wapiInfo.extra_prefix_len;
+
+ pRA = pskb->data + 4;
+ pTA = pskb->data + 10;
+ KeyIdx = *(pskb->data + IVOffset);
+ pRecvPN = pskb->data + IVOffset + 2;
+ pSecData = pskb->data + DataOffset;
+ DataLen = pskb->len - DataOffset;
+ pRecvMic = pskb->data + pskb->len - padapter->wapiInfo.extra_postfix_len;
+ TID = GetTid(pskb->data);
+
+ if (!list_empty(&(pWapiInfo->wapiSTAUsedList))){
+ list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
+ if (0 == memcmp(pWapiSta->PeerMacAddr, pTA, 6)){
+ bFindMatchPeer = true;
+ break;
+ }
+ }
+ }
+
+ if (!bFindMatchPeer){
+ WAPI_TRACE(WAPI_ERR, "%s: Can not find Peer Sta "MAC_FMT" for Key Info!!!\n", __FUNCTION__, MAC_ARG(pTA));
+ return false;
+ }
+
+ if( IS_MCAST(pRA) ){
+ WAPI_TRACE(WAPI_RX, "%s: Multicast decryption !!!\n", __FUNCTION__);
+ if (pWapiSta->wapiMsk.keyId == KeyIdx && pWapiSta->wapiMsk.bSet){
+ pLastRxPN = pWapiSta->lastRxMulticastPN;
+ if (!WapiComparePN(pRecvPN, pLastRxPN)){
+ WAPI_TRACE(WAPI_ERR, "%s: MSK PN is not larger than last, Dropped!!!\n", __FUNCTION__);
+ WAPI_DATA(WAPI_ERR, "pRecvPN:", pRecvPN, 16);
+ WAPI_DATA(WAPI_ERR, "pLastRxPN:", pLastRxPN, 16);
+ return false;
+ }
+
+ memcpy(pLastRxPN, pRecvPN, 16);
+ pMicKey = pWapiSta->wapiMsk.micKey;
+ pDataKey = pWapiSta->wapiMsk.dataKey;
+ }else if (pWapiSta->wapiMskUpdate.keyId == KeyIdx && pWapiSta->wapiMskUpdate.bSet){
+ WAPI_TRACE(WAPI_RX, "%s: Use Updated MSK for Decryption !!!\n", __FUNCTION__);
+ bUseUpdatedKey = true;
+ memcpy(pWapiSta->lastRxMulticastPN, pRecvPN, 16);
+ pMicKey = pWapiSta->wapiMskUpdate.micKey;
+ pDataKey = pWapiSta->wapiMskUpdate.dataKey;
+ }else{
+ WAPI_TRACE(WAPI_ERR, "%s: Can not find MSK with matched KeyIdx(%d), Dropped !!!\n", __FUNCTION__,KeyIdx);
+ return false;
+ }
+ }
+ else{
+ WAPI_TRACE(WAPI_RX, "%s: Unicast decryption !!!\n", __FUNCTION__);
+ if (pWapiSta->wapiUsk.keyId == KeyIdx && pWapiSta->wapiUsk.bSet){
+ WAPI_TRACE(WAPI_RX, "%s: Use USK for Decryption!!!\n", __FUNCTION__);
+ if(precv_hdr->bWapiCheckPNInDecrypt){
+ if(GetFrameType(pskb->data) == WIFI_QOS_DATA_TYPE){
+ WapiGetLastRxUnicastPNForQoSData(TID, pWapiSta, lastRxPNforQoS);
+ pLastRxPN = lastRxPNforQoS;
+ }else{
+ pLastRxPN = pWapiSta->lastRxUnicastPN;
+ }
+ if (!WapiComparePN(pRecvPN, pLastRxPN)){
+ return false;
+ }
+ if(bQosData){
+ WapiSetLastRxUnicastPNForQoSData(TID, pRecvPN, pWapiSta);
+ }else{
+ memcpy(pWapiSta->lastRxUnicastPN, pRecvPN, 16);
+ }
+ }else{
+ memcpy(precv_hdr->WapiTempPN,pRecvPN,16);
+ }
+
+ if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE))
+ {
+ if ((pRecvPN[0] & 0x1) == 0){
+ WAPI_TRACE(WAPI_ERR, "%s: Rx USK PN is not odd when Infra STA mode, Dropped !!!\n", __FUNCTION__);
+ return false;
+ }
+ }
+
+ pMicKey = pWapiSta->wapiUsk.micKey;
+ pDataKey = pWapiSta->wapiUsk.dataKey;
+ }
+ else if (pWapiSta->wapiUskUpdate.keyId == KeyIdx && pWapiSta->wapiUskUpdate.bSet ){
+ WAPI_TRACE(WAPI_RX, "%s: Use Updated USK for Decryption!!!\n", __FUNCTION__);
+ if(pWapiSta->bAuthenticatorInUpdata)
+ bUseUpdatedKey = true;
+ else
+ bUseUpdatedKey = false;
+
+ if(bQosData){
+ WapiSetLastRxUnicastPNForQoSData(TID, pRecvPN, pWapiSta);
+ }else{
+ memcpy(pWapiSta->lastRxUnicastPN, pRecvPN, 16);
+ }
+ pMicKey = pWapiSta->wapiUskUpdate.micKey;
+ pDataKey = pWapiSta->wapiUskUpdate.dataKey;
+ }else{
+ WAPI_TRACE(WAPI_ERR, "%s: No valid USK!!!KeyIdx=%d pWapiSta->wapiUsk.keyId=%d pWapiSta->wapiUskUpdate.keyId=%d\n", __FUNCTION__, KeyIdx, pWapiSta->wapiUsk.keyId, pWapiSta->wapiUskUpdate.keyId);
+ //dump_buf(pskb->data,pskb->len);
+ return false;
+ }
+ }
+
+ WAPI_DATA(WAPI_RX, "Decryption - DataKey", pDataKey, 16);
+ WAPI_DATA(WAPI_RX, "Decryption - IV", pRecvPN, 16);
+ WapiSMS4Decryption(pDataKey, pRecvPN, pSecData, DataLen, pSecData, &OutputLength);
+
+ if (OutputLength != DataLen)
+ WAPI_TRACE(WAPI_ERR, "%s: Output Length Error!!!!\n", __FUNCTION__);
+
+ WAPI_DATA(WAPI_RX, "Decryption - After decryption", pskb->data, pskb->len);
+
+ DataLen -= padapter->wapiInfo.extra_postfix_len;
+
+ SecCalculateMicSMS4(KeyIdx, pMicKey, pskb->data, pSecData, DataLen, MicBuffer);
+
+ WAPI_DATA(WAPI_RX, "Decryption - MIC received", pRecvMic, SMS4_MIC_LEN);
+ WAPI_DATA(WAPI_RX, "Decryption - MIC calculated", MicBuffer, SMS4_MIC_LEN);
+
+ if (0 == memcmp(MicBuffer, pRecvMic, padapter->wapiInfo.extra_postfix_len)){
+ WAPI_TRACE(WAPI_RX, "%s: Check MIC OK!!\n", __FUNCTION__);
+ if (bUseUpdatedKey){
+ // delete the old key
+ if ( IS_MCAST(pRA) ){
+ WAPI_TRACE(WAPI_API, "%s(): AE use new update MSK!!\n", __FUNCTION__);
+ pWapiSta->wapiMsk.keyId = pWapiSta->wapiMskUpdate.keyId;
+ memcpy(pWapiSta->wapiMsk.dataKey, pWapiSta->wapiMskUpdate.dataKey, 16);
+ memcpy(pWapiSta->wapiMsk.micKey, pWapiSta->wapiMskUpdate.micKey, 16);
+ pWapiSta->wapiMskUpdate.bTxEnable = pWapiSta->wapiMskUpdate.bSet = false;
+ }else{
+ WAPI_TRACE(WAPI_API, "%s(): AE use new update USK!!\n", __FUNCTION__);
+ pWapiSta->wapiUsk.keyId = pWapiSta->wapiUskUpdate.keyId;
+ memcpy(pWapiSta->wapiUsk.dataKey, pWapiSta->wapiUskUpdate.dataKey, 16);
+ memcpy(pWapiSta->wapiUsk.micKey, pWapiSta->wapiUskUpdate.micKey, 16);
+ pWapiSta->wapiUskUpdate.bTxEnable = pWapiSta->wapiUskUpdate.bSet = false;
+ }
+ }
+ }else{
+ WAPI_TRACE(WAPI_ERR, "%s: Check MIC Error, Dropped !!!!\n", __FUNCTION__);
+ return false;
+ }
+
+ pos = pskb->data;
+ memmove(pos+padapter->wapiInfo.extra_prefix_len, pos, IVOffset);
+ skb_pull(pskb, padapter->wapiInfo.extra_prefix_len);
+
+ WAPI_TRACE(WAPI_RX, "<=========%s\n", __FUNCTION__);
+
+ return true;
+}
+
+u32 rtw_sms4_encrypt(_adapter *padapter, u8 *pxmitframe)
+{
+
+ u8 *pframe;
+ u32 res = _SUCCESS;
+
+ WAPI_TRACE(WAPI_TX, "=========>%s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_TX, "<========== %s, WAPI not supported or enabled!\n", __FUNCTION__);
+ return _FAIL;
+ }
+
+ if(((struct xmit_frame*)pxmitframe)->buf_addr==NULL)
+ return _FAIL;
+
+ pframe = ((struct xmit_frame*)pxmitframe)->buf_addr + TXDESC_OFFSET;
+
+ SecSWSMS4Encryption(padapter, pxmitframe);
+
+ WAPI_TRACE(WAPI_TX, "<=========%s\n", __FUNCTION__);
+ return res;
+}
+
+u32 rtw_sms4_decrypt(_adapter *padapter, u8 *precvframe)
+{
+ u8 *pframe;
+ u32 res = _SUCCESS;
+
+ WAPI_TRACE(WAPI_RX, "=========>%s\n", __FUNCTION__);
+
+ if ((!padapter->WapiSupport) || (!padapter->wapiInfo.bWapiEnable))
+ {
+ WAPI_TRACE(WAPI_RX, "<========== %s, WAPI not supported or enabled!\n", __FUNCTION__);
+ return _FAIL;
+ }
+
+
+ //drop packet when hw decrypt fail
+ //return tempraily
+ return _FAIL;
+
+ //pframe=(unsigned char *)((union recv_frame*)precvframe)->u.hdr.rx_data;
+
+ if (false == SecSWSMS4Decryption(padapter, precvframe, &padapter->recvpriv))
+ {
+ WAPI_TRACE(WAPI_ERR, "%s():SMS4 decrypt frame error\n",__FUNCTION__);
+ return _FAIL;
+ }
+
+ WAPI_TRACE(WAPI_RX, "<=========%s\n", __FUNCTION__);
+ return res;
+}
+
+#else
+
+u32 rtw_sms4_encrypt(_adapter *padapter, u8 *pxmitframe)
+{
+ WAPI_TRACE(WAPI_TX, "=========>Dummy %s\n", __FUNCTION__);
+ WAPI_TRACE(WAPI_TX, "<=========Dummy %s\n", __FUNCTION__);
+ return _SUCCESS;
+}
+
+u32 rtw_sms4_decrypt(_adapter *padapter, u8 *precvframe)
+{
+ WAPI_TRACE(WAPI_RX, "=========>Dummy %s\n", __FUNCTION__);
+ WAPI_TRACE(WAPI_RX, "<=========Dummy %s\n", __FUNCTION__);
+ return _SUCCESS;
+}
+
+#endif
+
+#endif
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_wlan_util.c b/drivers/net/wireless/rtl8723as/core/rtw_wlan_util.c
index 182865daaab0..8615468f2648 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_wlan_util.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_wlan_util.c
@@ -24,6 +24,9 @@
#include <drv_types.h>
#include <wifi.h>
+#ifdef CONFIG_WOWLAN
+#include <linux/inetdevice.h>
+#endif
unsigned char ARTHEROS_OUI1[] = {0x00, 0x03, 0x7f};
unsigned char ARTHEROS_OUI2[] = {0x00, 0x13, 0x74};
@@ -361,66 +364,21 @@ void UpdateBrateTblForSoftAP(u8 *bssrateset, u32 bssratelen)
void Save_DM_Func_Flag(_adapter *padapter)
{
u8 bSaveFlag = _TRUE;
-
-#ifdef CONFIG_CONCURRENT_MODE
- _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
- if(pbuddy_adapter)
- rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag));
-#endif
-
rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag));
-
}
void Restore_DM_Func_Flag(_adapter *padapter)
{
u8 bSaveFlag = _FALSE;
-#ifdef CONFIG_CONCURRENT_MODE
- _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
- if(pbuddy_adapter)
- rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag));
-#endif
rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_OP, (u8 *)(&bSaveFlag));
}
void Switch_DM_Func(_adapter *padapter, u32 mode, u8 enable)
{
-#ifdef CONFIG_CONCURRENT_MODE
- _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
-#endif
-
if(enable == _TRUE)
- {
-#ifdef CONFIG_CONCURRENT_MODE
- if(pbuddy_adapter)
- rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_DM_FUNC_SET, (u8 *)(&mode));
-#endif
rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_SET, (u8 *)(&mode));
- }
else
- {
-#ifdef CONFIG_CONCURRENT_MODE
- if(pbuddy_adapter)
- rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode));
-#endif
rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode));
- }
-
-#if 0
- u8 val8;
-
- val8 = rtw_read8(padapter, FW_DYNAMIC_FUN_SWITCH);
-
- if(enable == _TRUE)
- {
- rtw_write8(padapter, FW_DYNAMIC_FUN_SWITCH, (val8 | mode));
- }
- else
- {
- rtw_write8(padapter, FW_DYNAMIC_FUN_SWITCH, (val8 & mode));
- }
-#endif
-
}
static void Set_NETYPE1_MSR(_adapter *padapter, u8 type)
@@ -454,6 +412,9 @@ inline u8 rtw_get_oper_ch(_adapter *adapter)
inline void rtw_set_oper_ch(_adapter *adapter, u8 ch)
{
+ if (adapter_to_dvobj(adapter)->oper_channel != ch)
+ adapter_to_dvobj(adapter)->on_oper_ch_time = rtw_get_current_time();
+
adapter_to_dvobj(adapter)->oper_channel = ch;
}
@@ -477,6 +438,19 @@ inline void rtw_set_oper_choffset(_adapter *adapter, u8 offset)
adapter_to_dvobj(adapter)->oper_ch_offset = offset;
}
+inline u32 rtw_get_on_oper_ch_time(_adapter *adapter)
+{
+ return adapter_to_dvobj(adapter)->on_oper_ch_time;
+}
+
+inline u32 rtw_get_on_cur_ch_time(_adapter *adapter)
+{
+ if (adapter->mlmeextpriv.cur_channel == adapter_to_dvobj(adapter)->oper_channel)
+ return adapter_to_dvobj(adapter)->on_oper_ch_time;
+ else
+ return 0;
+}
+
void SelectChannel(_adapter *padapter, unsigned char channel)
{
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
@@ -707,20 +681,25 @@ static u32 _ReadCAM(_adapter *padapter ,u32 addr)
return rtw_read32(padapter,REG_CAMREAD);
}
+#endif
void read_cam(_adapter *padapter ,u8 entry)
{
- u32 j,count = 0, addr, cmd;
+ u32 j,count = 0, addr;
+ u32 cam_val[2]; //cam_val[0] is read_val, cam_val[1] is the address
addr = entry << 3;
DBG_8192C("********* DUMP CAM Entry_#%02d***************\n",entry);
for (j = 0; j < 6; j++)
{
- cmd = _ReadCAM(padapter ,addr+j);
- DBG_8192C("offset:0x%02x => 0x%08x \n",addr+j,cmd);
+ //cmd = _ReadCAM(padapter ,addr+j);
+ //HW_VAR_CAM_READ
+ cam_val[1]=addr+j;
+ rtw_hal_get_hwreg(padapter, HW_VAR_CAM_READ, (u8 *)cam_val);
+ DBG_8192C("offset:0x%02x => 0x%08x \n",addr+j,cam_val[0]);
}
DBG_8192C("*********************************\n");
}
-#endif
+
void write_cam(_adapter *padapter, u8 entry, u16 ctrl, u8 *mac, u8 *key)
{
@@ -2612,4 +2591,72 @@ int rtw_handle_dualmac(_adapter *adapter, bool init)
exit:
return status;
}
+#ifdef CONFIG_WOWLAN
+void rtw_get_current_ip_address(PADAPTER padapter, u8 *pcurrentip)
+{
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct in_device *my_ip_ptr = padapter->pnetdev->ip_ptr;
+ u8 ipaddress[4];
+
+ if ( (pmlmeinfo->state & WIFI_FW_LINKING_STATE) ) {
+ if ( my_ip_ptr != NULL ) {
+ struct in_ifaddr *my_ifa_list = my_ip_ptr->ifa_list ;
+ if ( my_ifa_list != NULL ) {
+ ipaddress[0] = my_ifa_list->ifa_address & 0xFF;
+ ipaddress[1] = (my_ifa_list->ifa_address >> 8) & 0xFF;
+ ipaddress[2] = (my_ifa_list->ifa_address >> 16) & 0xFF;
+ ipaddress[3] = my_ifa_list->ifa_address >> 24;
+ DBG_871X("%s: %d.%d.%d.%d ==========\n", __func__,
+ ipaddress[0], ipaddress[1], ipaddress[2], ipaddress[3]);
+ _rtw_memcpy(pcurrentip, ipaddress, 4);
+ }
+ }
+ }
+}
+void rtw_get_sec_iv(PADAPTER padapter, u8*pcur_dot11txpn, u8 *StaAddr)
+{
+ struct sta_info *psta;
+ struct security_priv *psecpriv = &padapter->securitypriv;
+
+ _rtw_memset(pcur_dot11txpn, 0, 8);
+ if(NULL == StaAddr)
+ return;
+ psta = rtw_get_stainfo(&padapter->stapriv, StaAddr);
+ DBG_871X("%s(): StaAddr: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
+ __func__, StaAddr[0], StaAddr[1], StaAddr[2], StaAddr[3], StaAddr[4], StaAddr[5]);
+ if(psta)
+ {
+ if (psecpriv->dot11PrivacyAlgrthm != _NO_PRIVACY_ && psta->dot11txpn.val > 0)
+ psta->dot11txpn.val--;
+
+ _rtw_memcpy(pcur_dot11txpn, (u8*)&psta->dot11txpn, 8);
+
+ DBG_871X("%s(): CurrentIV: 0x%016llx\n", __func__, psta->dot11txpn.val);
+ }
+}
+void rtw_set_sec_iv(PADAPTER padapter)
+{
+ struct sta_info *psta;
+ struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
+ struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
+ struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
+ struct security_priv *psecpriv = &padapter->securitypriv;
+
+ psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&pmlmeinfo->network));
+
+ if(psta)
+ {
+ if (pwrpriv->wowlan_fw_iv > psta->dot11txpn.val)
+ {
+ if (psecpriv->dot11PrivacyAlgrthm != _NO_PRIVACY_)
+ psta->dot11txpn.val = pwrpriv->wowlan_fw_iv + 2;
+ } else {
+ DBG_871X("%s(): FW IV is smaller than driver\n", __func__);
+ psta->dot11txpn.val += 2;
+ }
+ DBG_871X("%s: dot11txpn: 0x%016llx\n", __func__ ,psta->dot11txpn.val);
+ }
+}
+#endif //CONFIG_WOWLAN
diff --git a/drivers/net/wireless/rtl8723as/core/rtw_xmit.c b/drivers/net/wireless/rtl8723as/core/rtw_xmit.c
index 0ba3bce864fb..73043534f56c 100755
--- a/drivers/net/wireless/rtl8723as/core/rtw_xmit.c
+++ b/drivers/net/wireless/rtl8723as/core/rtw_xmit.c
@@ -1960,6 +1960,244 @@ _func_exit_;
return res;
}
+#ifdef CONFIG_IEEE80211W
+//broadcast or multicast management pkt use BIP, unicast management pkt use CCMP encryption
+s32 rtw_mgmt_xmitframe_coalesce(_adapter *padapter, _pkt *pkt, struct xmit_frame *pxmitframe)
+{
+ struct pkt_file pktfile;
+ s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
+ SIZE_PTR addr;
+ u8 *pframe, *mem_start = NULL, *tmp_buf=NULL;
+ u8 hw_hdr_offset, subtype ;
+ struct sta_info *psta = NULL;
+ struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ struct pkt_attrib *pattrib = &pxmitframe->attrib;
+ u8 *pbuf_start;
+ s32 bmcst = IS_MCAST(pattrib->ra);
+ s32 res = _FAIL;
+ u8 *BIP_AAD;
+ u8 *MGMT_body=NULL;
+
+ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
+ struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
+ struct rtw_ieee80211_hdr *pwlanhdr;
+ u8 MME[_MME_IE_LENGTH_];
+
+ _irqL irqL;
+ u32 ori_len;
+ mem_start = pframe = (u8 *)(pxmitframe->buf_addr) + TXDESC_OFFSET;
+ pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
+ tmp_buf = BIP_AAD;
+
+_func_enter_;
+ ori_len = BIP_AAD_SIZE+pattrib->pktlen;
+ tmp_buf = BIP_AAD = rtw_zmalloc(ori_len);
+ subtype = GetFrameSubType(pframe); //bit(7)~bit(2)
+
+ if(BIP_AAD == NULL)
+ return _FAIL;
+
+ _enter_critical_bh(&padapter->security_key_mutex, &irqL);
+
+ //only support station mode
+ if(!check_fwstate(pmlmepriv, WIFI_STATION_STATE) || !check_fwstate(pmlmepriv, _FW_LINKED))
+ goto xmitframe_coalesce_success;
+
+ //IGTK key is not install, it may not support 802.11w
+ if(padapter->securitypriv.binstallBIPkey != _TRUE)
+ {
+ DBG_871X("no instll BIP key\n");
+ goto xmitframe_coalesce_success;
+ }
+ //station mode doesn't need TX BIP, just ready the code
+ if(bmcst)
+ {
+ int frame_body_len;
+ u8 mic[16];
+
+ _rtw_memset(MME, 0, 18);
+
+ //other types doesn't need the BIP
+ if(GetFrameSubType(pframe) != WIFI_DEAUTH && GetFrameSubType(pframe) != WIFI_DISASSOC)
+ goto xmitframe_coalesce_fail;
+
+ MGMT_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
+ pframe += pattrib->pktlen;
+
+ //octent 0 and 1 is key index ,BIP keyid is 4 or 5, LSB only need octent 0
+ MME[0]=padapter->securitypriv.dot11wBIPKeyid;
+ //copy packet number
+ _rtw_memcpy(&MME[2], &pmlmeext->mgnt_80211w_IPN, 6);
+ //increase the packet number
+ pmlmeext->mgnt_80211w_IPN++;
+
+ //add MME IE with MIC all zero, MME string doesn't include element id and length
+ pframe = rtw_set_ie(pframe, _MME_IE_ , 16 , MME, &(pattrib->pktlen));
+ pattrib->last_txcmdsz = pattrib->pktlen;
+ // total frame length - header length
+ frame_body_len = pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr);
+
+ //conscruct AAD, copy frame control field
+ _rtw_memcpy(BIP_AAD, &pwlanhdr->frame_ctl, 2);
+ ClearRetry(BIP_AAD);
+ ClearPwrMgt(BIP_AAD);
+ ClearMData(BIP_AAD);
+ //conscruct AAD, copy address 1 to address 3
+ _rtw_memcpy(BIP_AAD+2, pwlanhdr->addr1, 18);
+ //copy management fram body
+ _rtw_memcpy(BIP_AAD+BIP_AAD_SIZE, MGMT_body, frame_body_len);
+ /*//dump total packet include MME with zero MIC
+ {
+ int i;
+ printk("Total packet: ");
+ for(i=0; i < BIP_AAD_SIZE+frame_body_len; i++)
+ printk(" %02x ", BIP_AAD[i]);
+ printk("\n");
+ }*/
+ //calculate mic
+ if(omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey
+ , BIP_AAD, BIP_AAD_SIZE+frame_body_len, mic))
+ goto xmitframe_coalesce_fail;
+
+ /*//dump calculated mic result
+ {
+ int i;
+ printk("Calculated mic result: ");
+ for(i=0; i<16; i++)
+ printk(" %02x ", mic[i]);
+ printk("\n");
+ }*/
+ //copy right BIP mic value, total is 128bits, we use the 0~63 bits
+ _rtw_memcpy(pframe-8, mic, 8);
+ /*/dump all packet after mic ok
+ {
+ int pp;
+ printk("pattrib->pktlen = %d \n", pattrib->pktlen);
+ for(pp=0;pp< pattrib->pktlen; pp++)
+ printk(" %02x ", mem_start[pp]);
+ printk("\n");
+ }*/
+ }
+ else //unicast mgmt frame TX
+ {
+ //start to encrypt mgmt frame
+ if(subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC ||
+ subtype == WIFI_REASSOCREQ || subtype == WIFI_ACTION)
+ {
+ if (pattrib->psta)
+ psta = pattrib->psta;
+ else
+ {
+ psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
+ }
+
+ if(psta==NULL)
+ {
+
+ DBG_871X("%s, psta==NUL\n", __func__);
+ goto xmitframe_coalesce_fail;
+ }
+
+ if(!(psta->state & _FW_LINKED) || pxmitframe->buf_addr==NULL)
+ {
+ DBG_871X("%s, not _FW_LINKED or addr null\n", __func__);
+ goto xmitframe_coalesce_fail;
+ }
+
+ //DBG_871X("%s, action frame category=%d \n", __func__, pframe[WLAN_HDR_A3_LEN]);
+ //according 802.11-2012 standard, these five types are not robust types
+ if(subtype == WIFI_ACTION &&
+ (pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_PUBLIC ||
+ pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_HT ||
+ pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_UNPROTECTED_WNM ||
+ pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_SELF_PROTECTED ||
+ pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_P2P))
+ goto xmitframe_coalesce_fail;
+ /*//before encrypt dump the management packet content
+ {
+ int i;
+ printk("Management pkt: ");
+ for(i=0; i<pattrib->pktlen; i++)
+ printk(" %02x ", pframe[i]);
+ printk("=======\n");
+ }*/
+
+ //bakeup original management packet
+ _rtw_memcpy(tmp_buf, pframe, pattrib->pktlen);
+ //move to data portion
+ pframe += pattrib->hdrlen;
+
+ //802.11w unicast management packet must be _AES_
+ pattrib->iv_len = 8;
+ //it's MIC of AES
+ pattrib->icv_len = 8;
+
+ switch(pattrib->encrypt)
+ {
+ case _AES_:
+ //set AES IV header
+ AES_IV(pattrib->iv, psta->dot11wtxpn, 0);
+ break;
+ default:
+ goto xmitframe_coalesce_fail;
+ }
+ //insert iv header into management frame
+ _rtw_memcpy(pframe, pattrib->iv, pattrib->iv_len);
+ pframe += pattrib->iv_len;
+ //copy mgmt data portion after CCMP header
+ _rtw_memcpy(pframe, tmp_buf+pattrib->hdrlen, pattrib->pktlen-pattrib->hdrlen);
+ //move pframe to end of mgmt pkt
+ pframe += pattrib->pktlen-pattrib->hdrlen;
+ //add 8 bytes CCMP IV header to length
+ pattrib->pktlen += pattrib->iv_len;
+ /*//dump management packet include AES IV header
+ {
+ int i;
+ printk("Management pkt + IV: ");
+ //for(i=0; i<pattrib->pktlen; i++)
+ //printk(" %02x ", mem_start[i]);
+ printk("@@@@@@@@@@@@@\n");
+ }*/
+
+ if ((pattrib->icv_len >0 )&& (pattrib->bswenc)) {
+ _rtw_memcpy(pframe, pattrib->icv, pattrib->icv_len);
+ pframe += pattrib->icv_len;
+ }
+ //add 8 bytes MIC
+ pattrib->pktlen += pattrib->icv_len;
+ //set final tx command size
+ pattrib->last_txcmdsz = pattrib->pktlen;
+
+ //set protected bit must be beofre SW encrypt
+ SetPrivacy(mem_start);
+ /*//dump management packet include AES header
+ {
+ int i;
+ printk("prepare to enc Management pkt + IV: ");
+ for(i=0; i<pattrib->pktlen; i++)
+ printk(" %02x ", mem_start[i]);
+ printk("@@@@@@@@@@@@@\n");
+ }*/
+ //software encrypt
+ xmitframe_swencrypt(padapter, pxmitframe);
+ }
+ }
+
+xmitframe_coalesce_success:
+ _exit_critical_bh(&padapter->security_key_mutex, &irqL);
+ rtw_mfree(BIP_AAD, ori_len);
+_func_exit_;
+ return _SUCCESS;
+
+xmitframe_coalesce_fail:
+ _exit_critical_bh(&padapter->security_key_mutex, &irqL);
+ rtw_mfree(BIP_AAD, ori_len);
+_func_exit_;
+
+ return _FAIL;
+}
+#endif //CONFIG_IEEE80211W
+
/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
* IEEE LLC/SNAP header contains 8 octets
* First 3 octets comprise the LLC portion
@@ -2996,14 +3234,14 @@ int rtw_br_client_tx(_adapter *padapter, struct sk_buff **pskb)
*((unsigned short *)(skb->data+MACADDRLEN*2+2)) = vlan_hdr;
}
- newskb = skb_copy(skb, GFP_ATOMIC);
+ newskb = rtw_skb_copy(skb);
if (newskb == NULL) {
//priv->ext_stats.tx_drops++;
- DEBUG_ERR("TX DROP: skb_copy fail!\n");
+ DEBUG_ERR("TX DROP: rtw_skb_copy fail!\n");
//goto stop_proc;
return -1;
}
- dev_kfree_skb_any(skb);
+ rtw_skb_free(skb);
*pskb = skb = newskb;
if (is_vlan_tag) {
@@ -3606,10 +3844,12 @@ void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta)
struct sta_priv *pstapriv = &padapter->stapriv;
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
+ psta_bmc = rtw_get_bcmc_stainfo(padapter);
+
+
//_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);
@@ -3678,52 +3918,12 @@ void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta)
}
- if(psta->sleepq_len==0)
- {
-#ifdef CONFIG_TDLS
- if( psta->tdls_sta_state & TDLS_LINKED_STATE )
- {
- if(psta->state&WIFI_SLEEP_STATE)
- psta->state ^= WIFI_SLEEP_STATE;
-
- //_exit_critical_bh(&psta->sleep_q.lock, &irqL);
- _exit_critical_bh(&pxmitpriv->lock, &irqL);
- return;
- }
-#endif //CONFIG_TDLS
- pstapriv->tim_bitmap &= ~BIT(psta->aid);
-
- //DBG_871X("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap);
- //upate BCN for TIM IE
- //update_BCNTIM(padapter);
- update_mask = BIT(0);
-
- if(psta->state&WIFI_SLEEP_STATE)
- psta->state ^= WIFI_SLEEP_STATE;
-
- if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
- {
- psta->expire_to = pstapriv->expire_to;
- psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
- }
-
- pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
- }
-
- //_exit_critical_bh(&psta->sleep_q.lock, &irqL);
- _exit_critical_bh(&pxmitpriv->lock, &irqL);
-
-
//for BC/MC Frames
- psta_bmc = rtw_get_bcmc_stainfo(padapter);
if(!psta_bmc)
- return;
+ goto _exit;
if((pstapriv->sta_dz_bitmap&0xfffe) == 0x0)//no any sta in ps mode
{
- //_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
- _enter_critical_bh(&pxmitpriv->lock, &irqL);
-
xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
xmitframe_plist = get_next(xmitframe_phead);
@@ -3767,11 +3967,42 @@ void wakeup_sta_to_xmit(_adapter *padapter, struct sta_info *psta)
update_mask |= BIT(1);
}
- //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
- _exit_critical_bh(&pxmitpriv->lock, &irqL);
-
}
+ if(psta->sleepq_len==0)
+ {
+#ifdef CONFIG_TDLS
+ if( psta->tdls_sta_state & TDLS_LINKED_STATE )
+ {
+ if(psta->state&WIFI_SLEEP_STATE)
+ psta->state ^= WIFI_SLEEP_STATE;
+
+ goto _exit;
+ }
+#endif //CONFIG_TDLS
+ pstapriv->tim_bitmap &= ~BIT(psta->aid);
+
+ //DBG_871X("wakeup to xmit, qlen==0, update_BCNTIM, tim=%x\n", pstapriv->tim_bitmap);
+ //upate BCN for TIM IE
+ //update_BCNTIM(padapter);
+ update_mask = BIT(0);
+
+ if(psta->state&WIFI_SLEEP_STATE)
+ psta->state ^= WIFI_SLEEP_STATE;
+
+ if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
+ {
+ psta->expire_to = pstapriv->expire_to;
+ psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
+ }
+
+ pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
+ }
+
+_exit:
+
+ //_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
+ _exit_critical_bh(&pxmitpriv->lock, &irqL);
if(update_mask)
{
@@ -4150,8 +4381,66 @@ int rtw_ack_tx_polling(struct xmit_priv *pxmitpriv, u32 timeout_ms)
}
#endif
+#ifdef CONFIG_DETECT_C2H_BY_POLLING
+s32 c2h_evt_hdl(_adapter *adapter, struct c2h_evt_hdr *c2h_evt, c2h_id_filter filter);
+#endif
+
int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
{
+#ifdef CONFIG_DETECT_C2H_BY_POLLING
+ _adapter *adapter = container_of(pxmitpriv, _adapter, xmitpriv);
+ c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter);
+ struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
+ u8 check_c2hcmd;
+ u8 check_ccx;
+ int ret = _FAIL;
+
+ pack_tx_ops->submit_time = rtw_get_current_time();
+ pack_tx_ops->timeout_ms = timeout_ms;
+ pack_tx_ops->status = RTW_SCTX_SUBMITTED;
+
+ do {
+ rtw_msleep_os(10);
+ //check_c2hcmd = rtw_read8(adapter, 0x1AF);
+ //check_ccx = rtw_read8(adapter, 0x1A0);
+ rtw_hal_get_hwreg(adapter, HW_VAR_C2HEVT_CLEAR, (u8 *)(&check_c2hcmd));
+ rtw_hal_get_hwreg(adapter, HW_VAR_C2HEVT_MSG_NORMAL, (u8 *)(&check_ccx));
+
+
+ if (check_c2hcmd != 0)
+ {
+ if (check_c2hcmd != 0xFF)
+ {
+ c2h_evt_clear(adapter);
+ }
+ else if (ccx_id_filter(check_ccx & 0x0F) == _TRUE)
+ {
+ c2h_evt_hdl(adapter, NULL, ccx_id_filter);
+ if (pack_tx_ops->status != RTW_SCTX_SUBMITTED)
+ break;
+
+ if (adapter->bDriverStopped) {
+ pack_tx_ops->status = RTW_SCTX_DONE_DRV_STOP;
+ break;
+ }
+ if (adapter->bSurpriseRemoved) {
+ pack_tx_ops->status = RTW_SCTX_DONE_DEV_REMOVE;
+ break;
+ }
+ }
+ }
+ } while (rtw_get_passing_time_ms(pack_tx_ops->submit_time) < timeout_ms);
+
+ if (pack_tx_ops->status == RTW_SCTX_SUBMITTED) {
+ pack_tx_ops->status = RTW_SCTX_DONE_TIMEOUT;
+ DBG_871X("%s timeout\n", __func__);
+ }
+
+ if (pack_tx_ops->status == RTW_SCTX_DONE_SUCCESS)
+ ret = _SUCCESS;
+
+ return ret;
+#else
#ifdef CONFIG_XMIT_ACK_POLLING
return rtw_ack_tx_polling(pxmitpriv, timeout_ms);
#else
@@ -4163,6 +4452,7 @@ int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
return rtw_sctx_wait(pack_tx_ops);
#endif
+#endif
}
void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)