// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() NDIS_STATUS RTMPAllocateNdisPacket( IN PRTMP_ADAPTER pAd, OUT PNDIS_PACKET *ppPacket, IN PUCHAR pHeader, IN UINT HeaderLen, IN PUCHAR pData, IN UINT DataLen) { PNDIS_PACKET pPacket; ASSERT(pData); ASSERT(DataLen); // 1. Allocate a packet pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE); if (pPacket == NULL) { *ppPacket = NULL; #ifdef DEBUG printk("RTMPAllocateNdisPacket Fail\n\n"); #endif return NDIS_STATUS_FAILURE; } // 2. clone the frame content if (HeaderLen > 0) NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen); if (DataLen > 0) NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen); // 3. update length of packet skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen); RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS); // printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); *ppPacket = pPacket; return NDIS_STATUS_SUCCESS; }
int RtmpUSBMgmtKickOut( IN RTMP_ADAPTER *pAd, IN UCHAR QueIdx, IN PNDIS_PACKET pPacket, IN PUCHAR pSrcBufVA, IN UINT SrcBufLen) { PTXINFO_STRUC pTxInfo; ULONG BulkOutSize; UCHAR padLen; PUCHAR pDest; ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa; unsigned long IrqFlags; pTxInfo = (PTXINFO_STRUC)(pSrcBufVA); BulkOutSize = SrcBufLen; BulkOutSize = (BulkOutSize + 3) & (~3); RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); BulkOutSize += 4; if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0) BulkOutSize += 4; padLen = BulkOutSize - SrcBufLen; ASSERT((padLen <= RTMP_PKT_TAIL_PADDING)); pDest = (PUCHAR)(pSrcBufVA + SrcBufLen); skb_put(GET_OS_PKT_TYPE(pPacket), padLen); NdisZeroMemory(pDest, padLen); RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket; pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket)); pMLMEContext->BulkOutSize = BulkOutSize; pMLMEContext->InUse = TRUE; pMLMEContext->bWaitingBulkOut = TRUE; pAd->MgmtRing.TxSwFreeIdx--; INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); RTUSBKickBulkOut(pAd); return 0; }
/* Must be run in Interrupt context This function handle RT2870 specific TxDesc and cpu index update and kick the packet out. */ int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd, u8 QueIdx, void *pPacket, u8 *pSrcBufVA, u32 SrcBufLen) { struct rt_txinfo *pTxInfo; unsigned long BulkOutSize; u8 padLen; u8 *pDest; unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx; struct rt_tx_context *pMLMEContext = (struct rt_tx_context *)pAd->MgmtRing.Cell[SwIdx].AllocVa; unsigned long IrqFlags; pTxInfo = (struct rt_txinfo *)(pSrcBufVA); /* Build our URB for USBD */ BulkOutSize = SrcBufLen; BulkOutSize = (BulkOutSize + 3) & (~3); RTMPWriteTxInfo(pAd, pTxInfo, (u16)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); BulkOutSize += 4; /* Always add 4 extra bytes at every packet. */ /* If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. */ if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0) BulkOutSize += 4; padLen = BulkOutSize - SrcBufLen; ASSERT((padLen <= RTMP_PKT_TAIL_PADDING)); /* Now memzero all extra padding bytes. */ pDest = (u8 *)(pSrcBufVA + SrcBufLen); skb_put(GET_OS_PKT_TYPE(pPacket), padLen); NdisZeroMemory(pDest, padLen); RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket; pMLMEContext->TransferBuffer = (struct rt_tx_buffer *)(GET_OS_PKT_DATAPTR(pPacket)); /* Length in TxInfo should be 8 less than bulkout size. */ pMLMEContext->BulkOutSize = BulkOutSize; pMLMEContext->InUse = TRUE; pMLMEContext->bWaitingBulkOut = TRUE; /*for debug */ /*hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); */ /*pAd->RalinkCounters.KickTxCount++; */ /*pAd->RalinkCounters.OneSecTxDoneCount++; */ /*if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) */ /* needKickOut = TRUE; */ /* Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX */ pAd->MgmtRing.TxSwFreeIdx--; INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); /*if (needKickOut) */ RTUSBKickBulkOut(pAd); return 0; }
/* Must be run in Interrupt context This function handle RT2870 specific TxDesc and cpu index update and kick the packet out. */ int RtmpUSBMgmtKickOut( IN RTMP_ADAPTER *pAd, IN UCHAR QueIdx, IN PNDIS_PACKET pPacket, IN PUCHAR pSrcBufVA, IN UINT SrcBufLen) { PTXINFO_STRUC pTxInfo; ULONG BulkOutSize; UCHAR padLen; PUCHAR pDest; ULONG SwIdx = pAd->MgmtRing.TxCpuIdx; PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa; unsigned long IrqFlags; pTxInfo = (PTXINFO_STRUC)(pSrcBufVA); // Build our URB for USBD BulkOutSize = SrcBufLen; BulkOutSize = (BulkOutSize + 3) & (~3); RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE); BulkOutSize += 4; // Always add 4 extra bytes at every packet. // If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0) BulkOutSize += 4; padLen = BulkOutSize - SrcBufLen; ASSERT((padLen <= RTMP_PKT_TAIL_PADDING)); // Now memzero all extra padding bytes. pDest = (PUCHAR)(pSrcBufVA + SrcBufLen); skb_put(GET_OS_PKT_TYPE(pPacket), padLen); NdisZeroMemory(pDest, padLen); RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags); pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket; pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket)); // Length in TxInfo should be 8 less than bulkout size. pMLMEContext->BulkOutSize = BulkOutSize; pMLMEContext->InUse = TRUE; pMLMEContext->bWaitingBulkOut = TRUE; //for debug //hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); //pAd->RalinkCounters.KickTxCount++; //pAd->RalinkCounters.OneSecTxDoneCount++; //if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) // needKickOut = TRUE; // Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX pAd->MgmtRing.TxSwFreeIdx--; INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE); RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags); RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME); //if (needKickOut) RTUSBKickBulkOut(pAd); return 0; }
BOOLEAN PMF_PerformTxFrameAction( IN PRTMP_ADAPTER pAd, OUT PNDIS_PACKET pPacket) { PHEADER_802_11 pHeader_802_11; PACKET_INFO PacketInfo; PUCHAR pSrcBufVA; UINT SrcBufLen; UINT8 TXWISize = pAd->chipCap.TXWISize; INT FrameType; INT ret; PMAC_TABLE_ENTRY pEntry = NULL; RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); if (pSrcBufVA == NULL) return NORMAL_FRAME; pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWISize); #ifdef CONFIG_AP_SUPPORT pEntry = MacTableLookup(pAd, pHeader_802_11->Addr1); #endif /* CONFIG_AP_SUPPORT */ FrameType = PMF_RobustFrameClassify( (PHEADER_802_11)pHeader_802_11, (PUCHAR)( ((PUCHAR) pHeader_802_11) + LENGTH_802_11), (SrcBufLen - LENGTH_802_11 - TXINFO_SIZE - TXWISize), (PUCHAR) pEntry, FALSE); switch (FrameType) { case ERROR_FRAME: DBGPRINT(RT_DEBUG_ERROR, ("[PMF]%s: ERROR FRAME\n", __FUNCTION__)); return FALSE; case NORMAL_FRAME: case NOT_ROBUST_GROUP_FRAME: case NOT_ROBUST_UNICAST_FRAME: break; case UNICAST_ROBUST_FRAME: { pHeader_802_11->FC.Wep = 1; /* Format: Mac header|CCMP header|Data|MIC|FCS */ skb_put(GET_OS_PKT_TYPE(pPacket), LEN_CCMP_HDR + LEN_CCMP_MIC); RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen); if (pSrcBufVA == NULL) return NORMAL_FRAME; pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWISize); ret = PMF_EncryptUniRobustFrameAction(pAd, pHeader_802_11, (SrcBufLen - TXINFO_SIZE - TXWISize)); break; } case GROUP_ROBUST_FRAME: { ret = PMF_EncapBIPAction(pAd, pHeader_802_11, (SrcBufLen - TXINFO_SIZE - TXWISize)); break; } } if (ret == PMF_STATUS_SUCCESS) return TRUE; else return FALSE; }