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); }