/* * 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 PRTMP_ADAPTER pAd, IN ULONG Length, IN BOOLEAN Cached, OUT PVOID *VirtualAddress, OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) { PNDIS_PACKET pkt; pkt = RTPKT_TO_OSPKT(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(pkt, PKTSRC_NDIS); *VirtualAddress = (PVOID) RTPKT_TO_OSPKT(pkt)->data; *PhysicalAddress = PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1, PCI_DMA_FROMDEVICE); } else { *VirtualAddress = (PVOID) NULL; *PhysicalAddress = (NDIS_PHYSICAL_ADDRESS) NULL; } return (PNDIS_PACKET) pkt; }
VOID MeshClonePacket( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN UINT8 MeshSrc, IN UINT8 MeshLinkIdx) { INT idx; PUCHAR pSA = NULL; PUCHAR pDA = NULL; for (idx = 0; idx < MAX_MESH_LINKS; idx++) { if ((MeshSrc == MESH_FORWARD) && (MeshLinkIdx == idx)) continue; pSA = GET_OS_PKT_DATAPTR(pPacket) + MAC_ADDR_LEN; if (MAC_ADDR_EQUAL(pAd->MeshTab.MeshLink[idx].Entry.PeerMacAddr, pSA)) continue; pDA = GET_OS_PKT_DATAPTR(pPacket); if (IS_MULTICAST_MAC_ADDR(pDA) && (MultipathEntryLookUp(pAd, idx, pSA) != NULL)) continue; if (PeerLinkValidCheck(pAd, idx) == TRUE) { PNDIS_PACKET pPacketClone; /* pPacketClone = skb_clone(RTPKT_TO_OSPKT(pPacket), GFP_ATOMIC); */ OS_PKT_CLONE(pAd, pPacket, pPacketClone, GFP_ATOMIC); if (pPacketClone == NULL) continue; RTMP_SET_PACKET_NET_DEVICE_MESH(pPacketClone, 0); RTMP_SET_PACKET_SOURCE(pPacketClone, PKTSRC_NDIS); RTMP_SET_PACKET_MOREDATA(pPacketClone, FALSE); RTMP_SET_PACKET_WCID(pPacketClone, pAd->MeshTab.MeshLink[idx].Entry.MacTabMatchWCID); RTMP_SET_MESH_ROUTE_ID(pPacketClone, BMCAST_ROUTE_ID); RTMP_SET_MESH_SOURCE(pPacketClone, MeshSrc); #ifdef CONFIG_AP_SUPPORT APSendPacket(pAd, pPacketClone); #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT STASendPacket(pAd, pPacketClone); #endif /* CONFIG_STA_SUPPORT */ } } return; }
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; }
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")); } }
// 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; }
/* ======================================================================== 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; }
NDIS_STATUS IgmpPktClone( IN PRTMP_ADAPTER pAd, IN PNDIS_PACKET pPacket, IN int IgmpPktInGroup, IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry, IN UCHAR QueIdx, IN UINT8 UserPriority, IN PNET_DEV pNetDev) { PNDIS_PACKET pSkbClone = NULL; PMEMBER_ENTRY pMemberEntry = NULL; MAC_TABLE_ENTRY *pMacEntry = NULL; USHORT Aid; SST Sst = SST_ASSOC; UCHAR PsMode = PWR_ACTIVE; UCHAR Rate; unsigned long IrqFlags; int MacEntryIdx; BOOLEAN bContinue; PUCHAR pMemberAddr = NULL; bContinue = FALSE; if ((IgmpPktInGroup == IGMP_IN_GROUP) && (pGroupEntry == NULL)) return NDIS_STATUS_FAILURE; if (IgmpPktInGroup == IGMP_IN_GROUP) { pMemberEntry = (PMEMBER_ENTRY)pGroupEntry->MemberList.pHead; if (pMemberEntry != NULL) { pMemberAddr = pMemberEntry->Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); bContinue = TRUE; } } else if (IgmpPktInGroup == IGMP_PKT) { for(MacEntryIdx=1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry) && get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev) { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } } else { return NDIS_STATUS_FAILURE; } /* check all members of the IGMP group. */ while(bContinue == TRUE) { if (pMacEntry && (Sst == SST_ASSOC)) { OS_PKT_CLONE(pAd, pPacket, pSkbClone, MEM_ALLOC_FLAG); if ((pSkbClone) ) { RTMP_SET_PACKET_WCID(pSkbClone, (UCHAR)pMacEntry->Aid); /* Pkt type must set to PKTSRC_NDIS. */ /* It cause of the deason that APHardTransmit() */ /* doesn't handle PKTSRC_DRIVER pkt type in version 1.3.0.0. */ RTMP_SET_PACKET_SOURCE(pSkbClone, PKTSRC_NDIS); } else { if (IgmpPktInGroup == IGMP_IN_GROUP) { pMemberEntry = pMemberEntry->pNext; if (pMemberEntry != NULL) { pMemberAddr = pMemberEntry->Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); bContinue = TRUE; } else bContinue = FALSE; } else if (IgmpPktInGroup == IGMP_PKT) { for(MacEntryIdx=pMacEntry->Aid + 1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry) && get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev) { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } if (MacEntryIdx == MAX_NUMBER_OF_MAC) bContinue = FALSE; } else bContinue = FALSE; continue; } if (PsMode == PWR_SAVE) { APInsertPsQueue(pAd, pSkbClone, pMacEntry, QueIdx); } else { /* insert the pkt to TxSwQueue. */ if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE) { #ifdef BLOCK_NET_IF StopNetIfQueue(pAd, QueIdx, pSkbClone); #endif /* BLOCK_NET_IF */ RELEASE_NDIS_PACKET(pAd, pSkbClone, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } else { RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pSkbClone)); RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); } } #ifdef DOT11_N_SUPPORT RTMP_BASetup(pAd, pMacEntry, UserPriority); #endif /* DOT11_N_SUPPORT */ } if (IgmpPktInGroup == IGMP_IN_GROUP) { pMemberEntry = pMemberEntry->pNext; if (pMemberEntry != NULL) { pMemberAddr = pMemberEntry->Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); bContinue = TRUE; } else bContinue = FALSE; } else if (IgmpPktInGroup == IGMP_PKT) { for(MacEntryIdx=pMacEntry->Aid + 1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMemberAddr = pAd->MacTab.Content[MacEntryIdx].Addr; pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); if (pMacEntry && IS_ENTRY_CLIENT(pMacEntry) && get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev) { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } if (MacEntryIdx == MAX_NUMBER_OF_MAC) bContinue = FALSE; } else bContinue = FALSE; } return NDIS_STATUS_SUCCESS; }
/* ======================================================================== Routine Description: Send a packet to WLAN. Arguments: skb_p points to our adapter dev_p which WLAN network interface Return Value: 0: transmit successfully otherwise: transmit fail Note: ======================================================================== */ INT ApCli_VirtualIF_PacketSend( IN PNDIS_PACKET skb_p, IN PNET_DEV dev_p) { RTMP_ADAPTER *ad_p; PAPCLI_STRUCT pApCli; INT apcliIndex; ad_p = RTMP_OS_NETDEV_GET_PRIV(dev_p); ASSERT(ad_p); #ifdef RALINK_ATE if (ATE_ON(ad_p)) { RELEASE_NDIS_PACKET(ad_p, skb_p, NDIS_STATUS_FAILURE); return 0; } #endif // RALINK_ATE // if ((RTMP_TEST_FLAG(ad_p, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) || (RTMP_TEST_FLAG(ad_p, fRTMP_ADAPTER_RADIO_OFF)) || (RTMP_TEST_FLAG(ad_p, fRTMP_ADAPTER_RESET_IN_PROGRESS))) { /* wlan is scanning/disabled/reset */ RELEASE_NDIS_PACKET(ad_p, skb_p, NDIS_STATUS_FAILURE); return 0; } if (!(RTMP_OS_NETDEV_STATE_RUNNING(dev_p))) { /* the interface is down */ RELEASE_NDIS_PACKET(ad_p, skb_p, NDIS_STATUS_FAILURE); return 0; } pApCli = (PAPCLI_STRUCT)&ad_p->ApCfg.ApCliTab; for(apcliIndex = 0; apcliIndex < MAX_APCLI_NUM; apcliIndex++) { if (pApCli[apcliIndex].Valid != TRUE) continue; /* find the device in our ApCli list */ if (pApCli[apcliIndex].dev == dev_p) { /* ya! find it */ ad_p->RalinkCounters.PendingNdisPacketCount ++; RTMP_SET_PACKET_SOURCE(skb_p, PKTSRC_NDIS); RTMP_SET_PACKET_MOREDATA(skb_p, FALSE); RTMP_SET_PACKET_NET_DEVICE_APCLI(skb_p, apcliIndex); SET_OS_PKT_NETDEV(skb_p, ad_p->net_dev); /* transmit the packet */ return rt28xx_packet_xmit(RTPKT_TO_OSPKT(skb_p)); } } RELEASE_NDIS_PACKET(ad_p, skb_p, NDIS_STATUS_FAILURE); return 0; } /* End of ApCli_VirtualIF_PacketSend */
NDIS_STATUS IgmpPktClone( IN PRTMP_ADAPTER pAd, IN PUCHAR pSrcBufVA, IN PNDIS_PACKET pPacket, IN INT IgmpPktInGroup, IN PMULTICAST_FILTER_TABLE_ENTRY pGroupEntry, IN UCHAR QueIdx, IN UINT8 UserPriority) { PNET_DEV pNetDev = NULL; PNDIS_PACKET pSkbClone = NULL; PMEMBER_ENTRY pMemberEntry = NULL; MAC_TABLE_ENTRY *pMacEntry = NULL; USHORT Aid; SST Sst = SST_ASSOC; UCHAR PsMode = PWR_ACTIVE; UCHAR Rate; unsigned long IrqFlags; INT MacEntryIdx; BOOLEAN bContinue; PUCHAR pMemberAddr = NULL; PUCHAR pSrcMAC = NULL; bContinue = FALSE; if (IgmpPktInGroup == IGMP_IN_GROUP) { if (!pGroupEntry) return NDIS_STATUS_FAILURE; pMemberEntry = (PMEMBER_ENTRY)pGroupEntry->MemberList.pHead; if (pMemberEntry) { pMemberAddr = pMemberEntry->Addr; bContinue = TRUE; } } else if (IgmpPktInGroup == IGMP_PKT) { pNetDev = GET_OS_PKT_NETDEV(pPacket); pSrcMAC = pSrcBufVA + 6; for(MacEntryIdx=1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMacEntry = &pAd->MacTab.Content[MacEntryIdx]; if ((pMacEntry && IS_ENTRY_CLIENT(pMacEntry)) && (get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev) && (!MAC_ADDR_EQUAL(pMacEntry->Addr, pSrcMAC))) /* DAD IPv6 issue */ { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } } else { return NDIS_STATUS_FAILURE; } // check all members of the IGMP group. while(bContinue == TRUE) { pMacEntry = APSsPsInquiry(pAd, pMemberAddr, &Sst, &Aid, &PsMode, &Rate); if (pMacEntry && (Sst == SST_ASSOC) && (pMacEntry->PortSecured == WPA_802_1X_PORT_SECURED)) { OS_PKT_CLONE(pAd, pPacket, pSkbClone, MEM_ALLOC_FLAG); if (!pSkbClone) return NDIS_STATUS_FAILURE; RTMP_SET_PACKET_WCID(pSkbClone, (UCHAR)pMacEntry->Aid); // Pkt type must set to PKTSRC_NDIS. // It cause of the deason that APHardTransmit() // doesn't handle PKTSRC_DRIVER pkt type in version 1.3.0.0. RTMP_SET_PACKET_SOURCE(pSkbClone, PKTSRC_NDIS); if (PsMode == PWR_SAVE) { APInsertPsQueue(pAd, pSkbClone, pMacEntry, QueIdx); } else { // insert the pkt to TxSwQueue. if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE) { #ifdef BLOCK_NET_IF StopNetIfQueue(pAd, QueIdx, pSkbClone); #endif // BLOCK_NET_IF // RELEASE_NDIS_PACKET(pAd, pSkbClone, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; } else { RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); InsertTailQueueAc(pAd, pMacEntry, &pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pSkbClone)); RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); } } #ifdef DOT11_N_SUPPORT RTMP_BASetup(pAd, pMacEntry, UserPriority); #endif // DOT11_N_SUPPORT // } if (IgmpPktInGroup == IGMP_IN_GROUP) { pMemberEntry = pMemberEntry->pNext; if (pMemberEntry) { pMemberAddr = pMemberEntry->Addr; bContinue = TRUE; } else bContinue = FALSE; } else { for(MacEntryIdx=pMacEntry->Aid + 1; MacEntryIdx<MAX_NUMBER_OF_MAC; MacEntryIdx++) { pMacEntry = &pAd->MacTab.Content[MacEntryIdx]; if ((pMacEntry && IS_ENTRY_CLIENT(pMacEntry)) && (get_netdev_from_bssid(pAd, pMacEntry->apidx) == pNetDev) && (!MAC_ADDR_EQUAL(pMacEntry->Addr, pSrcMAC))) { pMemberAddr = pMacEntry->Addr; bContinue = TRUE; break; } } if (MacEntryIdx == MAX_NUMBER_OF_MAC) bContinue = FALSE; } } return NDIS_STATUS_SUCCESS; }
/* ======================================================================== 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; }