1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _RTL8723B_CMD_C_
22 #include <rtl8723b_hal.h>
23 #include "hal_com_h2c.h"
25 #define MAX_H2C_BOX_NUMS 4
26 #define MESSAGE_BOX_SIZE 4
28 #define RTL8723B_MAX_CMD_LEN 7
29 #define RTL8723B_EX_MESSAGE_BOX_SIZE 4
31 static u8 _is_fw_read_cmd_down(_adapter* padapter, u8 msgbox_num)
33 u8 read_down = _FALSE;
38 //DBG_8192C(" _is_fw_read_cmd_down ,reg_1cc(%x),msg_box(%d)...\n",rtw_read8(padapter,REG_HMETFR),msgbox_num);
41 valid = rtw_read8(padapter,REG_HMETFR) & BIT(msgbox_num);
49 }while( (!read_down) && (retry_cnts--));
56 /*****************************************
58 *| 31 - 8 |7-5 | 4 - 0 |
59 *| h2c_msg |Class |CMD_ID |
63 ******************************************/
64 s32 FillH2CCmd8723B(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)
69 PHAL_DATA_TYPE pHalData;
73 struct dvobj_priv *psdpriv = padapter->dvobj;
74 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
77 padapter = GET_PRIMARY_ADAPTER(padapter);
78 pHalData = GET_HAL_DATA(padapter);
79 #ifdef DBG_CHECK_FW_PS_STATE
80 #ifdef DBG_CHECK_FW_PS_STATE_H2C
81 if(rtw_fw_ps_state(padapter) == _FAIL)
83 DBG_871X("%s: h2c doesn't leave 32k ElementID=%02x \n", __FUNCTION__, ElementID);
84 pdbgpriv->dbg_h2c_leave32k_fail_cnt++;
87 //DBG_871X("H2C ElementID=%02x , pHalData->LastHMEBoxNum=%02x\n", ElementID, pHalData->LastHMEBoxNum);
88 #endif //DBG_CHECK_FW_PS_STATE_H2C
89 #endif //DBG_CHECK_FW_PS_STATE
90 _enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);
95 if(CmdLen > RTL8723B_MAX_CMD_LEN) {
98 if (padapter->bSurpriseRemoved == _TRUE)
101 //pay attention to if race condition happened in H2C cmd setting.
103 h2c_box_num = pHalData->LastHMEBoxNum;
105 if(!_is_fw_read_cmd_down(padapter, h2c_box_num)){
106 DBG_8192C(" fw read cmd failed...\n");
107 #ifdef DBG_CHECK_FW_PS_STATE
108 DBG_871X("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n", rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)
109 , rtw_read32(padapter, 0x1c8), rtw_read32(padapter, 0x1cc));
110 #endif //DBG_CHECK_FW_PS_STATE
111 //DBG_8192C(" 0x1c0: 0x%8x\n", rtw_read32(padapter, 0x1c0));
112 //DBG_8192C(" 0x1c4: 0x%8x\n", rtw_read32(padapter, 0x1c4));
118 _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, CmdLen );
121 _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, 3);
122 _rtw_memcpy((u8*)(&h2c_cmd_ex), pCmdBuffer+3, CmdLen-3);
123 // *(u8*)(&h2c_cmd) |= BIT(7);
126 *(u8*)(&h2c_cmd) |= ElementID;
129 msgbox_ex_addr = REG_HMEBOX_EXT0_8723B + (h2c_box_num *RTL8723B_EX_MESSAGE_BOX_SIZE);
130 h2c_cmd_ex = le32_to_cpu( h2c_cmd_ex );
131 rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex);
133 msgbox_addr =REG_HMEBOX_0 + (h2c_box_num *MESSAGE_BOX_SIZE);
134 h2c_cmd = le32_to_cpu( h2c_cmd );
135 rtw_write32(padapter,msgbox_addr, h2c_cmd);
137 //DBG_8192C("MSG_BOX:%d, CmdLen(%d), CmdID(0x%x), reg:0x%x =>h2c_cmd:0x%.8x, reg:0x%x =>h2c_cmd_ex:0x%.8x\n"
138 // ,pHalData->LastHMEBoxNum , CmdLen, ElementID, msgbox_addr, h2c_cmd, msgbox_ex_addr, h2c_cmd_ex);
140 pHalData->LastHMEBoxNum = (h2c_box_num+1) % MAX_H2C_BOX_NUMS;
148 _exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);
155 static void ConstructBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
157 struct rtw_ieee80211_hdr *pwlanhdr;
159 u32 rate_len, pktlen;
160 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
161 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
162 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
163 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
166 //DBG_871X("%s\n", __FUNCTION__);
168 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
170 fctrl = &(pwlanhdr->frame_ctl);
173 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
174 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
175 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
177 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
178 //pmlmeext->mgnt_seq++;
179 SetFrameSubType(pframe, WIFI_BEACON);
181 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
182 pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
184 //timestamp will be inserted by hardware
188 // beacon interval: 2 bytes
189 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
194 // capability info: 2 bytes
195 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
200 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
202 //DBG_871X("ie len=%d\n", cur_network->IELength);
203 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
204 _rtw_memcpy(pframe, cur_network->IEs+sizeof(NDIS_802_11_FIXED_IEs), pktlen);
206 goto _ConstructBeacon;
209 //below for ad-hoc mode
212 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
214 // supported rates...
215 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
216 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen);
219 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
221 if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
224 // IBSS Parameter Set...
225 //ATIMWindow = cur->Configuration.ATIMWindow;
227 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
234 // EXTERNDED SUPPORTED RATE
237 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
245 if ((pktlen + TXDESC_SIZE) > 512)
247 DBG_871X("beacon frame too large\n");
253 //DBG_871X("%s bcn_sz=%d\n", __FUNCTION__, pktlen);
257 static void ConstructPSPoll(_adapter *padapter, u8 *pframe, u32 *pLength)
259 struct rtw_ieee80211_hdr *pwlanhdr;
262 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
263 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
265 //DBG_871X("%s\n", __FUNCTION__);
267 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
270 fctrl = &(pwlanhdr->frame_ctl);
273 SetFrameSubType(pframe, WIFI_PSPOLL);
276 SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
279 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
282 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
287 static void ConstructNullFunctionData(
297 struct rtw_ieee80211_hdr *pwlanhdr;
300 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
301 struct wlan_network *cur_network = &pmlmepriv->cur_network;
302 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
303 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
306 //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
308 pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
310 fctrl = &pwlanhdr->frame_ctl;
317 switch(cur_network->network.InfrastructureMode)
319 case Ndis802_11Infrastructure:
321 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
322 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
323 _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
325 case Ndis802_11APMode:
327 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
328 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
329 _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
333 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
334 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
335 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
339 SetSeqNum(pwlanhdr, 0);
342 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
344 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
346 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;
347 SetPriority(&pwlanqoshdr->qc, AC);
348 SetEOSP(&pwlanqoshdr->qc, bEosp);
350 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
352 SetFrameSubType(pframe, WIFI_DATA_NULL);
354 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
364 // Construct the ARP response packet to support ARP offload.
366 static void ConstructARPResponse(
373 struct rtw_ieee80211_hdr *pwlanhdr;
376 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
377 struct wlan_network *cur_network = &pmlmepriv->cur_network;
378 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
379 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
380 struct security_priv *psecuritypriv = &padapter->securitypriv;
381 static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
382 u8 *pARPRspPkt = pframe;
384 u8 *payload = pframe;
385 u8 EncryptionHeadOverhead = 0;
386 //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
388 pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
390 fctrl = &pwlanhdr->frame_ctl;
393 //-------------------------------------------------------------------------
395 //-------------------------------------------------------------------------
396 SetFrameType(fctrl, WIFI_DATA);
397 //SetFrameSubType(fctrl, 0);
399 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
400 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
401 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
403 SetSeqNum(pwlanhdr, 0);
404 SetDuration(pwlanhdr, 0);
405 //SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0);
406 //SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data);
407 //SET_80211_HDR_TO_DS(pARPRspPkt, 1);
408 //SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid);
409 //SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress);
410 //SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid);
412 //SET_80211_HDR_DURATION(pARPRspPkt, 0);
413 //SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0);
414 #ifdef CONFIG_WAPI_SUPPORT
415 *pLength = sMacHdrLng;
422 //-------------------------------------------------------------------------
423 // Qos Header: leave space for it if necessary.
424 //-------------------------------------------------------------------------
425 if(pStaQos->CurrentQosMode > QOS_DISABLE)
427 SET_80211_HDR_QOS_EN(pARPRspPkt, 1);
428 PlatformZeroMemory(&(Buffer[*pLength]), sQoSCtlLng);
429 *pLength += sQoSCtlLng;
432 //-------------------------------------------------------------------------
433 // Security Header: leave space for it if necessary.
434 //-------------------------------------------------------------------------
437 switch (psecuritypriv->dot11PrivacyAlgrthm)
441 EncryptionHeadOverhead = 4;
444 EncryptionHeadOverhead = 8;
447 EncryptionHeadOverhead = 8;
449 #ifdef CONFIG_WAPI_SUPPORT
451 EncryptionHeadOverhead = 18;
455 EncryptionHeadOverhead = 0;
458 if(EncryptionHeadOverhead > 0)
460 _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);
461 *pLength += EncryptionHeadOverhead;
462 //SET_80211_HDR_WEP(pARPRspPkt, 1); //Suggested by CCW.
466 //-------------------------------------------------------------------------
468 //-------------------------------------------------------------------------
469 pARPRspPkt = (u8*)(pframe+ *pLength);
470 payload = pARPRspPkt; //Get Payload pointer
472 _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
477 SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
478 SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008); // IP protocol
479 SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
480 SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
481 SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); // ARP response
482 SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, myid(&(padapter->eeprompriv)));
483 SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
484 #ifdef CONFIG_ARP_KEEP_ALIVE
485 if (rtw_gw_addr_query(padapter)==0) {
486 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
487 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
492 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, get_my_bssid(&(pmlmeinfo->network)));
493 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pIPAddress);
494 DBG_871X("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
495 DBG_871X("%s Target IP Addr" IP_FMT "\n", __FUNCTION__, IP_ARG(pIPAddress));
500 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_)
503 struct mic_data micdata;
504 struct sta_info *psta = NULL;
505 u8 priority[4]={0x0,0x0,0x0,0x0};
506 u8 null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
508 DBG_871X("%s(): Add MIC\n",__FUNCTION__);
510 psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&(pmlmeinfo->network)));
512 if(_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],null_key, 16)==_TRUE){
513 DBG_871X("%s(): STA dot11tkiptxmickey==0\n",__FUNCTION__);
515 //start to calculate the mic code
516 rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
519 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); //DA
521 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); //SA
524 rtw_secmicappend(&micdata, &priority[0], 4);
526 rtw_secmicappend(&micdata, payload, 36); //payload length = 8 + 28
528 rtw_secgetmic(&micdata,&(mic[0]));
531 _rtw_memcpy(pARPRspPkt, &(mic[0]),8);
537 #ifdef CONFIG_PNO_SUPPORT
538 static void ConstructPnoInfo(
545 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
547 u8 *pPnoInfoPkt = pframe;
548 pPnoInfoPkt = (u8*)(pframe+ *pLength);
549 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 1);
553 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->hidden_ssid_num, 1);
557 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 1);
561 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
565 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
569 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length,
572 *pLength+=MAX_PNO_LIST_COUNT;
573 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
574 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_cipher_info,
577 *pLength+=MAX_PNO_LIST_COUNT;
578 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
579 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info,
582 *pLength+=MAX_PNO_LIST_COUNT;
583 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
584 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->loc_probe_req,
587 *pLength+=MAX_HIDDEN_AP;
588 pPnoInfoPkt += MAX_HIDDEN_AP;
591 static void ConstructSSIDList(
598 u8 *pSSIDListPkt = pframe;
599 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
601 pSSIDListPkt = (u8*)(pframe+ *pLength);
603 for(i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
604 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
605 pwrctl->pnlo_info->ssid_length[i]);
607 *pLength += WLAN_SSID_MAXLEN;
608 pSSIDListPkt += WLAN_SSID_MAXLEN;
612 static void ConstructScanInfo(
619 u8 *pScanInfoPkt = pframe;
620 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
622 pScanInfoPkt = (u8*)(pframe+ *pLength);
624 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
628 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
633 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
638 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
642 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
646 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
650 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
654 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
658 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
663 for(i = 0 ; i < MAX_SCAN_LIST_COUNT ; i ++) {
664 _rtw_memcpy(pScanInfoPkt,
665 &pwrctl->pscan_info->ssid_channel_info[i], 4);
673 static void ConstructGTKResponse(
679 struct rtw_ieee80211_hdr *pwlanhdr;
682 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
683 struct wlan_network *cur_network = &pmlmepriv->cur_network;
684 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
685 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
686 struct security_priv *psecuritypriv = &padapter->securitypriv;
687 static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
688 static u8 GTKbody_a[11] ={0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
689 u8 *pGTKRspPkt = pframe;
690 u8 EncryptionHeadOverhead = 0;
691 //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
693 pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
695 fctrl = &pwlanhdr->frame_ctl;
698 //-------------------------------------------------------------------------
700 //-------------------------------------------------------------------------
701 SetFrameType(fctrl, WIFI_DATA);
702 //SetFrameSubType(fctrl, 0);
704 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
705 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
706 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
708 SetSeqNum(pwlanhdr, 0);
709 SetDuration(pwlanhdr, 0);
711 #ifdef CONFIG_WAPI_SUPPORT
712 *pLength = sMacHdrLng;
715 #endif //CONFIG_WAPI_SUPPORT
719 //-------------------------------------------------------------------------
720 // Qos Header: leave space for it if necessary.
721 //-------------------------------------------------------------------------
722 if(pStaQos->CurrentQosMode > QOS_DISABLE)
724 SET_80211_HDR_QOS_EN(pGTKRspPkt, 1);
725 PlatformZeroMemory(&(Buffer[*pLength]), sQoSCtlLng);
726 *pLength += sQoSCtlLng;
729 //-------------------------------------------------------------------------
730 // Security Header: leave space for it if necessary.
731 //-------------------------------------------------------------------------
734 switch (psecuritypriv->dot11PrivacyAlgrthm)
738 EncryptionHeadOverhead = 4;
741 EncryptionHeadOverhead = 8;
744 EncryptionHeadOverhead = 8;
746 #ifdef CONFIG_WAPI_SUPPORT
748 EncryptionHeadOverhead = 18;
750 #endif //CONFIG_WAPI_SUPPORT
752 EncryptionHeadOverhead = 0;
755 if(EncryptionHeadOverhead > 0)
757 _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);
758 *pLength += EncryptionHeadOverhead;
759 //SET_80211_HDR_WEP(pGTKRspPkt, 1); //Suggested by CCW.
760 //GTK's privacy bit is done by FW
764 //-------------------------------------------------------------------------
766 //-------------------------------------------------------------------------
767 pGTKRspPkt = (u8*)(pframe+ *pLength);
769 _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
775 //GTK frame body after LLC, part 1
776 _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
779 //GTK frame body after LLC, part 2
780 _rtw_memset(&(pframe[*pLength]), 0, 88);
785 #endif //CONFIG_GTK_OL
787 #ifdef CONFIG_PNO_SUPPORT
788 static void ConstructProbeReq(_adapter *padapter, u8 *pframe, u32 *pLength,
791 struct rtw_ieee80211_hdr *pwlanhdr;
795 unsigned char bssrate[NumRates];
796 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
797 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
798 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
799 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
801 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
803 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
804 mac = myid(&(padapter->eeprompriv));
806 fctrl = &(pwlanhdr->frame_ctl);
809 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
810 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
812 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
814 SetSeqNum(pwlanhdr, 0);
815 SetFrameSubType(pframe, WIFI_PROBEREQ);
817 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
821 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
823 pframe = rtw_set_ie(pframe, _SSID_IE_, ssid->SSID_len, ssid->SSID, &pktlen);
826 get_rate_set(padapter, bssrate, &bssrate_len);
830 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
831 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
835 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
840 #endif //CONFIG_PNO_SUPPORT
841 #endif //CONFIG_WOWLAN
843 static void ConstructProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bHideSSID)
845 struct rtw_ieee80211_hdr *pwlanhdr;
849 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
850 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
851 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
852 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
855 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
856 #endif //#if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
858 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
865 //DBG_871X("%s\n", __FUNCTION__);
867 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
869 mac = myid(&(padapter->eeprompriv));
870 bssid = cur_network->MacAddress;
872 fctrl = &(pwlanhdr->frame_ctl);
874 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
875 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
876 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
878 DBG_871X("%s FW Mac Addr:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(mac));
879 DBG_871X("%s FW IP Addr" IP_FMT "\n", __FUNCTION__, IP_ARG(StaAddr));
881 SetSeqNum(pwlanhdr, 0);
882 SetFrameSubType(fctrl, WIFI_PROBERSP);
884 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
887 if(cur_network->IELength>MAX_IE_SZ)
890 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_,
891 cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
893 //inerset & update wps_probe_resp_ie
894 if ((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0)) {
895 uint wps_offset, remainder_ielen;
898 wps_offset = (uint)(pwps_ie - cur_network->IEs);
900 premainder_ie = pwps_ie + wps_ielen;
902 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
904 _rtw_memcpy(pframe, cur_network->IEs, wps_offset);
905 pframe += wps_offset;
906 pktlen += wps_offset;
908 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];//to get ie data len
909 if ((wps_offset+wps_ielen+2)<=MAX_IE_SZ) {
910 _rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
911 pframe += wps_ielen+2;
912 pktlen += wps_ielen+2;
915 if ((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ) {
916 _rtw_memcpy(pframe, premainder_ie, remainder_ielen);
917 pframe += remainder_ielen;
918 pktlen += remainder_ielen;
921 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
922 pframe += cur_network->IELength;
923 pktlen += cur_network->IELength;
926 /* retrieve SSID IE from cur_network->Ssid */
930 sint ssid_ielen_diff;
932 u8 *ies = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
934 ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
935 (pframe-ies)-_FIXED_IE_LENGTH_);
937 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
939 if (ssid_ie && cur_network->Ssid.SsidLength) {
940 uint remainder_ielen;
942 remainder_ie = ssid_ie+2;
943 remainder_ielen = (pframe-remainder_ie);
945 if (remainder_ielen > MAX_IE_SZ) {
946 DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
947 remainder_ielen = MAX_IE_SZ;
950 _rtw_memcpy(buf, remainder_ie, remainder_ielen);
951 _rtw_memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
952 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
953 _rtw_memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
954 pframe += ssid_ielen_diff;
955 pktlen += ssid_ielen_diff;
960 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) /*&& is_valid_p2p_probereq*/)
963 #ifdef CONFIG_IOCTL_CFG80211
964 if(adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211 )
966 //if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p()
967 len = pmlmepriv->p2p_go_probe_resp_ie_len;
968 if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
969 _rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
972 #endif //CONFIG_IOCTL_CFG80211
974 len = build_probe_resp_p2p_ie(pwdinfo, pframe);
981 #ifdef CONFIG_IOCTL_CFG80211
982 if(_TRUE == pwdinfo->wfd_info->wfd_enable)
983 #endif //CONFIG_IOCTL_CFG80211
985 len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
987 #ifdef CONFIG_IOCTL_CFG80211
991 if(pmlmepriv->wfd_probe_resp_ie && pmlmepriv->wfd_probe_resp_ie_len>0)
993 len = pmlmepriv->wfd_probe_resp_ie_len;
994 _rtw_memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, len);
997 #endif //CONFIG_IOCTL_CFG80211
1009 // To check if reserved page content is destroyed by beacon beacuse beacon is too large.
1010 // 2010.06.23. Added by tynli.
1012 CheckFwRsvdPageContent(
1016 HAL_DATA_TYPE* pHalData = GET_HAL_DATA(Adapter);
1019 if(pHalData->FwRsvdPageStartOffset != 0)
1021 /*MaxBcnPageNum = PageNum_128(pMgntInfo->MaxBeaconSize);
1022 RT_ASSERT((MaxBcnPageNum <= pHalData->FwRsvdPageStartOffset),
1023 ("CheckFwRsvdPageContent(): The reserved page content has been"\
1024 "destroyed by beacon!!! MaxBcnPageNum(%d) FwRsvdPageStartOffset(%d)\n!",
1025 MaxBcnPageNum, pHalData->FwRsvdPageStartOffset));*/
1030 // Description: Get the reserved page number in Tx packet buffer.
1031 // Retrun value: the page number.
1032 // 2012.08.09, by tynli.
1034 u8 GetTxBufferRsvdPageNum8723B(_adapter *padapter, bool wowlan)
1036 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1038 // default reseved 1 page for the IC type which is undefined.
1039 u8 TxPageBndy= LAST_ENTRY_OF_TX_PKT_BUFFER_8723B;
1041 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_BOUNDARY, (u8 *)&TxPageBndy);
1043 RsvdPageNum = LAST_ENTRY_OF_TX_PKT_BUFFER_8723B -TxPageBndy + 1;
1048 static void rtl8723b_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
1050 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN]={0};
1052 DBG_871X("8723BRsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
1053 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
1054 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
1055 rsvdpageloc->LocBTQosNull);
1057 SET_8723B_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
1058 SET_8723B_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
1059 SET_8723B_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
1060 SET_8723B_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
1061 SET_8723B_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
1063 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CRsvdPageParm:", u1H2CRsvdPageParm, H2C_RSVDPAGE_LOC_LEN);
1064 FillH2CCmd8723B(padapter, H2C_8723B_RSVD_PAGE, H2C_RSVDPAGE_LOC_LEN, u1H2CRsvdPageParm);
1067 static void rtl8723b_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
1069 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1070 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1071 u8 res = 0, count = 0;
1072 #ifdef CONFIG_WOWLAN
1073 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};
1075 DBG_871X("8723BAOACRsvdPageLoc: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",
1076 rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,
1077 rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,
1078 rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,
1079 rsvdpageloc->LocNetList);
1081 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1082 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
1083 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
1084 //SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv);
1085 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
1086 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
1087 #ifdef CONFIG_GTK_OL
1088 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
1089 #endif // CONFIG_GTK_OL
1090 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CAoacRsvdPageParm:", u1H2CAoacRsvdPageParm, H2C_AOAC_RSVDPAGE_LOC_LEN);
1091 FillH2CCmd8723B(padapter, H2C_8723B_AOAC_RSVD_PAGE, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm);
1093 #ifdef CONFIG_PNO_SUPPORT
1094 if(!pwrpriv->pno_in_resume) {
1095 DBG_871X("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
1096 _rtw_memset(&u1H2CAoacRsvdPageParm, 0, sizeof(u1H2CAoacRsvdPageParm));
1097 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocPNOInfo);
1098 FillH2CCmd8723B(padapter, H2C_AOAC_RSVDPAGE3, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm);
1104 #endif // CONFIG_WOWLAN
1107 #ifdef CONFIG_AP_WOWLAN
1108 static void rtl8723b_set_ap_wow_rsvdpage_cmd(PADAPTER padapter,
1109 PRSVDPAGE_LOC rsvdpageloc)
1111 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1112 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1113 u8 res = 0, count = 0, header = 0;
1114 u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};
1116 header = rtw_read8(padapter, REG_BCNQ_BDNY);
1118 DBG_871X("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
1119 rsvdpageloc->LocApOffloadBCN,
1120 rsvdpageloc->LocProbeRsp,
1123 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
1124 rsvdpageloc->LocApOffloadBCN + header);
1126 FillH2CCmd8723B(padapter, H2C_8723B_BCN_RSVDPAGE,
1127 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
1131 _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
1133 SET_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(
1135 rsvdpageloc->LocProbeRsp + header);
1137 FillH2CCmd8723B(padapter, H2C_8723B_PROBERSP_RSVDPAGE,
1138 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
1142 #endif //CONFIG_AP_WOWLAN
1144 void rtl8723b_set_FwMediaStatusRpt_cmd(PADAPTER padapter, u8 mstatus, u8 macid)
1146 u8 u1H2CMediaStatusRptParm[H2C_MEDIA_STATUS_RPT_LEN]={0};
1149 DBG_871X("%s(): mstatus = %d macid=%d\n", __func__, mstatus, macid);
1151 SET_8723B_H2CCMD_MSRRPT_PARM_OPMODE(u1H2CMediaStatusRptParm, mstatus);
1152 SET_8723B_H2CCMD_MSRRPT_PARM_MACID_IND(u1H2CMediaStatusRptParm, 0);
1153 SET_8723B_H2CCMD_MSRRPT_PARM_MACID(u1H2CMediaStatusRptParm, macid);
1154 SET_8723B_H2CCMD_MSRRPT_PARM_MACID_END(u1H2CMediaStatusRptParm, macid_end);
1156 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CMediaStatusRptParm:", u1H2CMediaStatusRptParm, H2C_MEDIA_STATUS_RPT_LEN);
1157 FillH2CCmd8723B(padapter, H2C_8723B_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, u1H2CMediaStatusRptParm);
1160 static void rtl8723b_set_FwKeepAlive_cmd(PADAPTER padapter, u8 benable, u8 pkt_type)
1162 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN]={0};
1164 #ifdef CONFIG_PLATFORM_INTEL_BYT
1165 u8 check_period = 10;
1167 u8 check_period = 5;
1170 DBG_871X("%s(): benable = %d\n", __func__, benable);
1171 SET_8723B_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, benable);
1172 SET_8723B_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
1173 SET_8723B_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
1174 SET_8723B_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
1176 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CKeepAliveParm:", u1H2CKeepAliveParm, H2C_KEEP_ALIVE_CTRL_LEN);
1178 FillH2CCmd8723B(padapter, H2C_8723B_KEEP_ALIVE, H2C_KEEP_ALIVE_CTRL_LEN, u1H2CKeepAliveParm);
1181 static void rtl8723b_set_FwDisconDecision_cmd(PADAPTER padapter, u8 benable)
1183 u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN]={0};
1184 u8 adopt = 1, check_period = 10, trypkt_num = 0;
1186 DBG_871X("%s(): benable = %d\n", __func__, benable);
1187 SET_8723B_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, benable);
1188 SET_8723B_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
1189 SET_8723B_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
1190 SET_8723B_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
1192 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CDisconDecisionParm:", u1H2CDisconDecisionParm, H2C_DISCON_DECISION_LEN);
1194 FillH2CCmd8723B(padapter, H2C_8723B_DISCON_DECISION, H2C_DISCON_DECISION_LEN, u1H2CDisconDecisionParm);
1197 void rtl8723b_set_FwMacIdConfig_cmd(_adapter* padapter, u8 mac_id, u8 raid, u8 bw, u8 sgi, u32 mask)
1199 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1200 u8 u1H2CMacIdConfigParm[H2C_MACID_CFG_LEN]={0};
1202 DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x\n", __func__, mac_id, raid, bw, mask);
1206 SET_8723B_H2CCMD_MACID_CFG_MACID(u1H2CMacIdConfigParm, mac_id);
1207 SET_8723B_H2CCMD_MACID_CFG_RAID(u1H2CMacIdConfigParm, raid);
1208 SET_8723B_H2CCMD_MACID_CFG_SGI_EN(u1H2CMacIdConfigParm, (sgi)? 1:0);
1209 SET_8723B_H2CCMD_MACID_CFG_BW(u1H2CMacIdConfigParm, bw);
1211 //DisableTXPowerTraining
1212 if(pHalData->bDisableTXPowerTraining){
1213 SET_8723B_H2CCMD_MACID_CFG_DISPT(u1H2CMacIdConfigParm,1);
1214 DBG_871X("%s,Disable PWT by driver\n",__FUNCTION__);
1217 PDM_ODM_T pDM_OutSrc = &pHalData->odmpriv;
1219 if(pDM_OutSrc->bDisablePowerTraining){
1220 SET_8723B_H2CCMD_MACID_CFG_DISPT(u1H2CMacIdConfigParm,1);
1221 DBG_871X("%s,Disable PWT by DM\n",__FUNCTION__);
1225 SET_8723B_H2CCMD_MACID_CFG_RATE_MASK0(u1H2CMacIdConfigParm, (u8)(mask & 0x000000ff));
1226 SET_8723B_H2CCMD_MACID_CFG_RATE_MASK1(u1H2CMacIdConfigParm, (u8)((mask & 0x0000ff00) >>8));
1227 SET_8723B_H2CCMD_MACID_CFG_RATE_MASK2(u1H2CMacIdConfigParm, (u8)((mask & 0x00ff0000) >> 16));
1228 SET_8723B_H2CCMD_MACID_CFG_RATE_MASK3(u1H2CMacIdConfigParm, (u8)((mask & 0xff000000) >> 24));
1230 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CMacIdConfigParm:", u1H2CMacIdConfigParm, H2C_MACID_CFG_LEN);
1231 FillH2CCmd8723B(padapter, H2C_8723B_MACID_CFG, H2C_MACID_CFG_LEN, u1H2CMacIdConfigParm);
1236 void rtl8723b_set_FwRssiSetting_cmd(_adapter*padapter, u8 *param)
1238 u8 u1H2CRssiSettingParm[H2C_RSSI_SETTING_LEN]={0};
1240 u8 rssi = *(param+2);
1244 //DBG_871X("%s(): param=%.2x-%.2x-%.2x\n", __func__, *param, *(param+1), *(param+2));
1245 //DBG_871X("%s(): mac_id=%d rssi=%d\n", __func__, mac_id, rssi);
1247 SET_8723B_H2CCMD_RSSI_SETTING_MACID(u1H2CRssiSettingParm, mac_id);
1248 SET_8723B_H2CCMD_RSSI_SETTING_RSSI(u1H2CRssiSettingParm, rssi);
1249 SET_8723B_H2CCMD_RSSI_SETTING_ULDL_STATE(u1H2CRssiSettingParm, uldl_state);
1251 RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "u1H2CRssiSettingParm:", u1H2CRssiSettingParm, H2C_RSSI_SETTING_LEN);
1252 FillH2CCmd8723B(padapter, H2C_8723B_RSSI_SETTING, H2C_RSSI_SETTING_LEN, u1H2CRssiSettingParm);
1257 void rtl8723b_set_FwAPReqRPT_cmd(PADAPTER padapter, u32 need_ack)
1259 u8 u1H2CApReqRptParm[H2C_AP_REQ_TXRPT_LEN]={0};
1260 u8 macid1 = 1, macid2 = 0;
1262 DBG_871X("%s(): need_ack = %d\n", __func__, need_ack);
1264 SET_8723B_H2CCMD_APREQRPT_PARM_MACID1(u1H2CApReqRptParm, macid1);
1265 SET_8723B_H2CCMD_APREQRPT_PARM_MACID2(u1H2CApReqRptParm, macid2);
1267 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CApReqRptParm:", u1H2CApReqRptParm, H2C_AP_REQ_TXRPT_LEN);
1268 FillH2CCmd8723B(padapter, H2C_8723B_AP_REQ_TXRPT, H2C_AP_REQ_TXRPT_LEN, u1H2CApReqRptParm);
1271 void rtl8723b_set_FwPwrMode_cmd(PADAPTER padapter, u8 psmode)
1275 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1276 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1277 u8 u1H2CPwrModeParm[H2C_PWRMODE_LEN]={0};
1278 u8 PowerState=0, awake_intvl = 1, byte5 = 0, rlbm = 0;
1280 struct wifidirect_info *wdinfo = &(padapter->wdinfo);
1281 #endif // CONFIG_P2P
1285 #ifdef CONFIG_PLATFORM_INTEL_BYT
1286 if(psmode == PS_MODE_DTIM)
1287 psmode = PS_MODE_MAX;
1288 #endif //CONFIG_PLATFORM_INTEL_BYT
1291 if(pwrpriv->dtim > 0)
1292 DBG_871X("%s(): FW LPS mode = %d, SmartPS=%d, dtim=%d\n", __func__, psmode, pwrpriv->smart_ps, pwrpriv->dtim);
1294 DBG_871X("%s(): FW LPS mode = %d, SmartPS=%d\n", __func__, psmode, pwrpriv->smart_ps);
1296 if(psmode == PS_MODE_MIN)
1300 smart_ps = pwrpriv->smart_ps;
1302 else if(psmode == PS_MODE_MAX)
1306 smart_ps = pwrpriv->smart_ps;
1308 else if(psmode == PS_MODE_DTIM) //For WOWLAN LPS, DTIM = (awake_intvl - 1)
1310 if(pwrpriv->dtim > 0 && pwrpriv->dtim < 16)
1311 awake_intvl = pwrpriv->dtim+1;//DTIM = (awake_intvl - 1)
1313 awake_intvl = 4;//DTIM=3
1317 smart_ps = pwrpriv->smart_ps;
1323 smart_ps = pwrpriv->smart_ps;
1327 if (!rtw_p2p_chk_state(wdinfo, P2P_STATE_NONE)) {
1331 #endif // CONFIG_P2P
1333 if(padapter->registrypriv.wifi_spec==1)
1341 #ifdef CONFIG_BT_COEXIST
1342 if (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)
1344 PowerState = rtw_btcoex_RpwmVal(padapter);
1345 byte5 = rtw_btcoex_LpsVal(padapter);
1347 if ((rlbm == 2) && (byte5 & BIT(4)))
1349 // Keep awake interval to 1 to prevent from
1350 // decreasing coex performance
1356 #endif // CONFIG_BT_COEXIST
1358 PowerState = 0x00;// AllON(0x0C), RFON(0x04), RFOFF(0x00)
1364 PowerState = 0x0C;// AllON(0x0C), RFON(0x04), RFOFF(0x00)
1368 SET_8723B_H2CCMD_PWRMODE_PARM_MODE(u1H2CPwrModeParm, (psmode>0)?1:0);
1369 SET_8723B_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CPwrModeParm, smart_ps);
1370 SET_8723B_H2CCMD_PWRMODE_PARM_RLBM(u1H2CPwrModeParm, rlbm);
1371 SET_8723B_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1H2CPwrModeParm, awake_intvl);
1372 SET_8723B_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1H2CPwrModeParm, padapter->registrypriv.uapsd_enable);
1373 SET_8723B_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CPwrModeParm, PowerState);
1374 SET_8723B_H2CCMD_PWRMODE_PARM_BYTE5(u1H2CPwrModeParm, byte5);
1375 #ifdef CONFIG_LPS_LCLK
1376 if(psmode != PS_MODE_ACTIVE)
1378 if(pmlmeext ->adaptive_tsf_done == _FALSE && pmlmeext->bcn_cnt>0)
1380 u8 ratio_20_delay, ratio_80_delay;
1382 //byte 6 for adaptive_early_32k
1383 //[0:3] = DrvBcnEarly (ms) , [4:7] = DrvBcnTimeOut (ms)
1384 // 20% for DrvBcnEarly, 80% for DrvBcnTimeOut
1387 pmlmeext->DrvBcnEarly = 0xff;
1388 pmlmeext->DrvBcnTimeOut = 0xff;
1390 //DBG_871X("%s(): bcn_cnt = %d\n", __func__, pmlmeext->bcn_cnt);
1394 pmlmeext->bcn_delay_ratio[i] = (pmlmeext->bcn_delay_cnt[i] * 100) /pmlmeext->bcn_cnt;
1396 //DBG_871X("%s(): bcn_delay_cnt[%d]=%d, bcn_delay_ratio[%d] = %d\n", __func__, i, pmlmeext->bcn_delay_cnt[i]
1397 // ,i ,pmlmeext->bcn_delay_ratio[i]);
1399 ratio_20_delay += pmlmeext->bcn_delay_ratio[i];
1400 ratio_80_delay += pmlmeext->bcn_delay_ratio[i];
1402 if(ratio_20_delay > 20 && pmlmeext->DrvBcnEarly == 0xff)
1404 pmlmeext->DrvBcnEarly = i;
1405 //DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly);
1408 if(ratio_80_delay > 80 && pmlmeext->DrvBcnTimeOut == 0xff)
1410 pmlmeext->DrvBcnTimeOut = i;
1411 //DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut);
1414 //reset adaptive_early_32k cnt
1415 pmlmeext->bcn_delay_cnt[i] = 0;
1416 pmlmeext->bcn_delay_ratio[i] = 0;
1420 pmlmeext->bcn_cnt = 0;
1421 pmlmeext ->adaptive_tsf_done = _TRUE;
1426 //DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly);
1427 //DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut);
1430 /* offload to FW if fw version > v15.10
1431 pmlmeext->DrvBcnEarly=0;
1432 pmlmeext->DrvBcnTimeOut=7;
1434 if((pmlmeext->DrvBcnEarly!=0Xff) && (pmlmeext->DrvBcnTimeOut!=0xff))
1435 u1H2CPwrModeParm[H2C_PWRMODE_LEN-1] = BIT(0) | ((pmlmeext->DrvBcnEarly<<1)&0x0E) |((pmlmeext->DrvBcnTimeOut<<4)&0xf0) ;
1441 #ifdef CONFIG_BT_COEXIST
1442 rtw_btcoex_RecordPwrMode(padapter, u1H2CPwrModeParm, H2C_PWRMODE_LEN);
1443 #endif // CONFIG_BT_COEXIST
1445 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CPwrModeParm:", u1H2CPwrModeParm, H2C_PWRMODE_LEN);
1447 FillH2CCmd8723B(padapter, H2C_8723B_SET_PWR_MODE, H2C_PWRMODE_LEN, u1H2CPwrModeParm);
1451 void rtl8723b_set_FwPsTuneParam_cmd(PADAPTER padapter)
1453 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1454 u8 u1H2CPsTuneParm[H2C_PSTUNEPARAM_LEN]={0};
1455 u8 bcn_to_limit = 10; //10 * 100 * awakeinterval (ms)
1456 u8 dtim_timeout = 5; //ms //wait broadcast data timer
1457 u8 ps_timeout = 20; //ms //Keep awake when tx
1461 //DBG_871X("%s(): FW LPS mode = %d\n", __func__, psmode);
1463 SET_8723B_H2CCMD_PSTUNE_PARM_BCN_TO_LIMIT(u1H2CPsTuneParm, bcn_to_limit);
1464 SET_8723B_H2CCMD_PSTUNE_PARM_DTIM_TIMEOUT(u1H2CPsTuneParm, dtim_timeout);
1465 SET_8723B_H2CCMD_PSTUNE_PARM_PS_TIMEOUT(u1H2CPsTuneParm, ps_timeout);
1466 SET_8723B_H2CCMD_PSTUNE_PARM_ADOPT(u1H2CPsTuneParm, 1);
1467 SET_8723B_H2CCMD_PSTUNE_PARM_DTIM_PERIOD(u1H2CPsTuneParm, dtim_period);
1469 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CPsTuneParm:", u1H2CPsTuneParm, H2C_PSTUNEPARAM_LEN);
1471 FillH2CCmd8723B(padapter, H2C_8723B_PS_TUNING_PARA, H2C_PSTUNEPARAM_LEN, u1H2CPsTuneParm);
1475 void rtl8723b_set_FwBtMpOper_cmd(PADAPTER padapter, u8 idx, u8 ver, u8 reqnum, u8 *param)
1477 u8 u1H2CBtMpOperParm[H2C_BTMP_OPER_LEN+1]={0};
1481 DBG_8192C("%s: idx=%d ver=%d reqnum=%d param1=0x%02x param2=0x%02x\n", __FUNCTION__, idx, ver, reqnum, param[0], param[1]);
1483 SET_8723B_H2CCMD_BT_MPOPER_VER(u1H2CBtMpOperParm, ver);
1484 SET_8723B_H2CCMD_BT_MPOPER_REQNUM(u1H2CBtMpOperParm, reqnum);
1485 SET_8723B_H2CCMD_BT_MPOPER_IDX(u1H2CBtMpOperParm, idx);
1486 SET_8723B_H2CCMD_BT_MPOPER_PARAM1(u1H2CBtMpOperParm, param[0]);
1487 SET_8723B_H2CCMD_BT_MPOPER_PARAM2(u1H2CBtMpOperParm, param[1]);
1488 SET_8723B_H2CCMD_BT_MPOPER_PARAM3(u1H2CBtMpOperParm, param[2]);
1490 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CBtMpOperParm:", u1H2CBtMpOperParm, H2C_BTMP_OPER_LEN);
1492 FillH2CCmd8723B(padapter, H2C_8723B_BT_MP_OPER, H2C_BTMP_OPER_LEN+1, u1H2CBtMpOperParm);
1496 void rtl8723b_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param)
1498 //u8 cmd_param; //BIT0:enable, BIT1:NoConnect32k
1500 DBG_871X("%s()\n", __func__);
1502 cmd_param = cmd_param;
1504 FillH2CCmd8723B(padapter, H2C_8723B_FWLPS_IN_IPS_, 1, &cmd_param);
1508 #ifdef CONFIG_WOWLAN
1509 static void rtl8723b_set_FwRemoteWakeCtrl_Cmd(PADAPTER padapter, u8 benable)
1511 u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN]={0};
1512 struct security_priv* psecuritypriv=&(padapter->securitypriv);
1513 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
1514 u8 res = 0, count = 0;
1516 DBG_871X("%s(): Enable=%d\n", __func__, benable);
1518 if (!ppwrpriv->wowlan_pno_enable) {
1519 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(u1H2CRemoteWakeCtrlParm, benable);
1520 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, 1);
1521 #ifdef CONFIG_GTK_OL
1522 if (psecuritypriv->binstallKCK_KEK == _TRUE &&
1523 psecuritypriv->dot11PrivacyAlgrthm == _AES_) {
1524 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, 1);
1526 DBG_871X("no kck or security is not AES\n");
1527 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, 0);
1529 #endif //CONFIG_GTK_OL
1531 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(u1H2CRemoteWakeCtrlParm, 1);
1533 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) ||
1534 (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_))
1536 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(u1H2CRemoteWakeCtrlParm, 0);
1538 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(u1H2CRemoteWakeCtrlParm, 1);
1541 #ifdef CONFIG_PNO_SUPPORT
1543 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(u1H2CRemoteWakeCtrlParm, benable);
1544 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, benable);
1548 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CRemoteWakeCtrlParm:", u1H2CRemoteWakeCtrlParm, H2C_REMOTE_WAKE_CTRL_LEN);
1549 FillH2CCmd8723B(padapter, H2C_8723B_REMOTE_WAKE_CTRL,
1550 H2C_REMOTE_WAKE_CTRL_LEN, u1H2CRemoteWakeCtrlParm);
1551 #ifdef CONFIG_PNO_SUPPORT
1552 if (ppwrpriv->wowlan_pno_enable && ppwrpriv->pno_in_resume == _FALSE) {
1553 res = rtw_read8(padapter, REG_PNO_STATUS);
1554 DBG_871X("cmd: 0x81 REG_PNO_STATUS: 0x%02x\n", res);
1555 while(!(res&BIT(7)) && count < 25) {
1556 DBG_871X("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n", count, res);
1557 res = rtw_read8(padapter, REG_PNO_STATUS);
1561 DBG_871X("cmd: 0x81 REG_PNO_STATUS: 0x%02x\n", res);
1563 #endif //CONFIG_PNO_SUPPORT
1566 static void rtl8723b_set_FwAOACGlobalInfo_Cmd(PADAPTER padapter, u8 group_alg, u8 pairwise_alg)
1568 u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN]={0};
1570 DBG_871X("%s(): group_alg=%d pairwise_alg=%d\n", __func__, group_alg, pairwise_alg);
1572 SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm, pairwise_alg);
1573 SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm, group_alg);
1575 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CAOACGlobalInfoParm:", u1H2CAOACGlobalInfoParm, H2C_AOAC_GLOBAL_INFO_LEN);
1577 FillH2CCmd8723B(padapter, H2C_8723B_AOAC_GLOBAL_INFO, H2C_AOAC_GLOBAL_INFO_LEN, u1H2CAOACGlobalInfoParm);
1580 #ifdef CONFIG_PNO_SUPPORT
1581 static void rtl8723b_set_FwScanOffloadInfo_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc, u8 enable)
1583 u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN]={0};
1584 u8 res = 0, count = 0;
1585 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1587 DBG_871X("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
1588 __func__, rsvdpageloc->LocProbePacket, rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
1590 SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
1591 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm, rsvdpageloc->LocScanInfo);
1592 SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm, rsvdpageloc->LocProbePacket);
1593 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm, rsvdpageloc->LocSSIDInfo);
1595 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CScanOffloadInfoParm:", u1H2CScanOffloadInfoParm, H2C_SCAN_OFFLOAD_CTRL_LEN);
1596 FillH2CCmd8723B(padapter, H2C_8723B_D0_SCAN_OFFLOAD_INFO, H2C_SCAN_OFFLOAD_CTRL_LEN, u1H2CScanOffloadInfoParm);
1600 #endif //CONFIG_PNO_SUPPORT
1602 static void rtl8723b_set_FwWoWlanRelated_cmd(_adapter* padapter, u8 enable)
1604 struct security_priv *psecpriv = &padapter->securitypriv;
1605 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
1606 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1607 struct sta_info *psta = NULL;
1610 DBG_871X_LEVEL(_drv_always_, "+%s()+: enable=%d\n", __func__, enable);
1614 rtl8723b_set_FwAOACGlobalInfo_Cmd(padapter, psecpriv->dot118021XGrpPrivacy, psecpriv->dot11PrivacyAlgrthm);
1616 rtl8723b_set_FwJoinBssRpt_cmd(padapter, RT_MEDIA_CONNECT); //RT_MEDIA_CONNECT will confuse in the future
1618 if(!(ppwrpriv->wowlan_pno_enable))
1620 psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(pmlmepriv));
1622 rtl8723b_set_FwMediaStatusRpt_cmd(padapter, RT_MEDIA_CONNECT, psta->mac_id);
1625 DBG_871X("%s(): Disconnected, no FwMediaStatusRpt CONNECT\n",__FUNCTION__);
1629 if(!(ppwrpriv->wowlan_pno_enable)) {
1630 rtl8723b_set_FwDisconDecision_cmd(padapter, enable);
1633 if ((psecpriv->dot11PrivacyAlgrthm != _WEP40_) || (psecpriv->dot11PrivacyAlgrthm != _WEP104_))
1635 rtl8723b_set_FwKeepAlive_cmd(padapter, enable, pkt_type);
1639 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable);
1642 rtl8723b_set_FwRemoteWakeCtrl_Cmd(padapter, enable);
1649 rtw_hal_get_def_var(adapter, HAL_DEF_TX_PAGE_SIZE, (u8 *)&PageSize);
1650 dump_TX_FIFO(padapter, 4, PageSize);
1653 rtl8723b_set_FwRemoteWakeCtrl_Cmd(padapter, enable);
1655 rtw_hal_set_wowlan_ctrl_cmd(padapter, enable);
1659 DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__);
1663 void rtl8723b_set_wowlan_cmd(_adapter* padapter, u8 enable)
1665 rtl8723b_set_FwWoWlanRelated_cmd(padapter, enable);
1667 #endif //CONFIG_WOWLAN
1669 #ifdef CONFIG_AP_WOWLAN
1670 static void rtl8723b_set_FwAPWoWlanCtrl_Cmd(PADAPTER padapter, u8 bFuncEn)
1672 u8 u1H2CAPWoWlanCtrlParm[H2C_WOWLAN_LEN]={0};
1673 u8 discont_wake = 1, gpionum = 0, gpio_dur = 0;
1674 u8 gpio_high_active = 1; //0: low active, 1: high active
1675 u8 gpio_pulse = bFuncEn;
1676 #ifdef CONFIG_GPIO_WAKEUP
1677 gpionum = WAKEUP_GPIO_IDX;
1680 DBG_871X("%s(): bFuncEn=%d\n", __func__, bFuncEn);
1687 SET_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
1689 SET_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
1691 SET_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
1693 SET_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
1695 SET_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
1698 FillH2CCmd8723B(padapter, H2C_8723B_AP_WOW_GPIO_CTRL,
1699 H2C_AP_WOW_GPIO_CTRL_LEN, u1H2CAPWoWlanCtrlParm);
1702 static void rtl8723b_set_Fw_AP_Offload_Cmd(PADAPTER padapter, u8 bFuncEn)
1704 u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN]={0};
1706 DBG_871X("%s(): bFuncEn=%d\n", __func__, bFuncEn);
1708 SET_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, bFuncEn);
1710 FillH2CCmd8723B(padapter, H2C_8723B_AP_OFFLOAD,
1711 H2C_AP_OFFLOAD_LEN, u1H2CAPOffloadCtrlParm);
1714 static void rtl8723b_set_AP_FwWoWlan_cmd(_adapter* padapter, u8 enable)
1716 struct security_priv *psecpriv = &padapter->securitypriv;
1717 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
1718 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1719 struct sta_info *psta = NULL;
1723 DBG_871X_LEVEL(_drv_always_, "+%s()+: enable=%d\n", __func__, enable);
1726 #ifdef CONFIG_CONCURRENT_MODE
1727 if (rtw_buddy_adapter_up(padapter) == _TRUE &&
1728 check_buddy_fwstate(padapter, WIFI_AP_STATE) == _TRUE) {
1729 rtl8723b_set_FwJoinBssRpt_cmd(padapter->pbuddy_adapter, RT_MEDIA_CONNECT);
1730 issue_beacon(padapter->pbuddy_adapter, 0);
1732 rtl8723b_set_FwJoinBssRpt_cmd(padapter, RT_MEDIA_CONNECT);
1733 issue_beacon(padapter, 0);
1736 rtl8723b_set_FwJoinBssRpt_cmd(padapter, RT_MEDIA_CONNECT);
1737 issue_beacon(padapter, 0);
1743 dump_TX_FIFO(padapter);
1745 rtl8723b_set_FwAPWoWlanCtrl_Cmd(padapter, enable);
1747 rtl8723b_set_Fw_AP_Offload_Cmd(padapter, enable);
1750 DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__);
1754 void rtl8723b_set_ap_wowlan_cmd(_adapter* padapter, u8 enable)
1756 rtl8723b_set_AP_FwWoWlan_cmd(padapter, enable);
1758 #endif //CONFIG_AP_WOWLAN
1760 static s32 rtl8723b_set_FwLowPwrLps_cmd(PADAPTER padapter, u8 enable)
1767 // Description: Fill the reserved packets that FW will use to RSVD page.
1768 // Now we just send 4 types packet to rsvd page.
1769 // (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
1771 // bDLFinished - FALSE: At the first time we will send all the packets as a large packet to Hw,
1772 // so we need to set the packet length to total lengh.
1773 // TRUE: At the second time, we should send the first packet (default:beacon)
1774 // to Hw again and set the lengh in descriptor to the real beacon lengh.
1775 // 2009.10.15 by tynli.
1776 static void rtl8723b_set_FwRsvdPagePkt(PADAPTER padapter, BOOLEAN bDLFinished)
1778 PHAL_DATA_TYPE pHalData;
1779 struct xmit_frame *pcmdframe;
1780 struct pkt_attrib *pattrib;
1781 struct xmit_priv *pxmitpriv;
1782 struct mlme_ext_priv *pmlmeext;
1783 struct mlme_ext_info *pmlmeinfo;
1784 struct pwrctrl_priv *pwrctl;
1785 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1786 u32 BeaconLength=0, ProbeRspLength=0, PSPollLength=0;
1787 u32 NullDataLength=0, QosNullLength=0, BTQosNullLength=0;
1788 u32 ProbeReqLength=0;
1789 u8 *ReservedPagePacket;
1790 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
1791 u8 TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0;
1792 u16 BufIndex, PageSize = 128;
1793 u32 TotalPacketLen, MaxRsvdPageBufSize=0;
1794 RSVDPAGE_LOC RsvdPageLoc;
1795 #ifdef CONFIG_WOWLAN
1796 u32 ARPLegnth = 0, GTKLegnth = 0, PNOLength = 0, ScanInfoLength = 0;
1798 struct security_priv *psecuritypriv = &padapter->securitypriv; //added by xx
1800 u8 cur_dot11txpn[8];
1801 #ifdef CONFIG_GTK_OL
1802 struct sta_priv *pstapriv = &padapter->stapriv;
1803 struct sta_info * psta;
1804 u8 kek[RTW_KEK_LEN];
1805 u8 kck[RTW_KCK_LEN];
1807 #ifdef CONFIG_PNO_SUPPORT
1810 #endif //CONFIG_PNO_SUPPORT
1812 #ifdef DBG_CONFIG_ERROR_DETECT
1813 struct sreset_priv *psrtpriv;
1814 #endif // DBG_CONFIG_ERROR_DETECT
1816 //DBG_871X("%s---->\n", __FUNCTION__);
1818 pHalData = GET_HAL_DATA(padapter);
1819 #ifdef DBG_CONFIG_ERROR_DETECT
1820 psrtpriv = &pHalData->srestpriv;
1822 pxmitpriv = &padapter->xmitpriv;
1823 pmlmeext = &padapter->mlmeextpriv;
1824 pmlmeinfo = &pmlmeext->mlmext_info;
1825 pwrctl = adapter_to_pwrctl(padapter);
1827 RsvdPageNum = BCNQ_PAGE_NUM_8723B + WOWLAN_PAGE_NUM_8723B;
1828 MaxRsvdPageBufSize = RsvdPageNum*PageSize;
1830 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
1831 if (pcmdframe == NULL) {
1832 DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
1836 ReservedPagePacket = pcmdframe->buf_addr;
1837 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
1840 BufIndex = TxDescOffset;
1841 ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);
1843 // When we count the first page size, we need to reserve description size for the RSVD
1844 // packet, it will be filled in front of the packet in TXPKTBUF.
1845 CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength);
1846 //If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware
1847 if (CurtPktPageNum == 1)
1849 CurtPktPageNum += 1;
1851 TotalPageNum += CurtPktPageNum;
1853 BufIndex += (CurtPktPageNum*PageSize);
1856 RsvdPageLoc.LocPsPoll = TotalPageNum;
1857 ConstructPSPoll(padapter, &ReservedPagePacket[BufIndex], &PSPollLength);
1858 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, _TRUE, _FALSE, _FALSE);
1860 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PS-POLL %p %d\n",
1861 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (PSPollLength+TxDescLen));
1863 CurtPktPageNum = (u8)PageNum_128(TxDescLen + PSPollLength);
1865 TotalPageNum += CurtPktPageNum;
1867 BufIndex += (CurtPktPageNum*PageSize);
1870 RsvdPageLoc.LocNullData = TotalPageNum;
1871 ConstructNullFunctionData(
1873 &ReservedPagePacket[BufIndex],
1875 get_my_bssid(&pmlmeinfo->network),
1876 _FALSE, 0, 0, _FALSE);
1877 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, _FALSE, _FALSE, _FALSE);
1879 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: NULL DATA %p %d\n",
1880 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (NullDataLength+TxDescLen));
1882 CurtPktPageNum = (u8)PageNum_128(TxDescLen + NullDataLength);
1884 TotalPageNum += CurtPktPageNum;
1886 BufIndex += (CurtPktPageNum*PageSize);
1889 //3 (4) probe response
1890 RsvdPageLoc.LocProbeRsp = TotalPageNum;
1893 &ReservedPagePacket[BufIndex],
1895 get_my_bssid(&pmlmeinfo->network),
1897 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, _FALSE, _FALSE, _FALSE);
1899 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
1900 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (ProbeRspLength+TxDescLen));
1902 CurtPktPageNum = (u8)PageNum_128(TxDescLen + ProbeRspLength);
1904 TotalPageNum += CurtPktPageNum;
1906 BufIndex += (CurtPktPageNum*PageSize);
1909 //3 (5) Qos null data
1910 RsvdPageLoc.LocQosNull = TotalPageNum;
1911 ConstructNullFunctionData(
1913 &ReservedPagePacket[BufIndex],
1915 get_my_bssid(&pmlmeinfo->network),
1916 _TRUE, 0, 0, _FALSE);
1917 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, _FALSE, _FALSE, _FALSE);
1919 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",
1920 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (QosNullLength+TxDescLen));
1922 CurtPktPageNum = (u8)PageNum_128(TxDescLen + QosNullLength);
1924 TotalPageNum += CurtPktPageNum;
1926 BufIndex += (CurtPktPageNum*PageSize);
1928 //3 (6) BT Qos null data
1929 RsvdPageLoc.LocBTQosNull = TotalPageNum;
1930 ConstructNullFunctionData(
1932 &ReservedPagePacket[BufIndex],
1934 get_my_bssid(&pmlmeinfo->network),
1935 _TRUE, 0, 0, _FALSE);
1936 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, _FALSE, _TRUE, _FALSE);
1938 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: BT QOS NULL DATA %p %d\n",
1939 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (BTQosNullLength+TxDescLen));
1941 CurtPktPageNum = (u8)PageNum_128(TxDescLen + BTQosNullLength);
1943 TotalPageNum += CurtPktPageNum;
1945 BufIndex += (CurtPktPageNum*PageSize);
1947 #ifdef CONFIG_WOWLAN
1948 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1949 //if (pwrctl->wowlan_mode == _TRUE) {
1950 //BufIndex += (CurtPktPageNum*PageSize);
1953 rtw_get_current_ip_address(padapter, currentip);
1954 RsvdPageLoc.LocArpRsp= TotalPageNum;
1955 #ifdef DBG_CONFIG_ERROR_DETECT
1956 if(psrtpriv->silent_reset_inprogress == _FALSE)
1957 #endif //DBG_CONFIG_ERROR_DETECT
1959 ConstructARPResponse(
1961 &ReservedPagePacket[BufIndex],
1965 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ARPLegnth, _FALSE, _FALSE, _TRUE);
1967 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: ARP RSP %p %d\n",
1968 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (ARPLegnth+TxDescLen));
1970 CurtPktPageNum = (u8)PageNum_128(TxDescLen + ARPLegnth);
1972 #ifdef DBG_CONFIG_ERROR_DETECT
1974 CurtPktPageNum = (u8)PageNum_128(128);
1975 #endif //DBG_CONFIG_ERROR_DETECT
1976 TotalPageNum += CurtPktPageNum;
1978 BufIndex += (CurtPktPageNum*PageSize);
1981 rtw_get_sec_iv(padapter, cur_dot11txpn, get_my_bssid(&pmlmeinfo->network));
1982 RsvdPageLoc.LocRemoteCtrlInfo = TotalPageNum;
1983 _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen, cur_dot11txpn, _AES_IV_LEN_);
1985 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: SEC IV %p %d\n",
1986 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], _AES_IV_LEN_);
1988 CurtPktPageNum = (u8)PageNum_128(_AES_IV_LEN_);
1990 TotalPageNum += CurtPktPageNum;
1992 #ifdef CONFIG_GTK_OL
1993 BufIndex += (CurtPktPageNum*PageSize);
1995 //if the ap staion info. exists, get the kek, kck from staion info.
1996 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
1999 _rtw_memset(kek, 0, RTW_KEK_LEN);
2000 _rtw_memset(kck, 0, RTW_KCK_LEN);
2001 DBG_8192C("%s, KEK, KCK download rsvd page all zero \n", __func__);
2005 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
2006 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
2010 RsvdPageLoc.LocGTKInfo = TotalPageNum;
2011 _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen, kck, RTW_KCK_LEN);
2012 _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen+RTW_KCK_LEN, kek, RTW_KEK_LEN);
2017 printk("\ntoFW KCK: ");
2019 printk(" %02x ", kck[i]);
2020 printk("\ntoFW KEK: ");
2022 printk(" %02x ", kek[i]);
2027 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
2028 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN));
2030 CurtPktPageNum = (u8)PageNum_128(TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN);
2032 TotalPageNum += CurtPktPageNum;
2034 BufIndex += (CurtPktPageNum*PageSize);
2036 //3(10) GTK Response
2037 RsvdPageLoc.LocGTKRsp= TotalPageNum;
2038 ConstructGTKResponse(
2040 &ReservedPagePacket[BufIndex],
2044 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], GTKLegnth, _FALSE, _FALSE, _TRUE);
2048 printk("123GTK pkt=> \n");
2049 for(gj=0; gj < GTKLegnth+TxDescLen; gj++) {
2050 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);
2058 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
2059 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (TxDescLen + GTKLegnth));
2061 CurtPktPageNum = (u8)PageNum_128(TxDescLen + GTKLegnth);
2063 TotalPageNum += CurtPktPageNum;
2065 BufIndex += (CurtPktPageNum*PageSize);
2067 //below page is empty for GTK extension memory
2069 RsvdPageLoc.LocGTKEXTMEM= TotalPageNum;
2073 TotalPageNum += CurtPktPageNum;
2075 TotalPacketLen = BufIndex-TxDescLen + 256; //extension memory for FW
2077 TotalPacketLen = BufIndex-TxDescLen + sizeof (union pn48); //IV len
2078 #endif //CONFIG_GTK_OL
2080 #endif //CONFIG_WOWLAN
2082 #ifdef CONFIG_PNO_SUPPORT
2083 if (pwrctl->pno_in_resume == _FALSE && pwrctl->pno_inited == _TRUE) {
2085 //Broadcast Probe Request
2086 RsvdPageLoc.LocProbePacket = TotalPageNum;
2090 &ReservedPagePacket[BufIndex],
2094 rtl8723b_fill_fake_txdesc(padapter,
2095 &ReservedPagePacket[BufIndex-TxDescLen],
2096 ProbeReqLength, _FALSE, _FALSE, _FALSE);
2098 #ifdef CONFIG_PNO_SET_DEBUG
2101 printk("probe req pkt=> \n");
2102 for(gj=0; gj < ProbeReqLength + TxDescLen; gj++) {
2103 printk(" %02x ",ReservedPagePacket[BufIndex- TxDescLen + gj]);
2111 (u8)PageNum_128(TxDescLen + ProbeReqLength);
2113 TotalPageNum += CurtPktPageNum;
2115 BufIndex += (CurtPktPageNum*PageSize);
2117 //Hidden SSID Probe Request
2118 ssid_num = pwrctl->pnlo_info->hidden_ssid_num;
2120 for (index = 0 ; index < ssid_num ; index++) {
2121 pwrctl->pnlo_info->loc_probe_req[index] = TotalPageNum;
2125 &ReservedPagePacket[BufIndex],
2127 &pwrctl->pno_ssid_list->node[index]);
2129 rtl8723b_fill_fake_txdesc(padapter,
2130 &ReservedPagePacket[BufIndex-TxDescLen],
2131 ProbeReqLength, _FALSE, _FALSE, _FALSE);
2133 #ifdef CONFIG_PNO_SET_DEBUG
2136 printk("probe req pkt=> \n");
2137 for(gj=0; gj < ProbeReqLength + TxDescLen; gj++) {
2138 printk(" %02x ", ReservedPagePacket[BufIndex- TxDescLen + gj]);
2146 (u8)PageNum_128(TxDescLen + ProbeReqLength);
2148 TotalPageNum += CurtPktPageNum;
2150 BufIndex += (CurtPktPageNum*PageSize);
2154 RsvdPageLoc.LocPNOInfo = TotalPageNum;
2155 ConstructPnoInfo(padapter, &ReservedPagePacket[BufIndex -TxDescLen], &PNOLength);
2156 #ifdef CONFIG_PNO_SET_DEBUG
2159 printk("PNO pkt=> \n");
2160 for(gj=0; gj < PNOLength; gj++) {
2161 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen +gj]);
2169 CurtPktPageNum = (u8)PageNum_128(PNOLength);
2170 TotalPageNum += CurtPktPageNum;
2171 BufIndex += (CurtPktPageNum*PageSize);
2174 RsvdPageLoc.LocSSIDInfo = TotalPageNum;
2175 ConstructSSIDList(padapter, &ReservedPagePacket[BufIndex-TxDescLen], &SSIDLegnth);
2176 #ifdef CONFIG_PNO_SET_DEBUG
2179 printk("SSID list pkt=> \n");
2180 for(gj=0; gj < SSIDLegnth; gj++) {
2181 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);
2188 CurtPktPageNum = (u8)PageNum_128(SSIDLegnth);
2189 TotalPageNum += CurtPktPageNum;
2190 BufIndex += (CurtPktPageNum*PageSize);
2193 RsvdPageLoc.LocScanInfo = TotalPageNum;
2194 ConstructScanInfo(padapter, &ReservedPagePacket[BufIndex-TxDescLen], &ScanInfoLength);
2195 #ifdef CONFIG_PNO_SET_DEBUG
2198 printk("Scan info pkt=> \n");
2199 for(gj=0; gj < ScanInfoLength; gj++) {
2200 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);
2207 CurtPktPageNum = (u8)PageNum_128(ScanInfoLength);
2208 TotalPageNum += CurtPktPageNum;
2209 BufIndex += (CurtPktPageNum*PageSize);
2211 TotalPacketLen = BufIndex + ScanInfoLength;
2213 TotalPacketLen = BufIndex + BTQosNullLength;
2215 #else //CONFIG_PNO_SUPPORT
2216 TotalPacketLen = BufIndex + BTQosNullLength;
2220 if(TotalPacketLen > MaxRsvdPageBufSize)
2222 DBG_871X("%s(): ERROR: The rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",__FUNCTION__,
2223 TotalPacketLen,MaxRsvdPageBufSize);
2229 pattrib = &pcmdframe->attrib;
2230 update_mgntframe_attrib(padapter, pattrib);
2231 pattrib->qsel = QSLT_BEACON;
2232 pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
2233 #ifdef CONFIG_PCI_HCI
2234 dump_mgntframe(padapter, pcmdframe);
2236 dump_mgntframe_and_wait(padapter, pcmdframe, 100);
2240 DBG_871X("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n", __FUNCTION__,TotalPacketLen,TotalPageNum);
2241 if(check_fwstate(pmlmepriv, _FW_LINKED)) {
2242 rtl8723b_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc);
2243 rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);
2245 rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);
2246 #ifdef CONFIG_PNO_SUPPORT
2247 if(pwrctl->pno_in_resume)
2248 rtl8723b_set_FwScanOffloadInfo_cmd(padapter,
2251 rtl8723b_set_FwScanOffloadInfo_cmd(padapter,
2259 rtw_free_xmitframe(pxmitpriv, pcmdframe);
2262 #ifdef CONFIG_AP_WOWLAN
2264 //Description: Fill the reserved packets that FW will use to RSVD page.
2265 //Now we just send 2 types packet to rsvd page. (1)Beacon, (2)ProbeRsp.
2267 //Input: bDLFinished
2269 //FALSE: At the first time we will send all the packets as a large packet to Hw,
2270 // so we need to set the packet length to total lengh.
2272 //TRUE: At the second time, we should send the first packet (default:beacon)
2273 // to Hw again and set the lengh in descriptor to the real beacon lengh.
2274 // 2009.10.15 by tynli.
2275 static void rtl8723b_set_AP_FwRsvdPagePkt(PADAPTER padapter,
2276 BOOLEAN bDLFinished)
2278 PHAL_DATA_TYPE pHalData;
2279 struct xmit_frame *pcmdframe;
2280 struct pkt_attrib *pattrib;
2281 struct xmit_priv *pxmitpriv;
2282 struct mlme_ext_priv *pmlmeext;
2283 struct mlme_ext_info *pmlmeinfo;
2284 struct pwrctrl_priv *pwrctl;
2285 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2286 u32 BeaconLength=0, ProbeRspLength=0;
2287 u8 *ReservedPagePacket;
2288 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
2289 u8 TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0;
2291 u16 BufIndex, PageSize = 128;
2292 u32 TotalPacketLen = 0, MaxRsvdPageBufSize=0;
2293 RSVDPAGE_LOC RsvdPageLoc;
2294 #ifdef DBG_CONFIG_ERROR_DETECT
2295 struct sreset_priv *psrtpriv;
2296 #endif // DBG_CONFIG_ERROR_DETECT
2298 //DBG_871X("%s---->\n", __FUNCTION__);
2299 DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d\n",
2300 FUNC_ADPT_ARG(padapter), get_iface_type(padapter));
2302 pHalData = GET_HAL_DATA(padapter);
2303 #ifdef DBG_CONFIG_ERROR_DETECT
2304 psrtpriv = &pHalData->srestpriv;
2306 pxmitpriv = &padapter->xmitpriv;
2307 pmlmeext = &padapter->mlmeextpriv;
2308 pmlmeinfo = &pmlmeext->mlmext_info;
2309 pwrctl = adapter_to_pwrctl(padapter);
2311 RsvdPageNum = BCNQ_PAGE_NUM_8723B + AP_WOWLAN_PAGE_NUM_8723B;
2312 MaxRsvdPageBufSize = RsvdPageNum*PageSize;
2314 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
2315 if (pcmdframe == NULL) {
2316 DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
2320 ReservedPagePacket = pcmdframe->buf_addr;
2321 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
2324 BufIndex = TxDescOffset;
2325 ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);
2327 // When we count the first page size, we need to reserve description size for the RSVD
2328 // packet, it will be filled in front of the packet in TXPKTBUF.
2329 CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength);
2330 //If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware
2331 if (CurtPktPageNum == 1)
2333 CurtPktPageNum += 1;
2335 TotalPageNum += CurtPktPageNum;
2337 BufIndex += (CurtPktPageNum*PageSize);
2339 //2 (4) probe response
2340 RsvdPageLoc.LocProbeRsp = TotalPageNum;
2342 rtw_get_current_ip_address(padapter, currentip);
2346 &ReservedPagePacket[BufIndex],
2350 rtl8723b_fill_fake_txdesc(padapter,
2351 &ReservedPagePacket[BufIndex-TxDescLen],
2353 _FALSE, _FALSE, _FALSE);
2355 DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
2356 __func__, &ReservedPagePacket[BufIndex-TxDescLen],
2357 (ProbeRspLength+TxDescLen));
2359 CurtPktPageNum = (u8)PageNum_128(TxDescLen + ProbeRspLength);
2361 TotalPageNum += CurtPktPageNum;
2363 BufIndex += (CurtPktPageNum*PageSize);
2365 TotalPacketLen = BufIndex + ProbeRspLength;
2367 if (TotalPacketLen > MaxRsvdPageBufSize) {
2368 DBG_871X("%s(): ERROR: The rsvd page size is not enough \
2369 !!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
2370 __func__, TotalPacketLen,MaxRsvdPageBufSize);
2374 pattrib = &pcmdframe->attrib;
2375 update_mgntframe_attrib(padapter, pattrib);
2376 pattrib->qsel = QSLT_BEACON;
2377 pattrib->pktlen = TotalPacketLen - TxDescOffset;
2378 pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
2379 #ifdef CONFIG_PCI_HCI
2380 dump_mgntframe(padapter, pcmdframe);
2382 dump_mgntframe_and_wait(padapter, pcmdframe, 100);
2386 DBG_871X("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n", __FUNCTION__,TotalPacketLen,TotalPageNum);
2387 rtl8723b_set_ap_wow_rsvdpage_cmd(padapter, &RsvdPageLoc);
2391 rtw_free_xmitframe(pxmitpriv, pcmdframe);
2393 #endif //CONFIG_AP_WOWLAN
2395 void rtl8723b_download_rsvd_page(PADAPTER padapter, u8 mstatus)
2397 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2398 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2399 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2400 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2401 BOOLEAN bcn_valid = _FALSE;
2408 DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d mstatus(%x)\n",
2409 FUNC_ADPT_ARG(padapter), get_iface_type(padapter), mstatus);
2411 if(mstatus == RT_MEDIA_CONNECT)
2413 BOOLEAN bRecover = _FALSE;
2416 // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.
2417 // Suggested by filen. Added by tynli.
2418 rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));
2421 v8 = rtw_read8(padapter, REG_CR+1);
2422 v8 |= BIT(0); // ENSWBCN
2423 rtw_write8(padapter, REG_CR+1, v8);
2425 // Disable Hw protection for a time which revserd for Hw sending beacon.
2426 // Fix download reserved page packet fail that access collision with the protection time.
2427 // 2010.05.11. Added by tynli.
2428 val8 = rtw_read8(padapter, REG_BCN_CTRL);
2429 val8 &= ~EN_BCN_FUNCTION;
2430 val8 |= DIS_TSF_UDT;
2431 rtw_write8(padapter, REG_BCN_CTRL, val8);
2433 // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
2434 if (pHalData->RegFwHwTxQCtrl & BIT(6))
2437 // To tell Hw the packet is not a real beacon frame.
2438 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl & ~BIT(6));
2439 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
2441 // Clear beacon valid check bit.
2442 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
2443 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
2449 #ifdef CONFIG_AP_WOWLAN
2450 if (pwrpriv->wowlan_ap_mode)
2451 rtl8723b_set_AP_FwRsvdPagePkt(padapter, 0);
2453 rtl8723b_set_FwRsvdPagePkt(padapter, 0);
2455 // download rsvd page.
2456 rtl8723b_set_FwRsvdPagePkt(padapter, 0);
2462 //rtw_mdelay_os(10);
2463 // check rsvd page download OK.
2464 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8*)(&bcn_valid));
2466 } while(!bcn_valid && (poll%10)!=0 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
2468 }while(!bcn_valid && DLBcnCount<=100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
2470 if(padapter->bSurpriseRemoved || padapter->bDriverStopped)
2474 DBG_871X(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n",
2475 ADPT_ARG(padapter) ,DLBcnCount, poll);
2477 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
2478 pwrctl->fw_psmode_iface_id = padapter->iface_id;
2479 DBG_871X(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n",
2480 ADPT_ARG(padapter), DLBcnCount, poll);
2483 // 2010.05.11. Added by tynli.
2484 val8 = rtw_read8(padapter, REG_BCN_CTRL);
2485 val8 |= EN_BCN_FUNCTION;
2486 val8 &= ~DIS_TSF_UDT;
2487 rtw_write8(padapter, REG_BCN_CTRL, val8);
2489 // To make sure that if there exists an adapter which would like to send beacon.
2490 // If exists, the origianl value of 0x422[6] will be 1, we should check this to
2491 // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
2492 // the beacon cannot be sent by HW.
2493 // 2010.06.23. Added by tynli.
2496 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl | BIT(6));
2497 pHalData->RegFwHwTxQCtrl |= BIT(6);
2500 // Clear CR[8] or beacon packet will not be send to TxBuf anymore.
2501 #ifndef CONFIG_PCI_HCI
2502 v8 = rtw_read8(padapter, REG_CR+1);
2503 v8 &= ~BIT(0); // ~ENSWBCN
2504 rtw_write8(padapter, REG_CR+1, v8);
2511 void rtl8723b_set_rssi_cmd(_adapter*padapter, u8 *param)
2513 rtl8723b_set_FwRssiSetting_cmd(padapter, param);
2516 void rtl8723b_set_FwJoinBssRpt_cmd(PADAPTER padapter, u8 mstatus)
2518 struct sta_info *psta = NULL;
2519 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
2520 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2523 rtl8723b_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
2528 //arg[2] = shortGIrate
2529 //arg[3] = init_rate
2530 void rtl8723b_Add_RateATid(PADAPTER pAdapter, u32 bitmap, u8* arg, u8 rssi_level)
2532 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
2533 struct mlme_ext_priv *pmlmeext = &pAdapter->mlmeextpriv;
2534 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2535 struct sta_info *psta;
2538 u8 shortGI = arg[2];
2540 u32 mask = bitmap&0x0FFFFFFF;
2542 psta = pmlmeinfo->FW_sta_info[mac_id].psta;
2550 if(rssi_level != DM_RATR_STA_INIT)
2551 mask = ODM_Get_Rate_Bitmap(&pHalData->odmpriv, mac_id, mask, rssi_level);
2553 DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x\n", __func__, mac_id, raid, bw, mask);
2554 rtl8723b_set_FwMacIdConfig_cmd(pAdapter, mac_id, raid, bw, shortGI, mask);
2558 void rtl8723b_fw_try_ap_cmd(PADAPTER padapter, u32 need_ack)
2560 rtl8723b_set_FwAPReqRPT_cmd(padapter, need_ack);
2564 #ifdef CONFIG_BT_COEXIST
2565 static void ConstructBtNullFunctionData(
2575 struct rtw_ieee80211_hdr *pwlanhdr;
2578 struct mlme_ext_priv *pmlmeext;
2579 struct mlme_ext_info *pmlmeinfo;
2583 DBG_871X("+" FUNC_ADPT_FMT ": qos=%d eosp=%d ps=%d\n",
2584 FUNC_ADPT_ARG(padapter), bQoS, bEosp, bForcePowerSave);
2586 pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
2587 pmlmeext = &padapter->mlmeextpriv;
2588 pmlmeinfo = &pmlmeext->mlmext_info;
2590 if (NULL == StaAddr)
2592 _rtw_memcpy(bssid, myid(&padapter->eeprompriv), ETH_ALEN);
2596 fctrl = &pwlanhdr->frame_ctl;
2598 if (bForcePowerSave)
2602 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
2603 _rtw_memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
2604 _rtw_memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
2606 SetDuration(pwlanhdr, 0);
2607 SetSeqNum(pwlanhdr, 0);
2611 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
2613 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
2615 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;
2616 SetPriority(&pwlanqoshdr->qc, AC);
2617 SetEOSP(&pwlanqoshdr->qc, bEosp);
2619 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
2623 SetFrameSubType(pframe, WIFI_DATA_NULL);
2625 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2631 static void SetFwRsvdPagePkt_BTCoex(PADAPTER padapter)
2633 PHAL_DATA_TYPE pHalData;
2634 struct xmit_frame *pcmdframe;
2635 struct pkt_attrib *pattrib;
2636 struct xmit_priv *pxmitpriv;
2637 struct mlme_ext_priv *pmlmeext;
2638 struct mlme_ext_info *pmlmeinfo;
2639 u32 BeaconLength = 0;
2640 u32 BTQosNullLength = 0;
2641 u8 *ReservedPagePacket;
2642 u8 TxDescLen, TxDescOffset;
2643 u8 TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0;
2644 u16 BufIndex, PageSize;
2645 u32 TotalPacketLen, MaxRsvdPageBufSize=0;
2646 RSVDPAGE_LOC RsvdPageLoc;
2649 // DBG_8192C("+" FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter));
2651 pHalData = GET_HAL_DATA(padapter);
2652 pxmitpriv = &padapter->xmitpriv;
2653 pmlmeext = &padapter->mlmeextpriv;
2654 pmlmeinfo = &pmlmeext->mlmext_info;
2655 TxDescLen = TXDESC_SIZE;
2656 TxDescOffset = TXDESC_OFFSET;
2657 PageSize = PAGE_SIZE_TX_8723B;
2659 RsvdPageNum = BCNQ_PAGE_NUM_8723B;
2660 MaxRsvdPageBufSize = RsvdPageNum*PageSize;
2662 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
2663 if (pcmdframe == NULL) {
2664 DBG_8192C("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
2668 ReservedPagePacket = pcmdframe->buf_addr;
2669 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
2672 BufIndex = TxDescOffset;
2673 ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);
2675 // When we count the first page size, we need to reserve description size for the RSVD
2676 // packet, it will be filled in front of the packet in TXPKTBUF.
2677 CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength);
2678 //If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware
2679 if (CurtPktPageNum == 1)
2681 CurtPktPageNum += 1;
2683 TotalPageNum += CurtPktPageNum;
2685 BufIndex += (CurtPktPageNum*PageSize);
2687 // Jump to lastest page
2688 if (BufIndex < (MaxRsvdPageBufSize - PageSize))
2690 BufIndex = TxDescOffset + (MaxRsvdPageBufSize - PageSize);
2691 TotalPageNum = BCNQ_PAGE_NUM_8723B - 1;
2694 //3 (6) BT Qos null data
2695 RsvdPageLoc.LocBTQosNull = TotalPageNum;
2696 ConstructBtNullFunctionData(
2698 &ReservedPagePacket[BufIndex],
2701 _TRUE, 0, 0, _FALSE);
2702 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, _FALSE, _TRUE, _FALSE);
2704 CurtPktPageNum = (u8)PageNum_128(TxDescLen + BTQosNullLength);
2706 TotalPageNum += CurtPktPageNum;
2708 TotalPacketLen = BufIndex + BTQosNullLength;
2709 if (TotalPacketLen > MaxRsvdPageBufSize)
2711 DBG_8192C(FUNC_ADPT_FMT ": ERROR: The rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
2712 FUNC_ADPT_ARG(padapter), TotalPacketLen, MaxRsvdPageBufSize);
2717 pattrib = &pcmdframe->attrib;
2718 update_mgntframe_attrib(padapter, pattrib);
2719 pattrib->qsel = QSLT_BEACON;
2720 pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
2721 #ifdef CONFIG_PCI_HCI
2722 dump_mgntframe(padapter, pcmdframe);
2724 dump_mgntframe_and_wait(padapter, pcmdframe, 100);
2727 // DBG_8192C(FUNC_ADPT_FMT ": Set RSVD page location to Fw, TotalPacketLen(%d), TotalPageNum(%d)\n",
2728 // FUNC_ADPT_ARG(padapter), TotalPacketLen, TotalPageNum);
2729 rtl8723b_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc);
2730 rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);
2735 rtw_free_xmitframe(pxmitpriv, pcmdframe);
2738 void rtl8723b_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter)
2740 PHAL_DATA_TYPE pHalData;
2741 struct mlme_ext_priv *pmlmeext;
2742 struct mlme_ext_info *pmlmeinfo;
2743 u8 bRecover = _FALSE;
2744 u8 bcn_valid = _FALSE;
2750 DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d fw_state=0x%08X\n",
2751 FUNC_ADPT_ARG(padapter), get_iface_type(padapter), get_fwstate(&padapter->mlmepriv));
2754 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _FALSE)
2756 DBG_8192C(FUNC_ADPT_FMT ": [WARNING] not in AP mode!!\n",
2757 FUNC_ADPT_ARG(padapter));
2759 #endif // CONFIG_DEBUG
2761 pHalData = GET_HAL_DATA(padapter);
2762 pmlmeext = &padapter->mlmeextpriv;
2763 pmlmeinfo = &pmlmeext->mlmext_info;
2765 // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.
2766 // Suggested by filen. Added by tynli.
2767 rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));
2770 val8 = rtw_read8(padapter, REG_CR+1);
2771 val8 |= BIT(0); // ENSWBCN
2772 rtw_write8(padapter, REG_CR+1, val8);
2774 // Disable Hw protection for a time which revserd for Hw sending beacon.
2775 // Fix download reserved page packet fail that access collision with the protection time.
2776 // 2010.05.11. Added by tynli.
2777 val8 = rtw_read8(padapter, REG_BCN_CTRL);
2778 val8 &= ~EN_BCN_FUNCTION;
2779 val8 |= DIS_TSF_UDT;
2780 rtw_write8(padapter, REG_BCN_CTRL, val8);
2782 // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
2783 if (pHalData->RegFwHwTxQCtrl & BIT(6))
2786 // To tell Hw the packet is not a real beacon frame.
2787 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
2788 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
2790 // Clear beacon valid check bit.
2791 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
2792 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
2797 SetFwRsvdPagePkt_BTCoex(padapter);
2801 // rtw_mdelay_os(10);
2802 // check rsvd page download OK.
2803 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, &bcn_valid);
2805 } while (!bcn_valid && (poll%10)!=0 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
2806 } while (!bcn_valid && (DLBcnCount<=100) && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
2808 if (_TRUE == bcn_valid)
2810 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
2811 pwrctl->fw_psmode_iface_id = padapter->iface_id;
2812 DBG_8192C(ADPT_FMT": DL RSVD page success! DLBcnCount:%d, poll:%d\n",
2813 ADPT_ARG(padapter), DLBcnCount, poll);
2817 DBG_8192C(ADPT_FMT": DL RSVD page fail! DLBcnCount:%d, poll:%d\n",
2818 ADPT_ARG(padapter), DLBcnCount, poll);
2819 DBG_8192C(ADPT_FMT": DL RSVD page fail! bSurpriseRemoved=%d\n",
2820 ADPT_ARG(padapter), padapter->bSurpriseRemoved);
2821 DBG_8192C(ADPT_FMT": DL RSVD page fail! bDriverStopped=%d\n",
2822 ADPT_ARG(padapter), padapter->bDriverStopped);
2825 // 2010.05.11. Added by tynli.
2826 val8 = rtw_read8(padapter, REG_BCN_CTRL);
2827 val8 |= EN_BCN_FUNCTION;
2828 val8 &= ~DIS_TSF_UDT;
2829 rtw_write8(padapter, REG_BCN_CTRL, val8);
2831 // To make sure that if there exists an adapter which would like to send beacon.
2832 // If exists, the origianl value of 0x422[6] will be 1, we should check this to
2833 // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
2834 // the beacon cannot be sent by HW.
2835 // 2010.06.23. Added by tynli.
2838 pHalData->RegFwHwTxQCtrl |= BIT(6);
2839 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
2842 // Clear CR[8] or beacon packet will not be send to TxBuf anymore.
2843 #ifndef CONFIG_PCI_HCI
2844 val8 = rtw_read8(padapter, REG_CR+1);
2845 val8 &= ~BIT(0); // ~ENSWBCN
2846 rtw_write8(padapter, REG_CR+1, val8);
2849 #endif // CONFIG_BT_COEXIST
2852 void rtl8723b_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state)
2854 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2855 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2856 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
2857 struct P2P_PS_Offload_t *p2p_ps_offload = (struct P2P_PS_Offload_t *)(&pHalData->p2p_ps_offload);
2863 switch(p2p_ps_state)
2865 case P2P_PS_DISABLE:
2866 DBG_8192C("P2P_PS_DISABLE \n");
2867 _rtw_memset(p2p_ps_offload, 0 ,1);
2870 DBG_8192C("P2P_PS_ENABLE \n");
2871 // update CTWindow value.
2872 if( pwdinfo->ctwindow > 0 )
2874 p2p_ps_offload->CTWindow_En = 1;
2875 rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow);
2878 // hw only support 2 set of NoA
2879 for( i=0 ; i<pwdinfo->noa_num ; i++)
2881 // To control the register setting for which NOA
2882 rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4));
2884 p2p_ps_offload->NoA0_En = 1;
2886 p2p_ps_offload->NoA1_En = 1;
2888 // config P2P NoA Descriptor Register
2889 //DBG_8192C("%s(): noa_duration = %x\n",__FUNCTION__,pwdinfo->noa_duration[i]);
2890 rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);
2892 //DBG_8192C("%s(): noa_interval = %x\n",__FUNCTION__,pwdinfo->noa_interval[i]);
2893 rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);
2895 //DBG_8192C("%s(): start_time = %x\n",__FUNCTION__,pwdinfo->noa_start_time[i]);
2896 rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);
2898 //DBG_8192C("%s(): noa_count = %x\n",__FUNCTION__,pwdinfo->noa_count[i]);
2899 rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);
2902 if( (pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0) )
2905 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4));
2907 p2p_ps_offload->Offload_En = 1;
2909 if(pwdinfo->role == P2P_ROLE_GO)
2911 p2p_ps_offload->role= 1;
2912 p2p_ps_offload->AllStaSleep = 0;
2916 p2p_ps_offload->role= 0;
2919 p2p_ps_offload->discovery = 0;
2923 DBG_8192C("P2P_PS_SCAN \n");
2924 p2p_ps_offload->discovery = 1;
2926 case P2P_PS_SCAN_DONE:
2927 DBG_8192C("P2P_PS_SCAN_DONE \n");
2928 p2p_ps_offload->discovery = 0;
2929 pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
2935 FillH2CCmd8723B(padapter, H2C_8723B_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
2944 #ifdef CONFIG_TSF_RESET_OFFLOAD
2946 ask FW to Reset sync register at Beacon early interrupt
2948 u8 rtl8723b_reset_tsf(_adapter *padapter, u8 reset_port )
2954 if (IFACE_PORT0==reset_port) {
2955 buf[0] = 0x1; buf[1] = 0;
2958 buf[0] = 0x0; buf[1] = 0x1;
2960 FillH2CCmd8723B(padapter, H2C_8723B_RESET_TSF, 2, buf);
2965 #endif // CONFIG_TSF_RESET_OFFLOAD