firda.c
来自「S3C24A0的完整BSP包,对开发此芯片的开发者很有用.」· C语言 代码 · 共 2,000 行 · 第 1/5 页
C
2,000 行
LOG(TEXT("Indicated rcv complete (Async) bytes:"),
rcvBuf->dataLen);
DBGSTAT((TEXT("Rcv Pending. Rcvd %d packets"),
++thisDev->packetsRcvd));
}
else {
/*
* If there was an error, we are dropping this
* packet; otherwise, this packet was delivered
* synchronously. We can free the packet
* buffer and make this rcv frame available.
*/
LOG_RemoveEntryList(thisDev, rcvBuf);
RemoveEntryList(&rcvBuf->listEntry);
LOG(TEXT("Indicated rcv complete (sync) bytes:"),
rcvBuf->dataLen);
LOG_PacketUnchain(thisDev, rcvBuf->packet);
NdisUnchainBufferAtFront(rcvBuf->packet,
&packetBuf);
if (packetBuf){
NdisFreeBuffer(packetBuf);
}
rcvBuf->state = STATE_FREE;
VerifyNdisPacket(rcvBuf->packet, 0);
if (!rcvBuf->isDmaBuf) {
//
// At SIR speeds, we manage a group of buffers that
// we keep on the rcvBufBuf queue.
//
InsertTailList(&thisDev->rcvBufBuf, RCV_BUF_TO_LIST_ENTRY(rcvBuf->dataBuf));
// ASSERT the pointer is actually outside our FIR DMA buffer
ASSERT(rcvBuf->dataBuf < thisDev->portInfo.dmaReadBuf ||
rcvBuf->dataBuf >= thisDev->portInfo.dmaReadBuf+RCV_DMA_SIZE);
}
rcvBuf->dataBuf = NULL;
VerifyNdisPacket(rcvBuf->packet, 0);
InsertHeadList(&thisDev->rcvBufFree, &rcvBuf->listEntry);
if (stat == NDIS_STATUS_SUCCESS){
DBGSTAT((TEXT("Rcvd %d packets"),
++thisDev->packetsRcvd));
}
else {
DBGSTAT((TEXT("Dropped %d/%d rcv packets."),
thisDev->packetsDropped++,
thisDev->packetsDropped +
thisDev->packetsRcvd));
}
}
}
LOG(TEXT("<== DeliverFullBuffers"), 1);
DBGOUT((TEXT("<== DeliverFullBuffers")));
return result;
}
/*
*************************************************************************
* MiniportHandleInterrupt
*************************************************************************
*
*
* This is the deferred interrupt processing routine (DPC) which is
* optionally called following an interrupt serviced by MiniportISR.
*
*/
VOID MiniportHandleInterrupt(NDIS_HANDLE MiniportAdapterContext)
{
IrDevice *thisDev = CONTEXT_TO_DEV( MiniportAdapterContext);
// DEBUGFIR(DBGIRDA, (TEXT("==> MiniportHandleInterrupt(0x%x)\r\n"), (UINT)MiniportAdapterContext));
NdisAcquireSpinLock(&thisDev->Lock);
if (thisDev->resourcesReleased){
NdisReleaseSpinLock(&thisDev->Lock);
DBGERR((TEXT("<== MiniportHandleInterrupt, blow off, no resources!")));
return;
}
/*
* If we finished the last send packet in the interrupt, we must change
* speed.
*/
if (thisDev->setSpeedNow){
thisDev->setSpeedNow = FALSE;
SetSpeed(thisDev);
}
/*
* If we have just started receiving a packet, indicate media-busy
* to the protocol.
*/
if (thisDev->mediaBusy && !thisDev->haveIndicatedMediaBusy) {
DBGISR((TEXT("HandleInterrupt indicating media busy")));
if (thisDev->currentSpeed > MAX_SIR_SPEED) {
LOG(TEXT("Error: MiniportHandleInterrupt is in wrong state"),
thisDev->currentSpeed);
DBGERR((TEXT("%s speed is 0x%x"),
TEXT("MiniportHandleInterrupt is in wrong state:"),
thisDev->currentSpeed));
DbgBreakPoint();
}
NdisReleaseSpinLock(&thisDev->Lock);
NdisMIndicateStatus(thisDev->ndisAdapterHandle, NDIS_STATUS_MEDIA_BUSY, NULL, 0);
NdisMIndicateStatusComplete(thisDev->ndisAdapterHandle);
NdisAcquireSpinLock(&thisDev->Lock);
thisDev->haveIndicatedMediaBusy = TRUE;
}
/* FIR mode */
if (thisDev->currentSpeed > MAX_SIR_SPEED) {
DEBUGFIR(DBGIRDA, (TEXT("HandleInterrupt - FIR")));
if (thisDev->portInfo.writePending) {
FIR_SendComplete(thisDev);
thisDev->AdapterState = ADAPTER_NONE;
/*
* Any more Tx packets?
*/
if (!IsListEmpty(&thisDev->SendQueue)) {
/* Kick off another Tx. */
DBGISR((TEXT("More packets in the Q Calling FIR_Send (0x%x)"), thisDev));
FIR_Send(thisDev);
} else {
thisDev->IntMask = 0x04;
DBGISR((TEXT("No More packets in the Q Calling SetupRecv (0x%x)"), thisDev));
FirSetupIntRecv(thisDev);
/*
* If we just sent the last frame to be sent at the old speed,
* set the hardware to the new speed.
* From OLD sytle!
*/
#if 1
if (thisDev->setSpeedAfterCurrentSendPacket) {
thisDev->setSpeedAfterCurrentSendPacket = FALSE;
SetSpeed(thisDev);
}
#endif
}
} else {
DBGISR((TEXT("Recvd PAcket .. Handling..... (0x%x)"), thisDev));
// FIR_HandleRxFrame(thisDev);
DeliverFullBuffers(thisDev);
}
}else {
DBGISR((TEXT("HandleInterrupt - SIR")));
DeliverFullBuffers(thisDev);
/*
* Send any pending write packets if possible.
*/
if (IsCommReadyForTransmit(thisDev)) {
PortReadyForWrite(thisDev, TRUE);
}
}
NdisReleaseSpinLock(&thisDev->Lock);
// LOG(TEXT("<== MiniportHandleInterrupt"), 1);
DBGOUT((TEXT("<== MiniportHandleInterrupt")));
}
/*
*************************************************************************
* Configure
*************************************************************************
*
* Read configurable parameters out of the system registry.
*
*/
BOOLEAN Configure(
IrDevice *thisDev,
NDIS_HANDLE WrapperConfigurationContext
)
{
//
// Status of Ndis calls.
//
NDIS_STATUS Status;
//
// The handle for reading from the registry.
//
NDIS_HANDLE ConfigHandle;
//
// TRUE if there is a configuration error.
//
BOOLEAN ConfigError = FALSE;
//
// A special value to log concerning the error.
//
ULONG ConfigErrorValue = 0;
#ifndef UNDER_CE
ULONG SlotNumber;
#endif // !UNDER_CE
ULONG PCI_ConfigInfo = 0;
//
// The value read from the registry.
//
PNDIS_CONFIGURATION_PARAMETER ReturnedValue;
//
// String names of all the parameters that will be read.
//
NDIS_STRING CardTypeStr = CARDTYPE;
NDIS_STRING ConfigIOAddressStr = CONFIGIOADDRESS;
NDIS_STRING UartIOAddressStr = UARTIOADDRESS;
NDIS_STRING InterruptStr = INTERRUPT;
DBGOUT((TEXT("Configure(0x%x)"), (UINT)thisDev));
NdisOpenConfiguration(&Status, &ConfigHandle, WrapperConfigurationContext);
if (Status != NDIS_STATUS_SUCCESS){
DBGERR((TEXT("NdisOpenConfiguration failed in Configure()")));
return FALSE;
}
//
// Read SMDK24A0(A) FIR Configuration I/O base Address
//
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&ConfigIOAddressStr,
NdisParameterHexInteger
);
if (Status != NDIS_STATUS_SUCCESS){
DBGERR((TEXT("NdisReadConfiguration failed in accessing ConfigIoBaseAddr.")));
return FALSE;
}
else
thisDev->portInfo.ConfigIoBaseAddr = (UINT)(ReturnedValue->ParameterData.IntegerData);
// WinCE does not support the GetPnPResources. Will configure using
// registry settings.
//
// Read I/O Address
//
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&UartIOAddressStr,
NdisParameterHexInteger
);
if (Status != NDIS_STATUS_SUCCESS){
DBGERR((TEXT("NdisReadConfiguration failed in accessing UartIoBaseAddr.")));
return FALSE;
}
thisDev->portInfo.ioBase = (UINT)(ReturnedValue->ParameterData.IntegerData);
//
// Read interrupt number
//
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&InterruptStr,
NdisParameterHexInteger
);
if (Status != NDIS_STATUS_SUCCESS){
DBGERR((TEXT("NdisReadConfiguration failed in accessing InterruptNumber.")));
return FALSE;
}
thisDev->portInfo.irq = (UINT)(ReturnedValue->ParameterData.IntegerData);
NdisCloseConfiguration(ConfigHandle);
DBGINIT((TEXT("Irda configure done: ConfigIO=0x%x UartIO=0x%x irq=%d "),
thisDev->portInfo.ConfigIoBaseAddr,thisDev->portInfo.ioBase, thisDev->portInfo.irq));
RETAILMSG(1, (TEXT("Irda configure done: ConfigIO=0x%x UartIO=0x%x irq=%d "),
thisDev->portInfo.ConfigIoBaseAddr,thisDev->portInfo.ioBase, thisDev->portInfo.irq));
return TRUE;
}
/*
*************************************************************************
* MiniportInitialize
*************************************************************************
*
*
* Initializes the network interface card.
*
*
*
*/
NDIS_STATUS MiniportInitialize ( PNDIS_STATUS OpenErrorStatus,
PUINT SelectedMediumIndex,
PNDIS_MEDIUM MediumArray,
UINT MediumArraySize,
NDIS_HANDLE NdisAdapterHandle,
NDIS_HANDLE WrapperConfigurationContext
)
{
UINT mediumIndex;
IrDevice *thisDev = NULL;
NDIS_STATUS retStat, result = NDIS_STATUS_SUCCESS;
DBGOUT((TEXT("MiniportInitialize()")));
/*
* Search the passed-in array of supported media for the IrDA medium.
*/
for (mediumIndex = 0; mediumIndex < MediumArraySize; mediumIndex++){
if (MediumArray[mediumIndex] == NdisMediumIrda){
break;
}
}
if (mediumIndex < MediumArraySize){
*SelectedMediumIndex = mediumIndex;
}
else {
/*
* Didn't see the IrDA medium
*/
DBGERR((TEXT("Didn't see the IRDA medium in MiniportInitialize")));
result = NDIS_STATUS_UNSUPPORTED_MEDIA;
goto _initDone;
}
/*
* Allocate a new device object to represent this connection.
*/
thisDev = NewDevice();
if (!thisDev){
return NDIS_STATUS_NOT_ACCEPTED;
}
NdisAcquireSpinLock(&thisDev->Lock);
#ifdef UNDER_CE
// CE - calls NdisMInitializeTimer instead of NdisInitializeTimer. This
// requires the NdisAdapterHandle. Else the timer is initialized
// in InitDevice.
NdisMInitializeTimer(&thisDev->TurnaroundTimer,
NdisAdapterHandle,
DelayedWrite,
thisDev);
#endif // UNDER_CE
/*
* Allocate resources for this connection.
*/
if (!OpenDevice(thisDev)){
DBGERR((TEXT("OpenDevice failed")));
result = NDIS_STATUS_FAILURE;
goto _initDone;
}
/*
* Read the system registry to get parameters like ConfigBase address, DMA address etc
*/
if (!Configure(thisDev, WrapperConfigurationContext)){
result = NDIS_STATUS_FAILURE;
goto _initDone;
}
/*
* This call will associate our adapter handle with the wrapper's
* adapter handle. The wrapper will then always use our handle
* when calling us. We use a pointer to the device object as the context.
*/
NdisMSetAttributesEx ( NdisAdapterHandle,
(NDIS_HANDLE)thisDev,
0,
NDIS_ATTRIBUTE_DESERIALIZE,
NdisInterfaceInternal
);
#if 1
/*
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?