⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cs8900a.c

📁 IMX开发板
💻 C
📖 第 1 页 / 共 3 页
字号:
                                            pEthernet->intLine,
                                            pEthernet->intLine,
                                            FALSE,
                                            FALSE,
                                            NdisInterruptLatched);

            if (Status != NDIS_STATUS_SUCCESS)
            {
                DEBUGMSG(ZONE_INIT, (TEXT("CS8900A: NdisMRegisterInterrupt failed 0x%x\r\n"), Status));
                NdisWriteErrorLogEntry(MiniportAdapterHandle, NDIS_ERROR_CODE_INTERRUPT_CONNECT, 0);
                break;
            }

            pEthernet->CurrentState = NdisHardwareStatusReady;
            pEthernet->MediaState = UpdateMediaConnectStatus(pEthernet, NdisMediaStateDisconnected);
        }
        else
        {
            Status = NDIS_STATUS_FAILURE;
        }

    } while(FALSE); 

	// clear all stale events on CS8900.
	do
	{
		NdisRawReadPortUshort( (ULONG)&(g_pCS8900Reg->CS8900_ISQ), &InterruptEvent );
	} while (InterruptEvent & REG_NUM_MASK);

	// last thing done: enable the interrupt.
	EnablePBCInterrupt();


    if (ConfigHandle)
    {
        NdisCloseConfiguration(ConfigHandle);
    }

    if (Status == NDIS_STATUS_SUCCESS)
    {
        DEBUGMSG(ZONE_INIT, (TEXT("CS8900A:Initialize succeeded\n")));
    }
    else
    {
    
        if(g_pCS8900Reg != NULL)
        {
            VirtualFree((void *) g_pCS8900Reg, 0, MEM_RELEASE);
            g_pCS8900Reg = NULL;
        }

        if (pEthernet)
            NdisFreeMemory(pEthernet, sizeof(cs8900_t), 0);
    }

    DEBUGMSG(ZONE_INIT, (TEXT("CS8900A: -Cs8900aInitialize\r\n")));
    return Status;
}


//------------------------------------------------------------------------------
//
// Function: Cs8900aHalt
//
// This function is called when the driver is to remove itself.
//
// Parameters:
//      MiniportAdapterContext
//          [in] pointer to adapter.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
#pragma NDIS_PAGABLE_FUNCTION(Cs8900aHalt)
void Cs8900aHalt(IN NDIS_HANDLE MiniportAdapterContext)
{

    pCs8900_t pEthernet = ((pCs8900_t)(MiniportAdapterContext));
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aHalt\r\n")));

    pEthernet->CurrentState = NdisHardwareStatusClosing;
    // Disable interrupt
    InterruptChip(pEthernet, FALSE);

    NdisMDeregisterAdapterShutdownHandler(pEthernet->ndisAdapterHandle);

    NdisMDeregisterInterrupt(&(pEthernet->interruptObj));    

    pEthernet->CurrentState = NdisHardwareStatusNotReady;

    if(g_pCS8900Reg != NULL)
    {
        VirtualFree((void *) g_pCS8900Reg, 0, MEM_RELEASE);
        g_pCS8900Reg = NULL;
    }

    NdisFreeMemory( (PVOID)pEthernet, (UINT)sizeof(cs8900_t), 0);
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -Cs8900aHalt\r\n")));
    return;

}


//------------------------------------------------------------------------------
//
// Function: Cs8900aQueryInformation
//
// This function handles a query operation for a single OID.
//
// Parameters:
//      MiniportAdapterContext
//          [in] pointer to adapter.
//
//      Oid
//          [out] The OID of the query.
//
//      InformationBuffer
//          [in] Holds the result of the query.
//
//      InformationBufferLength
//          [in] Length of InformationBuffer.
//
//      BytesWritten
//          [out] If the call is successful, returns the number of bytes written 
//                to InformationBuffer.
//
//      BytesNeeded
//          [out] If there is not enough room in InformationBuffer to satisfy the OID, 
//                returns the amount of storage needed.
//
// Returns:
//      Returns NDIS_STATUS_SUCCESS if success. 
//      Return NDIS_STATUS_INVALID_LENGTH or NDIS_STATUS_INVALID_OID if not.
//
//------------------------------------------------------------------------------
NDIS_STATUS
Cs8900aQueryInformation(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN NDIS_OID Oid,
    IN PVOID InformationBuffer,
    IN ULONG InformationBufferLength,
    OUT PULONG BytesWritten,
    OUT PULONG BytesNeeded
    )

{
    NDIS_STATUS result = NDIS_STATUS_SUCCESS;
    UINT BytesLeft = InformationBufferLength;
    PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);

    // This variable holds result of query
    ULONG GenericULong;
    USHORT GenericUShort;
    UCHAR GenericArray[6];
    UINT MoveBytes = sizeof(ULONG);
    PVOID MoveSource = (PVOID)(&GenericULong);
    pCs8900_t pEthernet = ((pCs8900_t)(MiniportAdapterContext));

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aQueryInformation\r\n")));
    // Make sure that int is 4 bytes.  Else GenericULong must change
    // to something of size 4.
    ASSERT(sizeof(ULONG) == 4);

    // Switch on request type
    switch(Oid)
    {
        case OID_GEN_VENDOR_DRIVER_VERSION:
            GenericULong = (CS8900A_NDIS_MAJOR_VERSION << 16) + CS8900A_NDIS_MINOR_VERSION;
            break;

        case OID_GEN_SUPPORTED_LIST:
            MoveSource = (PVOID)(Cs8900aSupportedOids);
            MoveBytes = sizeof(Cs8900aSupportedOids);
            break;

        case OID_GEN_HARDWARE_STATUS:
            GenericULong = pEthernet->CurrentState;
            break;

        case OID_GEN_MEDIA_SUPPORTED:
        case OID_GEN_MEDIA_IN_USE:
            GenericULong = NdisMedium802_3;
            break;

        case OID_GEN_MEDIA_CONNECT_STATUS:
            GenericULong = UpdateMediaConnectStatus(pEthernet, pEthernet->MediaState);
            break;

        case OID_GEN_MAXIMUM_LOOKAHEAD:
            GenericULong = ETH_MAX_PACKET -ETHER_HDR_SIZE ;
            break;

        case OID_GEN_MAXIMUM_FRAME_SIZE:
            GenericULong = ETH_MAX_PACKET -ETHER_HDR_SIZE ;
            break;

        case OID_GEN_MAXIMUM_TOTAL_SIZE:
            GenericULong = ETH_MAX_PACKET;
            break;

        case OID_GEN_MAC_OPTIONS:
            GenericULong = (ULONG)(
                           NDIS_MAC_OPTION_TRANSFERS_NOT_PEND   |
                           NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
                           NDIS_MAC_OPTION_NO_LOOPBACK
                           );
            break;

        case OID_GEN_LINK_SPEED:
            GenericULong = 100000;    // 10 Mbps in 100 bps units
            break;

        case OID_GEN_TRANSMIT_BUFFER_SPACE:
            GenericULong = MAXIMUM_TRANSMIT_PACKET * ETH_MAX_PACKET;
            break;

        case OID_GEN_RECEIVE_BUFFER_SPACE:
            GenericULong = ETH_MAX_PACKET;
            break;

        case OID_GEN_TRANSMIT_BLOCK_SIZE:
            GenericULong = ETH_MAX_PACKET;
            break;

        case OID_GEN_RECEIVE_BLOCK_SIZE:
            GenericULong = ETH_MAX_PACKET;
            break;

        case OID_GEN_VENDOR_DESCRIPTION:
            MoveSource = (PVOID)"Crystal LAN(tm) CS8900 Ethernet Adapter";
            MoveBytes = 40;
            break;

        case OID_GEN_VENDOR_ID:
            NdisMoveMemory((PVOID)&GenericULong,
                            &(pEthernet->PermanentAddress),
                            (ULONG)ETHER_ADDR_SIZE);
            GenericULong &= 0xFFFFFF00;
            GenericULong |= 0x01;
            MoveSource = (PVOID)(&GenericULong);
            MoveBytes = sizeof(GenericULong);
            break;

        case OID_GEN_DRIVER_VERSION:
            GenericUShort = ((USHORT)CS8900A_NDIS_MAJOR_VERSION << 8) |
                                      CS8900A_NDIS_MINOR_VERSION;

            MoveSource = (PVOID)(&GenericUShort);
            MoveBytes = sizeof(GenericUShort);
            break;

        case OID_GEN_CURRENT_PACKET_FILTER:
            GenericULong = (ULONG)(pEthernet->PacketFilter);
            break;

        case OID_GEN_CURRENT_LOOKAHEAD:
            GenericULong = (ULONG)(pEthernet->CurrentLookAhead);
            break;

        case OID_GEN_XMIT_OK:
            GenericULong = (UINT)(pEthernet->FramesXmitGood);
            break;

        case OID_GEN_RCV_OK:
            GenericULong = (UINT)(pEthernet->FramesRcvGood);
            break;

        case OID_GEN_XMIT_ERROR:
            GenericULong = (UINT)(pEthernet->FramesXmitBad);
            break;

        case OID_GEN_RCV_ERROR:
            GenericULong = (UINT)(pEthernet->RcvErrors);
            break;

        case OID_GEN_RCV_NO_BUFFER:
            GenericULong = (UINT)(pEthernet->MissedPackets);
            break;

        case OID_802_3_PERMANENT_ADDRESS:
            NdisMoveMemory((PCHAR)GenericArray,
                    pEthernet->PermanentAddress,
                    (ULONG)ETHER_ADDR_SIZE);

            MoveSource = (PVOID)(GenericArray);
            MoveBytes = sizeof(pEthernet->PermanentAddress);
            break;

        case OID_802_3_CURRENT_ADDRESS:
            NdisMoveMemory((PCHAR)GenericArray,
                    pEthernet->CurrentAddress,
                    (ULONG)ETHER_ADDR_SIZE);

            MoveSource = (PVOID)(GenericArray);
            MoveBytes = sizeof(pEthernet->CurrentAddress);
            break;

        case OID_802_3_MULTICAST_LIST:
            MoveSource = (PVOID)(pEthernet->McastList);
            MoveBytes = pEthernet->NumMulticastAddressesInUse * ETHER_ADDR_SIZE;
            break;

        case OID_802_3_MAXIMUM_LIST_SIZE:
            GenericULong = MCAST_LIST_SIZE;
            break;

        case OID_802_3_RCV_ERROR_ALIGNMENT:
            GenericULong = (UINT)(pEthernet->FrameAlignmentErrors);
            break;

        case OID_802_3_XMIT_ONE_COLLISION:
            GenericULong = (UINT)(pEthernet->FramesXmitOneCollision);
            break;

        case OID_802_3_XMIT_MORE_COLLISIONS:
            GenericULong = (UINT)(pEthernet->FramesXmitManyCollisions);
            break;

        case OID_GEN_MAXIMUM_SEND_PACKETS:
            GenericULong = (UINT)(pEthernet->TxMaxCount);
            break;

        case OID_GEN_RCV_CRC_ERROR:
            GenericULong = (UINT)(pEthernet->RcvCRCErrors);
            break;

        case OID_GEN_TRANSMIT_QUEUE_LENGTH:
            GenericULong = 0L;
            break;

        case OID_802_3_XMIT_MAX_COLLISIONS:
            GenericULong = (UINT)(pEthernet->XmitMaxCollisions);
            break;

        case OID_802_3_RCV_OVERRUN:
            GenericULong = (UINT)(pEthernet->RcvOverrun);
            break;

        case OID_802_3_XMIT_UNDERRUN:
            GenericULong = (UINT)(pEthernet->XmitUnderrun);
            break;

        default:
            result = NDIS_STATUS_INVALID_OID;
            break;

    }


    if (result == NDIS_STATUS_SUCCESS) 
    {

        if (MoveBytes > BytesLeft) 
        {
            // Not enough room in InformationBuffer. 
            *BytesNeeded = MoveBytes;
            result = NDIS_STATUS_INVALID_LENGTH;
        } 
    else 
    {
            // Store result.
             NdisMoveMemory(InfoBuffer, MoveSource, MoveBytes);
            *BytesWritten = MoveBytes;
        }
    }
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -Cs8900aQueryInformation\r\n")));
    return result;
}

//------------------------------------------------------------------------------
//
// Function: Cs8900aReset
//
// The function instructs the driver to issue a hardware reset to the network adapter. 
// The driver also resets its software state.  See the description of MiniportMReset 
// for a detailed description of this request.
// No hardware function call to soft reset adapter as it will fail the CETK test in WINCE 4.2.
//
// Parameters:
//      AddressingReset
//          [out] Does the adapter need the addressing information reloaded?
//
//      MiniportAdapterContext
//          [in] pointer to adapter.
//
// Returns:
//      Returns NDIS_STATUS_SUCCESS if success. 
//
//------------------------------------------------------------------------------
NDIS_STATUS
Cs8900aReset(
    OUT PBOOLEAN AddressingReset,
    IN NDIS_HANDLE MiniportAdapterContext
    )
{

    PNDIS_PACKET pNdisPacket;
    pCs8900_t pEthernet = ((pCs8900_t)(MiniportAdapterContext));
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aReset\r\n")));

    pEthernet->CurrentState = NdisHardwareStatusReset;

    // Disable interrupt at the chip
    InterruptChip(pEthernet, FALSE);

    pEthernet->TransmitInProgress = FALSE;
    pEthernet->StartTX = FALSE;
    pEthernet->TransmitBidPending = FALSE;
    //
    // Remove the packet from the queue.
    //
    EnterCriticalSection (&gCS8900BufCs);
    pNdisPacket = pEthernet->HeadPacket;
    while(pNdisPacket != NULL)
    {
       pEthernet->HeadPacket = RESERVED(pNdisPacket)->Next;
       if (pNdisPacket == pEthernet->TailPacket) 
       {
            pEthernet->TailPacket = NULL;
       }
       NdisMSendComplete(pEthernet->ndisAdapterHandle, pNdisPacket, NDIS_STATUS_SUCCESS);
       pNdisPacket = pEthernet->HeadPacket;
    }
    LeaveCriticalSection (&gCS8900BufCs);
    *AddressingReset = TRUE;
    pEthernet->CurrentState = NdisHardwareStatusReady;

     // Enable interrupt at the chip
    InterruptChip(pEthernet, TRUE);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -Cs8900aReset\r\n")));
    return NDIS_STATUS_SUCCESS;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -