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")); } }
struct cmd_msg *AndesAllocCmdMsg(RTMP_ADAPTER *ad, unsigned int length) { struct cmd_msg *msg = NULL; RTMP_CHIP_CAP *cap = &ad->chipCap; struct MCU_CTRL *ctl = &ad->MCUCtrl; PNDIS_PACKET net_pkt = NULL; INT32 AllocateSize = cap->cmd_header_len + length + cap->cmd_padding_len; #ifdef RTMP_SDIO_SUPPORT if (AllocateSize >= ad->BlockSize) AllocateSize = (AllocateSize + ((-AllocateSize) & (ad->BlockSize - 1))); #endif net_pkt = RTMP_AllocateFragPacketBuffer(ad, AllocateSize); if (!net_pkt) { DBGPRINT(RT_DEBUG_ERROR, ("can not allocate net_pkt\n")); goto error0; } if ((ctl->Stage == FW_NO_INIT) || (ctl->Stage == FW_DOWNLOAD) || (ctl->Stage == ROM_PATCH_DOWNLOAD)) OS_PKT_RESERVE(net_pkt, cap->cmd_header_len); else if (ctl->Stage == FW_RUN_TIME) OS_PKT_RESERVE(net_pkt, sizeof(FW_TXD *)); os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(*msg)); if (!msg) { DBGPRINT(RT_DEBUG_ERROR, ("can not allocate cmd msg\n")); goto error1; } CMD_MSG_CB(net_pkt)->msg = msg; memset(msg, 0x00, sizeof(*msg)); msg->priv = (void *)ad; msg->net_pkt = net_pkt; ctl->alloc_cmd_msg++; return msg; os_free_mem(NULL, msg); error1: RTMPFreeNdisPacket(ad, net_pkt); error0: return NULL; }
struct cmd_msg *AndesAllocCmdMsg(RTMP_ADAPTER *ad, unsigned int length) { struct cmd_msg *msg = NULL; RTMP_CHIP_CAP *cap = &ad->chipCap; struct MCU_CTRL *ctl = &ad->MCUCtrl; PNDIS_PACKET net_pkt = NULL; INT32 AllocateSize = cap->cmd_header_len + length + cap->cmd_padding_len; net_pkt = RTMP_AllocateFragPacketBuffer(ad, AllocateSize); if (!net_pkt) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("can not allocate net_pkt\n")); goto error0; } OS_PKT_RESERVE(net_pkt, cap->cmd_header_len); os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(*msg)); if (!msg) { MTWF_LOG(DBG_CAT_ALL, DBG_SUBCAT_ALL, DBG_LVL_ERROR, ("can not allocate cmd msg\n")); goto error1; } CMD_MSG_CB(net_pkt)->msg = msg; memset(msg, 0x00, sizeof(*msg)); msg->priv = (void *)ad; msg->net_pkt = net_pkt; ctl->alloc_cmd_msg++; return msg; os_free_mem(NULL, msg); error1: RTMPFreeNdisPacket(ad, net_pkt); error0: return NULL; }
/* ======================================================================== 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 RTMP_ADAPTER *pAd, OUT RX_BLK *pRxBlk, OUT BOOLEAN *pbReschedule, INOUT UINT32 *pRxPending, OUT BOOLEAN *bCmdRspPacket) { RX_CONTEXT *pRxContext; PNDIS_PACKET pNetPkt; UCHAR *pData, *RXDMA; ULONG ThisFrameLen, RxBufferLength, valid_len; RXWI_STRUC *pRxWI; UINT8 RXWISize = pAd->chipCap.RXWISize; RXINFO_STRUC *pRxInfo; #ifdef RLT_MAC RXFCE_INFO *pRxFceInfo; #endif /* RLT_MAC */ *bCmdRspPacket = FALSE; pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex]; if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE)) return NULL; RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition; valid_len = RXDMA_FIELD_SIZE * 2; if (RxBufferLength < valid_len) { goto label_null; } pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; RXDMA = pData; /* 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 (RXDMA_FIELD_SIZE + sizeof(RXINFO_STRUC))*/ { DBGPRINT(RT_DEBUG_ERROR,("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 += RXDMA_FIELD_SIZE; #ifdef RLT_MAC pRxFceInfo = (RXFCE_INFO *)(pData + ThisFrameLen); /* Check if command response or data packet */ if ((pRxFceInfo->info_type == CMD_PACKET) && (pAd->chipCap.CmdRspRxRing == RX_RING0)) { //CmdRspEventCallbackHandle(pAd, RXDMA); /* Update next packet read position.*/ pAd->ReadPosition += (sizeof(*pRxFceInfo) * 2 + pRxFceInfo->pkt_len); *bCmdRspPacket = TRUE; goto label_null; } pRxInfo = (RXINFO_STRUC *)pData; pData += RXINFO_SIZE; #endif /* RLT_MAC */ #ifdef RTMP_MAC pRxInfo = *(RXINFO_STRUC *)(pData + ThisFrameLen); #endif /* RTMP_MAC */ pRxWI = (RXWI_STRUC *)pData; #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, pData, TYPE_RXWI); #endif /* RT_BIG_ENDIAN */ if (pRxWI->RxWIMPDUByteCnt > ThisFrameLen) { DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n", __FUNCTION__, pRxWI->RxWIMPDUByteCnt, ThisFrameLen)); goto label_null; } #ifdef RT_BIG_ENDIAN RTMPWIEndianChange(pAd, 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*/ RTMP_USB_PKT_COPY(get_netdev_from_bssid(pAd, BSS0), pNetPkt, ThisFrameLen, pData); #ifdef RT_BIG_ENDIAN RTMPDescriptorEndianChange((PUCHAR)pRxInfo, TYPE_RXINFO); #endif /* RT_BIG_ENDIAN */ #ifdef RLT_MAC NdisMoveMemory((VOID *)&pRxBlk->hw_rx_info[0], (VOID *)pRxFceInfo, sizeof(RXFCE_INFO)); pRxBlk->pRxFceInfo = (RXFCE_INFO *)&pRxBlk->hw_rx_info[0]; #endif /* RLT_MAC */ NdisMoveMemory(&pRxBlk->hw_rx_info[RXINFO_OFFSET], pRxInfo, RXINFO_SIZE); pRxBlk->pRxInfo = (RXINFO_STRUC *)&pRxBlk->hw_rx_info[RXINFO_OFFSET]; /* update next packet read position.*/ pAd->ReadPosition += (ThisFrameLen + RXDMA_FIELD_SIZE + RXINFO_SIZE); /* 8 for (RXDMA_FIELD_SIZE + sizeof(RXINFO_STRUC))*/ return pNetPkt; label_null: return NULL; }
/* ======================================================================== 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; }
NDIS_STATUS RTMPAllocTxRxRingMemory( IN PRTMP_ADAPTER pAd) { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; ULONG RingBasePaHigh; ULONG RingBasePaLow; PVOID RingBaseVa; INT index, num; PTXD_STRUC pTxD; PRXD_STRUC pRxD; ULONG ErrorValue = 0; PRTMP_TX_RING pTxRing; PRTMP_DMABUF pDmaBuf; PNDIS_PACKET pPacket; DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); do { for (num=0; num<NUM_OF_TX_RING; num++) { ULONG BufBasePaHigh; ULONG BufBasePaLow; PVOID BufBaseVa; pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE; RTMP_AllocateTxDescMemory( pAd, num, pAd->TxDescRing[num].AllocSize, FALSE, &pAd->TxDescRing[num].AllocVa, &pAd->TxDescRing[num].AllocPa); if (pAd->TxDescRing[num].AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize); RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa); RingBaseVa = pAd->TxDescRing[num].AllocVa; pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE; RTMP_AllocateFirstTxBuffer( pAd, num, pAd->TxBufSpace[num].AllocSize, FALSE, &pAd->TxBufSpace[num].AllocVa, &pAd->TxBufSpace[num].AllocPa); if (pAd->TxBufSpace[num].AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize); BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa); BufBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa); BufBaseVa = pAd->TxBufSpace[num].AllocVa; pTxRing = &pAd->TxRing[num]; for (index = 0; index < TX_RING_SIZE; index++) { pTxRing->Cell[index].pNdisPacket = NULL; pTxRing->Cell[index].pNextNdisPacket = NULL; pTxRing->Cell[index].AllocSize = TXD_SIZE; pTxRing->Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow); pDmaBuf = &pTxRing->Cell[index].DmaBuf; pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE; pDmaBuf->AllocVa = BufBaseVa; RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh); RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow); pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa; pTxD->SDPtr0 = BufBasePaLow; pTxD->DMADONE = 1; RingBasePaLow += TXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE; BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE; } DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index)); } if (Status == NDIS_STATUS_RESOURCES) break; pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE; RTMP_AllocateMgmtDescMemory( pAd, pAd->MgmtDescRing.AllocSize, FALSE, &pAd->MgmtDescRing.AllocVa, &pAd->MgmtDescRing.AllocPa); if (pAd->MgmtDescRing.AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa); RingBaseVa = pAd->MgmtDescRing.AllocVa; for (index = 0; index < MGMT_RING_SIZE; index++) { pAd->MgmtRing.Cell[index].pNdisPacket = NULL; pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL; pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE; pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow); RingBasePaLow += TXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa; pTxD->DMADONE = 1; } DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index)); pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE; RTMP_AllocateRxDescMemory( pAd, pAd->RxDescRing.AllocSize, FALSE, &pAd->RxDescRing.AllocVa, &pAd->RxDescRing.AllocPa); if (pAd->RxDescRing.AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize); printk("RX DESC %p size = %ld\n", pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize); RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa); RingBaseVa = pAd->RxDescRing.AllocVa; for (index = 0; index < RX_RING_SIZE; index++) { pAd->RxRing.Cell[index].AllocSize = RXD_SIZE; pAd->RxRing.Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow); RingBasePaLow += RXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE; pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf; pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE; pPacket = RTMP_AllocateRxPacketBuffer( pAd, pDmaBuf->AllocSize, FALSE, &pDmaBuf->AllocVa, &pDmaBuf->AllocPa); pAd->RxRing.Cell[index].pNdisPacket = pPacket; if (pDmaBuf->AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize); pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa; pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa); pRxD->DDONE = 0; } DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index)); } while (FALSE); NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME)); pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); if (pAd->FragFrame.pFragPacket == NULL) { Status = NDIS_STATUS_RESOURCES; } if (Status != NDIS_STATUS_SUCCESS) { NdisWriteErrorLogEntry( pAd->AdapterHandle, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 1, ErrorValue); } DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); return Status; }
/* ======================================================================== Routine Description: Allocate DMA memory blocks for send, receive. Arguments: pAd Pointer to our adapter Return Value: NDIS_STATUS_SUCCESS NDIS_STATUS_FAILURE NDIS_STATUS_RESOURCES Note: ======================================================================== */ NDIS_STATUS RTMPAllocTxRxRingMemory( IN PRTMP_ADAPTER pAd) { // COUNTER_802_11 pCounter = &pAd->WlanCounters; NDIS_STATUS Status; INT num; DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); do { // Init the CmdQ and CmdQLock NdisAllocateSpinLock(&pAd->CmdQLock); NdisAcquireSpinLock(&pAd->CmdQLock); RTUSBInitializeCmdQ(&pAd->CmdQ); NdisReleaseSpinLock(&pAd->CmdQLock); NdisAllocateSpinLock(&pAd->MLMEBulkOutLock); //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock); NdisAllocateSpinLock(&pAd->BulkOutLock[0]); NdisAllocateSpinLock(&pAd->BulkOutLock[1]); NdisAllocateSpinLock(&pAd->BulkOutLock[2]); NdisAllocateSpinLock(&pAd->BulkOutLock[3]); NdisAllocateSpinLock(&pAd->BulkOutLock[4]); NdisAllocateSpinLock(&pAd->BulkOutLock[5]); NdisAllocateSpinLock(&pAd->BulkInLock); for (num = 0; num < NUM_OF_TX_RING; num++) { NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]); } #ifdef RALINK_ATE NdisAllocateSpinLock(&pAd->GenericLock); #endif // RALINK_ATE // // NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX // NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit() // NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit() // for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++) // { // NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock); // } // // Init Mac Table // // MacTableInitialize(pAd); // // Init send data structures and related parameters // Status = NICInitTransmit(pAd); if (Status != NDIS_STATUS_SUCCESS) break; // // Init receive data structures and related parameters // Status = NICInitRecv(pAd); if (Status != NDIS_STATUS_SUCCESS) break; pAd->PendingIoCount = 1; } while (FALSE); NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME)); pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); if (pAd->FragFrame.pFragPacket == NULL) { Status = NDIS_STATUS_RESOURCES; } DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); return Status; }
/* ======================================================================== Routine Description: Allocate DMA memory blocks for send, receive Arguments: Adapter Pointer to our adapter Return Value: NDIS_STATUS_SUCCESS NDIS_STATUS_FAILURE NDIS_STATUS_RESOURCES IRQL = PASSIVE_LEVEL Note: ======================================================================== */ NDIS_STATUS RTMPAllocTxRxRingMemory( IN PRTMP_ADAPTER pAd) { NDIS_STATUS Status = NDIS_STATUS_SUCCESS; ULONG RingBasePaHigh; ULONG RingBasePaLow; PVOID RingBaseVa; INT index, num; PTXD_STRUC pTxD; PRXD_STRUC pRxD; ULONG ErrorValue = 0; PRTMP_TX_RING pTxRing; PRTMP_DMABUF pDmaBuf; PNDIS_PACKET pPacket; DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n")); do { // // Allocate all ring descriptors, include TxD, RxD, MgmtD. // Although each size is different, to prevent cacheline and alignment // issue, I intentional set them all to 64 bytes. // for (num=0; num<NUM_OF_TX_RING; num++) { ULONG BufBasePaHigh; ULONG BufBasePaLow; PVOID BufBaseVa; // // Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA) // pAd->TxDescRing[num].AllocSize = TX_RING_SIZE * TXD_SIZE; RTMP_AllocateTxDescMemory( pAd, num, pAd->TxDescRing[num].AllocSize, FALSE, &pAd->TxDescRing[num].AllocVa, &pAd->TxDescRing[num].AllocPa); if (pAd->TxDescRing[num].AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } // Zero init this memory block NdisZeroMemory(pAd->TxDescRing[num].AllocVa, pAd->TxDescRing[num].AllocSize); // Save PA & VA for further operation RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxDescRing[num].AllocPa); RingBaseVa = pAd->TxDescRing[num].AllocVa; // // Allocate all 1st TXBuf's memory for this TxRing // pAd->TxBufSpace[num].AllocSize = TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE; RTMP_AllocateFirstTxBuffer( pAd, num, pAd->TxBufSpace[num].AllocSize, FALSE, &pAd->TxBufSpace[num].AllocVa, &pAd->TxBufSpace[num].AllocPa); if (pAd->TxBufSpace[num].AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } // Zero init this memory block NdisZeroMemory(pAd->TxBufSpace[num].AllocVa, pAd->TxBufSpace[num].AllocSize); // Save PA & VA for further operation BufBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].AllocPa); BufBasePaLow = RTMP_GetPhysicalAddressLow (pAd->TxBufSpace[num].AllocPa); BufBaseVa = pAd->TxBufSpace[num].AllocVa; // // Initialize Tx Ring Descriptor and associated buffer memory // pTxRing = &pAd->TxRing[num]; for (index = 0; index < TX_RING_SIZE; index++) { pTxRing->Cell[index].pNdisPacket = NULL; pTxRing->Cell[index].pNextNdisPacket = NULL; // Init Tx Ring Size, Va, Pa variables pTxRing->Cell[index].AllocSize = TXD_SIZE; pTxRing->Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pTxRing->Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pTxRing->Cell[index].AllocPa, RingBasePaLow); // Setup Tx Buffer size & address. only 802.11 header will store in this space pDmaBuf = &pTxRing->Cell[index].DmaBuf; pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE; pDmaBuf->AllocVa = BufBaseVa; RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa, BufBasePaHigh); RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa, BufBasePaLow); // link the pre-allocated TxBuf to TXD pTxD = (PTXD_STRUC) pTxRing->Cell[index].AllocVa; pTxD->SDPtr0 = BufBasePaLow; // advance to next ring descriptor address pTxD->DMADONE = 1; RingBasePaLow += TXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; // advance to next TxBuf address BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE; BufBaseVa = (PUCHAR) BufBaseVa + TX_DMA_1ST_BUFFER_SIZE; } DBGPRINT(RT_DEBUG_TRACE, ("TxRing[%d]: total %d entry allocated\n", num, index)); } if (Status == NDIS_STATUS_RESOURCES) break; // // Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler // pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE; RTMP_AllocateMgmtDescMemory( pAd, pAd->MgmtDescRing.AllocSize, FALSE, &pAd->MgmtDescRing.AllocVa, &pAd->MgmtDescRing.AllocPa); if (pAd->MgmtDescRing.AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } // Zero init this memory block NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize); // Save PA & VA for further operation RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->MgmtDescRing.AllocPa); RingBaseVa = pAd->MgmtDescRing.AllocVa; // // Initialize MGMT Ring and associated buffer memory // for (index = 0; index < MGMT_RING_SIZE; index++) { pAd->MgmtRing.Cell[index].pNdisPacket = NULL; pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL; // Init MGMT Ring Size, Va, Pa variables pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE; pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pAd->MgmtRing.Cell[index].AllocPa, RingBasePaLow); // Offset to next ring descriptor address RingBasePaLow += TXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + TXD_SIZE; // link the pre-allocated TxBuf to TXD pTxD = (PTXD_STRUC) pAd->MgmtRing.Cell[index].AllocVa; pTxD->DMADONE = 1; // no pre-allocated buffer required in MgmtRing for scatter-gather case } DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", index)); // // Allocate RX ring descriptor's memory except Tx ring which allocated eariler // pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE; RTMP_AllocateRxDescMemory( pAd, pAd->RxDescRing.AllocSize, FALSE, &pAd->RxDescRing.AllocVa, &pAd->RxDescRing.AllocPa); if (pAd->RxDescRing.AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate a big buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } // Zero init this memory block NdisZeroMemory(pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize); printk("RX DESC %p size = %ld\n", pAd->RxDescRing.AllocVa, pAd->RxDescRing.AllocSize); // Save PA & VA for further operation RingBasePaHigh = RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa); RingBasePaLow = RTMP_GetPhysicalAddressLow (pAd->RxDescRing.AllocPa); RingBaseVa = pAd->RxDescRing.AllocVa; // // Initialize Rx Ring and associated buffer memory // for (index = 0; index < RX_RING_SIZE; index++) { // Init RX Ring Size, Va, Pa variables pAd->RxRing.Cell[index].AllocSize = RXD_SIZE; pAd->RxRing.Cell[index].AllocVa = RingBaseVa; RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].AllocPa, RingBasePaHigh); RTMP_SetPhysicalAddressLow (pAd->RxRing.Cell[index].AllocPa, RingBasePaLow); // Offset to next ring descriptor address RingBasePaLow += RXD_SIZE; RingBaseVa = (PUCHAR) RingBaseVa + RXD_SIZE; // Setup Rx associated Buffer size & allocate share memory pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf; pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE; pPacket = RTMP_AllocateRxPacketBuffer( pAd, pDmaBuf->AllocSize, FALSE, &pDmaBuf->AllocVa, &pDmaBuf->AllocPa); /* keep allocated rx packet */ pAd->RxRing.Cell[index].pNdisPacket = pPacket; // Error handling if (pDmaBuf->AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n")); Status = NDIS_STATUS_RESOURCES; break; } // Zero init this memory block NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize); // Write RxD buffer address & allocated buffer length pRxD = (PRXD_STRUC) pAd->RxRing.Cell[index].AllocVa; pRxD->SDP0 = RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa); pRxD->DDONE = 0; } DBGPRINT(RT_DEBUG_TRACE, ("Rx Ring: total %d entry allocated\n", index)); } while (FALSE); NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME)); pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE); if (pAd->FragFrame.pFragPacket == NULL) { Status = NDIS_STATUS_RESOURCES; } if (Status != NDIS_STATUS_SUCCESS) { // Log error inforamtion NdisWriteErrorLogEntry( pAd->AdapterHandle, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 1, ErrorValue); } DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status)); return Status; }