1 /******************************************************************************
\r
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
\r
5 * This program is free software; you can redistribute it and/or modify it
\r
6 * under the terms of version 2 of the GNU General Public License as
\r
7 * published by the Free Software Foundation.
\r
9 * This program is distributed in the hope that it will be useful, but WITHOUT
\r
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
14 * You should have received a copy of the GNU General Public License along with
\r
15 * this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
\r
19 ******************************************************************************/
\r
20 #define _RTL8723B_CMD_C_
\r
22 #include <rtl8723b_hal.h>
\r
23 #include "hal_com_h2c.h"
\r
25 #define MAX_H2C_BOX_NUMS 4
\r
26 #define MESSAGE_BOX_SIZE 4
\r
28 #define RTL8723B_MAX_CMD_LEN 7
\r
29 #define RTL8723B_EX_MESSAGE_BOX_SIZE 4
\r
31 static u8 _is_fw_read_cmd_down(_adapter* padapter, u8 msgbox_num)
\r
33 u8 read_down = _FALSE;
\r
34 int retry_cnts = 100;
\r
38 //DBG_8192C(" _is_fw_read_cmd_down ,reg_1cc(%x),msg_box(%d)...\n",rtw_read8(padapter,REG_HMETFR),msgbox_num);
\r
41 valid = rtw_read8(padapter,REG_HMETFR) & BIT(msgbox_num);
\r
45 #ifdef CONFIG_WOWLAN
\r
49 }while( (!read_down) && (retry_cnts--));
\r
56 /*****************************************
\r
58 *| 31 - 8 |7-5 | 4 - 0 |
\r
59 *| h2c_msg |Class |CMD_ID |
\r
63 ******************************************/
\r
64 s32 FillH2CCmd8723B(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)
\r
66 u8 bcmd_down = _FALSE;
\r
67 s32 retry_cnts = 100;
\r
70 u32 msgbox_ex_addr=0;
\r
71 PHAL_DATA_TYPE pHalData;
\r
75 struct dvobj_priv *psdpriv = padapter->dvobj;
\r
76 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
\r
79 padapter = GET_PRIMARY_ADAPTER(padapter);
\r
80 pHalData = GET_HAL_DATA(padapter);
\r
81 #ifdef DBG_CHECK_FW_PS_STATE
\r
82 #ifdef DBG_CHECK_FW_PS_STATE_H2C
\r
83 if(rtw_fw_ps_state(padapter) == _FAIL)
\r
85 DBG_871X("%s: h2c doesn't leave 32k ElementID=%02x \n", __FUNCTION__, ElementID);
\r
86 pdbgpriv->dbg_h2c_leave32k_fail_cnt++;
\r
89 //DBG_871X("H2C ElementID=%02x , pHalData->LastHMEBoxNum=%02x\n", ElementID, pHalData->LastHMEBoxNum);
\r
90 #endif //DBG_CHECK_FW_PS_STATE_H2C
\r
91 #endif //DBG_CHECK_FW_PS_STATE
\r
92 _enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);
\r
97 if(CmdLen > RTL8723B_MAX_CMD_LEN) {
\r
100 if (padapter->bSurpriseRemoved == _TRUE)
\r
103 //pay attention to if race condition happened in H2C cmd setting.
\r
105 h2c_box_num = pHalData->LastHMEBoxNum;
\r
107 if(!_is_fw_read_cmd_down(padapter, h2c_box_num)){
\r
108 DBG_8192C(" fw read cmd failed...\n");
\r
109 #ifdef DBG_CHECK_FW_PS_STATE
\r
110 DBG_871X("MAC_1C0=%08x, MAC_1C4=%08x, MAC_1C8=%08x, MAC_1CC=%08x\n", rtw_read32(padapter, 0x1c0), rtw_read32(padapter, 0x1c4)
\r
111 , rtw_read32(padapter, 0x1c8), rtw_read32(padapter, 0x1cc));
\r
112 #endif //DBG_CHECK_FW_PS_STATE
\r
113 //DBG_8192C(" 0x1c0: 0x%8x\n", rtw_read32(padapter, 0x1c0));
\r
114 //DBG_8192C(" 0x1c4: 0x%8x\n", rtw_read32(padapter, 0x1c4));
\r
120 _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, CmdLen );
\r
123 _rtw_memcpy((u8*)(&h2c_cmd)+1, pCmdBuffer, 3);
\r
124 _rtw_memcpy((u8*)(&h2c_cmd_ex), pCmdBuffer+3, CmdLen-3);
\r
125 // *(u8*)(&h2c_cmd) |= BIT(7);
\r
128 *(u8*)(&h2c_cmd) |= ElementID;
\r
131 msgbox_ex_addr = REG_HMEBOX_EXT0_8723B + (h2c_box_num *RTL8723B_EX_MESSAGE_BOX_SIZE);
\r
132 h2c_cmd_ex = le32_to_cpu( h2c_cmd_ex );
\r
133 rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex);
\r
135 msgbox_addr =REG_HMEBOX_0 + (h2c_box_num *MESSAGE_BOX_SIZE);
\r
136 h2c_cmd = le32_to_cpu( h2c_cmd );
\r
137 rtw_write32(padapter,msgbox_addr, h2c_cmd);
\r
141 //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"
\r
142 // ,pHalData->LastHMEBoxNum , CmdLen, ElementID, msgbox_addr, h2c_cmd, msgbox_ex_addr, h2c_cmd_ex);
\r
144 pHalData->LastHMEBoxNum = (h2c_box_num+1) % MAX_H2C_BOX_NUMS;
\r
146 }while((!bcmd_down) && (retry_cnts--));
\r
152 _exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);
\r
159 static void ConstructBeacon(_adapter *padapter, u8 *pframe, u32 *pLength)
\r
161 struct rtw_ieee80211_hdr *pwlanhdr;
\r
163 u32 rate_len, pktlen;
\r
164 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
165 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
166 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
\r
167 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
\r
170 //DBG_871X("%s\n", __FUNCTION__);
\r
172 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
174 fctrl = &(pwlanhdr->frame_ctl);
\r
177 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
\r
178 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
179 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
\r
181 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
\r
182 //pmlmeext->mgnt_seq++;
\r
183 SetFrameSubType(pframe, WIFI_BEACON);
\r
185 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
186 pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
\r
188 //timestamp will be inserted by hardware
\r
192 // beacon interval: 2 bytes
\r
193 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
\r
198 // capability info: 2 bytes
\r
199 _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
\r
204 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
\r
206 //DBG_871X("ie len=%d\n", cur_network->IELength);
\r
207 pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs);
\r
208 _rtw_memcpy(pframe, cur_network->IEs+sizeof(NDIS_802_11_FIXED_IEs), pktlen);
\r
210 goto _ConstructBeacon;
\r
213 //below for ad-hoc mode
\r
216 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen);
\r
218 // supported rates...
\r
219 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
\r
220 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen);
\r
222 // DS parameter set
\r
223 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen);
\r
225 if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
\r
228 // IBSS Parameter Set...
\r
229 //ATIMWindow = cur->Configuration.ATIMWindow;
\r
231 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen);
\r
238 // EXTERNDED SUPPORTED RATE
\r
241 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen);
\r
245 //todo:HT for adhoc
\r
249 if ((pktlen + TXDESC_SIZE) > 512)
\r
251 DBG_871X("beacon frame too large\n");
\r
257 //DBG_871X("%s bcn_sz=%d\n", __FUNCTION__, pktlen);
\r
261 static void ConstructPSPoll(_adapter *padapter, u8 *pframe, u32 *pLength)
\r
263 struct rtw_ieee80211_hdr *pwlanhdr;
\r
266 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
267 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
269 //DBG_871X("%s\n", __FUNCTION__);
\r
271 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
274 fctrl = &(pwlanhdr->frame_ctl);
\r
277 SetFrameSubType(pframe, WIFI_PSPOLL);
\r
280 SetDuration(pframe, (pmlmeinfo->aid | 0xc000));
\r
283 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
286 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
291 static void ConstructNullFunctionData(
\r
299 u8 bForcePowerSave)
\r
301 struct rtw_ieee80211_hdr *pwlanhdr;
\r
304 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
305 struct wlan_network *cur_network = &pmlmepriv->cur_network;
\r
306 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
307 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
310 //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
\r
312 pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
\r
314 fctrl = &pwlanhdr->frame_ctl;
\r
316 if (bForcePowerSave)
\r
321 switch(cur_network->network.InfrastructureMode)
\r
323 case Ndis802_11Infrastructure:
\r
325 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
326 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
327 _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN);
\r
329 case Ndis802_11APMode:
\r
331 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
\r
332 _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
333 _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
335 case Ndis802_11IBSS:
\r
337 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
\r
338 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
339 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
343 SetSeqNum(pwlanhdr, 0);
\r
345 if (bQoS == _TRUE) {
\r
346 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
\r
348 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
\r
350 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;
\r
351 SetPriority(&pwlanqoshdr->qc, AC);
\r
352 SetEOSP(&pwlanqoshdr->qc, bEosp);
\r
354 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
\r
356 SetFrameSubType(pframe, WIFI_DATA_NULL);
\r
358 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
365 #ifdef CONFIG_WOWLAN
\r
368 // Construct the ARP response packet to support ARP offload.
\r
370 static void ConstructARPResponse(
\r
377 struct rtw_ieee80211_hdr *pwlanhdr;
\r
380 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
381 struct wlan_network *cur_network = &pmlmepriv->cur_network;
\r
382 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
383 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
384 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
385 static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};
\r
386 u8 *pARPRspPkt = pframe;
\r
388 u8 *payload = pframe;
\r
389 u8 EncryptionHeadOverhead = 0;
\r
390 //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
\r
392 pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
\r
394 fctrl = &pwlanhdr->frame_ctl;
\r
397 //-------------------------------------------------------------------------
\r
399 //-------------------------------------------------------------------------
\r
400 SetFrameType(fctrl, WIFI_DATA);
\r
401 //SetFrameSubType(fctrl, 0);
\r
403 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
404 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
405 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
407 SetSeqNum(pwlanhdr, 0);
\r
408 SetDuration(pwlanhdr, 0);
\r
409 //SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0);
\r
410 //SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data);
\r
411 //SET_80211_HDR_TO_DS(pARPRspPkt, 1);
\r
412 //SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid);
\r
413 //SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress);
\r
414 //SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid);
\r
416 //SET_80211_HDR_DURATION(pARPRspPkt, 0);
\r
417 //SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0);
\r
418 #ifdef CONFIG_WAPI_SUPPORT
\r
419 *pLength = sMacHdrLng;
\r
426 //-------------------------------------------------------------------------
\r
427 // Qos Header: leave space for it if necessary.
\r
428 //-------------------------------------------------------------------------
\r
429 if(pStaQos->CurrentQosMode > QOS_DISABLE)
\r
431 SET_80211_HDR_QOS_EN(pARPRspPkt, 1);
\r
432 PlatformZeroMemory(&(Buffer[*pLength]), sQoSCtlLng);
\r
433 *pLength += sQoSCtlLng;
\r
436 //-------------------------------------------------------------------------
\r
437 // Security Header: leave space for it if necessary.
\r
438 //-------------------------------------------------------------------------
\r
441 switch (psecuritypriv->dot11PrivacyAlgrthm)
\r
445 EncryptionHeadOverhead = 4;
\r
448 EncryptionHeadOverhead = 8;
\r
451 EncryptionHeadOverhead = 8;
\r
453 #ifdef CONFIG_WAPI_SUPPORT
\r
455 EncryptionHeadOverhead = 18;
\r
459 EncryptionHeadOverhead = 0;
\r
462 if(EncryptionHeadOverhead > 0)
\r
464 _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);
\r
465 *pLength += EncryptionHeadOverhead;
\r
466 //SET_80211_HDR_WEP(pARPRspPkt, 1); //Suggested by CCW.
\r
470 //-------------------------------------------------------------------------
\r
472 //-------------------------------------------------------------------------
\r
473 pARPRspPkt = (u8*)(pframe+ *pLength);
\r
474 payload = pARPRspPkt; //Get Payload pointer
\r
476 _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
\r
481 SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
\r
482 SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008); // IP protocol
\r
483 SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
\r
484 SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
\r
485 SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); // ARP response
\r
486 SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, myid(&(padapter->eeprompriv)));
\r
487 SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
\r
488 #ifdef CONFIG_ARP_KEEP_ALIVE
\r
489 if (rtw_gw_addr_query(padapter)==0) {
\r
490 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
\r
491 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
\r
496 SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, get_my_bssid(&(pmlmeinfo->network)));
\r
497 SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pIPAddress);
\r
498 DBG_871X("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
\r
499 DBG_871X("%s Target IP Addr" IP_FMT "\n", __FUNCTION__, IP_ARG(pIPAddress));
\r
504 if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_)
\r
507 struct mic_data micdata;
\r
508 struct sta_info *psta = NULL;
\r
509 u8 priority[4]={0x0,0x0,0x0,0x0};
\r
510 u8 null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
\r
512 DBG_871X("%s(): Add MIC\n",__FUNCTION__);
\r
514 psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&(pmlmeinfo->network)));
\r
515 if (psta != NULL) {
\r
516 if(_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],null_key, 16)==_TRUE){
\r
517 DBG_871X("%s(): STA dot11tkiptxmickey==0\n",__FUNCTION__);
\r
519 //start to calculate the mic code
\r
520 rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
\r
523 rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); //DA
\r
525 rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); //SA
\r
528 rtw_secmicappend(&micdata, &priority[0], 4);
\r
530 rtw_secmicappend(&micdata, payload, 36); //payload length = 8 + 28
\r
532 rtw_secgetmic(&micdata,&(mic[0]));
\r
535 _rtw_memcpy(pARPRspPkt, &(mic[0]),8);
\r
541 #ifdef CONFIG_PNO_SUPPORT
\r
542 static void ConstructPnoInfo(
\r
549 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
\r
551 u8 *pPnoInfoPkt = pframe;
\r
552 pPnoInfoPkt = (u8*)(pframe+ *pLength);
\r
553 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_num, 4);
\r
557 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_period, 4);
\r
561 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->fast_scan_iterations, 4);
\r
565 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->slow_scan_period, 4);
\r
569 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_length,
\r
570 MAX_PNO_LIST_COUNT);
\r
572 *pLength+=MAX_PNO_LIST_COUNT;
\r
573 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
\r
574 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_chiper_info,
\r
575 MAX_PNO_LIST_COUNT);
\r
577 *pLength+=MAX_PNO_LIST_COUNT;
\r
578 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
\r
579 _rtw_memcpy(pPnoInfoPkt, &pwrctl->pnlo_info->ssid_channel_info,
\r
580 MAX_PNO_LIST_COUNT);
\r
582 *pLength+=MAX_PNO_LIST_COUNT;
\r
583 pPnoInfoPkt += MAX_PNO_LIST_COUNT;
\r
586 static void ConstructSSIDList(
\r
593 u8 *pSSIDListPkt = pframe;
\r
594 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
\r
596 pSSIDListPkt = (u8*)(pframe+ *pLength);
\r
598 for(i = 0; i < pwrctl->pnlo_info->ssid_num ; i++) {
\r
599 _rtw_memcpy(pSSIDListPkt, &pwrctl->pno_ssid_list->node[i].SSID,
\r
600 pwrctl->pnlo_info->ssid_length[i]);
\r
602 *pLength += WLAN_SSID_MAXLEN;
\r
603 pSSIDListPkt += WLAN_SSID_MAXLEN;
\r
607 static void ConstructScanInfo(
\r
614 u8 *pScanInfoPkt = pframe;
\r
615 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
\r
617 pScanInfoPkt = (u8*)(pframe+ *pLength);
\r
619 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->channel_num, 1);
\r
623 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_ch, 1);
\r
628 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_bw, 1);
\r
633 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_40_offset, 1);
\r
637 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->orig_80_offset, 1);
\r
641 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->periodScan, 1);
\r
645 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->period_scan_time, 1);
\r
649 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->enableRFE, 1);
\r
653 _rtw_memcpy(pScanInfoPkt, &pwrctl->pscan_info->rfe_type, 8);
\r
658 for(i = 0 ; i < MAX_SCAN_LIST_COUNT ; i ++) {
\r
659 _rtw_memcpy(pScanInfoPkt,
\r
660 &pwrctl->pscan_info->ssid_channel_info[i], 4);
\r
667 #ifdef CONFIG_GTK_OL
\r
668 static void ConstructGTKResponse(
\r
674 struct rtw_ieee80211_hdr *pwlanhdr;
\r
677 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
678 struct wlan_network *cur_network = &pmlmepriv->cur_network;
\r
679 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
680 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
681 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
682 static u8 LLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8E};
\r
683 static u8 GTKbody_a[11] ={0x01, 0x03, 0x00, 0x5F, 0x02, 0x03, 0x12, 0x00, 0x10, 0x42, 0x0B};
\r
684 u8 *pGTKRspPkt = pframe;
\r
685 u8 EncryptionHeadOverhead = 0;
\r
686 //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave);
\r
688 pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
\r
690 fctrl = &pwlanhdr->frame_ctl;
\r
693 //-------------------------------------------------------------------------
\r
695 //-------------------------------------------------------------------------
\r
696 SetFrameType(fctrl, WIFI_DATA);
\r
697 //SetFrameSubType(fctrl, 0);
\r
699 _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
700 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
701 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
703 SetSeqNum(pwlanhdr, 0);
\r
704 SetDuration(pwlanhdr, 0);
\r
706 #ifdef CONFIG_WAPI_SUPPORT
\r
707 *pLength = sMacHdrLng;
\r
710 #endif //CONFIG_WAPI_SUPPORT
\r
714 //-------------------------------------------------------------------------
\r
715 // Qos Header: leave space for it if necessary.
\r
716 //-------------------------------------------------------------------------
\r
717 if(pStaQos->CurrentQosMode > QOS_DISABLE)
\r
719 SET_80211_HDR_QOS_EN(pGTKRspPkt, 1);
\r
720 PlatformZeroMemory(&(Buffer[*pLength]), sQoSCtlLng);
\r
721 *pLength += sQoSCtlLng;
\r
724 //-------------------------------------------------------------------------
\r
725 // Security Header: leave space for it if necessary.
\r
726 //-------------------------------------------------------------------------
\r
729 switch (psecuritypriv->dot11PrivacyAlgrthm)
\r
733 EncryptionHeadOverhead = 4;
\r
736 EncryptionHeadOverhead = 8;
\r
739 EncryptionHeadOverhead = 8;
\r
741 #ifdef CONFIG_WAPI_SUPPORT
\r
743 EncryptionHeadOverhead = 18;
\r
745 #endif //CONFIG_WAPI_SUPPORT
\r
747 EncryptionHeadOverhead = 0;
\r
750 if(EncryptionHeadOverhead > 0)
\r
752 _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);
\r
753 *pLength += EncryptionHeadOverhead;
\r
754 //SET_80211_HDR_WEP(pGTKRspPkt, 1); //Suggested by CCW.
\r
755 //GTK's privacy bit is done by FW
\r
756 //SetPrivacy(fctrl);
\r
759 //-------------------------------------------------------------------------
\r
761 //-------------------------------------------------------------------------
\r
762 pGTKRspPkt = (u8*)(pframe+ *pLength);
\r
764 _rtw_memcpy(pGTKRspPkt, LLCHeader, 8);
\r
770 //GTK frame body after LLC, part 1
\r
771 _rtw_memcpy(pGTKRspPkt, GTKbody_a, 11);
\r
774 //GTK frame body after LLC, part 2
\r
775 _rtw_memset(&(pframe[*pLength]), 0, 88);
\r
780 #endif //CONFIG_GTK_OL
\r
782 #ifdef CONFIG_PNO_SUPPORT
\r
783 static void ConstructProbeReq(_adapter *padapter, u8 *pframe, u32 *pLength)
\r
785 struct rtw_ieee80211_hdr *pwlanhdr;
\r
788 unsigned char *mac;
\r
789 unsigned char bssrate[NumRates];
\r
790 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
791 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
792 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
793 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
794 int bssrate_len = 0;
\r
795 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
\r
797 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
798 mac = myid(&(padapter->eeprompriv));
\r
800 fctrl = &(pwlanhdr->frame_ctl);
\r
803 //broadcast probe request frame
\r
804 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
\r
805 _rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
\r
807 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
\r
809 SetSeqNum(pwlanhdr, 0);
\r
810 SetFrameSubType(pframe, WIFI_PROBEREQ);
\r
812 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
815 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &pktlen);
\r
817 get_rate_set(padapter, bssrate, &bssrate_len);
\r
819 if (bssrate_len > 8)
\r
821 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &pktlen);
\r
822 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &pktlen);
\r
826 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &pktlen);
\r
831 #endif //CONFIG_PNO_SUPPORT
\r
832 #endif //CONFIG_WOWLAN
\r
834 static void ConstructProbeRsp(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bHideSSID)
\r
836 struct rtw_ieee80211_hdr *pwlanhdr;
\r
840 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
841 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
842 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
\r
845 //DBG_871X("%s\n", __FUNCTION__);
\r
847 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
849 mac = myid(&(padapter->eeprompriv));
\r
850 bssid = cur_network->MacAddress;
\r
852 fctrl = &(pwlanhdr->frame_ctl);
\r
854 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
\r
855 _rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
\r
856 _rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
\r
858 SetSeqNum(pwlanhdr, 0);
\r
859 SetFrameSubType(fctrl, WIFI_PROBERSP);
\r
861 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
864 if(cur_network->IELength>MAX_IE_SZ)
\r
867 _rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
\r
868 pframe += cur_network->IELength;
\r
869 pktlen += cur_network->IELength;
\r
874 // To check if reserved page content is destroyed by beacon beacuse beacon is too large.
\r
875 // 2010.06.23. Added by tynli.
\r
877 CheckFwRsvdPageContent(
\r
878 IN PADAPTER Adapter
\r
881 HAL_DATA_TYPE* pHalData = GET_HAL_DATA(Adapter);
\r
884 if(pHalData->FwRsvdPageStartOffset != 0)
\r
886 /*MaxBcnPageNum = PageNum_128(pMgntInfo->MaxBeaconSize);
\r
887 RT_ASSERT((MaxBcnPageNum <= pHalData->FwRsvdPageStartOffset),
\r
888 ("CheckFwRsvdPageContent(): The reserved page content has been"\
\r
889 "destroyed by beacon!!! MaxBcnPageNum(%d) FwRsvdPageStartOffset(%d)\n!",
\r
890 MaxBcnPageNum, pHalData->FwRsvdPageStartOffset));*/
\r
894 static void rtl8723b_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
\r
896 u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN]={0};
\r
898 DBG_871X("8723BRsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",
\r
899 rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,
\r
900 rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,
\r
901 rsvdpageloc->LocBTQosNull);
\r
903 SET_8723B_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);
\r
904 SET_8723B_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);
\r
905 SET_8723B_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);
\r
906 SET_8723B_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);
\r
907 SET_8723B_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);
\r
909 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CRsvdPageParm:", u1H2CRsvdPageParm, H2C_RSVDPAGE_LOC_LEN);
\r
910 FillH2CCmd8723B(padapter, H2C_8723B_RSVD_PAGE, H2C_RSVDPAGE_LOC_LEN, u1H2CRsvdPageParm);
\r
913 static void rtl8723b_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)
\r
915 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
\r
916 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
917 u8 res = 0, count = 0;
\r
918 #ifdef CONFIG_WOWLAN
\r
919 u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};
\r
921 DBG_871X("8723BAOACRsvdPageLoc: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",
\r
922 rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,
\r
923 rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,
\r
924 rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,
\r
925 rsvdpageloc->LocNetList);
\r
927 #ifdef CONFIG_PNO_SUPPORT
\r
928 DBG_871X("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);
\r
930 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
\r
931 SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);
\r
932 SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);
\r
933 //SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv);
\r
934 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);
\r
935 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);
\r
936 #ifdef CONFIG_GTK_OL
\r
937 SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);
\r
938 #endif // CONFIG_GTK_OL
\r
940 #ifdef CONFIG_PNO_SUPPORT
\r
941 if(!pwrpriv->pno_in_resume) {
\r
942 SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocPNOInfo);
\r
947 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CAoacRsvdPageParm:", u1H2CAoacRsvdPageParm, H2C_AOAC_RSVDPAGE_LOC_LEN);
\r
948 FillH2CCmd8723B(padapter, H2C_8723B_AOAC_RSVD_PAGE, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm);
\r
950 #ifdef CONFIG_PNO_SUPPORT
\r
951 if (!check_fwstate(pmlmepriv, WIFI_AP_STATE) &&
\r
952 !check_fwstate(pmlmepriv, _FW_LINKED) &&
\r
953 pwrpriv->pno_in_resume == _FALSE) {
\r
955 res = rtw_read8(padapter, 0x1b8);
\r
956 while(res == 0 && count < 25) {
\r
957 DBG_871X("[%d] FW loc_NLOInfo: %d\n", count, res);
\r
958 res = rtw_read8(padapter, 0x1b8);
\r
963 #endif // CONFIG_PNO_SUPPORT
\r
964 #endif // CONFIG_WOWLAN
\r
967 #ifdef CONFIG_AP_WOWLAN
\r
968 static void rtl8723b_set_ap_wow_rsvdpage_cmd(PADAPTER padapter,
\r
969 PRSVDPAGE_LOC rsvdpageloc)
\r
971 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
\r
972 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
973 u8 res = 0, count = 0, header = 0;
\r
974 u8 rsvdparm[H2C_AOAC_RSVDPAGE_LOC_LEN]={0};
\r
976 header = rtw_read8(padapter, REG_BCNQ_BDNY);
\r
978 DBG_871X("%s: beacon: %d, probeRsp: %d, header:0x%02x\n", __func__,
\r
979 rsvdpageloc->LocApOffloadBCN,
\r
980 rsvdpageloc->LocProbeRsp,
\r
983 SET_8723B_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_BCN(rsvdparm,
\r
984 rsvdpageloc->LocApOffloadBCN + header);
\r
986 FillH2CCmd8723B(padapter, H2C_8723B_BCN_RSVDPAGE,
\r
987 H2C_BCN_RSVDPAGE_LEN, rsvdparm);
\r
991 _rtw_memset(&rsvdparm, 0, sizeof(rsvdparm));
\r
993 SET_8723B_H2CCMD_AP_WOWLAN_RSVDPAGE_LOC_ProbeRsp(
\r
995 rsvdpageloc->LocProbeRsp + header);
\r
997 FillH2CCmd8723B(padapter, H2C_8723B_PROBERSP_RSVDPAGE,
\r
998 H2C_PROBERSP_RSVDPAGE_LEN, rsvdparm);
\r
1000 rtw_msleep_os(10);
\r
1002 #endif //CONFIG_AP_WOWLAN
\r
1004 void rtl8723b_set_FwMediaStatusRpt_cmd(PADAPTER padapter, u8 mstatus, u8 macid)
\r
1006 u8 u1H2CMediaStatusRptParm[H2C_MEDIA_STATUS_RPT_LEN]={0};
\r
1009 DBG_871X("%s(): mstatus = %d macid=%d\n", __func__, mstatus, macid);
\r
1011 SET_8723B_H2CCMD_MSRRPT_PARM_OPMODE(u1H2CMediaStatusRptParm, mstatus);
\r
1012 SET_8723B_H2CCMD_MSRRPT_PARM_MACID_IND(u1H2CMediaStatusRptParm, 0);
\r
1013 SET_8723B_H2CCMD_MSRRPT_PARM_MACID(u1H2CMediaStatusRptParm, macid);
\r
1014 SET_8723B_H2CCMD_MSRRPT_PARM_MACID_END(u1H2CMediaStatusRptParm, macid_end);
\r
1016 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CMediaStatusRptParm:", u1H2CMediaStatusRptParm, H2C_MEDIA_STATUS_RPT_LEN);
\r
1017 FillH2CCmd8723B(padapter, H2C_8723B_MEDIA_STATUS_RPT, H2C_MEDIA_STATUS_RPT_LEN, u1H2CMediaStatusRptParm);
\r
1020 static void rtl8723b_set_FwKeepAlive_cmd(PADAPTER padapter, u8 benable, u8 pkt_type)
\r
1022 u8 u1H2CKeepAliveParm[H2C_KEEP_ALIVE_CTRL_LEN]={0};
\r
1023 u8 adopt = 1, check_period = 5;
\r
1025 DBG_871X("%s(): benable = %d\n", __func__, benable);
\r
1026 SET_8723B_H2CCMD_KEEPALIVE_PARM_ENABLE(u1H2CKeepAliveParm, benable);
\r
1027 SET_8723B_H2CCMD_KEEPALIVE_PARM_ADOPT(u1H2CKeepAliveParm, adopt);
\r
1028 SET_8723B_H2CCMD_KEEPALIVE_PARM_PKT_TYPE(u1H2CKeepAliveParm, pkt_type);
\r
1029 SET_8723B_H2CCMD_KEEPALIVE_PARM_CHECK_PERIOD(u1H2CKeepAliveParm, check_period);
\r
1031 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CKeepAliveParm:", u1H2CKeepAliveParm, H2C_KEEP_ALIVE_CTRL_LEN);
\r
1033 FillH2CCmd8723B(padapter, H2C_8723B_KEEP_ALIVE, H2C_KEEP_ALIVE_CTRL_LEN, u1H2CKeepAliveParm);
\r
1036 static void rtl8723b_set_FwDisconDecision_cmd(PADAPTER padapter, u8 benable)
\r
1038 u8 u1H2CDisconDecisionParm[H2C_DISCON_DECISION_LEN]={0};
\r
1039 u8 adopt = 1, check_period = 10, trypkt_num = 0;
\r
1041 DBG_871X("%s(): benable = %d\n", __func__, benable);
\r
1042 SET_8723B_H2CCMD_DISCONDECISION_PARM_ENABLE(u1H2CDisconDecisionParm, benable);
\r
1043 SET_8723B_H2CCMD_DISCONDECISION_PARM_ADOPT(u1H2CDisconDecisionParm, adopt);
\r
1044 SET_8723B_H2CCMD_DISCONDECISION_PARM_CHECK_PERIOD(u1H2CDisconDecisionParm, check_period);
\r
1045 SET_8723B_H2CCMD_DISCONDECISION_PARM_TRY_PKT_NUM(u1H2CDisconDecisionParm, trypkt_num);
\r
1047 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CDisconDecisionParm:", u1H2CDisconDecisionParm, H2C_DISCON_DECISION_LEN);
\r
1049 FillH2CCmd8723B(padapter, H2C_8723B_DISCON_DECISION, H2C_DISCON_DECISION_LEN, u1H2CDisconDecisionParm);
\r
1052 void rtl8723b_set_FwMacIdConfig_cmd(_adapter* padapter, u8 mac_id, u8 raid, u8 bw, u8 sgi, u32 mask)
\r
1054 u8 u1H2CMacIdConfigParm[H2C_MACID_CFG_LEN]={0};
\r
1056 DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x\n", __func__, mac_id, raid, bw, mask);
\r
1060 SET_8723B_H2CCMD_MACID_CFG_MACID(u1H2CMacIdConfigParm, mac_id);
\r
1061 SET_8723B_H2CCMD_MACID_CFG_RAID(u1H2CMacIdConfigParm, raid);
\r
1062 SET_8723B_H2CCMD_MACID_CFG_SGI_EN(u1H2CMacIdConfigParm, (sgi)? 1:0);
\r
1063 SET_8723B_H2CCMD_MACID_CFG_BW(u1H2CMacIdConfigParm, bw);
\r
1064 SET_8723B_H2CCMD_MACID_CFG_RATE_MASK0(u1H2CMacIdConfigParm, (u8)(mask & 0x000000ff));
\r
1065 SET_8723B_H2CCMD_MACID_CFG_RATE_MASK1(u1H2CMacIdConfigParm, (u8)((mask & 0x0000ff00) >>8));
\r
1066 SET_8723B_H2CCMD_MACID_CFG_RATE_MASK2(u1H2CMacIdConfigParm, (u8)((mask & 0x00ff0000) >> 16));
\r
1067 SET_8723B_H2CCMD_MACID_CFG_RATE_MASK3(u1H2CMacIdConfigParm, (u8)((mask & 0xff000000) >> 24));
\r
1069 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CMacIdConfigParm:", u1H2CMacIdConfigParm, H2C_MACID_CFG_LEN);
\r
1070 FillH2CCmd8723B(padapter, H2C_8723B_MACID_CFG, H2C_MACID_CFG_LEN, u1H2CMacIdConfigParm);
\r
1075 void rtl8723b_set_FwRssiSetting_cmd(_adapter*padapter, u8 *param)
\r
1077 u8 u1H2CRssiSettingParm[H2C_RSSI_SETTING_LEN]={0};
\r
1078 u8 mac_id = *param;
\r
1079 u8 rssi = *(param+2);
\r
1080 u8 uldl_state = 0;
\r
1083 //DBG_871X("%s(): param=%.2x-%.2x-%.2x\n", __func__, *param, *(param+1), *(param+2));
\r
1084 //DBG_871X("%s(): mac_id=%d rssi=%d\n", __func__, mac_id, rssi);
\r
1086 SET_8723B_H2CCMD_RSSI_SETTING_MACID(u1H2CRssiSettingParm, mac_id);
\r
1087 SET_8723B_H2CCMD_RSSI_SETTING_RSSI(u1H2CRssiSettingParm, rssi);
\r
1088 SET_8723B_H2CCMD_RSSI_SETTING_ULDL_STATE(u1H2CRssiSettingParm, uldl_state);
\r
1090 RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "u1H2CRssiSettingParm:", u1H2CRssiSettingParm, H2C_RSSI_SETTING_LEN);
\r
1091 FillH2CCmd8723B(padapter, H2C_8723B_RSSI_SETTING, H2C_RSSI_SETTING_LEN, u1H2CRssiSettingParm);
\r
1096 void rtl8723b_set_FwAPReqRPT_cmd(PADAPTER padapter, u32 need_ack)
\r
1098 u8 u1H2CApReqRptParm[H2C_AP_REQ_TXRPT_LEN]={0};
\r
1099 u8 macid1 = 1, macid2 = 0;
\r
1101 DBG_871X("%s(): need_ack = %d\n", __func__, need_ack);
\r
1103 SET_8723B_H2CCMD_APREQRPT_PARM_MACID1(u1H2CApReqRptParm, macid1);
\r
1104 SET_8723B_H2CCMD_APREQRPT_PARM_MACID2(u1H2CApReqRptParm, macid2);
\r
1106 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CApReqRptParm:", u1H2CApReqRptParm, H2C_AP_REQ_TXRPT_LEN);
\r
1107 FillH2CCmd8723B(padapter, H2C_8723B_AP_REQ_TXRPT, H2C_AP_REQ_TXRPT_LEN, u1H2CApReqRptParm);
\r
1110 void rtl8723b_set_FwPwrMode_cmd(PADAPTER padapter, u8 psmode)
\r
1113 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
\r
1114 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
1115 u8 u1H2CPwrModeParm[H2C_PWRMODE_LEN]={0};
\r
1116 u8 PowerState=0, awake_intvl = 1, byte5 = 0, rlbm = 0;
\r
1117 struct wifidirect_info *wdinfo = &(padapter->wdinfo);
\r
1121 if(pwrpriv->dtim > 0)
\r
1122 DBG_871X("%s(): FW LPS mode = %d, SmartPS=%d, dtim=%d\n", __func__, psmode, pwrpriv->smart_ps, pwrpriv->dtim);
\r
1124 DBG_871X("%s(): FW LPS mode = %d, SmartPS=%d\n", __func__, psmode, pwrpriv->smart_ps);
\r
1126 #ifdef CONFIG_WOWLAN
\r
1127 if(psmode == PS_MODE_DTIM) //For WOWLAN LPS, DTIM = (awake_intvl - 1)
\r
1129 #ifdef CONFIG_PLATFORM_ARM_SUN8I
\r
1130 awake_intvl = 4;//DTIM=3
\r
1132 awake_intvl = 3;//DTIM=2
\r
1137 #endif //CONFIG_WOWLAN
\r
1139 if(pwrpriv->dtim > 0 && pwrpriv->dtim < 16)
\r
1140 awake_intvl = pwrpriv->dtim+1;//DTIM = (awake_intvl - 1)
\r
1142 #ifdef CONFIG_PLATFORM_ARM_SUN8I
\r
1143 awake_intvl = 4;//DTIM=3
\r
1145 awake_intvl = 3;//DTIM=2
\r
1152 if (!rtw_p2p_chk_state(wdinfo, P2P_STATE_NONE)) {
\r
1157 if(padapter->registrypriv.wifi_spec==1)
\r
1165 #ifdef CONFIG_BT_COEXIST
\r
1166 if (rtw_btcoex_IsBtControlLps(padapter) == _TRUE)
\r
1168 PowerState = rtw_btcoex_RpwmVal(padapter);
\r
1169 byte5 = rtw_btcoex_LpsVal(padapter);
\r
1171 if ((rlbm == 2) && (byte5 & BIT(4)))
\r
1173 // Keep awake interval to 1 to prevent from
\r
1174 // decreasing coex performance
\r
1180 #endif // CONFIG_BT_COEXIST
\r
1182 PowerState = 0x00;// AllON(0x0C), RFON(0x04), RFOFF(0x00)
\r
1188 PowerState = 0x0C;// AllON(0x0C), RFON(0x04), RFOFF(0x00)
\r
1192 SET_8723B_H2CCMD_PWRMODE_PARM_MODE(u1H2CPwrModeParm, (psmode>0)?1:0);
\r
1193 SET_8723B_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CPwrModeParm, pwrpriv->smart_ps);
\r
1194 SET_8723B_H2CCMD_PWRMODE_PARM_RLBM(u1H2CPwrModeParm, rlbm);
\r
1195 SET_8723B_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1H2CPwrModeParm, awake_intvl);
\r
1196 SET_8723B_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1H2CPwrModeParm, padapter->registrypriv.uapsd_enable);
\r
1197 SET_8723B_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CPwrModeParm, PowerState);
\r
1198 SET_8723B_H2CCMD_PWRMODE_PARM_BYTE5(u1H2CPwrModeParm, byte5);
\r
1199 #ifdef CONFIG_LPS_LCLK
\r
1200 if(psmode != PS_MODE_ACTIVE)
\r
1202 if(pmlmeext ->adaptive_tsf_done == _FALSE && pmlmeext->bcn_cnt>0)
\r
1204 u8 ratio_20_delay, ratio_80_delay;
\r
1206 //byte 6 for adaptive_early_32k
\r
1207 //[0:3] = DrvBcnEarly (ms) , [4:7] = DrvBcnTimeOut (ms)
\r
1208 // 20% for DrvBcnEarly, 80% for DrvBcnTimeOut
\r
1209 ratio_20_delay = 0;
\r
1210 ratio_80_delay = 0;
\r
1211 pmlmeext->DrvBcnEarly = 0xff;
\r
1212 pmlmeext->DrvBcnTimeOut = 0xff;
\r
1214 DBG_871X("%s(): bcn_cnt = %d\n", __func__, pmlmeext->bcn_cnt);
\r
1216 for(i=0; i<9; i++)
\r
1218 pmlmeext->bcn_delay_ratio[i] = (pmlmeext->bcn_delay_cnt[i] * 100) /pmlmeext->bcn_cnt;
\r
1220 DBG_871X("%s(): bcn_delay_cnt[%d]=%d, bcn_delay_ratio[%d] = %d\n", __func__, i, pmlmeext->bcn_delay_cnt[i]
\r
1221 ,i ,pmlmeext->bcn_delay_ratio[i]);
\r
1223 ratio_20_delay += pmlmeext->bcn_delay_ratio[i];
\r
1224 ratio_80_delay += pmlmeext->bcn_delay_ratio[i];
\r
1226 if(ratio_20_delay > 20 && pmlmeext->DrvBcnEarly == 0xff)
\r
1228 pmlmeext->DrvBcnEarly = i;
\r
1229 DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly);
\r
1232 if(ratio_80_delay > 80 && pmlmeext->DrvBcnTimeOut == 0xff)
\r
1234 pmlmeext->DrvBcnTimeOut = i;
\r
1235 DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut);
\r
1238 //reset adaptive_early_32k cnt
\r
1239 pmlmeext->bcn_delay_cnt[i] = 0;
\r
1240 pmlmeext->bcn_delay_ratio[i] = 0;
\r
1244 pmlmeext->bcn_cnt = 0;
\r
1245 pmlmeext ->adaptive_tsf_done = _TRUE;
\r
1250 DBG_871X("%s(): DrvBcnEarly = %d\n", __func__, pmlmeext->DrvBcnEarly);
\r
1251 DBG_871X("%s(): DrvBcnTimeOut = %d\n", __func__, pmlmeext->DrvBcnTimeOut);
\r
1254 /* offload to FW if fw version > v15.10
\r
1255 pmlmeext->DrvBcnEarly=0;
\r
1256 pmlmeext->DrvBcnTimeOut=7;
\r
1258 if((pmlmeext->DrvBcnEarly!=0Xff) && (pmlmeext->DrvBcnTimeOut!=0xff))
\r
1259 u1H2CPwrModeParm[H2C_PWRMODE_LEN-1] = BIT(0) | ((pmlmeext->DrvBcnEarly<<1)&0x0E) |((pmlmeext->DrvBcnTimeOut<<4)&0xf0) ;
\r
1265 #ifdef CONFIG_BT_COEXIST
\r
1266 rtw_btcoex_RecordPwrMode(padapter, u1H2CPwrModeParm, H2C_PWRMODE_LEN);
\r
1267 #endif // CONFIG_BT_COEXIST
\r
1269 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CPwrModeParm:", u1H2CPwrModeParm, H2C_PWRMODE_LEN);
\r
1271 FillH2CCmd8723B(padapter, H2C_8723B_SET_PWR_MODE, H2C_PWRMODE_LEN, u1H2CPwrModeParm);
\r
1275 void rtl8723b_set_FwPsTuneParam_cmd(PADAPTER padapter)
\r
1277 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
\r
1278 u8 u1H2CPsTuneParm[H2C_PSTUNEPARAM_LEN]={0};
\r
1279 u8 bcn_to_limit = 10; //10 * 100 * awakeinterval (ms)
\r
1280 u8 dtim_timeout = 5; //ms //wait broadcast data timer
\r
1281 u8 ps_timeout = 20; //ms //Keep awake when tx
\r
1282 u8 dtim_period = 3;
\r
1285 //DBG_871X("%s(): FW LPS mode = %d\n", __func__, psmode);
\r
1287 SET_8723B_H2CCMD_PSTUNE_PARM_BCN_TO_LIMIT(u1H2CPsTuneParm, bcn_to_limit);
\r
1288 SET_8723B_H2CCMD_PSTUNE_PARM_DTIM_TIMEOUT(u1H2CPsTuneParm, dtim_timeout);
\r
1289 SET_8723B_H2CCMD_PSTUNE_PARM_PS_TIMEOUT(u1H2CPsTuneParm, ps_timeout);
\r
1290 SET_8723B_H2CCMD_PSTUNE_PARM_ADOPT(u1H2CPsTuneParm, 1);
\r
1291 SET_8723B_H2CCMD_PSTUNE_PARM_DTIM_PERIOD(u1H2CPsTuneParm, dtim_period);
\r
1293 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CPsTuneParm:", u1H2CPsTuneParm, H2C_PSTUNEPARAM_LEN);
\r
1295 FillH2CCmd8723B(padapter, H2C_8723B_PS_TUNING_PARA, H2C_PSTUNEPARAM_LEN, u1H2CPsTuneParm);
\r
1299 void rtl8723b_set_FwBtMpOper_cmd(PADAPTER padapter, u8 idx, u8 ver, u8 reqnum, u8 *param)
\r
1301 u8 u1H2CBtMpOperParm[H2C_BTMP_OPER_LEN]={0};
\r
1305 DBG_8192C("%s: idx=%d ver=%d reqnum=%d param1=0x%02x param2=0x%02x\n", __FUNCTION__, idx, ver, reqnum, param[0], param[1]);
\r
1307 SET_8723B_H2CCMD_BT_MPOPER_VER(u1H2CBtMpOperParm, ver);
\r
1308 SET_8723B_H2CCMD_BT_MPOPER_REQNUM(u1H2CBtMpOperParm, reqnum);
\r
1309 SET_8723B_H2CCMD_BT_MPOPER_IDX(u1H2CBtMpOperParm, idx);
\r
1310 SET_8723B_H2CCMD_BT_MPOPER_PARAM1(u1H2CBtMpOperParm, param[0]);
\r
1311 SET_8723B_H2CCMD_BT_MPOPER_PARAM2(u1H2CBtMpOperParm, param[1]);
\r
1313 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CBtMpOperParm:", u1H2CBtMpOperParm, H2C_BTMP_OPER_LEN);
\r
1315 FillH2CCmd8723B(padapter, H2C_8723B_BT_MP_OPER, H2C_BTMP_OPER_LEN, u1H2CBtMpOperParm);
\r
1319 void rtl8723b_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param)
\r
1321 //u8 cmd_param; //BIT0:enable, BIT1:NoConnect32k
\r
1323 DBG_871X("%s()\n", __func__);
\r
1325 cmd_param = cmd_param;
\r
1327 FillH2CCmd8723B(padapter, H2C_8723B_FWLPS_IN_IPS_, 1, &cmd_param);
\r
1331 #ifdef CONFIG_WOWLAN
\r
1332 static void rtl8723b_set_FwWoWlanCtrl_Cmd(PADAPTER padapter, u8 bFuncEn)
\r
1334 struct security_priv *psecpriv = &padapter->securitypriv;
\r
1335 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
\r
1336 u8 u1H2CWoWlanCtrlParm[H2C_WOWLAN_LEN]={0};
\r
1337 u8 discont_wake = 1, gpionum = 0, gpio_dur = 0, hw_unicast = 0, gpio_pulse_cnt=100;
\r
1338 u8 sdio_wakeup_enable = 1;
\r
1339 u8 gpio_high_active = 0; //0: low active, 1: high active
\r
1342 #ifdef CONFIG_GPIO_WAKEUP
\r
1343 gpionum = WAKEUP_GPIO_IDX;
\r
1344 sdio_wakeup_enable = 0;
\r
1347 #ifdef CONFIG_PNO_SUPPORT
\r
1348 if (!ppwrpriv->wowlan_pno_enable) {
\r
1353 if (psecpriv->dot11PrivacyAlgrthm == _WEP40_ || psecpriv->dot11PrivacyAlgrthm == _WEP104_)
\r
1356 DBG_871X("%s(): bFuncEn=%d\n", __func__, bFuncEn);
\r
1358 SET_H2CCMD_WOWLAN_FUNC_ENABLE(u1H2CWoWlanCtrlParm, bFuncEn);
\r
1359 SET_H2CCMD_WOWLAN_PATTERN_MATCH_ENABLE(u1H2CWoWlanCtrlParm, 0);
\r
1360 SET_H2CCMD_WOWLAN_MAGIC_PKT_ENABLE(u1H2CWoWlanCtrlParm, magic_pkt);
\r
1361 SET_H2CCMD_WOWLAN_UNICAST_PKT_ENABLE(u1H2CWoWlanCtrlParm, hw_unicast);
\r
1362 SET_H2CCMD_WOWLAN_ALL_PKT_DROP(u1H2CWoWlanCtrlParm, 0);
\r
1363 SET_H2CCMD_WOWLAN_GPIO_ACTIVE(u1H2CWoWlanCtrlParm, gpio_high_active);
\r
1364 SET_H2CCMD_WOWLAN_DISCONNECT_WAKE_UP(u1H2CWoWlanCtrlParm, discont_wake);
\r
1365 SET_H2CCMD_WOWLAN_GPIONUM(u1H2CWoWlanCtrlParm, gpionum);
\r
1366 SET_H2CCMD_WOWLAN_DATAPIN_WAKE_UP(u1H2CWoWlanCtrlParm, sdio_wakeup_enable);
\r
1367 SET_H2CCMD_WOWLAN_GPIO_DURATION(u1H2CWoWlanCtrlParm, gpio_dur);
\r
1368 //SET_H2CCMD_WOWLAN_GPIO_PULSE_EN(u1H2CWoWlanCtrlParm, 1);
\r
1369 SET_H2CCMD_WOWLAN_GPIO_PULSE_COUNT(u1H2CWoWlanCtrlParm, 0x09);
\r
1371 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CWoWlanCtrlParm:", u1H2CWoWlanCtrlParm, H2C_WOWLAN_LEN);
\r
1373 FillH2CCmd8723B(padapter, H2C_8723B_WOWLAN, H2C_WOWLAN_LEN, u1H2CWoWlanCtrlParm);
\r
1376 static void rtl8723b_set_FwRemoteWakeCtrl_Cmd(PADAPTER padapter, u8 benable)
\r
1378 u8 u1H2CRemoteWakeCtrlParm[H2C_REMOTE_WAKE_CTRL_LEN]={0};
\r
1379 struct security_priv* psecuritypriv=&(padapter->securitypriv);
\r
1380 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
\r
1381 u8 res = 0, count = 0;
\r
1383 DBG_871X("%s(): Enable=%d\n", __func__, benable);
\r
1385 #ifdef CONFIG_PNO_SUPPORT
\r
1386 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(u1H2CRemoteWakeCtrlParm, benable);
\r
1387 SET_H2CCMD_REMOTE_WAKE_CTRL_NLO_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, benable);
\r
1390 if (!ppwrpriv->wowlan_pno_enable) {
\r
1391 SET_H2CCMD_REMOTE_WAKECTRL_ENABLE(u1H2CRemoteWakeCtrlParm, benable);
\r
1392 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, 1);
\r
1393 #ifdef CONFIG_GTK_OL
\r
1394 if(psecuritypriv->binstallKCK_KEK == _TRUE && psecuritypriv->dot11PrivacyAlgrthm == _AES_)
\r
1396 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, 1);
\r
1400 DBG_871X("no kck or security is not AES\n");
\r
1401 SET_H2CCMD_REMOTE_WAKE_CTRL_GTK_OFFLOAD_EN(u1H2CRemoteWakeCtrlParm, 0);
\r
1403 #endif //CONFIG_GTK_OL
\r
1405 SET_H2CCMD_REMOTE_WAKE_CTRL_FW_UNICAST_EN(u1H2CRemoteWakeCtrlParm, 1);
\r
1407 if ((psecuritypriv->dot11PrivacyAlgrthm == _AES_) || (psecuritypriv->dot11PrivacyAlgrthm == _NO_PRIVACY_))
\r
1409 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(u1H2CRemoteWakeCtrlParm, 0);
\r
1413 SET_H2CCMD_REMOTE_WAKE_CTRL_ARP_ACTION(u1H2CRemoteWakeCtrlParm, 1);
\r
1417 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CRemoteWakeCtrlParm:", u1H2CRemoteWakeCtrlParm, H2C_REMOTE_WAKE_CTRL_LEN);
\r
1418 FillH2CCmd8723B(padapter, H2C_8723B_REMOTE_WAKE_CTRL,
\r
1419 H2C_REMOTE_WAKE_CTRL_LEN, u1H2CRemoteWakeCtrlParm);
\r
1420 #ifdef CONFIG_PNO_SUPPORT
\r
1421 if (ppwrpriv->wowlan_pno_enable && ppwrpriv->pno_in_resume == _FALSE) {
\r
1422 res = rtw_read8(padapter, REG_PNO_STATUS);
\r
1423 DBG_871X("cmd: 0x81 REG_PNO_STATUS: 0x%02x\n", res);
\r
1424 while(!(res&BIT(7)) && count < 25) {
\r
1425 DBG_871X("[%d] cmd: 0x81 REG_PNO_STATUS: 0x%02x\n", count, res);
\r
1426 res = rtw_read8(padapter, REG_PNO_STATUS);
\r
1430 DBG_871X("cmd: 0x81 REG_PNO_STATUS: 0x%02x\n", res);
\r
1432 #endif //CONFIG_PNO_SUPPORT
\r
1435 static void rtl8723b_set_FwAOACGlobalInfo_Cmd(PADAPTER padapter, u8 group_alg, u8 pairwise_alg)
\r
1437 u8 u1H2CAOACGlobalInfoParm[H2C_AOAC_GLOBAL_INFO_LEN]={0};
\r
1439 DBG_871X("%s(): group_alg=%d pairwise_alg=%d\n", __func__, group_alg, pairwise_alg);
\r
1441 SET_H2CCMD_AOAC_GLOBAL_INFO_PAIRWISE_ENC_ALG(u1H2CAOACGlobalInfoParm, pairwise_alg);
\r
1442 SET_H2CCMD_AOAC_GLOBAL_INFO_GROUP_ENC_ALG(u1H2CAOACGlobalInfoParm, group_alg);
\r
1444 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CAOACGlobalInfoParm:", u1H2CAOACGlobalInfoParm, H2C_AOAC_GLOBAL_INFO_LEN);
\r
1446 FillH2CCmd8723B(padapter, H2C_8723B_AOAC_GLOBAL_INFO, H2C_AOAC_GLOBAL_INFO_LEN, u1H2CAOACGlobalInfoParm);
\r
1449 #ifdef CONFIG_PNO_SUPPORT
\r
1450 static void rtl8723b_set_FwScanOffloadInfo_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc, u8 enable)
\r
1452 u8 u1H2CScanOffloadInfoParm[H2C_SCAN_OFFLOAD_CTRL_LEN]={0};
\r
1453 u8 res = 0, count = 0;
\r
1454 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
\r
1456 DBG_871X("%s: loc_probe_packet:%d, loc_scan_info: %d loc_ssid_info:%d\n",
\r
1457 __func__, rsvdpageloc->LocProbePacket, rsvdpageloc->LocScanInfo, rsvdpageloc->LocSSIDInfo);
\r
1459 SET_H2CCMD_AOAC_NLO_FUN_EN(u1H2CScanOffloadInfoParm, enable);
\r
1460 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SCAN_INFO(u1H2CScanOffloadInfoParm, rsvdpageloc->LocScanInfo);
\r
1461 SET_H2CCMD_AOAC_RSVDPAGE_LOC_PROBE_PACKET(u1H2CScanOffloadInfoParm, rsvdpageloc->LocProbePacket);
\r
1462 SET_H2CCMD_AOAC_RSVDPAGE_LOC_SSID_INFO(u1H2CScanOffloadInfoParm, rsvdpageloc->LocSSIDInfo);
\r
1464 RT_PRINT_DATA(_module_hal_init_c_, _drv_always_, "u1H2CScanOffloadInfoParm:", u1H2CScanOffloadInfoParm, H2C_SCAN_OFFLOAD_CTRL_LEN);
\r
1465 FillH2CCmd8723B(padapter, H2C_8723B_D0_SCAN_OFFLOAD_INFO, H2C_SCAN_OFFLOAD_CTRL_LEN, u1H2CScanOffloadInfoParm);
\r
1467 if (pwrpriv->pno_in_resume == _FALSE) {
\r
1468 res = rtw_read8(padapter, 0x1b9);
\r
1469 while( res == 0 && count < 25) {
\r
1470 DBG_871X("[%d] 0x1b9 0x%02x\n", count, res);
\r
1471 res = rtw_read8(padapter, 0x1b9);
\r
1472 DBG_871X("[%d] 0x1c4: 0x%08x 0x1cc:0x%08x\n",
\r
1473 count, rtw_read32(padapter, 0x1c4), rtw_read32(padapter, 0x1cc));
\r
1478 res = rtw_read8(padapter, 0x1b9);
\r
1479 while( res != 0x77 && count < 50) {
\r
1480 DBG_871X("[%d] 0x1b9 0x%02x\n", count, res);
\r
1481 res = rtw_read8(padapter, 0x1b9);
\r
1482 DBG_871X("[%d] 0x1c4: 0x%08x 0x1cc:0x%08x\n",
\r
1483 count, rtw_read32(padapter, 0x1c4), rtw_read32(padapter, 0x1cc));
\r
1487 DBG_871X("0x1b9: 0x%02x\n", res);
\r
1490 #endif //CONFIG_PNO_SUPPORT
\r
1493 void dump_TX_FIFO(_adapter* padapter){
\r
1499 DBG_871X("+%s+\n", __func__);
\r
1500 val = rtw_read8(padapter, 0x106);
\r
1501 rtw_write8(padapter, 0x106, 0x69);
\r
1502 DBG_871X("0x106: 0x%02x\n", val);
\r
1503 base = rtw_read8(padapter, 0x209);
\r
1504 DBG_871X("0x209: 0x%02x\n", base);
\r
1506 DBG_871X("beacon:\n");
\r
1507 addr = ((base)*128)/8;
\r
1508 for (i = 0 ; i < 32 ; i+=2) {
\r
1509 rtw_write32(padapter, 0x140, addr + i);
\r
1510 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1511 rtw_write32(padapter, 0x140, addr + i + 1);
\r
1512 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1515 DBG_871X("probe_response:\n");
\r
1516 addr = ((base + 2)*128)/8;
\r
1517 for (i = 0 ; i < 48 ; i+=2) {
\r
1518 rtw_write32(padapter, 0x140, addr + i);
\r
1519 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1520 rtw_write32(padapter, 0x140, addr + i + 1);
\r
1521 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1524 DBG_871X("GTK Info:\n");
\r
1525 addr = ((base + 8)*128)/8;
\r
1526 for (i = 0 ; i < 4 ; i+=2) {
\r
1527 rtw_write32(padapter, 0x140, addr + i);
\r
1528 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1529 rtw_write32(padapter, 0x140, addr + i + 1);
\r
1530 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1533 DBG_871X("GTK Rsp:\n");
\r
1534 addr = ((base + 9)*128)/8;
\r
1535 for (i = 0 ; i < 32 ; i+=2) {
\r
1536 rtw_write32(padapter, 0x140, addr + i);
\r
1537 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1538 rtw_write32(padapter, 0x140, addr + i + 1);
\r
1539 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1543 DBG_871X("probe request:\n");
\r
1544 addr = ((base + 6)*128)/8;
\r
1545 for (i = 0 ; i < 16 ; i+=2) {
\r
1546 rtw_write32(padapter, 0x140, addr + i);
\r
1547 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1548 rtw_write32(padapter, 0x140, addr + i + 1);
\r
1549 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1552 DBG_871X("PNO_INFO:\n");
\r
1553 addr = ((base + 7)*128)/8;
\r
1554 for (i = 0 ; i < 16 ; i+=2) {
\r
1555 rtw_write32(padapter, 0x140, addr + i);
\r
1556 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1557 rtw_write32(padapter, 0x140, addr + i + 1);
\r
1558 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1561 DBG_871X("SSID_INFO:\n");
\r
1562 addr = ((base + 8)*128)/8;
\r
1563 for (i = 0 ; i < 16 ; i+=2) {
\r
1564 rtw_write32(padapter, 0x140, addr + i);
\r
1565 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1566 rtw_write32(padapter, 0x140, addr + i + 1);
\r
1567 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1570 DBG_871X("SCAN_INFO:\n");
\r
1571 addr = ((base + 9)*128)/8;
\r
1572 for (i = 0 ; i < 16 ; i+=2) {
\r
1573 rtw_write32(padapter, 0x140, addr + i);
\r
1574 printk(" %08x %08x ", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1575 rtw_write32(padapter, 0x140, addr + i + 1);
\r
1576 printk(" %08x %08x \n", rtw_read32(padapter, 0x144), rtw_read32(padapter, 0x148));
\r
1579 rtw_write8(padapter, 0x106, val);
\r
1580 DBG_871X("-%s-\n", __func__);
\r
1584 static void rtl8723b_set_FwWoWlanRelated_cmd(_adapter* padapter, u8 enable)
\r
1586 struct security_priv *psecpriv = &padapter->securitypriv;
\r
1587 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
\r
1588 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1589 struct sta_info *psta = NULL;
\r
1592 DBG_871X_LEVEL(_drv_always_, "+%s()+: enable=%d\n", __func__, enable);
\r
1596 rtl8723b_set_FwAOACGlobalInfo_Cmd(padapter, psecpriv->dot118021XGrpPrivacy, psecpriv->dot11PrivacyAlgrthm);
\r
1598 rtl8723b_set_FwJoinBssRpt_cmd(padapter, RT_MEDIA_CONNECT); //RT_MEDIA_CONNECT will confuse in the future
\r
1600 if(!(ppwrpriv->wowlan_pno_enable))
\r
1602 psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(pmlmepriv));
\r
1604 rtl8723b_set_FwMediaStatusRpt_cmd(padapter, RT_MEDIA_CONNECT, psta->mac_id);
\r
1607 DBG_871X("%s(): Disconnected, no FwMediaStatusRpt CONNECT\n",__FUNCTION__);
\r
1611 if(!(ppwrpriv->wowlan_pno_enable)) {
\r
1612 rtl8723b_set_FwDisconDecision_cmd(padapter, enable);
\r
1615 if ((psecpriv->dot11PrivacyAlgrthm != _WEP40_) || (psecpriv->dot11PrivacyAlgrthm != _WEP104_))
\r
1617 rtl8723b_set_FwKeepAlive_cmd(padapter, enable, pkt_type);
\r
1621 rtl8723b_set_FwWoWlanCtrl_Cmd(padapter, enable);
\r
1624 rtl8723b_set_FwRemoteWakeCtrl_Cmd(padapter, enable);
\r
1629 dump_TX_FIFO(padapter);
\r
1631 rtl8723b_set_FwRemoteWakeCtrl_Cmd(padapter, enable);
\r
1632 rtw_msleep_os(2);
\r
1633 rtl8723b_set_FwWoWlanCtrl_Cmd(padapter, enable);
\r
1637 DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__);
\r
1641 void rtl8723b_set_wowlan_cmd(_adapter* padapter, u8 enable)
\r
1643 rtl8723b_set_FwWoWlanRelated_cmd(padapter, enable);
\r
1645 #endif //CONFIG_WOWLAN
\r
1647 #ifdef CONFIG_AP_WOWLAN
\r
1648 static void rtl8723b_set_FwAPWoWlanCtrl_Cmd(PADAPTER padapter, u8 bFuncEn)
\r
1650 u8 u1H2CAPWoWlanCtrlParm[H2C_WOWLAN_LEN]={0};
\r
1651 u8 discont_wake = 1, gpionum = 0, gpio_dur = 0;
\r
1652 u8 gpio_high_active = 1; //0: low active, 1: high active
\r
1653 u8 gpio_pulse = bFuncEn;
\r
1654 #ifdef CONFIG_GPIO_WAKEUP
\r
1655 gpionum = WAKEUP_GPIO_IDX;
\r
1658 DBG_871X("%s(): bFuncEn=%d\n", __func__, bFuncEn);
\r
1665 SET_8723B_H2CCMD_AP_WOW_GPIO_CTRL_INDEX(u1H2CAPWoWlanCtrlParm,
\r
1667 SET_8723B_H2CCMD_AP_WOW_GPIO_CTRL_PLUS(u1H2CAPWoWlanCtrlParm,
\r
1669 SET_8723B_H2CCMD_AP_WOW_GPIO_CTRL_HIGH_ACTIVE(u1H2CAPWoWlanCtrlParm,
\r
1670 gpio_high_active);
\r
1671 SET_8723B_H2CCMD_AP_WOW_GPIO_CTRL_EN(u1H2CAPWoWlanCtrlParm,
\r
1673 SET_8723B_H2CCMD_AP_WOW_GPIO_CTRL_DURATION(u1H2CAPWoWlanCtrlParm,
\r
1676 FillH2CCmd8723B(padapter, H2C_8723B_AP_WOW_GPIO_CTRL,
\r
1677 H2C_AP_WOW_GPIO_CTRL_LEN, u1H2CAPWoWlanCtrlParm);
\r
1680 static void rtl8723b_set_Fw_AP_Offload_Cmd(PADAPTER padapter, u8 bFuncEn)
\r
1682 u8 u1H2CAPOffloadCtrlParm[H2C_WOWLAN_LEN]={0};
\r
1684 DBG_871X("%s(): bFuncEn=%d\n", __func__, bFuncEn);
\r
1686 SET_8723B_H2CCMD_AP_WOWLAN_EN(u1H2CAPOffloadCtrlParm, bFuncEn);
\r
1688 FillH2CCmd8723B(padapter, H2C_8723B_AP_OFFLOAD,
\r
1689 H2C_AP_OFFLOAD_LEN, u1H2CAPOffloadCtrlParm);
\r
1692 static void rtl8723b_set_AP_FwWoWlan_cmd(_adapter* padapter, u8 enable)
\r
1694 struct security_priv *psecpriv = &padapter->securitypriv;
\r
1695 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
\r
1696 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1697 struct sta_info *psta = NULL;
\r
1700 DBG_871X_LEVEL(_drv_always_, "+%s()+: enable=%d\n", __func__, enable);
\r
1703 rtl8723b_set_FwJoinBssRpt_cmd(padapter, RT_MEDIA_CONNECT);
\r
1704 issue_beacon(padapter, 0);
\r
1709 dump_TX_FIFO(padapter);
\r
1711 rtl8723b_set_FwAPWoWlanCtrl_Cmd(padapter, enable);
\r
1712 rtw_msleep_os(10);
\r
1713 rtl8723b_set_Fw_AP_Offload_Cmd(padapter, enable);
\r
1714 rtw_msleep_os(10);
\r
1716 DBG_871X_LEVEL(_drv_always_, "-%s()-\n", __func__);
\r
1720 void rtl8723b_set_ap_wowlan_cmd(_adapter* padapter, u8 enable)
\r
1722 rtl8723b_set_AP_FwWoWlan_cmd(padapter, enable);
\r
1724 #endif //CONFIG_AP_WOWLAN
\r
1726 static s32 rtl8723b_set_FwLowPwrLps_cmd(PADAPTER padapter, u8 enable)
\r
1733 // Description: Fill the reserved packets that FW will use to RSVD page.
\r
1734 // Now we just send 4 types packet to rsvd page.
\r
1735 // (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp.
\r
1737 // bDLFinished - FALSE: At the first time we will send all the packets as a large packet to Hw,
\r
1738 // so we need to set the packet length to total lengh.
\r
1739 // TRUE: At the second time, we should send the first packet (default:beacon)
\r
1740 // to Hw again and set the lengh in descriptor to the real beacon lengh.
\r
1741 // 2009.10.15 by tynli.
\r
1742 static void rtl8723b_set_FwRsvdPagePkt(PADAPTER padapter, BOOLEAN bDLFinished)
\r
1744 PHAL_DATA_TYPE pHalData;
\r
1745 struct xmit_frame *pcmdframe;
\r
1746 struct pkt_attrib *pattrib;
\r
1747 struct xmit_priv *pxmitpriv;
\r
1748 struct mlme_ext_priv *pmlmeext;
\r
1749 struct mlme_ext_info *pmlmeinfo;
\r
1750 struct pwrctrl_priv *pwrctl;
\r
1751 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1752 u32 BeaconLength=0, ProbeRspLength=0, PSPollLength=0;
\r
1753 u32 NullDataLength=0, QosNullLength=0, BTQosNullLength=0;
\r
1754 u32 ProbeReqLength=0;
\r
1755 u8 *ReservedPagePacket;
\r
1756 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
\r
1757 u8 TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0;
\r
1758 u16 BufIndex, PageSize = 128;
\r
1759 u32 TotalPacketLen, MaxRsvdPageBufSize=0;
\r
1760 RSVDPAGE_LOC RsvdPageLoc;
\r
1761 #ifdef CONFIG_WOWLAN
\r
1762 u32 ARPLegnth = 0, GTKLegnth = 0, PNOLength = 0, ScanInfoLength = 0;
\r
1763 u32 SSIDLegnth = 0;
\r
1764 struct security_priv *psecuritypriv = &padapter->securitypriv; //added by xx
\r
1766 u8 cur_dot11txpn[8];
\r
1767 #ifdef CONFIG_GTK_OL
\r
1768 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1769 struct sta_info * psta;
\r
1770 u8 kek[RTW_KEK_LEN];
\r
1771 u8 kck[RTW_KCK_LEN];
\r
1774 #ifdef DBG_CONFIG_ERROR_DETECT
\r
1775 struct sreset_priv *psrtpriv;
\r
1776 #endif // DBG_CONFIG_ERROR_DETECT
\r
1778 //DBG_871X("%s---->\n", __FUNCTION__);
\r
1780 pHalData = GET_HAL_DATA(padapter);
\r
1781 #ifdef DBG_CONFIG_ERROR_DETECT
\r
1782 psrtpriv = &pHalData->srestpriv;
\r
1784 pxmitpriv = &padapter->xmitpriv;
\r
1785 pmlmeext = &padapter->mlmeextpriv;
\r
1786 pmlmeinfo = &pmlmeext->mlmext_info;
\r
1787 pwrctl = adapter_to_pwrctl(padapter);
\r
1789 RsvdPageNum = BCNQ_PAGE_NUM_8723B + WOWLAN_PAGE_NUM_8723B;
\r
1790 MaxRsvdPageBufSize = RsvdPageNum*PageSize;
\r
1792 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
\r
1793 if (pcmdframe == NULL) {
\r
1794 DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
\r
1798 ReservedPagePacket = pcmdframe->buf_addr;
\r
1799 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
\r
1802 BufIndex = TxDescOffset;
\r
1803 ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);
\r
1805 // When we count the first page size, we need to reserve description size for the RSVD
\r
1806 // packet, it will be filled in front of the packet in TXPKTBUF.
\r
1807 CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength);
\r
1808 //If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware
\r
1809 if (CurtPktPageNum == 1)
\r
1811 CurtPktPageNum += 1;
\r
1813 TotalPageNum += CurtPktPageNum;
\r
1815 BufIndex += (CurtPktPageNum*PageSize);
\r
1818 RsvdPageLoc.LocPsPoll = TotalPageNum;
\r
1819 ConstructPSPoll(padapter, &ReservedPagePacket[BufIndex], &PSPollLength);
\r
1820 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, _TRUE, _FALSE, _FALSE);
\r
1822 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PS-POLL %p %d\n",
\r
1823 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (PSPollLength+TxDescLen));
\r
1825 CurtPktPageNum = (u8)PageNum_128(TxDescLen + PSPollLength);
\r
1827 TotalPageNum += CurtPktPageNum;
\r
1829 BufIndex += (CurtPktPageNum*PageSize);
\r
1832 RsvdPageLoc.LocNullData = TotalPageNum;
\r
1833 ConstructNullFunctionData(
\r
1835 &ReservedPagePacket[BufIndex],
\r
1837 get_my_bssid(&pmlmeinfo->network),
\r
1838 _FALSE, 0, 0, _FALSE);
\r
1839 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, _FALSE, _FALSE, _FALSE);
\r
1841 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: NULL DATA %p %d\n",
\r
1842 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (NullDataLength+TxDescLen));
\r
1844 CurtPktPageNum = (u8)PageNum_128(TxDescLen + NullDataLength);
\r
1846 TotalPageNum += CurtPktPageNum;
\r
1848 BufIndex += (CurtPktPageNum*PageSize);
\r
1851 //3 (4) probe response
\r
1852 RsvdPageLoc.LocProbeRsp = TotalPageNum;
\r
1853 ConstructProbeRsp(
\r
1855 &ReservedPagePacket[BufIndex],
\r
1857 get_my_bssid(&pmlmeinfo->network),
\r
1859 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, _FALSE, _FALSE, _FALSE);
\r
1861 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
\r
1862 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (ProbeRspLength+TxDescLen));
\r
1864 CurtPktPageNum = (u8)PageNum_128(TxDescLen + ProbeRspLength);
\r
1866 TotalPageNum += CurtPktPageNum;
\r
1868 BufIndex += (CurtPktPageNum*PageSize);
\r
1871 //3 (5) Qos null data
\r
1872 RsvdPageLoc.LocQosNull = TotalPageNum;
\r
1873 ConstructNullFunctionData(
\r
1875 &ReservedPagePacket[BufIndex],
\r
1877 get_my_bssid(&pmlmeinfo->network),
\r
1878 _TRUE, 0, 0, _FALSE);
\r
1879 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, _FALSE, _FALSE, _FALSE);
\r
1881 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: QOS NULL DATA %p %d\n",
\r
1882 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (QosNullLength+TxDescLen));
\r
1884 CurtPktPageNum = (u8)PageNum_128(TxDescLen + QosNullLength);
\r
1886 TotalPageNum += CurtPktPageNum;
\r
1888 BufIndex += (CurtPktPageNum*PageSize);
\r
1890 //3 (6) BT Qos null data
\r
1891 RsvdPageLoc.LocBTQosNull = TotalPageNum;
\r
1892 ConstructNullFunctionData(
\r
1894 &ReservedPagePacket[BufIndex],
\r
1896 get_my_bssid(&pmlmeinfo->network),
\r
1897 _TRUE, 0, 0, _FALSE);
\r
1898 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, _FALSE, _TRUE, _FALSE);
\r
1900 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: BT QOS NULL DATA %p %d\n",
\r
1901 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (BTQosNullLength+TxDescLen));
\r
1903 CurtPktPageNum = (u8)PageNum_128(TxDescLen + BTQosNullLength);
\r
1905 TotalPageNum += CurtPktPageNum;
\r
1907 BufIndex += (CurtPktPageNum*PageSize);
\r
1909 #ifdef CONFIG_WOWLAN
\r
1910 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
\r
1911 //if (pwrctl->wowlan_mode == _TRUE) {
\r
1912 //BufIndex += (CurtPktPageNum*PageSize);
\r
1915 rtw_get_current_ip_address(padapter, currentip);
\r
1916 RsvdPageLoc.LocArpRsp= TotalPageNum;
\r
1917 #ifdef DBG_CONFIG_ERROR_DETECT
\r
1918 if(psrtpriv->silent_reset_inprogress == _FALSE)
\r
1919 #endif //DBG_CONFIG_ERROR_DETECT
\r
1921 ConstructARPResponse(
\r
1923 &ReservedPagePacket[BufIndex],
\r
1927 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ARPLegnth, _FALSE, _FALSE, _TRUE);
\r
1929 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: ARP RSP %p %d\n",
\r
1930 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (ARPLegnth+TxDescLen));
\r
1932 CurtPktPageNum = (u8)PageNum_128(TxDescLen + ARPLegnth);
\r
1934 #ifdef DBG_CONFIG_ERROR_DETECT
\r
1936 CurtPktPageNum = (u8)PageNum_128(128);
\r
1937 #endif //DBG_CONFIG_ERROR_DETECT
\r
1938 TotalPageNum += CurtPktPageNum;
\r
1940 BufIndex += (CurtPktPageNum*PageSize);
\r
1943 rtw_get_sec_iv(padapter, cur_dot11txpn, get_my_bssid(&pmlmeinfo->network));
\r
1944 RsvdPageLoc.LocRemoteCtrlInfo = TotalPageNum;
\r
1945 _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen, cur_dot11txpn, _AES_IV_LEN_);
\r
1947 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: SEC IV %p %d\n",
\r
1948 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], _AES_IV_LEN_);
\r
1950 CurtPktPageNum = (u8)PageNum_128(_AES_IV_LEN_);
\r
1952 TotalPageNum += CurtPktPageNum;
\r
1954 #ifdef CONFIG_GTK_OL
\r
1955 BufIndex += (CurtPktPageNum*PageSize);
\r
1957 //if the ap staion info. exists, get the kek, kck from staion info.
\r
1958 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
\r
1959 if (psta == NULL)
\r
1961 _rtw_memset(kek, 0, RTW_KEK_LEN);
\r
1962 _rtw_memset(kck, 0, RTW_KCK_LEN);
\r
1963 DBG_8192C("%s, KEK, KCK download rsvd page all zero \n", __func__);
\r
1967 _rtw_memcpy(kek, psta->kek, RTW_KEK_LEN);
\r
1968 _rtw_memcpy(kck, psta->kck, RTW_KCK_LEN);
\r
1972 RsvdPageLoc.LocGTKInfo = TotalPageNum;
\r
1973 _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen, kck, RTW_KCK_LEN);
\r
1974 _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen+RTW_KCK_LEN, kek, RTW_KEK_LEN);
\r
1979 printk("\ntoFW KCK: ");
\r
1980 for(i=0;i<16; i++)
\r
1981 printk(" %02x ", kck[i]);
\r
1982 printk("\ntoFW KEK: ");
\r
1983 for(i=0;i<16; i++)
\r
1984 printk(" %02x ", kek[i]);
\r
1989 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: KEK KCK %p %d\n",
\r
1990 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN));
\r
1992 CurtPktPageNum = (u8)PageNum_128(TxDescLen + RTW_KCK_LEN + RTW_KEK_LEN);
\r
1994 TotalPageNum += CurtPktPageNum;
\r
1996 BufIndex += (CurtPktPageNum*PageSize);
\r
1998 //3(10) GTK Response
\r
1999 RsvdPageLoc.LocGTKRsp= TotalPageNum;
\r
2000 ConstructGTKResponse(
\r
2002 &ReservedPagePacket[BufIndex],
\r
2006 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], GTKLegnth, _FALSE, _FALSE, _TRUE);
\r
2010 printk("123GTK pkt=> \n");
\r
2011 for(gj=0; gj < GTKLegnth+TxDescLen; gj++) {
\r
2012 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);
\r
2013 if ((gj + 1)%16==0)
\r
2016 printk(" <=end\n");
\r
2020 //DBG_871X("%s(): HW_VAR_SET_TX_CMD: GTK RSP %p %d\n",
\r
2021 // __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (TxDescLen + GTKLegnth));
\r
2023 CurtPktPageNum = (u8)PageNum_128(TxDescLen + GTKLegnth);
\r
2025 TotalPageNum += CurtPktPageNum;
\r
2027 BufIndex += (CurtPktPageNum*PageSize);
\r
2029 //below page is empty for GTK extension memory
\r
2030 //3(11) GTK EXT MEM
\r
2031 RsvdPageLoc.LocGTKEXTMEM= TotalPageNum;
\r
2033 CurtPktPageNum = 2;
\r
2035 TotalPageNum += CurtPktPageNum;
\r
2037 TotalPacketLen = BufIndex-TxDescLen + 256; //extension memory for FW
\r
2039 TotalPacketLen = BufIndex-TxDescLen + sizeof (union pn48); //IV len
\r
2040 #endif //CONFIG_GTK_OL
\r
2042 #endif //CONFIG_WOWLAN
\r
2044 #ifdef CONFIG_PNO_SUPPORT
\r
2045 if (pwrctl->pno_in_resume == _FALSE) {
\r
2047 RsvdPageLoc.LocProbePacket = TotalPageNum;
\r
2048 ConstructProbeReq(
\r
2050 &ReservedPagePacket[BufIndex],
\r
2053 rtl8723b_fill_fake_txdesc(padapter,
\r
2054 &ReservedPagePacket[BufIndex-TxDescLen],
\r
2055 ProbeReqLength, _FALSE, _FALSE, _FALSE);
\r
2056 #ifdef CONFIG_PNO_SET_DEBUG
\r
2059 printk("probe req pkt=> \n");
\r
2060 for(gj=0; gj < ProbeReqLength + TxDescLen; gj++) {
\r
2061 printk(" %02x ",ReservedPagePacket[BufIndex- TxDescLen + gj]);
\r
2062 if ((gj + 1)%8==0)
\r
2065 printk(" <=end\n");
\r
2069 (u8)PageNum_128(TxDescLen + ProbeReqLength);
\r
2071 TotalPageNum += CurtPktPageNum;
\r
2073 BufIndex += (CurtPktPageNum*PageSize);
\r
2076 RsvdPageLoc.LocPNOInfo = TotalPageNum;
\r
2077 ConstructPnoInfo(padapter, &ReservedPagePacket[BufIndex -TxDescLen], &PNOLength);
\r
2078 #ifdef CONFIG_PNO_SET_DEBUG
\r
2081 printk("PNO pkt=> \n");
\r
2082 for(gj=0; gj < PNOLength; gj++) {
\r
2083 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen +gj]);
\r
2084 if ((gj + 1)%8==0)
\r
2087 printk(" <=end\n");
\r
2091 CurtPktPageNum = (u8)PageNum_128(PNOLength);
\r
2092 TotalPageNum += CurtPktPageNum;
\r
2093 BufIndex += (CurtPktPageNum*PageSize);
\r
2096 RsvdPageLoc.LocSSIDInfo = TotalPageNum;
\r
2097 ConstructSSIDList(padapter, &ReservedPagePacket[BufIndex-TxDescLen], &SSIDLegnth);
\r
2098 #ifdef CONFIG_PNO_SET_DEBUG
\r
2101 printk("SSID list pkt=> \n");
\r
2102 for(gj=0; gj < SSIDLegnth; gj++) {
\r
2103 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);
\r
2104 if ((gj + 1)%8==0)
\r
2107 printk(" <=end\n");
\r
2110 CurtPktPageNum = (u8)PageNum_128(SSIDLegnth);
\r
2111 TotalPageNum += CurtPktPageNum;
\r
2112 BufIndex += (CurtPktPageNum*PageSize);
\r
2115 RsvdPageLoc.LocScanInfo = TotalPageNum;
\r
2116 ConstructScanInfo(padapter, &ReservedPagePacket[BufIndex-TxDescLen], &ScanInfoLength);
\r
2117 #ifdef CONFIG_PNO_SET_DEBUG
\r
2120 printk("Scan info pkt=> \n");
\r
2121 for(gj=0; gj < ScanInfoLength; gj++) {
\r
2122 printk(" %02x ", ReservedPagePacket[BufIndex-TxDescLen+gj]);
\r
2123 if ((gj + 1)%8==0)
\r
2126 printk(" <=end\n");
\r
2129 CurtPktPageNum = (u8)PageNum_128(ScanInfoLength);
\r
2130 TotalPageNum += CurtPktPageNum;
\r
2131 BufIndex += (CurtPktPageNum*PageSize);
\r
2133 TotalPacketLen = BufIndex + ScanInfoLength;
\r
2135 TotalPacketLen = BufIndex + BTQosNullLength;
\r
2137 #else //CONFIG_PNO_SUPPORT
\r
2138 TotalPacketLen = BufIndex + BTQosNullLength;
\r
2142 if(TotalPacketLen > MaxRsvdPageBufSize)
\r
2144 DBG_871X("%s(): ERROR: The rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",__FUNCTION__,
\r
2145 TotalPacketLen,MaxRsvdPageBufSize);
\r
2150 // update attribute
\r
2151 pattrib = &pcmdframe->attrib;
\r
2152 update_mgntframe_attrib(padapter, pattrib);
\r
2153 pattrib->qsel = 0x10;
\r
2154 pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
\r
2155 #ifdef CONFIG_PCI_HCI
\r
2156 dump_mgntframe(padapter, pcmdframe);
\r
2158 dump_mgntframe_and_wait(padapter, pcmdframe, 100);
\r
2162 DBG_871X("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n", __FUNCTION__,TotalPacketLen,TotalPageNum);
\r
2163 if(check_fwstate(pmlmepriv, _FW_LINKED)) {
\r
2164 rtl8723b_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc);
\r
2165 rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);
\r
2167 rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);
\r
2168 #ifdef CONFIG_PNO_SUPPORT
\r
2169 if(pwrctl->pno_in_resume)
\r
2170 rtl8723b_set_FwScanOffloadInfo_cmd(padapter,
\r
2173 rtl8723b_set_FwScanOffloadInfo_cmd(padapter,
\r
2181 rtw_free_xmitframe(pxmitpriv, pcmdframe);
\r
2184 #ifdef CONFIG_AP_WOWLAN
\r
2186 //Description: Fill the reserved packets that FW will use to RSVD page.
\r
2187 //Now we just send 2 types packet to rsvd page. (1)Beacon, (2)ProbeRsp.
\r
2189 //Input: bDLFinished
\r
2191 //FALSE: At the first time we will send all the packets as a large packet to Hw,
\r
2192 // so we need to set the packet length to total lengh.
\r
2194 //TRUE: At the second time, we should send the first packet (default:beacon)
\r
2195 // to Hw again and set the lengh in descriptor to the real beacon lengh.
\r
2196 // 2009.10.15 by tynli.
\r
2197 static void rtl8723b_set_AP_FwRsvdPagePkt(PADAPTER padapter,
\r
2198 BOOLEAN bDLFinished)
\r
2200 PHAL_DATA_TYPE pHalData;
\r
2201 struct xmit_frame *pcmdframe;
\r
2202 struct pkt_attrib *pattrib;
\r
2203 struct xmit_priv *pxmitpriv;
\r
2204 struct mlme_ext_priv *pmlmeext;
\r
2205 struct mlme_ext_info *pmlmeinfo;
\r
2206 struct pwrctrl_priv *pwrctl;
\r
2207 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2208 u32 BeaconLength=0, ProbeRspLength=0;
\r
2209 u8 *ReservedPagePacket;
\r
2210 u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;
\r
2211 u8 TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0;
\r
2212 u16 BufIndex, PageSize = 128;
\r
2213 u32 TotalPacketLen = 0, MaxRsvdPageBufSize=0;
\r
2214 RSVDPAGE_LOC RsvdPageLoc;
\r
2215 #ifdef DBG_CONFIG_ERROR_DETECT
\r
2216 struct sreset_priv *psrtpriv;
\r
2217 #endif // DBG_CONFIG_ERROR_DETECT
\r
2219 //DBG_871X("%s---->\n", __FUNCTION__);
\r
2221 pHalData = GET_HAL_DATA(padapter);
\r
2222 #ifdef DBG_CONFIG_ERROR_DETECT
\r
2223 psrtpriv = &pHalData->srestpriv;
\r
2225 pxmitpriv = &padapter->xmitpriv;
\r
2226 pmlmeext = &padapter->mlmeextpriv;
\r
2227 pmlmeinfo = &pmlmeext->mlmext_info;
\r
2228 pwrctl = adapter_to_pwrctl(padapter);
\r
2230 RsvdPageNum = BCNQ_PAGE_NUM_8723B + WOWLAN_PAGE_NUM_8723B;
\r
2231 MaxRsvdPageBufSize = RsvdPageNum*PageSize;
\r
2233 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
\r
2234 if (pcmdframe == NULL) {
\r
2235 DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
\r
2239 ReservedPagePacket = pcmdframe->buf_addr;
\r
2240 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
\r
2243 BufIndex = TxDescOffset;
\r
2244 ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);
\r
2246 // When we count the first page size, we need to reserve description size for the RSVD
\r
2247 // packet, it will be filled in front of the packet in TXPKTBUF.
\r
2248 CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength);
\r
2249 //If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware
\r
2250 if (CurtPktPageNum == 1)
\r
2252 CurtPktPageNum += 1;
\r
2254 TotalPageNum += CurtPktPageNum;
\r
2256 BufIndex += (CurtPktPageNum*PageSize);
\r
2258 //2 (4) probe response
\r
2259 RsvdPageLoc.LocProbeRsp = TotalPageNum;
\r
2260 ConstructProbeRsp(
\r
2262 &ReservedPagePacket[BufIndex],
\r
2264 get_my_bssid(&pmlmeinfo->network),
\r
2266 rtl8723b_fill_fake_txdesc(padapter,
\r
2267 &ReservedPagePacket[BufIndex-TxDescLen],
\r
2269 _FALSE, _FALSE, _FALSE);
\r
2271 DBG_871X("%s(): HW_VAR_SET_TX_CMD: PROBE RSP %p %d\n",
\r
2272 __func__, &ReservedPagePacket[BufIndex-TxDescLen],
\r
2273 (ProbeRspLength+TxDescLen));
\r
2275 CurtPktPageNum = (u8)PageNum_128(TxDescLen + ProbeRspLength);
\r
2277 TotalPageNum += CurtPktPageNum;
\r
2279 BufIndex += (CurtPktPageNum*PageSize);
\r
2281 TotalPacketLen = BufIndex + ProbeRspLength;
\r
2283 if (TotalPacketLen > MaxRsvdPageBufSize) {
\r
2284 DBG_871X("%s(): ERROR: The rsvd page size is not enough \
\r
2285 !!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
\r
2286 __func__, TotalPacketLen,MaxRsvdPageBufSize);
\r
2289 // update attribute
\r
2290 pattrib = &pcmdframe->attrib;
\r
2291 update_mgntframe_attrib(padapter, pattrib);
\r
2292 pattrib->qsel = 0x10;
\r
2293 pattrib->pktlen = TotalPacketLen - TxDescOffset;
\r
2294 pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
\r
2295 #ifdef CONFIG_PCI_HCI
\r
2296 dump_mgntframe(padapter, pcmdframe);
\r
2298 dump_mgntframe_and_wait(padapter, pcmdframe, 100);
\r
2302 DBG_871X("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n", __FUNCTION__,TotalPacketLen,TotalPageNum);
\r
2303 rtl8723b_set_ap_wow_rsvdpage_cmd(padapter, &RsvdPageLoc);
\r
2307 rtw_free_xmitframe(pxmitpriv, pcmdframe);
\r
2309 #endif //CONFIG_AP_WOWLAN
\r
2311 void rtl8723b_download_rsvd_page(PADAPTER padapter, u8 mstatus)
\r
2313 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
\r
2314 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
2315 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2316 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
\r
2317 BOOLEAN bcn_valid = _FALSE;
\r
2324 DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d mstatus(%x)\n",
\r
2325 FUNC_ADPT_ARG(padapter), get_iface_type(padapter), mstatus);
\r
2327 if(mstatus == RT_MEDIA_CONNECT)
\r
2329 BOOLEAN bRecover = _FALSE;
\r
2332 // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.
\r
2333 // Suggested by filen. Added by tynli.
\r
2334 rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));
\r
2336 // set REG_CR bit 8
\r
2337 v8 = rtw_read8(padapter, REG_CR+1);
\r
2338 v8 |= BIT(0); // ENSWBCN
\r
2339 rtw_write8(padapter, REG_CR+1, v8);
\r
2341 // Disable Hw protection for a time which revserd for Hw sending beacon.
\r
2342 // Fix download reserved page packet fail that access collision with the protection time.
\r
2343 // 2010.05.11. Added by tynli.
\r
2344 val8 = rtw_read8(padapter, REG_BCN_CTRL);
\r
2347 rtw_write8(padapter, REG_BCN_CTRL, val8);
\r
2349 // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
\r
2350 if (pHalData->RegFwHwTxQCtrl & BIT(6))
\r
2353 // To tell Hw the packet is not a real beacon frame.
\r
2354 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl & ~BIT(6));
\r
2355 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
\r
2357 // Clear beacon valid check bit.
\r
2358 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
\r
2359 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
\r
2365 #ifdef CONFIG_AP_WOWLAN
\r
2366 if (pwrpriv->wowlan_ap_mode)
\r
2367 rtl8723b_set_AP_FwRsvdPagePkt(padapter, 0);
\r
2369 rtl8723b_set_FwRsvdPagePkt(padapter, 0);
\r
2371 // download rsvd page.
\r
2372 rtl8723b_set_FwRsvdPagePkt(padapter, 0);
\r
2378 //rtw_mdelay_os(10);
\r
2379 // check rsvd page download OK.
\r
2380 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8*)(&bcn_valid));
\r
2382 } while(!bcn_valid && (poll%10)!=0 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
\r
2384 }while(!bcn_valid && DLBcnCount<=100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
\r
2386 if(padapter->bSurpriseRemoved || padapter->bDriverStopped)
\r
2389 else if(!bcn_valid)
\r
2390 DBG_871X(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n",
\r
2391 ADPT_ARG(padapter) ,DLBcnCount, poll);
\r
2393 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
\r
2394 pwrctl->fw_psmode_iface_id = padapter->iface_id;
\r
2395 DBG_871X(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n",
\r
2396 ADPT_ARG(padapter), DLBcnCount, poll);
\r
2399 // 2010.05.11. Added by tynli.
\r
2400 val8 = rtw_read8(padapter, REG_BCN_CTRL);
\r
2403 rtw_write8(padapter, REG_BCN_CTRL, val8);
\r
2405 // To make sure that if there exists an adapter which would like to send beacon.
\r
2406 // If exists, the origianl value of 0x422[6] will be 1, we should check this to
\r
2407 // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
\r
2408 // the beacon cannot be sent by HW.
\r
2409 // 2010.06.23. Added by tynli.
\r
2412 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl | BIT(6));
\r
2413 pHalData->RegFwHwTxQCtrl |= BIT(6);
\r
2416 // Clear CR[8] or beacon packet will not be send to TxBuf anymore.
\r
2417 v8 = rtw_read8(padapter, REG_CR+1);
\r
2418 v8 &= ~BIT(0); // ~ENSWBCN
\r
2419 rtw_write8(padapter, REG_CR+1, v8);
\r
2425 void rtl8723b_set_rssi_cmd(_adapter*padapter, u8 *param)
\r
2427 rtl8723b_set_FwRssiSetting_cmd(padapter, param);
\r
2430 void rtl8723b_set_FwJoinBssRpt_cmd(PADAPTER padapter, u8 mstatus)
\r
2432 struct sta_info *psta = NULL;
\r
2433 struct pwrctrl_priv *ppwrpriv = adapter_to_pwrctl(padapter);
\r
2434 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2437 rtl8723b_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
\r
2442 //arg[2] = shortGIrate
\r
2443 //arg[3] = init_rate
\r
2444 void rtl8723b_Add_RateATid(PADAPTER pAdapter, u32 bitmap, u8* arg, u8 rssi_level)
\r
2446 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
\r
2447 struct mlme_ext_priv *pmlmeext = &pAdapter->mlmeextpriv;
\r
2448 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2449 struct sta_info *psta;
\r
2450 u8 mac_id = arg[0];
\r
2452 u8 shortGI = arg[2];
\r
2454 u32 mask = bitmap&0x0FFFFFFF;
\r
2456 psta = pmlmeinfo->FW_sta_info[mac_id].psta;
\r
2462 bw = psta->bw_mode;
\r
2464 if(rssi_level != DM_RATR_STA_INIT)
\r
2465 mask = ODM_Get_Rate_Bitmap(&pHalData->odmpriv, mac_id, mask, rssi_level);
\r
2467 DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x\n", __func__, mac_id, raid, bw, mask);
\r
2468 rtl8723b_set_FwMacIdConfig_cmd(pAdapter, mac_id, raid, bw, shortGI, mask);
\r
2472 void rtl8723b_fw_try_ap_cmd(PADAPTER padapter, u32 need_ack)
\r
2474 rtl8723b_set_FwAPReqRPT_cmd(padapter, need_ack);
\r
2478 #ifdef CONFIG_BT_COEXIST
\r
2479 static void ConstructBtNullFunctionData(
\r
2480 PADAPTER padapter,
\r
2487 u8 bForcePowerSave)
\r
2489 struct rtw_ieee80211_hdr *pwlanhdr;
\r
2492 struct mlme_ext_priv *pmlmeext;
\r
2493 struct mlme_ext_info *pmlmeinfo;
\r
2494 u8 bssid[ETH_ALEN];
\r
2497 DBG_871X("+" FUNC_ADPT_FMT ": qos=%d eosp=%d ps=%d\n",
\r
2498 FUNC_ADPT_ARG(padapter), bQoS, bEosp, bForcePowerSave);
\r
2500 pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;
\r
2501 pmlmeext = &padapter->mlmeextpriv;
\r
2502 pmlmeinfo = &pmlmeext->mlmext_info;
\r
2504 if (NULL == StaAddr)
\r
2506 _rtw_memcpy(bssid, myid(&padapter->eeprompriv), ETH_ALEN);
\r
2510 fctrl = &pwlanhdr->frame_ctl;
\r
2512 if (bForcePowerSave)
\r
2516 _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN);
\r
2517 _rtw_memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
\r
2518 _rtw_memcpy(pwlanhdr->addr3, myid(&padapter->eeprompriv), ETH_ALEN);
\r
2520 SetDuration(pwlanhdr, 0);
\r
2521 SetSeqNum(pwlanhdr, 0);
\r
2523 if (bQoS == _TRUE)
\r
2525 struct rtw_ieee80211_hdr_3addr_qos *pwlanqoshdr;
\r
2527 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
\r
2529 pwlanqoshdr = (struct rtw_ieee80211_hdr_3addr_qos*)pframe;
\r
2530 SetPriority(&pwlanqoshdr->qc, AC);
\r
2531 SetEOSP(&pwlanqoshdr->qc, bEosp);
\r
2533 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
\r
2537 SetFrameSubType(pframe, WIFI_DATA_NULL);
\r
2539 pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
2542 *pLength = pktlen;
\r
2545 static void SetFwRsvdPagePkt_BTCoex(PADAPTER padapter)
\r
2547 PHAL_DATA_TYPE pHalData;
\r
2548 struct xmit_frame *pcmdframe;
\r
2549 struct pkt_attrib *pattrib;
\r
2550 struct xmit_priv *pxmitpriv;
\r
2551 struct mlme_ext_priv *pmlmeext;
\r
2552 struct mlme_ext_info *pmlmeinfo;
\r
2553 u32 BeaconLength = 0;
\r
2554 u32 BTQosNullLength = 0;
\r
2555 u8 *ReservedPagePacket;
\r
2556 u8 TxDescLen, TxDescOffset;
\r
2557 u8 TotalPageNum=0, CurtPktPageNum=0, RsvdPageNum=0;
\r
2558 u16 BufIndex, PageSize;
\r
2559 u32 TotalPacketLen, MaxRsvdPageBufSize=0;
\r
2560 RSVDPAGE_LOC RsvdPageLoc;
\r
2563 // DBG_8192C("+" FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter));
\r
2565 pHalData = GET_HAL_DATA(padapter);
\r
2566 pxmitpriv = &padapter->xmitpriv;
\r
2567 pmlmeext = &padapter->mlmeextpriv;
\r
2568 pmlmeinfo = &pmlmeext->mlmext_info;
\r
2569 TxDescLen = TXDESC_SIZE;
\r
2570 TxDescOffset = TXDESC_OFFSET;
\r
2571 PageSize = PAGE_SIZE_TX_8723B;
\r
2573 RsvdPageNum = BCNQ_PAGE_NUM_8723B;
\r
2574 MaxRsvdPageBufSize = RsvdPageNum*PageSize;
\r
2576 pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);
\r
2577 if (pcmdframe == NULL) {
\r
2578 DBG_8192C("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);
\r
2582 ReservedPagePacket = pcmdframe->buf_addr;
\r
2583 _rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));
\r
2586 BufIndex = TxDescOffset;
\r
2587 ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength);
\r
2589 // When we count the first page size, we need to reserve description size for the RSVD
\r
2590 // packet, it will be filled in front of the packet in TXPKTBUF.
\r
2591 CurtPktPageNum = (u8)PageNum_128(TxDescLen + BeaconLength);
\r
2592 //If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware
\r
2593 if (CurtPktPageNum == 1)
\r
2595 CurtPktPageNum += 1;
\r
2597 TotalPageNum += CurtPktPageNum;
\r
2599 BufIndex += (CurtPktPageNum*PageSize);
\r
2601 // Jump to lastest page
\r
2602 if (BufIndex < (MaxRsvdPageBufSize - PageSize))
\r
2604 BufIndex = TxDescOffset + (MaxRsvdPageBufSize - PageSize);
\r
2605 TotalPageNum = BCNQ_PAGE_NUM_8723B - 1;
\r
2608 //3 (6) BT Qos null data
\r
2609 RsvdPageLoc.LocBTQosNull = TotalPageNum;
\r
2610 ConstructBtNullFunctionData(
\r
2612 &ReservedPagePacket[BufIndex],
\r
2615 _TRUE, 0, 0, _FALSE);
\r
2616 rtl8723b_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, _FALSE, _TRUE, _FALSE);
\r
2618 CurtPktPageNum = (u8)PageNum_128(TxDescLen + BTQosNullLength);
\r
2620 TotalPageNum += CurtPktPageNum;
\r
2622 TotalPacketLen = BufIndex + BTQosNullLength;
\r
2623 if (TotalPacketLen > MaxRsvdPageBufSize)
\r
2625 DBG_8192C(FUNC_ADPT_FMT ": ERROR: The rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n",
\r
2626 FUNC_ADPT_ARG(padapter), TotalPacketLen, MaxRsvdPageBufSize);
\r
2630 // update attribute
\r
2631 pattrib = &pcmdframe->attrib;
\r
2632 update_mgntframe_attrib(padapter, pattrib);
\r
2633 pattrib->qsel = 0x10;
\r
2634 pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;
\r
2635 #ifdef CONFIG_PCI_HCI
\r
2636 dump_mgntframe(padapter, pcmdframe);
\r
2638 dump_mgntframe_and_wait(padapter, pcmdframe, 100);
\r
2641 // DBG_8192C(FUNC_ADPT_FMT ": Set RSVD page location to Fw, TotalPacketLen(%d), TotalPageNum(%d)\n",
\r
2642 // FUNC_ADPT_ARG(padapter), TotalPacketLen, TotalPageNum);
\r
2643 rtl8723b_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc);
\r
2644 rtl8723b_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);
\r
2649 rtw_free_xmitframe(pxmitpriv, pcmdframe);
\r
2652 void rtl8723b_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter)
\r
2654 PHAL_DATA_TYPE pHalData;
\r
2655 struct mlme_ext_priv *pmlmeext;
\r
2656 struct mlme_ext_info *pmlmeinfo;
\r
2657 u8 bRecover = _FALSE;
\r
2658 u8 bcn_valid = _FALSE;
\r
2659 u8 DLBcnCount = 0;
\r
2664 DBG_8192C("+" FUNC_ADPT_FMT ": iface_type=%d fw_state=0x%08X\n",
\r
2665 FUNC_ADPT_ARG(padapter), get_iface_type(padapter), get_fwstate(&padapter->mlmepriv));
\r
2667 #ifdef CONFIG_DEBUG
\r
2668 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _FALSE)
\r
2670 DBG_8192C(FUNC_ADPT_FMT ": [WARNING] not in AP mode!!\n",
\r
2671 FUNC_ADPT_ARG(padapter));
\r
2673 #endif // CONFIG_DEBUG
\r
2675 pHalData = GET_HAL_DATA(padapter);
\r
2676 pmlmeext = &padapter->mlmeextpriv;
\r
2677 pmlmeinfo = &pmlmeext->mlmext_info;
\r
2679 // We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C.
\r
2680 // Suggested by filen. Added by tynli.
\r
2681 rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000|pmlmeinfo->aid));
\r
2683 // set REG_CR bit 8
\r
2684 val8 = rtw_read8(padapter, REG_CR+1);
\r
2685 val8 |= BIT(0); // ENSWBCN
\r
2686 rtw_write8(padapter, REG_CR+1, val8);
\r
2688 // Disable Hw protection for a time which revserd for Hw sending beacon.
\r
2689 // Fix download reserved page packet fail that access collision with the protection time.
\r
2690 // 2010.05.11. Added by tynli.
\r
2691 val8 = rtw_read8(padapter, REG_BCN_CTRL);
\r
2694 rtw_write8(padapter, REG_BCN_CTRL, val8);
\r
2696 // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
\r
2697 if (pHalData->RegFwHwTxQCtrl & BIT(6))
\r
2700 // To tell Hw the packet is not a real beacon frame.
\r
2701 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
\r
2702 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
\r
2704 // Clear beacon valid check bit.
\r
2705 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
\r
2706 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
\r
2711 SetFwRsvdPagePkt_BTCoex(padapter);
\r
2715 // rtw_mdelay_os(10);
\r
2716 // check rsvd page download OK.
\r
2717 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, &bcn_valid);
\r
2719 } while (!bcn_valid && (poll%10)!=0 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
\r
2720 } while (!bcn_valid && (DLBcnCount<=100) && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
\r
2722 if (_TRUE == bcn_valid)
\r
2724 struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);
\r
2725 pwrctl->fw_psmode_iface_id = padapter->iface_id;
\r
2726 DBG_8192C(ADPT_FMT": DL RSVD page success! DLBcnCount:%d, poll:%d\n",
\r
2727 ADPT_ARG(padapter), DLBcnCount, poll);
\r
2731 DBG_8192C(ADPT_FMT": DL RSVD page fail! DLBcnCount:%d, poll:%d\n",
\r
2732 ADPT_ARG(padapter), DLBcnCount, poll);
\r
2733 DBG_8192C(ADPT_FMT": DL RSVD page fail! bSurpriseRemoved=%d\n",
\r
2734 ADPT_ARG(padapter), padapter->bSurpriseRemoved);
\r
2735 DBG_8192C(ADPT_FMT": DL RSVD page fail! bDriverStopped=%d\n",
\r
2736 ADPT_ARG(padapter), padapter->bDriverStopped);
\r
2739 // 2010.05.11. Added by tynli.
\r
2740 val8 = rtw_read8(padapter, REG_BCN_CTRL);
\r
2743 rtw_write8(padapter, REG_BCN_CTRL, val8);
\r
2745 // To make sure that if there exists an adapter which would like to send beacon.
\r
2746 // If exists, the origianl value of 0x422[6] will be 1, we should check this to
\r
2747 // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
\r
2748 // the beacon cannot be sent by HW.
\r
2749 // 2010.06.23. Added by tynli.
\r
2752 pHalData->RegFwHwTxQCtrl |= BIT(6);
\r
2753 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
\r
2756 // Clear CR[8] or beacon packet will not be send to TxBuf anymore.
\r
2757 val8 = rtw_read8(padapter, REG_CR+1);
\r
2758 val8 &= ~BIT(0); // ~ENSWBCN
\r
2759 rtw_write8(padapter, REG_CR+1, val8);
\r
2761 #endif // CONFIG_BT_COEXIST
\r
2764 void rtl8723b_set_p2p_ps_offload_cmd(_adapter* padapter, u8 p2p_ps_state)
\r
2766 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
\r
2767 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
\r
2768 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
\r
2769 struct P2P_PS_Offload_t *p2p_ps_offload = (struct P2P_PS_Offload_t *)(&pHalData->p2p_ps_offload);
\r
2775 switch(p2p_ps_state)
\r
2777 case P2P_PS_DISABLE:
\r
2778 DBG_8192C("P2P_PS_DISABLE \n");
\r
2779 _rtw_memset(p2p_ps_offload, 0 ,1);
\r
2781 case P2P_PS_ENABLE:
\r
2782 DBG_8192C("P2P_PS_ENABLE \n");
\r
2783 // update CTWindow value.
\r
2784 if( pwdinfo->ctwindow > 0 )
\r
2786 p2p_ps_offload->CTWindow_En = 1;
\r
2787 rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow);
\r
2790 // hw only support 2 set of NoA
\r
2791 for( i=0 ; i<pwdinfo->noa_num ; i++)
\r
2793 // To control the register setting for which NOA
\r
2794 rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4));
\r
2796 p2p_ps_offload->NoA0_En = 1;
\r
2798 p2p_ps_offload->NoA1_En = 1;
\r
2800 // config P2P NoA Descriptor Register
\r
2801 //DBG_8192C("%s(): noa_duration = %x\n",__FUNCTION__,pwdinfo->noa_duration[i]);
\r
2802 rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);
\r
2804 //DBG_8192C("%s(): noa_interval = %x\n",__FUNCTION__,pwdinfo->noa_interval[i]);
\r
2805 rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);
\r
2807 //DBG_8192C("%s(): start_time = %x\n",__FUNCTION__,pwdinfo->noa_start_time[i]);
\r
2808 rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);
\r
2810 //DBG_8192C("%s(): noa_count = %x\n",__FUNCTION__,pwdinfo->noa_count[i]);
\r
2811 rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);
\r
2814 if( (pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0) )
\r
2816 // rst p2p circuit
\r
2817 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(4));
\r
2819 p2p_ps_offload->Offload_En = 1;
\r
2821 if(pwdinfo->role == P2P_ROLE_GO)
\r
2823 p2p_ps_offload->role= 1;
\r
2824 p2p_ps_offload->AllStaSleep = 0;
\r
2828 p2p_ps_offload->role= 0;
\r
2831 p2p_ps_offload->discovery = 0;
\r
2835 DBG_8192C("P2P_PS_SCAN \n");
\r
2836 p2p_ps_offload->discovery = 1;
\r
2838 case P2P_PS_SCAN_DONE:
\r
2839 DBG_8192C("P2P_PS_SCAN_DONE \n");
\r
2840 p2p_ps_offload->discovery = 0;
\r
2841 pwdinfo->p2p_ps_state = P2P_PS_ENABLE;
\r
2847 FillH2CCmd8723B(padapter, H2C_8723B_P2P_PS_OFFLOAD, 1, (u8 *)p2p_ps_offload);
\r
2853 #endif //CONFIG_P2P
\r
2856 #ifdef CONFIG_TSF_RESET_OFFLOAD
\r
2858 ask FW to Reset sync register at Beacon early interrupt
\r
2860 u8 rtl8723b_reset_tsf(_adapter *padapter, u8 reset_port )
\r
2866 if (IFACE_PORT0==reset_port) {
\r
2867 buf[0] = 0x1; buf[1] = 0;
\r
2870 buf[0] = 0x0; buf[1] = 0x1;
\r
2872 FillH2CCmd8723B(padapter, H2C_8723B_RESET_TSF, 2, buf);
\r
2877 #endif // CONFIG_TSF_RESET_OFFLOAD
\r