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 + -
显示快捷键?