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

📄 cs8900a.c

📁 IMX开发板
💻 C
📖 第 1 页 / 共 3 页
字号:
//------------------------------------------------------------------------------
//
// Function: Cs8900aSend
//
// This function handles transmission of packet through adapter into the medium.
//
// Parameters:
//      MiniportAdapterContext
//          [in] pointer to adapter.
//
//      Packet
//          [in] pointer to a descriptor for the packet that is to be transmitted.
//
//      SendFlags
//          [in] optional send flags.
//
// Returns:
//      Returns NDIS_STATUS_PENDING if success. 
//      Returns NDIS_STATUS_FAILURE if bad frame encountered.
//
//------------------------------------------------------------------------------
NDIS_STATUS Cs8900aSend(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN PNDIS_PACKET Packet,
    IN UINT SendFlags
    )

{
    UINT PacketLength;
    pCs8900_t pEthernet = ((pCs8900_t)(MiniportAdapterContext));

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aSend\r\n")));
    NdisQueryPacket( Packet,NULL,NULL,NULL,&PacketLength);

    if ( (PacketLength > ETH_MAX_PACKET) ||(PacketLength < ETH_MIN_FRAME)) 
    {
        pEthernet->FramesXmitBad++;
        return NDIS_STATUS_FAILURE;
    }

     // Put the packet on the send queue.
    EnterCriticalSection (&gCS8900BufCs);
    if (pEthernet->HeadPacket == NULL)
    {
        pEthernet->HeadPacket = Packet;
    } 
    else 
    {
        RESERVED(pEthernet->TailPacket)->Next = Packet;
    }

    RESERVED(Packet)->Next = NULL;

    pEthernet->TailPacket = Packet;
    LeaveCriticalSection (&gCS8900BufCs);
   // check whether is there transmission going on

   if (!(pEthernet->TransmitInProgress)) 
   {
        pEthernet->TransmitInProgress = TRUE;
        // check whether is the chip ready for transmission
        if ( CheckReadyForTransmit(pEthernet) == TRUE ) 
        {
            TransferPacketToChip(pEthernet);
        }
     } 
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -Cs8900aSend\r\n")));
    return NDIS_STATUS_PENDING;
}

//------------------------------------------------------------------------------
//
// Function: Cs8900aTransferData
//
// A protocol calls the Cs8900aTransferData request (indirectly via NdisTransferData) 
// from within its Receive event handler to instruct the driver to copy the 
// contents of the received packet.
//
// Parameters:
//      Packet
//          [out] A pointer to a descriptor for the packet storage into which
//                the MAC is to copy the received packet.
//
//      BytesTransferred
//          [out] A pointer to an unsigned integer.  The MAC writes the actual number 
//                of bytes transferred into this location.  This value is not valid 
//                if the return status is STATUS_PENDING.
//
//      MiniportAdapterContext
//          [in] Context registered with the wrapper, a pointer to adapter.
//
//      MiniportReceiveContext
//          [in] The context value passed by the driver on its call to NdisMEthIndicateReceive.
//               The driver can use this value to determine which packet, 
//               on which adapter, is being received.
//
//      ByteOffset
//          [in] An unsigned integer specifying the offset within the received packet 
//               at which the copy is to begin.  If the entire packet is to be copied, 
//               ByteOffset must be zero.
//
//      BytesTransfered
//          [in] A pointer to an unsigned integer.  The MAC writes the actual number of bytes 
//               transferred into this location.  This value is not valid if the return status 
//               is STATUS_PENDING.
//
// Returns:
//      Returns NDIS_STATUS_SUCCESS if success. 
//      Return NDIS_STATUS_FAILURE if not.
//
//------------------------------------------------------------------------------
NDIS_STATUS
Cs8900aTransferData(
    OUT PNDIS_PACKET  Packet,
    OUT PUINT  BytesTransferred,
    IN NDIS_HANDLE MiniportAdapterContext,
    IN NDIS_HANDLE MiniportReceiveContext,
    IN UINT  ByteOffset,
    IN UINT  BytesToTransfer
    )

{
    PNDIS_BUFFER  pCurrentBuffer;
    UINT   BufferLength;
    PUCHAR pBufferSource;
    PUCHAR pBufferStart;
    UINT   BytesWanted, BytesCopied, BytesLeft;
    ULONG  PacketSize;

    // The adapter to transfer from.
    pCs8900_t pEthernet = ((pCs8900_t)(MiniportReceiveContext));
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aTransferData\r\n")));
    // Add the packet header onto the offset.
    ByteOffset += ETHER_HDR_SIZE;
    pBufferSource = pEthernet->ReceiveBuffer+ByteOffset;
    PacketSize = pEthernet->ReceivePacketSize;

    if ((BytesToTransfer==0) || ByteOffset >= PacketSize ) 
    {
         *BytesTransferred = 0;
         return NDIS_STATUS_FAILURE;
    } 

    NdisQueryPacket( Packet, NULL, NULL, &pCurrentBuffer, NULL);
    NdisQueryBuffer( pCurrentBuffer, &pBufferStart, &BufferLength);

    *BytesTransferred = 0;
    BytesWanted   = 0;
    BytesCopied = 0;
    BytesLeft=BytesToTransfer;
    do{

        if(!BufferLength)
        {
            NdisGetNextBuffer(pCurrentBuffer, &pCurrentBuffer);
            NdisQueryBuffer( pCurrentBuffer, &pBufferStart, &BufferLength);
        }

        if(BufferLength>BytesLeft)  // PacketSize == ByteToTransfer
        {
            BytesCopied +=BytesLeft;
            BytesWanted = BytesLeft;
        }
        else
        {
            BytesCopied += BufferLength;
            BytesWanted = BufferLength;
            BufferLength = 0;
        }

        NdisMoveMemory(  pBufferStart, pBufferSource, BytesWanted );
        pBufferStart += BytesWanted;
        pBufferSource += BytesWanted;
        BytesLeft -= BytesWanted;

    }while(BytesCopied<BytesToTransfer);

    *BytesTransferred=BytesCopied;

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

//------------------------------------------------------------------------------
//
// Function: Cs8900aSetInformation
//
// This function handles a set operation for a single OID.
//
// Parameters:
//      MiniportAdapterContext
//          [in] pointer to adapter.
//
//      Oid
//          [out] The OID of the set.
//
//      InformationBuffer
//          [in] Holds the data to be set.
//
//      InformationBufferLength
//          [in] Length of InformationBuffer.
//
//      BytesRead
//          [out] If the call is successful, returns the number of bytes read 
//                from InformationBuffer.
//
//      BytesNeeded
//          [out] If there is not enough data 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 or 
//      NDIS_STATUS_MULTICAST_FULL or NDIS_STATUS_NOT_SUPPORTED if not.
//
//------------------------------------------------------------------------------
NDIS_STATUS
Cs8900aSetInformation(
    IN NDIS_HANDLE MiniportAdapterContext,
    IN NDIS_OID Oid,
    IN PVOID InformationBuffer,
    IN ULONG InformationBufferLength,
    OUT PULONG BytesRead,
    OUT PULONG BytesNeeded
    )

{
    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;
    pCs8900_t pEthernet = ((pCs8900_t)(MiniportAdapterContext));

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aSetInformation\r\n")));

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


    switch (Oid) 
    {
        case OID_802_3_MULTICAST_LIST:
         // Verify length
            if ((OidLength % ETHER_ADDR_SIZE) != 0)
            {
                StatusToReturn = NDIS_STATUS_INVALID_DATA;
                *BytesRead = 0;
                *BytesNeeded = 0;
                break;

            }
            else
            {   // Ensure that the multi cast list is not full yet
                if(OidLength <= (MCAST_LIST_SIZE * ETHER_ADDR_SIZE))
                {
                    // Get the multicast address and update CS8900A
                    NdisMoveMemory(pEthernet->McastList, InfoBuffer, OidLength);
                    *BytesRead = OidLength;
                    pEthernet->NumMulticastAddressesInUse = OidLength / ETHER_ADDR_SIZE;

                    // clear all the value in Hash Table
                    ClearAllMultiCast(pEthernet);

                    // Add the hash table value according to the multicast address
                    for(LookAhead=0; LookAhead < pEthernet->NumMulticastAddressesInUse; LookAhead++)
                    {
                        AddMultiCast(pEthernet, &(pEthernet->McastList[LookAhead][0]));
                    }

                }
                else
                {
                    *BytesRead = 0;
                    StatusToReturn = NDIS_STATUS_MULTICAST_FULL;
                }
            }
            break;
        case OID_GEN_CURRENT_PACKET_FILTER:
                // Verify length
                if (OidLength != 4 ) 
                {
                    StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
                    *BytesRead = 0;
                    *BytesNeeded = 0;
                    break;
                }

                NdisMoveMemory((PUCHAR)&Filter, (PUCHAR)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 |
                                NDIS_PACKET_TYPE_ALL_MULTICAST | // Fails Cert test
                                NDIS_PACKET_TYPE_ALL_LOCAL // No Loopback!
                                )) 
                {
                    StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
                    *BytesRead = 4;
                    *BytesNeeded = 0;
                }
                else
                {
                    // Set the new value on the adapter.
                    pEthernet->PacketFilter = Filter;
                    if(Filter & NDIS_PACKET_TYPE_MULTICAST )
                    {
                        // clear all the value in Hash Table
                        ClearAllMultiCast(pEthernet);
                        // Add the hash table value according to the multicast address
                        for(LookAhead=0; LookAhead < pEthernet->NumMulticastAddressesInUse; LookAhead++)
                        {
                            AddMultiCast(pEthernet, &(pEthernet->McastList[LookAhead][0]));
                        }

                    }
                    SetFilterType(pEthernet);
                    StatusToReturn = NDIS_STATUS_SUCCESS;
                }
                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.
            NdisMoveMemory(&LookAhead, InfoBuffer, 4);
            if (LookAhead <= (ETH_MAX_PACKET -ETHER_HDR_SIZE) ) 
            {
                pEthernet->CurrentLookAhead= LookAhead;
            }
            else 
            {
                StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
            }
            break;

        case OID_GEN_PROTOCOL_OPTIONS:

            break;

        default:

            *BytesRead = 0;
            *BytesNeeded = 0;
            return NDIS_STATUS_INVALID_OID;
            break;
    }

   DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -Cs8900aSetInformation [0x%.8X]\r\n"), StatusToReturn));
   return(StatusToReturn);
}



//------------------------------------------------------------------------------
//
// Function: Cs8900aShutdown
//
// This function handles proper shutdown.
//
// Parameters:
//      MiniportAdapterContext
//          [in] pointer to adapter.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void Cs8900aShutdown(IN NDIS_HANDLE MiniportAdapterContext)
{
    pCs8900_t pEthernet = ((pCs8900_t)(MiniportAdapterContext));
    //MiniportShutdown should call no NdisXXX functions.
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aShutdown\r\n")));

    pEthernet->CurrentState = NdisHardwareStatusNotReady;
	  
    DeleteCriticalSection (&gCS8900RegCs);
	  DeleteCriticalSection (&gCS8900BufCs);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -Cs8900aShutdown\r\n")));
    return;

}

//------------------------------------------------------------------------------
//
// Function: Cs8900aCheckForHang
//
// This function checks for media connection status.
//
// Parameters:
//      MiniportAdapterContext
//          [in] pointer to adapter.
//
// Returns:
//      return TRUE if it detects that the network adapter is not operating correctly.
//      return FALSE if the asapter is operating correctly.
//
//------------------------------------------------------------------------------
BOOLEAN Cs8900aCheckForHang(IN NDIS_HANDLE MiniportAdapterContext)
{
    pCs8900_t pEthernet = ((pCs8900_t)(MiniportAdapterContext));
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +Cs8900aCheckForHang\r\n")));

    pEthernet->MediaState = UpdateMediaConnectStatus(pEthernet, pEthernet->MediaState);

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


⌨️ 快捷键说明

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