예제 #1
0
PNDIS_PACKET DuplicatePacket(
    IN	PRTMP_ADAPTER	pAd,
    IN	PNDIS_PACKET	pPacket,
    IN	UCHAR			FromWhichBSSID)
{
    struct sk_buff	*skb;
    PNDIS_PACKET	pRetPacket = NULL;
    USHORT			DataSize;
    UCHAR			*pData;

    DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
    pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);


    skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
    if (skb)
    {
        skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
        pRetPacket = OSPKT_TO_RTPKT(skb);
    }

#if 0
    if ((skb = __dev_alloc_skb(DataSize + 2+32, MEM_ALLOC_FLAG)) != NULL)
    {
        skb_reserve(skb, 2+32);
        NdisMoveMemory(skb->tail, pData, DataSize);
        skb_put(skb, DataSize);
        skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
        pRetPacket = OSPKT_TO_RTPKT(skb);
    }
#endif

    return pRetPacket;

}
예제 #2
0
/*
	========================================================================

	Routine Description:
		clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
		must have only one NDIS BUFFER
		return - byte copied. 0 means can't create NDIS PACKET
		NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket

	Arguments:
		pAd 	Pointer to our adapter
		pInsAMSDUHdr	EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
		*pSrcTotalLen			return total packet length. This lenght is calculated with 802.3 format packet.

	Return Value:
		NDIS_STATUS_SUCCESS
		NDIS_STATUS_FAILURE

	Note:

	========================================================================
*/
NDIS_STATUS RTMPCloneNdisPacket(
	IN	PRTMP_ADAPTER	pAd,
	IN	BOOLEAN			pInsAMSDUHdr,
	IN	PNDIS_PACKET	pInPacket,
	OUT PNDIS_PACKET   *ppOutPacket)
{

	struct sk_buff *pkt;

	ASSERT(pInPacket);
	ASSERT(ppOutPacket);

	// 1. Allocate a packet
	pkt = dev_alloc_skb(2048);

	if (pkt == NULL)
	{
		return NDIS_STATUS_FAILURE;
	}

 	skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
	NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
	*ppOutPacket = OSPKT_TO_RTPKT(pkt);


	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);

	printk("###Clone###\n");

	return NDIS_STATUS_SUCCESS;
}
예제 #3
0
PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
    IN	PRTMP_ADAPTER	pAd,
    IN	PNDIS_PACKET	pPacket)
{
    struct sk_buff	*skb, *newskb;


    skb = RTPKT_TO_OSPKT(pPacket);
    if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
    {
        // alloc a new skb and copy the packet
        newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
        dev_kfree_skb_any(skb);
        if (newskb == NULL)
        {
            DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
            return NULL;
        }
        skb = newskb;
    }

    return OSPKT_TO_RTPKT(skb);

#if 0
    if ((data = skb_put(skb, TKIP_TX_MIC_SIZE)) != NULL)
    {   // If we can extend it, well, copy it first.
        NdisMoveMemory(data, pAd->PrivateInfo.Tx.MIC, TKIP_TX_MIC_SIZE);
    }
    else
    {
        // Otherwise, copy the packet.
        newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
        dev_kfree_skb_any(skb);
        if (newskb == NULL)
        {
            DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC to packet failed!, dropping packet\n"));
            return NULL;
        }
        skb = newskb;

        NdisMoveMemory(skb->tail, pAd->PrivateInfo.Tx.MIC, TKIP_TX_MIC_SIZE);
        skb_put(skb, TKIP_TX_MIC_SIZE);
    }

    return OSPKT_TO_RTPKT(skb);
#endif

}
예제 #4
0
/*
 * FUNCTION: Allocate a packet buffer for DMA
 * ARGUMENTS:
 *     AdapterHandle:  AdapterHandle
 *     Length:  Number of bytes to allocate
 *     Cached:  Whether or not the memory can be cached
 *     VirtualAddress:  Pointer to memory is returned here
 *     PhysicalAddress:  Physical address corresponding to virtual address
 * Notes:
 *     Cached is ignored: always cached memory
 */
PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
	IN	VOID					*pReserved,
	IN	VOID					*pPciDev,
	IN	ULONG					Length,
	IN	BOOLEAN					Cached,
	OUT	PVOID					*VirtualAddress,
	OUT	PNDIS_PHYSICAL_ADDRESS	PhysicalAddress)
{
	struct sk_buff *pkt;

/*	pkt = dev_alloc_skb(Length); */
	DEV_ALLOC_SKB(pReserved, pkt, Length);

	if (pkt == NULL) {
		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate rx %ld size packet\n",Length));
	}

	if (pkt) {
		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
		*VirtualAddress = (PVOID) pkt->data;	
/*#ifdef CONFIG_5VT_ENHANCE */
/*		*PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, 1600, RTMP_PCI_DMA_FROMDEVICE); */
/*#else */
		*PhysicalAddress = PCI_MAP_SINGLE_DEV(pPciDev, *VirtualAddress, Length,  -1, RTMP_PCI_DMA_FROMDEVICE);
/*#endif */
	} else {
		*VirtualAddress = (PVOID) NULL;
		*PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) 0;
	}	

	return (PNDIS_PACKET) pkt;
}
예제 #5
0
PNDIS_PACKET duplicate_pkt(
	IN	PRTMP_ADAPTER	pAd,
	IN	PUCHAR			pHeader802_3,
    IN  UINT            HdrLen,
	IN	PUCHAR			pData,
	IN	ULONG			DataSize,
	IN	UCHAR			FromWhichBSSID)
{
	struct sk_buff	*skb;
	PNDIS_PACKET	pPacket = NULL;


	if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
	{
		skb_reserve(skb, 2);
		NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
		skb_put(skb, HdrLen);
		NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
		skb_put(skb, DataSize);
		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
		pPacket = OSPKT_TO_RTPKT(skb);
	}

	return pPacket;
}
예제 #6
0
PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
	IN	PRTMP_ADAPTER pAd,
	IN	ULONG	Length,
	IN	BOOLEAN	Cached,
	OUT	PVOID	*VirtualAddress)
{
	struct sk_buff *pkt;

	pkt = dev_alloc_skb(Length);

	if (pkt == NULL)
	{
		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
	}

	if (pkt)
	{
		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
		*VirtualAddress = (PVOID) pkt->data;
	}
	else
	{
		*VirtualAddress = (PVOID) NULL;
	}

	return (PNDIS_PACKET) pkt;
}
/*
 * FUNCTION: Allocate a packet buffer for DMA
 * ARGUMENTS:
 *     AdapterHandle:  AdapterHandle
 *     Length:  Number of bytes to allocate
 *     Cached:  Whether or not the memory can be cached
 *     VirtualAddress:  Pointer to memory is returned here
 *     PhysicalAddress:  Physical address corresponding to virtual address
 * Notes:
 *     Cached is ignored: always cached memory
 */
void *RTMP_AllocateRxPacketBuffer(struct rt_rtmp_adapter *pAd,
                                  unsigned long Length,
                                  IN BOOLEAN Cached,
                                  void **VirtualAddress,
                                  OUT dma_addr_t *
                                  PhysicalAddress)
{
    struct sk_buff *pkt;

    pkt = dev_alloc_skb(Length);

    if (pkt == NULL) {
        DBGPRINT(RT_DEBUG_ERROR,
                 ("can't allocate rx %ld size packet\n", Length));
    }

    if (pkt) {
        RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
        *VirtualAddress = (void *)pkt->data;
        *PhysicalAddress =
            PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1,
                           PCI_DMA_FROMDEVICE);
    } else {
        *VirtualAddress = (void *)NULL;
        *PhysicalAddress = (dma_addr_t)NULL;
    }

    return (void *)pkt;
}
예제 #8
0
VOID REPORT_AMSDU_FRAMES_TO_LLC(
	IN	PRTMP_ADAPTER	pAd,
	IN	PUCHAR			pData,
	IN	ULONG			DataSize)
{	
	PNDIS_PACKET	pPacket;
	UINT			nMSDU;
	struct			sk_buff *pSkb;

	nMSDU = 0;
	/* allocate a rx packet */
	pSkb = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_AGGRESIZE);
	pPacket = (PNDIS_PACKET)OSPKT_TO_RTPKT(pSkb);
	if (pSkb)
	{

		/* convert 802.11 to 802.3 packet */
		GET_OS_PKT_NETDEV(pSkb) = get_netdev_from_bssid(pAd, BSS0);	
		RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
		deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
	}
	else
	{
		DBGPRINT(RT_DEBUG_ERROR,("Can't allocate skb\n"));
	}
}
예제 #9
0
PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
	IN	PRTMP_ADAPTER pAd,
	IN	ULONG	Length)
{
	struct sk_buff *pkt;

	pkt = dev_alloc_skb(Length);

	if (pkt == NULL)
	{
		DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
	}

	if (pkt)
	{
		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
	}

	return (PNDIS_PACKET) pkt;
}
예제 #10
0
void REPORT_AMSDU_FRAMES_TO_LLC(struct rt_rtmp_adapter *pAd,
				u8 *pData, unsigned long DataSize)
{
	void *pPacket;
	u32 nMSDU;
	struct sk_buff *pSkb;

	nMSDU = 0;
	/* allocate a rx packet */
	pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE);
	pPacket = (void *)OSPKT_TO_RTPKT(pSkb);
	if (pSkb) {

		/* convert 802.11 to 802.3 packet */
		pSkb->dev = get_netdev_from_bssid(pAd, BSS0);
		RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
		deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
	} else {
		DBGPRINT(RT_DEBUG_ERROR, ("Can't allocate skb\n"));
	}
}
예제 #11
0
PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
	IN	PRTMP_ADAPTER	pAd,
	IN	PNDIS_PACKET	pPacket)
{
	struct sk_buff	*skb, *newskb;


	skb = RTPKT_TO_OSPKT(pPacket);
	if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
	{
		// alloc a new skb and copy the packet
		newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
		dev_kfree_skb_any(skb);
		if (newskb == NULL)
		{
			DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
			return NULL;
		}
		skb = newskb;
	}

	return OSPKT_TO_RTPKT(skb);
}
예제 #12
0
PNDIS_PACKET DuplicatePacket(
	IN	PRTMP_ADAPTER	pAd,
	IN	PNDIS_PACKET	pPacket,
	IN	UCHAR			FromWhichBSSID)
{
	struct sk_buff	*skb;
	PNDIS_PACKET	pRetPacket = NULL;
	USHORT			DataSize;
	UCHAR			*pData;

	DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
	pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);


	skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
	if (skb)
	{
		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
		pRetPacket = OSPKT_TO_RTPKT(skb);
	}

	return pRetPacket;

}
예제 #13
0
/*
========================================================================
Routine Description:
    Get a received packet.

Arguments:
	pAd					device control block
	pSaveRxD			receive descriptor information
	*pbReschedule		need reschedule flag
	*pRxPending			pending received packet flag

Return Value:
    the received packet

Note:
========================================================================
*/
void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
				 OUT PRT28XX_RXD_STRUC pSaveRxD,
				 OUT BOOLEAN * pbReschedule,
				 IN u32 * pRxPending)
{
	struct rt_rx_context *pRxContext;
	void *pSkb;
	u8 *pData;
	unsigned long ThisFrameLen;
	unsigned long RxBufferLength;
	struct rt_rxwi * pRxWI;

	pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
	if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
		return NULL;

	RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
	if (RxBufferLength <
	    (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxwi) +
	     sizeof(struct rt_rxinfo))) {
		goto label_null;
	}

	pData = &pRxContext->TransferBuffer[pAd->ReadPosition];	/* 4KB */
	/* The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding) */
	ThisFrameLen = *pData + (*(pData + 1) << 8);
	if (ThisFrameLen == 0) {
		DBGPRINT(RT_DEBUG_TRACE,
			 ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
			  pAd->NextRxBulkInReadIndex, ThisFrameLen,
			  pRxContext->BulkInOffset));
		goto label_null;
	}
	if ((ThisFrameLen & 0x3) != 0) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
			  pAd->NextRxBulkInReadIndex, ThisFrameLen,
			  pRxContext->BulkInOffset));
		goto label_null;
	}

	if ((ThisFrameLen + 8) > RxBufferLength)	/* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */
	{
		DBGPRINT(RT_DEBUG_TRACE,
			 ("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
			  pAd->NextRxBulkInReadIndex, ThisFrameLen,
			  pRxContext->BulkInOffset, RxBufferLength,
			  pAd->ReadPosition));

		/* error frame. finish this loop */
		goto label_null;
	}
	/* skip USB frame length field */
	pData += RT2870_RXDMALEN_FIELD_SIZE;
	pRxWI = (struct rt_rxwi *) pData;
	if (pRxWI->MPDUtotalByteCount > ThisFrameLen) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
			  __FUNCTION__, pRxWI->MPDUtotalByteCount,
			  ThisFrameLen));
		goto label_null;
	}
	/* allocate a rx packet */
	pSkb = dev_alloc_skb(ThisFrameLen);
	if (pSkb == NULL) {
		DBGPRINT(RT_DEBUG_ERROR,
			 ("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n",
			  __FUNCTION__));
		goto label_null;
	}
	/* copy the rx packet */
	memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
	RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);

	/* copy RxD */
	*pSaveRxD = *(struct rt_rxinfo *) (pData + ThisFrameLen);

	/* update next packet read position. */
	pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE);	/* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */

	return pSkb;

label_null:

	return NULL;
}
예제 #14
0
/*
========================================================================
Routine Description:
    Get a received packet.

Arguments:
	pAd					device control block
	pSaveRxD			receive descriptor information
	*pbReschedule		need reschedule flag
	*pRxPending			pending received packet flag

Return Value:
    the recieved packet

Note:
========================================================================
*/
PNDIS_PACKET GetPacketFromRxRing(
	IN		PRTMP_ADAPTER		pAd,
	OUT		PRT28XX_RXD_STRUC	pSaveRxD,
	OUT		BOOLEAN				*pbReschedule,
	IN OUT	UINT32				*pRxPending)
{
	PRX_CONTEXT		pRxContext;
	PNDIS_PACKET	pNetPkt;
	PUCHAR			pData;
	ULONG			ThisFrameLen;
	ULONG			RxBufferLength;
	PRXWI_STRUC		pRxWI;
	
	pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
	if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
		return NULL;

	RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
	if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
	{
		goto label_null;
	}
	
	pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
	// The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
	ThisFrameLen = *pData + (*(pData+1)<<8);
    if (ThisFrameLen == 0)
	{	    
		DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n", 
								pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));     
		goto label_null;
	}   
	if ((ThisFrameLen&0x3) != 0)
	{
		DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n", 
								pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
		goto label_null;
	}

	if ((ThisFrameLen + 8)> RxBufferLength)	// 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
	{
		DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n", 
						pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));

		// error frame. finish this loop
		goto label_null;
	}

	// skip USB frame length field
	pData += RT2870_RXDMALEN_FIELD_SIZE;
	pRxWI = (PRXWI_STRUC)pData;
#ifdef RT_BIG_ENDIAN
	RTMPWIEndianChange(pData, TYPE_RXWI);
#endif // RT_BIG_ENDIAN //
	if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
	{
		DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n", 
									__FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
		goto label_null;
	}
#ifdef RT_BIG_ENDIAN
	RTMPWIEndianChange(pData, TYPE_RXWI);
#endif // RT_BIG_ENDIAN //

	// allocate a rx packet
	pNetPkt = RTMP_AllocateFragPacketBuffer(pAd, ThisFrameLen);
	if (pNetPkt == NULL)
	{
		DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__));
		goto label_null;
	}

	// copy the rx packet
	memcpy(skb_put(pNetPkt, ThisFrameLen), pData, ThisFrameLen);
	GET_OS_PKT_NETDEV(pNetPkt) = get_netdev_from_bssid(pAd, BSS0);;
	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pNetPkt), PKTSRC_NDIS);

	// copy RxD
	*pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
#ifdef RT_BIG_ENDIAN
	RTMPDescriptorEndianChange((PUCHAR)pSaveRxD, TYPE_RXINFO);
#endif // RT_BIG_ENDIAN //	

	// update next packet read position.
	pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE);	// 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))

	return pNetPkt;

label_null:
	
	return NULL;
}