1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * 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 _RTL8188E_CMD_C_
22 #include <drv_types.h>
23 #include <rtl8188e_hal.h>
24 #include "hal_com_h2c.h"
28 #define RTL88E_MAX_H2C_BOX_NUMS 4
29 #define RTL88E_MAX_CMD_LEN 7
30 #define RTL88E_MESSAGE_BOX_SIZE 4
31 #define RTL88E_EX_MESSAGE_BOX_SIZE 4
33 static u8 _is_fw_read_cmd_down(_adapter* padapter, u8 msgbox_num)
35 u8 read_down = _FALSE;
40 //DBG_8192C(" _is_fw_read_cmd_down ,reg_1cc(%x),msg_box(%d)...\n",rtw_read8(padapter,REG_HMETFR),msgbox_num);
43 valid = rtw_read8(padapter,REG_HMETFR) & BIT(msgbox_num);
49 }while( (!read_down) && (retry_cnts--));
56 /*****************************************
59 *| 31 - 8 | 7-5 4 - 0 |
60 *| h2c_msg |Class_ID CMD_ID |
62 * Extend 0x1FF - 0x1F0
65 ******************************************/
66 s32 FillH2CCmd_88E(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)
68 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
69 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
72 u32 msgbox_ex_addr = 0;
73 u8 cmd_idx,ext_cmd_len;
80 padapter = GET_PRIMARY_ADAPTER(padapter);
81 pHalData = GET_HAL_DATA(padapter);
83 if(padapter->bFWReady == _FALSE)
85 DBG_8192C("FillH2CCmd_88E(): return H2C cmd because fw is not ready\n");
89 _enter_critical_mutex(&(dvobj->h2c_fwcmd_mutex), NULL);
94 if (CmdLen > RTL88E_MAX_CMD_LEN) {
97 if (rtw_is_surprise_removed(padapter))
100 //pay attention to if race condition happened in H2C cmd setting.
102 h2c_box_num = pHalData->LastHMEBoxNum;
104 if(!_is_fw_read_cmd_down(padapter, h2c_box_num)){
105 DBG_8192C(" fw read cmd failed...\n");
109 *(u8*)(&h2c_cmd) = ElementID;
113 _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, CmdLen );
116 _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer,3);
117 ext_cmd_len = CmdLen-3;
118 _rtw_memcpy((u8*)(&h2c_cmd_ex), pCmdBuffer+3,ext_cmd_len );
121 msgbox_ex_addr = REG_HMEBOX_EXT_0 + (h2c_box_num *RTL88E_EX_MESSAGE_BOX_SIZE);
123 for(cmd_idx=0;cmd_idx<ext_cmd_len;cmd_idx++ ){
124 rtw_write8(padapter,msgbox_ex_addr+cmd_idx,*((u8*)(&h2c_cmd_ex)+cmd_idx));
127 h2c_cmd_ex = le32_to_cpu( h2c_cmd_ex );
128 rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex);
132 msgbox_addr =REG_HMEBOX_0 + (h2c_box_num *RTL88E_MESSAGE_BOX_SIZE);
134 for(cmd_idx=0;cmd_idx<RTL88E_MESSAGE_BOX_SIZE;cmd_idx++ ){
135 rtw_write8(padapter,msgbox_addr+cmd_idx,*((u8*)(&h2c_cmd)+cmd_idx));
138 h2c_cmd = le32_to_cpu( h2c_cmd );
139 rtw_write32(padapter,msgbox_addr, h2c_cmd);
143 // DBG_8192C("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n"
144 // ,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex);
146 pHalData->LastHMEBoxNum = (h2c_box_num+1) % RTL88E_MAX_H2C_BOX_NUMS;
154 _exit_critical_mutex(&(dvobj->h2c_fwcmd_mutex), NULL);
161 u8 rtl8192c_h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
163 u8 ElementID, CmdLen;
165 struct cmd_msg_parm *pcmdmsg;
168 return H2C_PARAMETERS_ERROR;
170 pcmdmsg = (struct cmd_msg_parm*)pbuf;
171 ElementID = pcmdmsg->eid;
172 CmdLen = pcmdmsg->sz;
173 pCmdBuffer = pcmdmsg->buf;
175 FillH2CCmd_88E(padapter, ElementID, CmdLen, pCmdBuffer);
180 #if defined(CONFIG_AUTOSUSPEND) && defined(SUPPORT_HW_RFOFF_DETECTED)
181 u8 rtl8192c_set_FwSelectSuspend_cmd(_adapter *padapter ,u8 bfwpoll, u16 period)
184 struct H2C_SS_RFOFF_PARAM param;
185 DBG_8192C("==>%s bfwpoll(%x)\n",__FUNCTION__,bfwpoll);
186 param.gpio_period = period;//Polling GPIO_11 period time
187 param.ROFOn = (_TRUE == bfwpoll)?1:0;
188 FillH2CCmd_88E(padapter, SELECTIVE_SUSPEND_ROF_CMD, sizeof(param), (u8*)(¶m));
191 #endif //CONFIG_AUTOSUSPEND && SUPPORT_HW_RFOFF_DETECTED
193 u8 rtl8188e_set_rssi_cmd(_adapter*padapter, u8 *param)
196 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
199 if(pHalData->fw_ractrl == _FALSE){
200 DBG_8192C("==>%s fw dont support RA \n",__FUNCTION__);
204 *((u32*) param ) = cpu_to_le32( *((u32*) param ) );
205 FillH2CCmd_88E(padapter, H2C_RSSI_REPORT, 3, param);
212 u8 rtl8188e_set_raid_cmd(_adapter*padapter, u32 bitmap, u8* arg)
215 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
216 struct sta_info *psta = NULL;
217 struct macid_ctl_t *macid_ctl = &padapter->dvobj->macid_ctl;
218 u8 macid, init_rate, raid, shortGIrate=_FALSE;
219 u8 H2CCommand[7]={0};
221 if(pHalData->fw_ractrl == _FALSE){
222 DBG_8192C("==>%s fw dont support RA \n",__FUNCTION__);
228 shortGIrate = arg[2];
231 if (macid < macid_ctl->num)
232 psta = macid_ctl->sta[macid];
234 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" macid:%u, sta is NULL\n"
235 , FUNC_ADPT_ARG(padapter), macid);
239 H2CCommand[0] = macid;
240 H2CCommand[1] = raid | (shortGIrate?0x80:0x00) ;
241 H2CCommand[2] = psta->bw_mode & 0x03; //BW;
243 #ifdef CONFIG_INTEL_PROXIM
244 if(padapter->proximity.proxim_on ==_TRUE)
245 pHalData->bDisableTXPowerTraining = _FALSE;
248 //DisableTXPowerTraining
249 if(pHalData->bDisableTXPowerTraining){
250 H2CCommand[2] |= BIT6;
251 DBG_871X("%s,Disable PWT by driver\n",__FUNCTION__);
254 PDM_ODM_T pDM_OutSrc = &pHalData->odmpriv;
256 if(pDM_OutSrc->bDisablePowerTraining){
257 H2CCommand[2] |= BIT6;
258 DBG_871X("%s,Disable PWT by DM\n",__FUNCTION__);
262 H2CCommand[3] = (u1Byte)(bitmap & 0x000000ff);
263 H2CCommand[4] = (u1Byte)((bitmap & 0x0000ff00) >>8);
264 H2CCommand[5] = (u1Byte)((bitmap & 0x00ff0000) >> 16);
265 H2CCommand[6] = (u1Byte)((bitmap & 0xff000000) >> 24);
267 FillH2CCmd_88E(padapter, H2C_DM_MACID_CFG, 7, H2CCommand);
269 //The firmware Rate Adaption function is triggered by TBTT INT, so to
270 // enable the rate adaption, we need to enable the hardware Beacon function Reg 0x550[3]
271 //SetBcnCtrlReg(padapter, BIT3, 0);
272 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|BIT3);
278 //bitmap[0:27] = tx_rate_bitmap
279 //bitmap[28:31]= Rate Adaptive id
282 void rtl8188e_Add_RateATid(PADAPTER pAdapter, u64 rate_bitmap, u8 *arg, u8 rssi_level)
284 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
285 u8 macid, init_rate, raid, shortGIrate=_FALSE;
286 u32 bitmap = (u32) rate_bitmap;
290 shortGIrate = arg[2];
295 if(rssi_level != DM_RATR_STA_INIT)
296 bitmap = ODM_Get_Rate_Bitmap(&pHalData->odmpriv, macid, bitmap, rssi_level);
298 if (shortGIrate==_TRUE)
301 bitmap &= 0x0fffffff;
303 DBG_871X("%s=> mac_id:%d , raid:%d , ra_bitmap=0x%x, shortGIrate=0x%02x\n",
304 __FUNCTION__,macid ,raid ,bitmap, shortGIrate);
307 #if(RATE_ADAPTIVE_SUPPORT == 1)
308 if(!pHalData->fw_ractrl ){
309 ODM_RA_UpdateRateInfo_8188E(
310 &(pHalData->odmpriv),
320 rtl8188e_set_raid_cmd(pAdapter,bitmap,arg);
326 void rtl8188e_set_FwPwrMode_cmd(PADAPTER padapter, u8 Mode)
328 SETPWRMODE_PARM H2CSetPwrMode;
329 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
330 u8 RLBM = 0; // 0:Min, 1:Max , 2:User define
333 DBG_871X("%s: Mode=%d SmartPS=%d UAPSD=%d\n", __FUNCTION__,
334 Mode, pwrpriv->smart_ps, padapter->registrypriv.uapsd_enable);
336 H2CSetPwrMode.AwakeInterval = 2; //DTIM = 1
341 H2CSetPwrMode.Mode = 0;
344 H2CSetPwrMode.Mode = 1;
348 H2CSetPwrMode.Mode = 1;
352 H2CSetPwrMode.AwakeInterval = 3; //DTIM = 2
353 H2CSetPwrMode.Mode = 1;
355 case PS_MODE_UAPSD_WMM:
356 H2CSetPwrMode.Mode = 2;
359 H2CSetPwrMode.Mode = 0;
363 //H2CSetPwrMode.Mode = Mode;
365 H2CSetPwrMode.SmartPS_RLBM = (((pwrpriv->smart_ps<<4)&0xf0) | (RLBM & 0x0f));
367 H2CSetPwrMode.bAllQueueUAPSD = padapter->registrypriv.uapsd_enable;
371 H2CSetPwrMode.PwrState = 0x00;// AllON(0x0C), RFON(0x04), RFOFF(0x00)
372 #ifdef CONFIG_EXT_CLK
373 H2CSetPwrMode.Mode |= BIT(7);//supporting 26M XTAL CLK_Request feature.
374 #endif //CONFIG_EXT_CLK
377 H2CSetPwrMode.PwrState = 0x0C;// AllON(0x0C), RFON(0x04), RFOFF(0x00)
379 FillH2CCmd_88E(padapter, H2C_PS_PWR_MODE, sizeof(H2CSetPwrMode), (u8 *)&H2CSetPwrMode);
385 void ConstructBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
387 struct rtw_ieee80211_hdr *pwlanhdr;
389 u32 rate_len, pktlen;
390 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
391 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
392 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
393 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
396 //DBG_871X("%s\n", __FUNCTION__);
398 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
400 fctrl = &(pwlanhdr->frame_ctl);
403 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
404 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
405 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
407 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
408 //pmlmeext->mgnt_seq++;
409 SetFrameSubType(pframe, WIFI_BEACON);
411 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
412 pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
414 //timestamp will be inserted by hardware
418 // beacon interval: 2 bytes
419 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
424 // capability info: 2 bytes
425 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
430 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
432 //DBG_871X("ie len=%d\n", cur_network->IELength);
433 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
434 _rtw_memcpy(pframe, cur_network->IEs+sizeof(NDIS_802_11_FIXED_IEs), pktlen);
436 goto _ConstructBeacon;
439 //below for ad-hoc mode
442 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
444 // supported rates...
445 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
446 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen);
449 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
451 if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
454 // IBSS Parameter Set...
455 //ATIMWindow = cur->Configuration.ATIMWindow;
457 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
464 // EXTERNDED SUPPORTED RATE
467 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
475 if ((pktlen + TXDESC_SIZE) > 512)
477 DBG_871X("beacon frame too large\n");
483 //DBG_871X("%s bcn_sz=%d\n", __FUNCTION__, pktlen);
487 void ConstructPSPoll(_adapter *padapter, u8 *pframe, u32 *pLength)
489 struct rtw_ieee80211_hdr *pwlanhdr;
492 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
493 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
495 //DBG_871X("%s\n", __FUNCTION__);
497 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
500 fctrl = &(pwlanhdr->frame_ctl);
503 SetFrameSubType(pframe, WIFI_PSPOLL);
506 SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
509 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
512 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
517 void ConstructNullFunctionData(
527 struct rtw_ieee80211_hdr *pwlanhdr;
530 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
531 struct wlan_network *cur_network = &pmlmepriv->cur_network;
532 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
533 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
536 //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
538 pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
540 fctrl = &pwlanhdr->frame_ctl;
547 switch(cur_network->network.InfrastructureMode)
549 case Ndis802_11Infrastructure:
551 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
552 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
553 _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
555 case Ndis802_11APMode:
557 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
558 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
559 _rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
563 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
564 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
565 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
569 SetSeqNum(pwlanhdr, 0);
572 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
574 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
576 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;
577 SetPriority(&pwlanqoshdr->qc, AC);
578 SetEOSP(&pwlanqoshdr->qc, bEosp);
580 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
582 SetFrameSubType(pframe, WIFI_DATA_NULL);
584 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
590 void rtl8188e_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
592 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN]={0};
593 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};
595 //DBG_871X("8188RsvdPageLoc: PsPoll=%d Null=%d QoSNull=%d\n",
596 // rsvdpageloc->LocPsPoll, rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull);
598 SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
599 SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
600 SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
602 FillH2CCmd_88E(padapter, H2C_COM_RSVD_PAGE, H2C_RSVDPAGE_LOC_LEN, u1H2CRsvdPageParm);
605 //DBG_871X("8188E_AOACRsvdPageLoc: RWC=%d ArpRsp=%d\n", rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp);
606 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
607 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
609 FillH2CCmd_88E(padapter, H2C_COM_AOAC_RSVD_PAGE, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm);
613 // To check if reserved page content is destroyed by beacon beacuse beacon is too large.
614 // 2010.06.23. Added by tynli.
616 CheckFwRsvdPageContent(
620 HAL_DATA_TYPE* pHalData = GET_HAL_DATA(Adapter);
623 if(pHalData->FwRsvdPageStartOffset != 0)
625 /*MaxBcnPageNum = PageNum_128(pMgntInfo->MaxBeaconSize);
626 RT_ASSERT((MaxBcnPageNum <= pHalData->FwRsvdPageStartOffset),
627 ("CheckFwRsvdPageContent(): The reserved page content has been"\
628 "destroyed by beacon!!! MaxBcnPageNum(%d) FwRsvdPageStartOffset(%d)\n!",
629 MaxBcnPageNum, pHalData->FwRsvdPageStartOffset));*/
634 // Description: Get the reserved page number in Tx packet buffer.
635 // Retrun value: the page number.
636 // 2012.08.09, by tynli.
639 GetTxBufferRsvdPageNum8188E(_adapter *padapter, bool wowlan)
641 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
643 // default reseved 1 page for the IC type which is undefined.
644 u8 TxPageBndy= LAST_ENTRY_OF_TX_PKT_BUFFER_8188E(padapter);
646 rtw_hal_get_def_var(padapter, HAL_DEF_TX_PAGE_BOUNDARY, (u8 *)&TxPageBndy);
648 RsvdPageNum = LAST_ENTRY_OF_TX_PKT_BUFFER_8188E(padapter) - TxPageBndy + 1;
653 void rtl8188e_set_FwJoinBssReport_cmd(PADAPTER padapter, u8 mstatus)
655 JOINBSSRPT_PARM_88E JoinBssRptParm;
656 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
657 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
658 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
660 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
661 struct sta_info *psta = NULL;
663 BOOLEAN bSendBeacon=_FALSE;
664 BOOLEAN bcn_valid = _FALSE;
670 DBG_871X("%s mstatus(%x)\n", __FUNCTION__,mstatus);
674 // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.
675 // Suggested by filen. Added by tynli.
676 rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));
677 // Do not set TSF again here or vWiFi beacon DMA INT will not work.
678 //correct_TSF(padapter, pmlmeext);
679 // Hw sequende enable by dedault. 2010.06.23. by tynli.
680 //rtw_write16(padapter, REG_NQOS_SEQ, ((pmlmeext->mgnt_seq+100)&0xFFF));
681 //rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF);
683 //Set REG_CR bit 8. DMA beacon by SW.
684 pHalData->RegCR_1 |= BIT0;
685 rtw_write8(padapter, REG_CR+1, pHalData->RegCR_1);
687 // Disable Hw protection for a time which revserd for Hw sending beacon.
688 // Fix download reserved page packet fail that access collision with the protection time.
689 // 2010.05.11. Added by tynli.
690 //SetBcnCtrlReg(padapter, 0, BIT3);
691 //SetBcnCtrlReg(padapter, BIT4, 0);
692 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)&(~BIT(3)));
693 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|BIT(4));
695 if(pHalData->RegFwHwTxQCtrl&BIT6)
697 DBG_871X("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n");
701 // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
702 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl&(~BIT6)));
703 pHalData->RegFwHwTxQCtrl &= (~BIT6);
705 // Clear beacon valid check bit.
706 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
711 /* download rsvd page.*/
712 rtw_hal_set_fw_rsvd_page(padapter, _FALSE);
718 // check rsvd page download OK.
719 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8*)(&bcn_valid));
721 } while (!bcn_valid && (poll%10) != 0 && !RTW_CANNOT_RUN(padapter));
723 } while (!bcn_valid && DLBcnCount <= 100 && !RTW_CANNOT_RUN(padapter));
725 //RT_ASSERT(bcn_valid, ("HalDownloadRSVDPage88ES(): 1 Download RSVD page failed!\n"));
726 if (RTW_CANNOT_RUN(padapter))
729 DBG_871X(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n",
730 ADPT_ARG(padapter) ,DLBcnCount, poll);
732 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
733 pwrctl->fw_psmode_iface_id = padapter->iface_id;
734 DBG_871X(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n",
735 ADPT_ARG(padapter), DLBcnCount, poll);
739 //SetBcnCtrlReg(padapter, BIT3, 0);
740 //SetBcnCtrlReg(padapter, 0, BIT4);
741 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|BIT(3));
742 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)&(~BIT(4)));
744 // To make sure that if there exists an adapter which would like to send beacon.
745 // If exists, the origianl value of 0x422[6] will be 1, we should check this to
746 // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
747 // the beacon cannot be sent by HW.
748 // 2010.06.23. Added by tynli.
751 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl|BIT6));
752 pHalData->RegFwHwTxQCtrl |= BIT6;
756 // Update RSVD page location H2C to Fw.
760 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
761 DBG_871X("Set RSVD page location to Fw.\n");
762 //FillH2CCmd88E(Adapter, H2C_88E_RSVDPAGE, H2C_RSVDPAGE_LOC_LENGTH, pMgntInfo->u1RsvdPageLoc);
765 // Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.
766 //if(!padapter->bEnterPnpSleep)
768 // Clear CR[8] or beacon packet will not be send to TxBuf anymore.
769 pHalData->RegCR_1 &= (~BIT0);
770 rtw_write8(padapter, REG_CR+1, pHalData->RegCR_1);
777 void rtl8188e_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state)
779 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
780 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
781 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
782 struct P2P_PS_Offload_t *p2p_ps_offload = (struct P2P_PS_Offload_t *)(&pHalData->p2p_ps_offload);
791 DBG_8192C("P2P_PS_DISABLE \n");
792 _rtw_memset(p2p_ps_offload, 0 ,1);
795 DBG_8192C("P2P_PS_ENABLE \n");
796 // update CTWindow value.
797 if( pwdinfo->ctwindow > 0 )
799 p2p_ps_offload->CTWindow_En = 1;
800 rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow);
803 // hw only support 2 set of NoA
804 for( i=0 ; i<pwdinfo->noa_num ; i++)
806 // To control the register setting for which NOA
807 rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4));
809 p2p_ps_offload->NoA0_En = 1;
811 p2p_ps_offload->NoA1_En = 1;
813 // config P2P NoA Descriptor Register
814 //DBG_8192C("%s(): noa_duration = %x\n",__FUNCTION__,pwdinfo->noa_duration[i]);
815 rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);
817 //DBG_8192C("%s(): noa_interval = %x\n",__FUNCTION__,pwdinfo->noa_interval[i]);
818 rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);
820 //DBG_8192C("%s(): start_time = %x\n",__FUNCTION__,pwdinfo->noa_start_time[i]);
821 rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);
823 //DBG_8192C("%s(): noa_count = %x\n",__FUNCTION__,pwdinfo->noa_count[i]);
824 rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);
827 if( (pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0) )
830 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4));
832 p2p_ps_offload->Offload_En = 1;
834 if(pwdinfo->role == P2P_ROLE_GO)
836 p2p_ps_offload->role= 1;
837 p2p_ps_offload->AllStaSleep = 0;
841 p2p_ps_offload->role= 0;
844 p2p_ps_offload->discovery = 0;
848 DBG_8192C("P2P_PS_SCAN \n");
849 p2p_ps_offload->discovery = 1;
851 case P2P_PS_SCAN_DONE:
852 DBG_8192C("P2P_PS_SCAN_DONE \n");
853 p2p_ps_offload->discovery = 0;
854 pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
860 FillH2CCmd_88E(padapter, H2C_PS_P2P_OFFLOAD, 1, (u8 *)p2p_ps_offload);
866 #endif //CONFIG_P2P_PS
868 #ifdef CONFIG_TSF_RESET_OFFLOAD
870 ask FW to Reset sync register at Beacon early interrupt
872 u8 rtl8188e_reset_tsf(_adapter *padapter, u8 reset_port )
879 if (IFACE_PORT0==reset_port) {
880 buf[0] = 0x1; buf[1] = 0;
882 buf[0] = 0x0; buf[1] = 0x1;
885 ret = FillH2CCmd_88E(padapter, H2C_RESET_TSF, 2, buf);
892 int reset_tsf(PADAPTER Adapter, u8 reset_port )
894 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
895 u32 reg_reset_tsf_cnt = (IFACE_PORT0==reset_port) ?
896 REG_FW_RESET_TSF_CNT_0:REG_FW_RESET_TSF_CNT_1;
897 u32 reg_bcncrtl = (IFACE_PORT0==reset_port) ?
898 REG_BCN_CTRL_1:REG_BCN_CTRL;
900 rtw_scan_abort(Adapter->pbuddy_adapter); /* site survey will cause reset_tsf fail */
901 reset_cnt_after = reset_cnt_before = rtw_read8(Adapter,reg_reset_tsf_cnt);
902 rtl8188e_reset_tsf(Adapter, reset_port);
904 while ((reset_cnt_after == reset_cnt_before ) && (loop_cnt < 10)) {
907 reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt);
910 return(loop_cnt >= 10) ? _FAIL : _TRUE;
914 #endif // CONFIG_TSF_RESET_OFFLOAD