void ConstructNullFunctionData(_adapter *padapter, u8 *pframe, u32 *pLength, u8 *StaAddr, BOOLEAN bForcePowerSave) { struct rtw_ieee80211_hdr *pwlanhdr; u16 *fctrl; u32 pktlen; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *cur_network = &pmlmepriv->cur_network; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); //DBG_871X("%s:%d\n", __FUNCTION__, bForcePowerSave); pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; fctrl = &(pwlanhdr->frame_ctl); *(fctrl) = 0; if (bForcePowerSave) { SetPwrMgt(fctrl); } switch(cur_network->network.InfrastructureMode) { case Ndis802_11Infrastructure: SetToDs(fctrl); _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr3, StaAddr, ETH_ALEN); break; case Ndis802_11APMode: SetFrDs(fctrl); _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); _rtw_memcpy(pwlanhdr->addr2, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN); break; case Ndis802_11IBSS: default: _rtw_memcpy(pwlanhdr->addr1, StaAddr, ETH_ALEN); _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); break; } SetSeqNum(pwlanhdr, 0); SetFrameSubType(pframe, WIFI_DATA_NULL); pframe += sizeof(struct rtw_ieee80211_hdr_3addr); pktlen = sizeof(struct rtw_ieee80211_hdr_3addr); *pLength = pktlen; }
ssize_t proc_set_rx_ampdu(struct file *file, const char __user *buffer, size_t count, loff_t *pos, void *data) { struct net_device *dev = data; _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); struct registry_priv *pregpriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); char tmp[32]; u32 mode; if (count < 1) return -EFAULT; if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) { int num = sscanf(tmp, "%d ", &mode); if( pregpriv && mode >= 0 && mode < 2 ) { pmlmeinfo->bAcceptAddbaReq = mode; DBG_871X("pmlmeinfo->bAcceptAddbaReq=%d \n",pmlmeinfo->bAcceptAddbaReq); if(mode == 0) { //tear down Rx AMPDU send_delba(padapter, 0, get_my_bssid(&(pmlmeinfo->network)));// recipient } } } return count; }
void ConstructPSPoll(_adapter *padapter, u8 *pframe, u32 *pLength) { struct rtw_ieee80211_hdr *pwlanhdr; u16 *fctrl; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); //DBG_871X("%s\n", __FUNCTION__); pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; // Frame control. fctrl = &(pwlanhdr->frame_ctl); *(fctrl) = 0; SetPwrMgt(fctrl); SetFrameSubType(pframe, WIFI_PSPOLL); // AID. SetDuration(pframe, (pmlmeinfo->aid| 0xc000)); // BSSID. _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); // TA. _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); *pLength = 16; }
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); }
void ConstructBeacon(_adapter *padapter, u8 *pframe, u32 *pLength) { struct rtw_ieee80211_hdr *pwlanhdr; u16 *fctrl; u32 rate_len, pktlen; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; //DBG_871X("%s\n", __FUNCTION__); pwlanhdr = (struct rtw_ieee80211_hdr *)pframe; fctrl = &(pwlanhdr->frame_ctl); *(fctrl) = 0; _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN); _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); SetFrameSubType(pframe, WIFI_BEACON); pframe += sizeof(struct rtw_ieee80211_hdr_3addr); pktlen = sizeof (struct rtw_ieee80211_hdr_3addr); //timestamp will be inserted by hardware pframe += 8; pktlen += 8; // beacon interval: 2 bytes _rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); pframe += 2; pktlen += 2; // capability info: 2 bytes _rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); pframe += 2; pktlen += 2; if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { DBG_871X("ie len=%u\n", cur_network->IELength); pktlen += cur_network->IELength - sizeof(NDIS_802_11_FIXED_IEs); _rtw_memcpy(pframe, cur_network->IEs+sizeof(NDIS_802_11_FIXED_IEs), pktlen); goto _ConstructBeacon; } //below for ad-hoc mode // SSID pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pktlen); // supported rates... rate_len = rtw_get_rateset_len(cur_network->SupportedRates); pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pktlen); // DS parameter set pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pktlen); if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) { u32 ATIMWindow; // IBSS Parameter Set... //ATIMWindow = cur->Configuration.ATIMWindow; ATIMWindow = 0; pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pktlen); } //todo: ERP IE // EXTERNDED SUPPORTED RATE if (rate_len > 8) { pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pktlen); } //todo:HT for adhoc _ConstructBeacon: if ((pktlen + TXDESC_SIZE) > 512) { DBG_871X("beacon frame too large\n"); return; } *pLength = pktlen; //DBG_871X("%s bcn_sz=%u\n", __FUNCTION__, pktlen); }
// // 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); }
// // Description: // Construct the ARP response packet to support ARP offload. // static void ConstructARPResponse( PADAPTER padapter, u8 *pframe, u32 *pLength, u8 *pIPAddress ) { struct rtw_ieee80211_hdr *pwlanhdr; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *cur_network = &pmlmepriv->cur_network; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct security_priv *psecuritypriv = &padapter->securitypriv; static u8 ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06}; u16 *fctrl; u32 pktlen; u8 *pARPRspPkt = pframe; //for TKIP Cal MIC u8 *payload = pframe; u8 EncryptionHeadOverhead = 0; pwlanhdr = (struct rtw_ieee80211_hdr*)pframe; fctrl = &pwlanhdr->frame_ctl; *(fctrl) = 0; //------------------------------------------------------------------------- // MAC Header. //------------------------------------------------------------------------- SetFrameType(fctrl, WIFI_DATA); //SetFrameSubType(fctrl, 0); SetToDs(fctrl); _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); SetSeqNum(pwlanhdr, 0); SetDuration(pwlanhdr, 0); //SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0); //SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data); //SET_80211_HDR_TO_DS(pARPRspPkt, 1); //SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid); //SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress); //SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid); //SET_80211_HDR_DURATION(pARPRspPkt, 0); //SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0); #ifdef CONFIG_WAPI_SUPPORT *pLength = sMacHdrLng; #else *pLength = 24; #endif //YJ,del,120503 #if 0 //------------------------------------------------------------------------- // Qos Header: leave space for it if necessary. //------------------------------------------------------------------------- if(pStaQos->CurrentQosMode > QOS_DISABLE) { SET_80211_HDR_QOS_EN(pARPRspPkt, 1); PlatformZeroMemory(&(Buffer[*pLength]), sQoSCtlLng); *pLength += sQoSCtlLng; } #endif //------------------------------------------------------------------------- // Security Header: leave space for it if necessary. //------------------------------------------------------------------------- switch (psecuritypriv->dot11PrivacyAlgrthm) { case _WEP40_: case _WEP104_: EncryptionHeadOverhead = 4; break; case _TKIP_: EncryptionHeadOverhead = 8; break; case _AES_: EncryptionHeadOverhead = 8; break; #ifdef CONFIG_WAPI_SUPPORT case _SMS4_: EncryptionHeadOverhead = 18; break; #endif default: EncryptionHeadOverhead = 0; } if(EncryptionHeadOverhead > 0) { _rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead); *pLength += EncryptionHeadOverhead; //SET_80211_HDR_WEP(pARPRspPkt, 1); //Suggested by CCW. SetPrivacy(fctrl); } //------------------------------------------------------------------------- // Frame Body. //------------------------------------------------------------------------- pARPRspPkt = (u8*)(pframe+ *pLength); // LLC header _rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8); *pLength += 8; // ARP element pARPRspPkt += 8; SET_ARP_PKT_HW(pARPRspPkt, 0x0100); SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008); // IP protocol SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6); SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4); SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); // ARP response SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, myid(&(padapter->eeprompriv))); SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress); #ifdef CONFIG_ARP_KEEP_ALIVE if (rtw_gw_addr_query(padapter)==0) { SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr); SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip); } else #endif { SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, get_my_bssid(&(pmlmeinfo->network))); SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pIPAddress); DBG_871X("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(get_my_bssid(&(pmlmeinfo->network)))); DBG_871X("%s Target IP Addr" IP_FMT "\n", __FUNCTION__, IP_ARG(pIPAddress)); } *pLength += 28; if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_) { u8 mic[8]; struct mic_data micdata; struct sta_info *psta = NULL; u8 priority[4]={0x0,0x0,0x0,0x0}; u8 null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}; DBG_871X("%s(): Add MIC\n",__FUNCTION__); psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&(pmlmeinfo->network))); if (psta != NULL) { if(_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],null_key, 16)==_TRUE){ DBG_871X("%s(): STA dot11tkiptxmickey==0\n",__FUNCTION__); } //start to calculate the mic code rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]); } rtw_secmicappend(&micdata, pwlanhdr->addr3, 6); //DA rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); //SA priority[0]=0; rtw_secmicappend(&micdata, &priority[0], 4); rtw_secmicappend(&micdata, payload, 36); //payload length = 8 + 28 rtw_secgetmic(&micdata,&(mic[0])); pARPRspPkt += 28; _rtw_memcpy(pARPRspPkt, &(mic[0]),8); *pLength += 8; } }