📄 nscfir.c
字号:
if((READ_REGISTER_UCHAR(pITSR) & CC_FIR_ITSR_TFUR) == CC_FIR_ITSR_TFUR){
WRITE_REGISTER_UCHAR(pIRSTCR, CC_FIR_IRSTCR_RSTC_UNDERRUN);/* Reset FIFO Underrun/EOM Latch */
RegStats.TxUnderruns++;
status = NDIS_STATUS_FAILURE;
WRITE_REGISTER_UCHAR(pIMSTCR, (READ_REGISTER_UCHAR(pIMSTCR) & CC_FIR_IMSTCR_RST_BANK) | CC_FIR_IMSTCR_BANK1);// Switch Bank 1
RETAILMSG(1, (TEXT("FIR_MegaSendComplete: Transmit Underrun (%d)\r\n"),
READ_REGISTER_UCHAR(pITBCLR) |
((READ_REGISTER_UCHAR(pITBCHR) & 0x1f) << 8)));
LOG(TEXT("FIR_MegaSendComplete: Transmit Underrun"), 0);
DEBUGFIR(DBG_TX|DBG_ERR,
(TEXT("NSC: FIR_MegaSendComplete: Transmit Underrun")));
#ifdef OUTMSG
RETAILMSG(0, (TEXT("FIR_MegaSendComplete: Transmit Underrun.\r\n")));
#endif
}
else {
status = NDIS_STATUS_SUCCESS;
//RETAILMSG(1, (TEXT("FIR_MegaSendComplete: no underrun.\r\n")));
}
/* Reset Tx pending. */
thisDev->portInfo.writePending = FALSE;
DBGOUT((TEXT("writePending = FALSE")));
/*
* Notify NDIS of TX complete.
*/
NdisMSendComplete(thisDev->ndisAdapterHandle, Packet, status);
}
LOG(TEXT("<== FIR_MegaSendComplete"), 1);
DEBUGFIR(DBG_TX|DBG_OUT, (TEXT("NSC: <== FIR_MegaSendComplete")));
DBGOUT((TEXT("<==FIR_MegaSendComplete")));
}
void FIR_DeliverFrames(IrDevice *thisDev)
{
UINT i;
ULONG FrameSizeQue[7];
UINT SizeQuePtr;
UCHAR frameStat;
NDIS_STATUS stat;
ULONG rcvFrameSize;
PUCHAR NewFrame,TopOfBuf;
ULONG LastReadDMACount, EndOfData;
BOOLEAN resetDma = FALSE, OverflowOccurred = FALSE;
const UINT fcsSize = ( thisDev->currentSpeed >= MIN_FIR_SPEED) ?
FAST_IR_FCS_SIZE : MEDIUM_IR_FCS_SIZE;
DBGOUT((TEXT("==>FIR_DeliverFrames")));
LOG(TEXT("==> FIR_DeliverFrames"), 0);
DEBUGFIR(DBG_RX|DBG_OUT, (TEXT("NSC: ==> FIR_DeliverFrames(0x%x)"),
(UINT) thisDev));
LastReadDMACount = NdisMReadDmaCounter(thisDev->DmaHandle);
// Check for data received since the last time we were here.
// We also check for data in FIFO. If ther is some, we waite as long
// as the DMA still has room to capture data.
thisDev->LineStatus = (UCHAR)READ_REGISTER_UCHAR(pIRSR);
if (LastReadDMACount != thisDev->LastReadDMACount ||
((thisDev->LineStatus & 0x08) && LastReadDMACount != 0)){
thisDev->LastReadDMACount = LastReadDMACount;
//
// Set Timer Enable bit for another Timeout.
//
if((thisDev->LastReadRFPCount == thisDev->ReadRFPCount) ||
(thisDev->ReadRFPCount == 0)){
;
}else if(thisDev->QueIndex < 7){
thisDev->RFPQue[thisDev->QueIndex++] = thisDev->ReadRFPCount;
thisDev->LastReadRFPCount = thisDev->ReadRFPCount;
}
return;
}
RegStats.RxDPC_Window++;
//thisDev->IntMask = 0x04;
//RETAILMSG(1, (TEXT("DLVFR\r\n")));
NdisMCompleteDmaTransfer(&stat, thisDev->DmaHandle,
thisDev->rcvDmaBuffer,
thisDev->rcvDmaOffset,
thisDev->rcvDmaSize, FALSE);
if (stat != NDIS_STATUS_SUCCESS) {
DbgBreakPoint();
}
if((thisDev->LastReadRFPCount != thisDev->ReadRFPCount) &&
(thisDev->ReadRFPCount != 0) &&
(thisDev->QueIndex < 7)){
thisDev->RFPQue[thisDev->QueIndex++] = thisDev->ReadRFPCount;
}
// Get the exact count.
thisDev->LastReadRFPCount = 0;
TopOfBuf = thisDev->portInfo.dmaReadBuf+ thisDev->rcvPktOffset;
LastReadDMACount = NdisMReadDmaCounter(thisDev->DmaHandle);
LOG(TEXT("frameStat: "), (UINT) frameStat);
DEBUGFIR(DBG_RX|DBG_OUT, (TEXT("NSC: frameStat = %xh"),
(UINT) frameStat));
if(thisDev->QueIndex){
for(i=0;i<thisDev->QueIndex;i++){
NewFrame = thisDev->portInfo.dmaReadBuf + thisDev->rcvPktOffset;
thisDev->rcvPktOffset = thisDev->RFPQue[i];
frameStat = TopOfBuf[thisDev->rcvPktOffset];
rcvFrameSize = (ULONG)(frameStat & 0x1f)*256 +
TopOfBuf[thisDev->rcvPktOffset-1];
EndOfData = TopOfBuf + thisDev->rcvPktOffset - NewFrame - 1;
thisDev->rcvPktOffset++;
if(rcvFrameSize == EndOfData){
if(!(frameStat & 0xe0)){
ASSERT(thisDev->rcvPktOffset< RCV_DMA_SIZE);
rcvFrameSize -= fcsSize;
if(rcvFrameSize <= MAX_NDIS_DATA_SIZE &&
rcvFrameSize >= IR_ADDR_SIZE + IR_CONTROL_SIZE){
QueueReceivePacket(thisDev,NewFrame,rcvFrameSize,TRUE);
#ifdef OUTMSG
RETAILMSG(1,(TEXT("Qued1 %d\r\n"), rcvFrameSize));
#endif
}
}
}else{
SizeQuePtr = 0;
while(((long)rcvFrameSize <= (long)EndOfData) && (SizeQuePtr < 7)){
FrameSizeQue[SizeQuePtr++] = rcvFrameSize;
if(rcvFrameSize == EndOfData){
EndOfData -= rcvFrameSize;
break;
}
EndOfData -= (rcvFrameSize + 2);
frameStat = NewFrame[EndOfData + 1];
rcvFrameSize = (ULONG)(frameStat & 0x1f)*256 + NewFrame[EndOfData];
}
if((EndOfData == 0) && (SizeQuePtr < 7)){
rcvFrameSize = 0;
do {
NewFrame += rcvFrameSize;
rcvFrameSize = FrameSizeQue[--SizeQuePtr];
frameStat = NewFrame[rcvFrameSize + 1];
if(!(frameStat & 0xe0)){
QueueReceivePacket(thisDev,NewFrame,rcvFrameSize-fcsSize, TRUE);
#ifdef OUTMSG
RETAILMSG(1,(TEXT("Qued2\r\n")));
#endif
}
rcvFrameSize += 2;
} while(SizeQuePtr);
}
}
}//loop-end
}
SetupRecv(thisDev);
LOG(TEXT("<== FIR_DeliverFrames"), 1);
DEBUGFIR(DBG_RX|DBG_OUT, (TEXT("NSC: <== FIR_DeliverFrames")));
DBGOUT((TEXT("<==FIR_DeliverFrames")));
}
BOOLEAN NSC_Setup(IrDevice *thisDev)
{
NDIS_DMA_DESCRIPTION DMAChannelDcr;
NDIS_STATUS stat;
DBGOUT((TEXT("==>NSC_Setup")));
thisDev->rcvDmaOffset = 0;
/*
* Because we enable rcv DMA while SIR receives may still be
* going on, we need to keep a separate receive buffer for DMA.
* This buffer gets swapped with the rcvBuffer data pointer
* and must be the same size.
*/
#ifdef UNDER_CE
// Windows CE. We get a chunk of memory from our contiguous physical
// buffer. See externs.h for detailed information.
ASSERT(g_pvDmaVirtualBase);
thisDev->portInfo.dmaReadBuf = (PUCHAR)g_pvDmaVirtualBase + RCVDMA_OFFSET;
#else // UNDER_CE
thisDev->portInfo.dmaReadBuf = MyMemAlloc(RCV_DMA_SIZE, TRUE);
if (!thisDev->portInfo.dmaReadBuf){
return FALSE;
}
#endif //!UNDER_CE
NdisAllocateBufferPool(&stat, &thisDev->dmaBufferPoolHandle, 2);
if (stat != NDIS_STATUS_SUCCESS){
LOG(TEXT("Error: NdisAllocateBufferPool failed in NSC_Setup"), 0);
DEBUGFIR(DBG_ERR,
(TEXT("NSC: NdisAllocateBufferPool failed in NSC_Setup")));
return FALSE;
}
NdisAllocateBuffer(&stat, &thisDev->rcvDmaBuffer,
thisDev->dmaBufferPoolHandle,
thisDev->portInfo.dmaReadBuf,
RCV_DMA_SIZE);
if (stat != NDIS_STATUS_SUCCESS) {
LOG(TEXT("Error: NdisAllocateBuffer failed (rcv) in NSC_Setup"), 0);
DEBUGFIR(DBG_ERR, (TEXT("NSC: NdisAllocateBuffer failed (rcv) in NSC_Setup")));
return FALSE;
}
NdisAllocateBuffer(&stat, &thisDev->xmitDmaBuffer,
thisDev->dmaBufferPoolHandle,
thisDev->portInfo.writeBuf,
MAX_IRDA_DATA_SIZE);
if (stat != NDIS_STATUS_SUCCESS) {
LOG(TEXT("NdisAllocateBuffer failed (xmit) in NSC_Setup"), 0);
DEBUGFIR(DBG_ERR, (TEXT("NSC: NdisAllocateBuffer failed (xmit) in NSC_Setup")));
return FALSE;
}
/*
* Initialize rcv DMA channel
*/
DMAChannelDcr.DemandMode = TRUE;
DMAChannelDcr.AutoInitialize = FALSE;
DMAChannelDcr.DmaChannelSpecified = FALSE;
DMAChannelDcr.DmaWidth = Width8Bits;
DMAChannelDcr.DmaSpeed = Compatible;
DMAChannelDcr.DmaPort = 0;
#ifdef UNDER_CE
// For now, ndismlib.c (NSC miniport's DMA functions) require this to
// be set in the DMAChannelDcr structure.
DMAChannelDcr.DmaChannel = thisDev->portInfo.DMAChannel;
#else // UNDER_CE
DMAChannelDcr.DmaChannel = 0;
#endif //!UNDER_CE
stat = NdisMRegisterDmaChannel(&thisDev->DmaHandle,
thisDev->ndisAdapterHandle,
thisDev->portInfo.DMAChannel,
FALSE, &DMAChannelDcr, RCV_DMA_SIZE);
DBGOUT((TEXT("<==NSC_Setup")));
if (stat != NDIS_STATUS_SUCCESS) {
DEBUGFIR(DBG_ERR, (TEXT("NSC: NdisMRegisterDmaChannel failed")));
DbgBreakPoint();
return FALSE;
}
return TRUE;
}
void NSC_Shutdown(IrDevice *thisDev)
{
DBGOUT((TEXT("==>NSC_Shutdown")));
if (thisDev->DmaHandle){
NdisMDeregisterDmaChannel(thisDev->DmaHandle);
thisDev->DmaHandle = NULL;
}
if (thisDev->xmitDmaBuffer){
NdisFreeBuffer( thisDev->xmitDmaBuffer);
thisDev->xmitDmaBuffer = NULL;
}
if (thisDev->rcvDmaBuffer){
NdisFreeBuffer(thisDev->rcvDmaBuffer);
thisDev->rcvDmaBuffer = NULL;
}
if (thisDev->dmaBufferPoolHandle){
NdisFreeBufferPool(thisDev->dmaBufferPoolHandle);
thisDev->dmaBufferPoolHandle = NULL;
}
if (thisDev->portInfo.dmaReadBuf){
#ifdef UNDER_CE
// Windows CE. Don't need to free since it is just a pointer in our
// reserved physical memory.
#else // UNDER_CE
MyMemFree(thisDev->portInfo.dmaReadBuf, RCV_DMA_SIZE, TRUE);
#endif //!UNDER_CE
thisDev->portInfo.dmaReadBuf = NULL;
}
DBGOUT((TEXT("<==NSC_Shutdown")));
}
BOOLEAN NdisToFirPacket(IrDevice *thisDev, PNDIS_PACKET Packet,
UCHAR *irPacketBuf, UINT irPacketBufLen, UINT *irPacketLen)
{
PNDIS_BUFFER ndisBuf;
UINT ndisPacketBytes = 0;
UINT ndisPacketLen;
DBGOUT((TEXT("==>NdisToFirPacket")));
LOG(TEXT("==> NdisToFirPacket"), 0);
DEBUGFIR(DBG_OUT, (TEXT("NSC: ==> NdisToFirPacket(0x%x)"), (UINT) thisDev));
/*
* Get the packet's entire length and its first NDIS buffer
*/
NdisQueryPacket(Packet, NULL, NULL, &ndisBuf, &ndisPacketLen);
LOG(TEXT("NdisToFirPacket, number of bytes:"), ndisPacketLen);
DEBUGFIR(DBG_OUT,
(TEXT("NSC: NdisToFirPacket, number of bytes: %d"), ndisPacketLen));
/*
* Make sure that the packet is big enough to be legal.
* It consists of an A, C, and variable-length I field.
*/
if (ndisPacketLen < IR_ADDR_SIZE + IR_CONTROL_SIZE){
LOG(TEXT("Error: packet too short in "), ndisPacketLen);
DEBUGFIR(DBG_ERR,
(TEXT("NSC: packet too short in NdisToFirPacket (%d bytes)"),
ndisPacketLen));
#ifdef OUTMSG
RETAILMSG(1, (TEXT("NSC: packet too short in NdisToFirPacket (%d bytes)"),
ndisPacketLen));
#endif
return FALSE;
}
/*
* Make sure that we won't overwrite our contiguous buffer.
*/
if (ndisPacketLen > irPacketBufLen){
/*
* The packet is too large
* Tell the caller to retry with a packet size large
* enough to get past this stage next time.
*/
LOG(TEXT("Error: packet too large in "), ndisPacketLen);
DEBUGFIR(DBG_ERR,
(TEXT("NSC: Packet too large in NdisToIrPacket (%d=%xh bytes), ")
TEXT("MAX_IRDA_DATA_SIZE=%d, irPacketBufLen=%d."),
ndisPacketLen, ndisPacketLen, MAX_IRDA_DATA_SIZE, irPacketBufLen));
*irPacketLen = ndisPacketLen;
#ifdef OUTMSG
RETAILMSG(1, (TEXT("NSC: Packet too large in NdisToIrPacket (%d=%xh bytes), ")
TEXT("MAX_IRDA_DATA_SIZE=%d, irPacketBufLen=%d."),
ndisPacketLen, ndisPacketLen, MAX_IRDA_DATA_SIZE, irPacketBufLen));
#endif
return FALSE;
}
/*
* Read the NDIS packet into a contiguous buffer.
* We have to do this in two steps so that we can compute the
* FCS BEFORE applying escape-byte transparency.
*/
while (ndisBuf) {
UCHAR *bufData;
UINT bufLen;
NdisQueryBuffer(ndisBuf, (PVOID *)&bufData, &bufLen);
if (ndisPacketBytes + bufLen > ndisPacketLen){
/*
* Packet was corrupt -- it misreported its size.
*/
*irPacketLen = 0;
#ifdef OUTMSG
RETAILMSG(1, (TEXT(" Packet was corrupt in NdisToIrPacket\r\n")));
#endif
return FALSE;
}
NdisMoveMemory((PVOID)(irPacketBuf+ndisPacketBytes),
(PVOID)bufData, (ULONG)bufLen);
ndisPacketBytes += bufLen;
NdisGetNextBuffer(ndisBuf, &ndisBuf);
}
LOG(TEXT("Ir Command byte "), (UINT)*(irPacketBuf+1));
/*
* Do a sanity check on the length of the packet.
*/
if (ndisPacketBytes != ndisPacketLen){
/*
* Packet was corrupt -- it misreported its size.
*/
LOG(TEXT("Error: Packet corrupt in NdisToIrPacket ")
TEXT("(buffer lengths don't add up to packet length)"), 0);
DEBUGFIR(DBG_ERR, (TEXT("NSC: Packet corrupt in NdisToIrPacket ")
TEXT("(buffer lengths don't add up to packet length).")));
*irPacketLen = 0;
#ifdef OUTMSG
RETAILMSG(1, (TEXT(" Error: Packet corrupt in NdisToIrPacket\r\n")));
#endif
return FALSE;
}
#ifdef DBG_ADD_PKT_ID
if (addPktIdOn){
static USHORT uniqueId = 0;
DEBUGFIR(DBG_OUT, ("NSC: *** --> SEND PKT ID: %xh", (UINT)uniqueId));
LOG("ID: Send (FIR) Pkt id:", uniqueId);
*(USHORT *)(irPacketBuf+ndisPacketBytes) = uniqueId++;
ndisPacketBytes += sizeof(USHORT);
}
#endif
*irPacketLen = ndisPacketBytes;
LOG(TEXT("<== NdisToFirPacket"), 0);
DEBUGFIR(DBG_OUT, (TEXT("NSC: <== NdisToFirPacket")));
DBGOUT((TEXT("<==NdisToFirPacket")));
return TRUE;
}
VOID FIR_WriteBankReg(UINT bank, PUINT16 reg, UCHAR val)
{
WRITE_REGISTER_UCHAR(pIMSTCR,READ_REGISTER_UCHAR(pIMSTCR) & CC_FIR_IMSTCR_RST_BANK);
WRITE_REGISTER_UCHAR(pIMSTCR,READ_REGISTER_UCHAR(pIMSTCR) | bank);
WRITE_REGISTER_UCHAR((PUINT8)reg,val);
}
UCHAR FIR_ReadBankReg(UINT bank, PUINT16 reg)
{
UCHAR val;
WRITE_REGISTER_UCHAR(pIMSTCR,READ_REGISTER_UCHAR(pIMSTCR) & CC_FIR_IMSTCR_RST_BANK);
WRITE_REGISTER_UCHAR(pIMSTCR,READ_REGISTER_UCHAR(pIMSTCR) | bank);
val = READ_REGISTER_UCHAR((PUINT8)reg);
return(val);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -