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

📄 chip.c

📁 IMX开发板
💻 C
📖 第 1 页 / 共 3 页
字号:
    for (i=MAX_RETRY; i>0; i--) {
        if (!(ReadCs8900Register(PKTPG_SELF_ST) & SELF_ST_SI_BUSY))
            break;
    }
    if (i <= 0) 
    {
        DEBUGMSG(ZONE_INIT, (TEXT("CS8900A readFromEEPROM:: Timeout0.\r\n")));
        return FALSE;
    }

    // Now write to EEPROM Command register 
    WriteCs8900Register(PKTPG_EEPROM_CMD, (EEPROM_CMD_READ | EEPROMAddress)); 

    // Wait for NO BUSY signal
    for (i=MAX_RETRY; i>0; i--)
    {
        if (!(ReadCs8900Register(PKTPG_SELF_ST) & SELF_ST_SI_BUSY))
            break;
    }
    if (i <= 0) 
    {
        DEBUGMSG(ZONE_INIT, (TEXT("CS8900A readFromEEPROM:: Timeout1.\r\n")));
        return FALSE;
    }

    // Get the data

    Value = ReadCs8900Register(PKTPG_EEPROM_DATA);
    DEBUGMSG(ZONE_INIT, (TEXT("CS8900A-readFromEEPROM (%x) value:%x\r\n"),EEPROMAddress, Value));

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

//------------------------------------------------------------------------------
//
// Function: InterruptChip
//
// This function enables or disables the interrupt of CS8900 chip
//
// Parameters:
//      pEthernet
//          [in] pointer to the CS8900 structure.
//
//      Action
//          [in] TRUE indicates interrupt enable. FALSE indicates interrupt disable.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void InterruptChip(pCs8900_t pEthernet, WORD Action)
{
    WORD Data;
  
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +InterruptChip\r\n")));

	EnterCriticalSection (&gCS8900RegCs);
    NdisRawWritePortUshort( (unsigned long)&(g_pCS8900Reg->CS8900_PAGE_POINTER), PKTPG_BUS_CTL );
    NdisRawReadPortUshort((unsigned long)&(g_pCS8900Reg->CS8900_PAGE_DATA_0), &Data);

    if(Action == TRUE)
    {
       NdisRawWritePortUshort((unsigned long)&(g_pCS8900Reg->CS8900_PAGE_DATA_0),(Data |IRQ_IE));
    }
    else
    {
       NdisRawWritePortUshort((unsigned long)&(g_pCS8900Reg->CS8900_PAGE_DATA_0),(Data & (~IRQ_IE)));
    }
	LeaveCriticalSection (&gCS8900RegCs);
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -InterruptChip\r\n")));
}

//------------------------------------------------------------------------------
//
// Function: UpdateMediaConnectStatus
//
// This function updates the status of media.
//
// Parameters:
//      pEthernet
//          [in] pointer to the CS8900 structure.
//
//      CurStatus
//          [in] Status of media.
//
// Returns:
//      Returns NDIS_STATUS_MEDIA_CONNECT if media is connected.
//      Returns NDIS_STATUS_MEDIA_DISCONNECT if media is disconnected.
//
//------------------------------------------------------------------------------
NDIS_STATUS UpdateMediaConnectStatus(pCs8900_t pEthernet, NDIS_STATUS CurStatus)
{
    WORD data;
    PNDIS_PACKET pNdisPacket;
    NDIS_STATUS Status;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +UpdateMediaConnectStatus\r\n")));
 
    data = ReadCs8900Register(PKTPG_LINE_ST);
    if(data & LSR_LINKOK)
    {
        pEthernet->MediaState = NdisMediaStateConnected;
        Status = NDIS_STATUS_MEDIA_CONNECT;

    }
    else
    {
        pEthernet->MediaState = NdisMediaStateDisconnected;
        Status = NDIS_STATUS_MEDIA_DISCONNECT;

    }

    if(CurStatus != pEthernet->MediaState)
    {
        if(CurStatus == NdisMediaStateConnected && pEthernet->MediaState == NdisMediaStateDisconnected)
        {
            RETAILMSG(1, (TEXT("cs8900a: PKTPG_LINE_ST: 0x%8x. removing the packet from queue in UpdateMediaConnectStatus. \r\n"), data));
            //
            // 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);
            
            
        }

        if ( pEthernet->CurrentState != NdisHardwareStatusInitializing )
        {
            NdisMIndicateStatus( pEthernet->ndisAdapterHandle, Status, NULL, 0 );
            NdisMIndicateStatusComplete( pEthernet->ndisAdapterHandle );
        }
    }
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -UpdateMediaConnectStatus\r\n")));
    return (pEthernet->MediaState);
}


//------------------------------------------------------------------------------
//
// Function: CalculateHashValue
//
// This function calculates the Hash value for multicasting.
//
// Parameters:
//      pAddr
//        [in] pointer to a ethernet address
//
// Returns:
//      Returns the calculated Hash value.
//
//------------------------------------------------------------------------------
UCHAR CalculateHashValue(UCHAR *pAddr)
{
    ULONG CRC;
    UCHAR HashValue;
    UCHAR AddrByte;
    int byte, j, DiscardBit;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +CalculateHashValue\r\n")));
    CRC = CRC_PRIME;

    for(byte=0; byte<ETHER_ADDR_SIZE; byte++)
    {
        AddrByte = *pAddr++;
        // calculation of CRC32 value based on straightfoward CRC implementation
        for(j=0; j<8; j++)
        {
            DiscardBit = ((CRC & 0x80000000) ? 0x01 : 0) ^ ((AddrByte >> j) & 0x01);
            CRC <<= 1;
            if(DiscardBit)
            {
                CRC ^=  CRC_POLYNOMIAL;
                CRC |= DiscardBit;
            }

        }
    }

    HashValue = 0;
    // Taking the 6 LSB of the CRC result and put it in reverse order
    for( j=0; j<6; j++ )
    {
        HashValue <<= 1;
        HashValue |= (UCHAR)((CRC>>j) & 1);
    }

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


}

//------------------------------------------------------------------------------
//
// Function: AddMultiCast
//
// This function adds the Hash value to the Hash table.
//
// Parameters:
//      pEthernet
//          [in] pointer to the CS8900 structure.
//
//      pAddr
//          [in] pointer to a ethernet address.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void AddMultiCast(pCs8900_t pEthernet, UCHAR *pAddr)
{
    UCHAR HashValue;
    WORD data;
    WORD HashTable[4];

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

    // Turn off the receiver
    data = ReadCs8900Register(PKTPG_LINE_CTL);
    data &= (~LCR_RX_ON);
    WriteCs8900Register(PKTPG_LINE_CTL, data);

    ReadMultiCastTable(pEthernet, HashTable);

    HashValue = CalculateHashValue(pAddr);
    HashTable[HashValue/16]  |=  1 << (HashValue%16);

    WriteMultiCastTable(pEthernet, HashTable);

    // Turn on the receiver
    data |= LCR_RX_ON;
    WriteCs8900Register(PKTPG_LINE_CTL, data);
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -AddMultiCast\r\n")));

}

//------------------------------------------------------------------------------
//
// Function: DeleteMultiCast
//
// This function delete the Hash value from the Hash table.
//
// Parameters:
//      pEthernet
//          [in] pointer to the CS8900 structure.
//
//      pAddr
//          [in] pointer to a ethernet address.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void DeleteMultiCast(pCs8900_t pEthernet, UCHAR *pAddr)
{
    UCHAR HashValue;
    WORD data;
    WORD HashTable[4];

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +DeleteMultiCast\r\n")));
 
    // Turn off the receiver
    data = ReadCs8900Register(PKTPG_LINE_CTL);
    data &= (~LCR_RX_ON);
    WriteCs8900Register(PKTPG_LINE_CTL, data);

    ReadMultiCastTable(pEthernet, HashTable);

    HashValue = CalculateHashValue(pAddr);
    HashTable[HashValue/16]   &=  (~(1 << (HashValue%16)));

    WriteMultiCastTable(pEthernet, HashTable);

    // Turn on the receiver
    data |= LCR_RX_ON;
    WriteCs8900Register(PKTPG_LINE_CTL, data);
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -DeleteMultiCast\r\n")));

}

//------------------------------------------------------------------------------
//
// Function: ReadMultiCastTable
//
// This function reads the Hash table.
//
// Parameters:
//      pEthernet
//          [in] pointer to the CS8900 structure.
//
//      pHashTable
//          [out] pointer to Hash table array.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void ReadMultiCastTable(pCs8900_t pEthernet, WORD *pHashTable)
{
    WORD Counter;
  
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +ReadMultiCastTable\r\n")));

    for(Counter=0; Counter < 4; Counter++)
    {
        *pHashTable = ReadCs8900Register(PKTPG_LOG_ADDR+Counter*2);
        pHashTable++;
    }
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -ReadMultiCastTable\r\n")));
}

//------------------------------------------------------------------------------
//
// Function: WriteMultiCastTable
//
// This function writes the Hash table.
//
// Parameters:
//      pEthernet
//          [in] pointer to the CS8900 structure.
//
//      pHashTable
//          [out] pointer to Hash table array.
//
// Returns:
//      None.

⌨️ 快捷键说明

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