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

📄 ne2000.c

📁 自制PDA系列之PCMCIA接口驱动(处理器PXA270)
💻 C
📖 第 1 页 / 共 4 页
字号:
        break;

    case OID_GEN_VENDOR_DESCRIPTION:

        MoveSource = (PVOID)"Novell 2000 Adapter.";
        MoveBytes = 21;

        break;

#else

    case OID_GEN_VENDOR_ID:

        NdisMoveMemory(
            (PVOID)&GenericULong,
            Adapter->PermanentAddress,
            3
            );
        GenericULong &= 0xFFFFFF00;
        GenericULong |= 0x01;
        MoveSource = (PVOID)(&GenericULong);
        MoveBytes = sizeof(GenericULong);
        break;

    case OID_GEN_VENDOR_DESCRIPTION:

        MoveSource = (PVOID)"Novell 1000 Adapter.";
        MoveBytes = 21;

        break;

#endif

    case OID_GEN_DRIVER_VERSION:

        GenericUShort = ((USHORT)NE2000_NDIS_MAJOR_VERSION << 8) |
                NE2000_NDIS_MINOR_VERSION;

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

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

    case OID_GEN_CURRENT_LOOKAHEAD:

        GenericULong = (ULONG)(Adapter->MaxLookAhead);
        break;

    case OID_802_3_PERMANENT_ADDRESS:

        NE2000_MOVE_MEM((PCHAR)GenericArray,
                    Adapter->PermanentAddress,
                    NE2000_LENGTH_OF_ADDRESS);

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

        break;

    case OID_802_3_CURRENT_ADDRESS:

        NE2000_MOVE_MEM((PCHAR)GenericArray,
                    Adapter->StationAddress,
                    NE2000_LENGTH_OF_ADDRESS);

        MoveSource = (PVOID)(GenericArray);
        MoveBytes = sizeof(Adapter->StationAddress);

        break;

    case OID_802_3_MULTICAST_LIST:
        MoveSource = (PVOID)(Adapter->Addresses);
		MoveBytes = Adapter->NumMulticastAddressesInUse * NE2000_LENGTH_OF_ADDRESS;
		break;

    case OID_802_3_MAXIMUM_LIST_SIZE:

        GenericULong = (ULONG) (Adapter->MulticastListMax);
        break;

    case OID_GEN_XMIT_OK:

        GenericULong = (UINT)(Adapter->FramesXmitGood);
        break;

    case OID_GEN_RCV_OK:

        GenericULong = (UINT)(Adapter->FramesRcvGood);
        break;

    case OID_GEN_XMIT_ERROR:

        GenericULong = (UINT)(Adapter->FramesXmitBad);
        break;

    case OID_GEN_RCV_ERROR:

        GenericULong = (UINT)(Adapter->CrcErrors);
        break;

    case OID_GEN_RCV_NO_BUFFER:

        GenericULong = (UINT)(Adapter->MissedPackets);
        break;

    case OID_802_3_RCV_ERROR_ALIGNMENT:

        GenericULong = (UINT)(Adapter->FrameAlignmentErrors);
        break;

    case OID_802_3_XMIT_ONE_COLLISION:

        GenericULong = (UINT)(Adapter->FramesXmitOneCollision);
        break;

    case OID_802_3_XMIT_MORE_COLLISIONS:

        GenericULong = (UINT)(Adapter->FramesXmitManyCollisions);
        break;

    default:

        StatusToReturn = NDIS_STATUS_INVALID_OID;
        break;

    }


    if (StatusToReturn == NDIS_STATUS_SUCCESS) {

        if (MoveBytes > BytesLeft) {

            //
            // Not enough room in InformationBuffer. 
            //

            *BytesNeeded = MoveBytes;

            StatusToReturn = NDIS_STATUS_INVALID_LENGTH;

        } else {

            //
            // Store result.
            //

            NE2000_MOVE_MEM(InfoBuffer, MoveSource, MoveBytes);

            (*BytesWritten) += MoveBytes;

        }
    }

    return StatusToReturn;
}

extern
NDIS_STATUS
Ne2000SetInformation(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN NDIS_OID Oid,
    IN PVOID InformationBuffer,
    IN ULONG InformationBufferLength,
    OUT PULONG BytesRead,
    OUT PULONG BytesNeeded
    )

/*++

Routine Description:

    NE2000SetInformation handles a set operation for a
    single OID.

Arguments:

    MiniportAdapterContext - Context registered with the wrapper, really
        a pointer to the adapter.

    Oid - The OID of the set.

    InformationBuffer - Holds the data to be set.

    InformationBufferLength - The length of InformationBuffer.

    BytesRead - If the call is successful, returns the number
        of bytes read from InformationBuffer.

    BytesNeeded - If there is not enough data in InformationBuffer
        to satisfy the OID, returns the amount of storage needed.

Return Value:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_PENDING
    NDIS_STATUS_INVALID_LENGTH
    NDIS_STATUS_INVALID_OID

--*/
{
    //
    // Pointer to the adapter structure.
    //
    PNE2000_ADAPTER Adapter = (PNE2000_ADAPTER)MiniportAdapterContext;

    //
    // General Algorithm:
    //
    //     Verify length
    //     Switch(Request)
    //        Process Request
    //

    UINT BytesLeft = InformationBufferLength;
    PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);

    //
    // Variables for a particular request
    //
    UINT OidLength;

    //
    // Variables for holding the new values to be used.
    //
    ULONG LookAhead;
    ULONG Filter;

    //
    // Status of the operation.
    //
    NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;


    DEBUGMSG(1,
        (TEXT("NE2000:SetInformation entered\n")));

    //
    // Get Oid and Length of request
    //
    OidLength = BytesLeft;

    switch (Oid) {

    case OID_802_3_MULTICAST_LIST:

        //
        // Verify length
        //
        if ((OidLength % NE2000_LENGTH_OF_ADDRESS) != 0){

            StatusToReturn = NDIS_STATUS_INVALID_LENGTH;

            *BytesRead = 0;
            *BytesNeeded = 0;

            break;

        }

        //
        // Set the new list on the adapter.
        //
        NdisMoveMemory(Adapter->Addresses, InfoBuffer, OidLength);
		Adapter->NumMulticastAddressesInUse = OidLength / NE2000_LENGTH_OF_ADDRESS;

        //
        //  If we are currently receiving all multicast or
        //  we are promiscuous then we DO NOT call this, or
        //  it will reset those settings.
        //
        if
        (
            !(Adapter->PacketFilter & (NDIS_PACKET_TYPE_ALL_MULTICAST |
                                       NDIS_PACKET_TYPE_PROMISCUOUS))
        )
        {
            StatusToReturn = DispatchSetMulticastAddressList(Adapter);
        }
        else
        {
            //
            //  Our list of multicast addresses is kept by the
            //  wrapper.
            //
            StatusToReturn = NDIS_STATUS_SUCCESS;
        }

        break;

    case OID_GEN_CURRENT_PACKET_FILTER:

        //
        // Verify length
        //

        if (OidLength != 4 ) {

            StatusToReturn = NDIS_STATUS_INVALID_LENGTH;

            *BytesRead = 0;
            *BytesNeeded = 0;

            break;

        }

        NE2000_MOVE_MEM(&Filter, InfoBuffer, 4);

        //
        // Verify bits
        //

        if (Filter & (NDIS_PACKET_TYPE_SOURCE_ROUTING |
              NDIS_PACKET_TYPE_SMT |
              NDIS_PACKET_TYPE_MAC_FRAME |
              NDIS_PACKET_TYPE_FUNCTIONAL |
              NDIS_PACKET_TYPE_ALL_FUNCTIONAL |
              NDIS_PACKET_TYPE_GROUP
             )) {

            StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;

            *BytesRead = 4;
            *BytesNeeded = 0;

            break;

        }

        //
        // Set the new value on the adapter.
        //
        Adapter->PacketFilter = Filter;
        StatusToReturn = DispatchSetPacketFilter(Adapter);
        break;

    case OID_GEN_CURRENT_LOOKAHEAD:

        //
        // Verify length
        //

        if (OidLength != 4) {

            StatusToReturn = NDIS_STATUS_INVALID_LENGTH;

            *BytesRead = 0;
            *BytesNeeded = 0;

            break;

        }

        //
        // Store the new value.
        //

        NE2000_MOVE_MEM(&LookAhead, InfoBuffer, 4);

        if (LookAhead <= NE2000_MAX_LOOKAHEAD) {
            Adapter->MaxLookAhead = LookAhead;
        } else {
            StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        }

        break;

    default:

        StatusToReturn = NDIS_STATUS_INVALID_OID;

        *BytesRead = 0;
        *BytesNeeded = 0;

        break;

    }


    if (StatusToReturn == NDIS_STATUS_SUCCESS) {

        *BytesRead = BytesLeft;
        *BytesNeeded = 0;

    }

    DEBUGMSG(1,
        (TEXT("NE2000:SetInformation done\n")));
    return(StatusToReturn);
}

NDIS_STATUS
DispatchSetPacketFilter(
    IN PNE2000_ADAPTER Adapter
    )

/*++

Routine Description:

    Sets the appropriate bits in the adapter filters
    and modifies the card Receive Configuration Register if needed.

Arguments:

    Adapter - Pointer to the adapter block

Return Value:

    The final status (always NDIS_STATUS_SUCCESS).

Notes:

  - Note that to receive all multicast packets the multicast
    registers on the card must be filled with 1's. To be
    promiscuous that must be done as well as setting the
    promiscuous physical flag in the RCR. This must be done
    as long as ANY protocol bound to this adapter has their
    filter set accordingly.

--*/


{
    //
    // See what has to be put on the card.
    //

    if
    (
        Adapter->PacketFilter & (NDIS_PACKET_TYPE_ALL_MULTICAST |
                                 NDIS_PACKET_TYPE_PROMISCUOUS)
    )
    {
        //
        // need "all multicast" now.
        //
        CardSetAllMulticast(Adapter);    // fills it with 1's
    }
    else
    {
        //
        // No longer need "all multicast".
        //
        DispatchSetMulticastAddressList(Adapter);
    }

    //
    // The multicast bit in the RCR should be on if ANY protocol wants
    // multicast/all multicast packets (or is promiscuous).
    //
    if
    (
        Adapter->PacketFilter & (NDIS_PACKET_TYPE_ALL_MULTICAST |
                                 NDIS_PACKET_TYPE_MULTICAST |
                                 NDIS_PACKET_TYPE_PROMISCUOUS)
    )
    {
        Adapter->NicReceiveConfig |= RCR_MULTICAST;
    }
    else
    {
        Adapter->NicReceiveConfig &= ~RCR_MULTICAST;
    }

    //
    // The promiscuous physical bit in the RCR should be on if ANY
    // protocol wants to be promiscuous.
    //
    if (Adapter->PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
    {
        Adapter->NicReceiveConfig |= RCR_ALL_PHYS;
    }
    else
    {
        Adapter->NicReceiveConfig &= ~RCR_ALL_PHYS;
    }

    //
    // The broadcast bit in the RCR should be on if ANY protocol wants
    // broadcast packets (or is promiscuous).
    //
    if
    (
        Adapter->PacketFilter & (NDIS_PACKET_TYPE_BROADCAST |
                                 NDIS_PACKET_TYPE_PROMISCUOUS)
    )
    {
        Adapter->NicReceiveConfig |= RCR_BROADCAST;
    }
    else
    {
        Adapter->NicReceiveConfig &= ~RCR_BROADCAST;
    }

    CardSetReceiveConfig(Adapter);

    return(NDIS_STATUS_SUCCESS);
}



NDIS_STATUS
DispatchSetMulticastAddressList(
    IN PNE2000_ADAPTER Adapter
    )

/*++

Routine Description:

    Sets the multicast list for this open

Arguments:

    Adapter - Pointer to the adapter block

Return Value:

    NDIS_STATUS_SUCESS

Implementation Note:

    When invoked, we are to make it so that the multicast list in the filter
    package becomes the multicast list for the adapter. To do this, we
    determine the required contents of the NIC multicast registers and
    update them.


--*/
{
    //
    // Update the local copy of the NIC multicast regs and copy them to the NIC
    //
    CardFillMulticastRegs(Adapter);
    CardCopyMulticastRegs(Adapter);

    return NDIS_STATUS_SUCCESS;
}

⌨️ 快捷键说明

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