// // Description: Fill the reserved packets that FW will use to RSVD page. // Now we just send 4 types packet to rsvd page. // (1)Beacon, (2)Ps-poll, (3)Null data, (4)ProbeRsp. // Input: // bDLFinished - FALSE: At the first time we will send all the packets as a large packet to Hw, // so we need to set the packet length to total lengh. // TRUE: At the second time, we should send the first packet (default:beacon) // to Hw again and set the lengh in descriptor to the real beacon lengh. // 2009.10.15 by tynli. static void SetFwRsvdPagePkt(PADAPTER padapter, BOOLEAN bDLFinished) { PHAL_DATA_TYPE pHalData; struct xmit_frame *pcmdframe; struct pkt_attrib *pattrib; struct xmit_priv *pxmitpriv; struct mlme_ext_priv *pmlmeext; struct mlme_ext_info *pmlmeinfo; u32 BeaconLength, ProbeRspLength, PSPollLength; u32 NullDataLength, QosNullLength, BTQosNullLength; u8 *ReservedPagePacket; u8 RsvdPageNum = 0; u8 PageNum, PageNeed, TxDescLen; u16 BufIndex, PageSize = 128; u32 TotalPacketLen, MaxRsvdPageBufSize=0; RSVDPAGE_LOC RsvdPageLoc; #ifdef CONFIG_WOWLAN u32 ARPLegnth = 0; struct security_priv *psecuritypriv = &padapter->securitypriv; //added by xx u8 currentip[4]; u8 cur_dot11txpn[8]; #endif DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); #ifdef CONFIG_WOWLAN RsvdPageNum = BCNQ_PAGE_NUM_88E + WOWLAN_PAGE_NUM_88E; #else RsvdPageNum = BCNQ_PAGE_NUM_88E; #endif printk("RsvdPageNum: %d\n", RsvdPageNum); MaxRsvdPageBufSize = RsvdPageNum*PageSize; ReservedPagePacket = (u8*)rtw_zmalloc(MaxRsvdPageBufSize); if (ReservedPagePacket == NULL) { DBG_871X("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__); } pHalData = GET_HAL_DATA(padapter); pxmitpriv = &padapter->xmitpriv; pmlmeext = &padapter->mlmeextpriv; pmlmeinfo = &pmlmeext->mlmext_info; TxDescLen = TXDESC_SIZE; PageNum = 0; //3 (1) beacon * 2 pages BufIndex = TXDESC_OFFSET; ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength); // When we count the first page size, we need to reserve description size for the RSVD // packet, it will be filled in front of the packet in TXPKTBUF. PageNeed = (u8)PageNum_128(TxDescLen + BeaconLength); // To reserved 2 pages for beacon buffer. 2010.06.24. if (PageNeed == 1) PageNeed += 1; PageNum += PageNeed; pHalData->FwRsvdPageStartOffset = PageNum; BufIndex += PageNeed * PageSize; //3 (2) ps-poll *1 page RsvdPageLoc.LocPsPoll = PageNum; ConstructPSPoll(padapter, &ReservedPagePacket[BufIndex], &PSPollLength); rtl8188e_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, _TRUE, _FALSE); PageNeed = (u8)PageNum_128(TxDescLen + PSPollLength); PageNum += PageNeed; BufIndex += PageNeed * PageSize; //3 (3) null data * 1 page RsvdPageLoc.LocNullData = PageNum; ConstructNullFunctionData( padapter, &ReservedPagePacket[BufIndex], &NullDataLength, get_my_bssid(&pmlmeinfo->network), _FALSE, 0, 0, _FALSE); rtl8188e_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, _FALSE, _FALSE); PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength); PageNum += PageNeed; BufIndex += PageNeed * PageSize; //3 (5) Qos null data RsvdPageLoc.LocQosNull = PageNum; ConstructNullFunctionData( padapter, &ReservedPagePacket[BufIndex], &QosNullLength, get_my_bssid(&pmlmeinfo->network), _TRUE, 0, 0, _FALSE); rtl8188e_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, _FALSE, _FALSE); PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength); PageNum += PageNeed; BufIndex += PageNeed * PageSize; /* //3 (6) BT Qos null data RsvdPageLoc.LocBTQosNull = PageNum; ConstructNullFunctionData( padapter, &ReservedPagePacket[BufIndex], &BTQosNullLength, get_my_bssid(&pmlmeinfo->network), _TRUE, 0, 0, _FALSE); rtl8188e_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, _FALSE, _TRUE); TotalPacketLen = BufIndex + BTQosNullLength; */ #ifdef CONFIG_WOWLAN //3(7) ARP rtw_get_current_ip_address(padapter, currentip); RsvdPageLoc.LocArpRsp = PageNum; ConstructARPResponse( padapter, &ReservedPagePacket[BufIndex], &ARPLegnth, currentip ); rtl8188e_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ARPLegnth, _FALSE, _FALSE); PageNeed = (u8)PageNum_128(TxDescLen + ARPLegnth); PageNum += PageNeed; BufIndex += PageNeed * PageSize; //3(8) sec IV rtw_get_sec_iv(padapter, cur_dot11txpn, get_my_bssid(&pmlmeinfo->network)); RsvdPageLoc.LocRemoteCtrlInfo = PageNum; _rtw_memcpy(ReservedPagePacket+BufIndex-TxDescLen, cur_dot11txpn, 8); TotalPacketLen = BufIndex-TxDescLen + sizeof (union pn48); //IV len #else TotalPacketLen = BufIndex + QosNullLength; #endif pcmdframe = alloc_mgtxmitframe(pxmitpriv); if (pcmdframe == NULL) goto exit; // update attribute pattrib = &pcmdframe->attrib; update_mgntframe_attrib(padapter, pattrib); pattrib->qsel = 0x10; pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TXDESC_OFFSET; if (TotalPacketLen < MaxRsvdPageBufSize) _rtw_memcpy(pcmdframe->buf_addr, ReservedPagePacket, TotalPacketLen); else DBG_871X("%s: memory copy fail at Line:%d\n", __FUNCTION__, __LINE__); rtw_hal_mgnt_xmit(padapter, pcmdframe); DBG_871X("%s: Set RSVD page location to Fw ,TotalPacketLen(%d)\n", __FUNCTION__,TotalPacketLen); rtl8188e_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc); exit: rtw_mfree(ReservedPagePacket, MaxRsvdPageBufSize); }
void SetFwRsvdPagePkt(PADAPTER Adapter, BOOLEAN bDLFinished) { HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); struct xmit_frame *pmgntframe; struct pkt_attrib *pattrib; struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv); struct mlme_ext_priv *pmlmeext = &(Adapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); u32 BeaconLength, ProbeRspLength, PSPollLength, NullFunctionDataLength; u8 *ReservedPagePacket; u8 PageNum=0, U1bTmp, TxDescLen=0, TxDescOffset=0; u16 BufIndex=0; u32 TotalPacketLen; u8 u1RsvdPageLoc[3]={0}; BOOLEAN bDLOK = _FALSE; DBG_871X("%s\n", __FUNCTION__); ReservedPagePacket = (u8*)rtw_malloc(1000); if(ReservedPagePacket == NULL){ DBG_871X("%s(): alloc ReservedPagePacket fail !!!\n", __FUNCTION__); return; } _rtw_memset(ReservedPagePacket, 0, 1000); TxDescLen = 32;//TX_DESC_SIZE; #ifdef CONFIG_USB_HCI BufIndex = TXDESC_OFFSET; TxDescOffset = TxDescLen + PACKET_OFFSET_SZ;; #else BufIndex = 0; TxDescOffset = 0; #endif //(1) beacon ConstructBeacon(Adapter,&ReservedPagePacket[BufIndex],&BeaconLength); RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: BCN\n", &ReservedPagePacket[BufIndex], (BeaconLength+BufIndex)); //-------------------------------------------------------------------- // When we count the first page size, we need to reserve description size for the RSVD // packet, it will be filled in front of the packet in TXPKTBUF. U1bTmp = (u8)PageNum_128(BeaconLength+TxDescLen); PageNum += U1bTmp; // To reserved 2 pages for beacon buffer. 2010.06.24. if(PageNum == 1) PageNum+=1; pHalData->FwRsvdPageStartOffset = PageNum; BufIndex = (PageNum*128) + TxDescOffset; //(2) ps-poll ConstructPSPoll(Adapter, &ReservedPagePacket[BufIndex],&PSPollLength); FillFakeTxDescriptor92D(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, _TRUE); RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: PS-POLL\n", &ReservedPagePacket[BufIndex-TxDescLen], (PSPollLength+TxDescLen)); SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PageNum ); //------------------------------------------------------------------ U1bTmp = (u8)PageNum_128(PSPollLength+TxDescLen); PageNum += U1bTmp; BufIndex = (PageNum*128) + TxDescOffset; //(3) null data ConstructNullFunctionData( Adapter, &ReservedPagePacket[BufIndex], &NullFunctionDataLength, get_my_bssid(&(pmlmeinfo->network)), _FALSE); FillFakeTxDescriptor92D(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], NullFunctionDataLength, _FALSE); SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, PageNum); RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: NULL DATA \n", &ReservedPagePacket[BufIndex-TxDescLen], (NullFunctionDataLength+TxDescLen)); //------------------------------------------------------------------ U1bTmp = (u8)PageNum_128(NullFunctionDataLength+TxDescLen); PageNum += U1bTmp; BufIndex = (PageNum*128) + TxDescOffset; //(4) probe response ConstructProbeRsp( Adapter, &ReservedPagePacket[BufIndex], &ProbeRspLength, get_my_bssid(&(pmlmeinfo->network)), _FALSE); FillFakeTxDescriptor92D(Adapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, _FALSE); SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PageNum); RT_PRINT_DATA(_module_rtl8712_cmd_c_, _drv_info_, "SetFwRsvdPagePkt(): HW_VAR_SET_TX_CMD: PROBE RSP \n", &ReservedPagePacket[BufIndex-TxDescLen], (ProbeRspLength-TxDescLen)); //------------------------------------------------------------------ U1bTmp = (u8)PageNum_128(ProbeRspLength+TxDescLen); PageNum += U1bTmp; TotalPacketLen = (PageNum*128); if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL) { return; } //update attribute pattrib = &pmgntframe->attrib; update_mgntframe_attrib(Adapter, pattrib); pattrib->qsel = 0x10; pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescLen; _rtw_memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen); rtw_hal_mgnt_xmit(Adapter, pmgntframe); bDLOK = _TRUE; if(bDLOK) { DBG_871X("Set RSVD page location to Fw.\n"); FillH2CCmd92D(Adapter, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); //FillH2CCmd92D(Adapter, H2C_RSVDPAGE, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc); } rtw_mfree(ReservedPagePacket,1000); }
/* 2009.10.15 by tynli. */ static void SetFwRsvdPagePkt(struct rtw_adapter *padapter, bool bDLFinished) { struct hal_data_8723a *pHalData; struct xmit_frame *pmgntframe; struct pkt_attrib *pattrib; struct xmit_priv *pxmitpriv; struct mlme_ext_priv *pmlmeext; struct mlme_ext_info *pmlmeinfo; u32 BeaconLength = 0, ProbeRspLength = 0, PSPollLength; u32 NullDataLength, QosNullLength, BTQosNullLength; u8 *ReservedPagePacket; u8 PageNum, PageNeed, TxDescLen; u16 BufIndex; u32 TotalPacketLen; struct rsvdpage_loc RsvdPageLoc; DBG_8723A("%s\n", __func__); ReservedPagePacket = kzalloc(1000, GFP_KERNEL); if (ReservedPagePacket == NULL) { DBG_8723A("%s: alloc ReservedPagePacket fail!\n", __func__); return; } pHalData = GET_HAL_DATA(padapter); pxmitpriv = &padapter->xmitpriv; pmlmeext = &padapter->mlmeextpriv; pmlmeinfo = &pmlmeext->mlmext_info; TxDescLen = TXDESC_SIZE; PageNum = 0; /* 3 (1) beacon */ BufIndex = TXDESC_OFFSET; ConstructBeacon(padapter, &ReservedPagePacket[BufIndex], &BeaconLength); /* When we count the first page size, we need to reserve description size for the RSVD */ /* packet, it will be filled in front of the packet in TXPKTBUF. */ PageNeed = (u8)PageNum_128(TxDescLen + BeaconLength); /* To reserved 2 pages for beacon buffer. 2010.06.24. */ if (PageNeed == 1) PageNeed += 1; PageNum += PageNeed; pHalData->FwRsvdPageStartOffset = PageNum; BufIndex += PageNeed*128; /* 3 (2) ps-poll */ RsvdPageLoc.LocPsPoll = PageNum; ConstructPSPoll(padapter, &ReservedPagePacket[BufIndex], &PSPollLength); rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], PSPollLength, true, false); PageNeed = (u8)PageNum_128(TxDescLen + PSPollLength); PageNum += PageNeed; BufIndex += PageNeed*128; /* 3 (3) null data */ RsvdPageLoc.LocNullData = PageNum; ConstructNullFunctionData(padapter, &ReservedPagePacket[BufIndex], &NullDataLength, get_my_bssid23a(&pmlmeinfo->network), false, 0, 0, false); rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], NullDataLength, false, false); PageNeed = (u8)PageNum_128(TxDescLen + NullDataLength); PageNum += PageNeed; BufIndex += PageNeed*128; /* 3 (4) probe response */ RsvdPageLoc.LocProbeRsp = PageNum; ConstructProbeRsp( padapter, &ReservedPagePacket[BufIndex], &ProbeRspLength, get_my_bssid23a(&pmlmeinfo->network), false); rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], ProbeRspLength, false, false); PageNeed = (u8)PageNum_128(TxDescLen + ProbeRspLength); PageNum += PageNeed; BufIndex += PageNeed*128; /* 3 (5) Qos null data */ RsvdPageLoc.LocQosNull = PageNum; ConstructNullFunctionData( padapter, &ReservedPagePacket[BufIndex], &QosNullLength, get_my_bssid23a(&pmlmeinfo->network), true, 0, 0, false); rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], QosNullLength, false, false); PageNeed = (u8)PageNum_128(TxDescLen + QosNullLength); PageNum += PageNeed; BufIndex += PageNeed*128; /* 3 (6) BT Qos null data */ RsvdPageLoc.LocBTQosNull = PageNum; ConstructNullFunctionData( padapter, &ReservedPagePacket[BufIndex], &BTQosNullLength, get_my_bssid23a(&pmlmeinfo->network), true, 0, 0, false); rtl8723a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex-TxDescLen], BTQosNullLength, false, true); TotalPacketLen = BufIndex + BTQosNullLength; pmgntframe = alloc_mgtxmitframe23a(pxmitpriv); if (pmgntframe == NULL) goto exit; /* update attribute */ pattrib = &pmgntframe->attrib; update_mgntframe_attrib23a(padapter, pattrib); pattrib->qsel = 0x10; pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TXDESC_OFFSET; memcpy(pmgntframe->buf_addr, ReservedPagePacket, TotalPacketLen); rtl8723au_mgnt_xmit(padapter, pmgntframe); DBG_8723A("%s: Set RSVD page location to Fw\n", __func__); FillH2CCmd(padapter, RSVD_PAGE_EID, sizeof(RsvdPageLoc), (u8 *)&RsvdPageLoc); exit: kfree(ReservedPagePacket); }