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

📄 chip.c

📁 IMX开发板
💻 C
📖 第 1 页 / 共 3 页
字号:
//
//------------------------------------------------------------------------------
void WriteMultiCastTable(pCs8900_t pEthernet, WORD *pHashTable)
{
    WORD Counter;

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

//------------------------------------------------------------------------------
//
// Function: SetAllMultiCastTable
//
// This function sets the Hash table.
//
// Parameters:
//      pEthernet
//          [in] pointer to the CS8900 structure.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void SetAllMultiCastTable(pCs8900_t pEthernet)
{
    WORD HashTable[4] = {0xffff,0xffff,0xffff,0xffff};
    WORD data;
  
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +SetAllMultiCastTable\r\n")));
 
    // Turn off the receiver
    data = ReadCs8900Register(PKTPG_LINE_CTL);
    data &= (~LCR_RX_ON);
    WriteCs8900Register(PKTPG_LINE_CTL, data);

    WriteMultiCastTable(pEthernet, HashTable);

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

//------------------------------------------------------------------------------
//
// Function: ClearAllMultiCast
//
// This function clears the Hash table.
//
// Parameters:
//      pEthernet
//          [in] pointer to the CS8900 structure.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void ClearAllMultiCast(pCs8900_t pEthernet)
{
    WORD HashTable[4] = {0, 0, 0, 0};
    WORD data;
  
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +ClearAllMultiCast\r\n")));
 
    // Turn off the receiver
    data = ReadCs8900Register(PKTPG_LINE_CTL);
    data &= (~LCR_RX_ON);
    WriteCs8900Register(PKTPG_LINE_CTL, data);

    WriteMultiCastTable(pEthernet, HashTable);

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

}

//------------------------------------------------------------------------------
//
// Function: SetFilterType
//
// This function sets the filter type for CS8900 chip.
//
// Parameters:
//      pEthernet
//          [in] pointer to the CS8900 structure.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void SetFilterType(pCs8900_t pEthernet)
{
    WORD LineData, FilterData;
    ULONG Filter;

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

    // Get the current filter settings from structure
    FilterData = ReadCs8900Register(PKTPG_RX_CTL);

    // Clear broadcast, multicast and promiscuous bits
    FilterData &= ~(RX_CTL_MCAST_A | RX_CTL_IND_A|RX_CTL_BCAST_A|
                    RX_CTL_PROM_A);

    Filter = pEthernet->PacketFilter;
    if(Filter & NDIS_PACKET_TYPE_DIRECTED)
    {
        FilterData |= RX_CTL_IND_A;

    }
    if(Filter & NDIS_PACKET_TYPE_BROADCAST)
    {
        FilterData |= RX_CTL_BCAST_A;
    }
    if(Filter & NDIS_PACKET_TYPE_MULTICAST)
    {
        FilterData |= RX_CTL_MCAST_A;
    }
    if(Filter & NDIS_PACKET_TYPE_PROMISCUOUS)
    {
        FilterData |= RX_CTL_PROM_A;
    }

    // Update the filtering in the CS8900A
    WriteCs8900Register(PKTPG_RX_CTL, FilterData);

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

}

//------------------------------------------------------------------------------
//
// Function: CheckReadyForTransmit
//
// This function checks CS8900 chip for ready to transmit.
//
// Parameters:
//      pEthernet
//          [in] pointer to the CS8900 structure.
//
// Returns:
//      Returns TRUE if ready for transmit. Returns FALSE if not ready.
//
//------------------------------------------------------------------------------
WORD CheckReadyForTransmit(pCs8900_t pEthernet)
{
    WORD Data;
    UINT PacketSize;
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +CheckReadyForTransmit\r\n")));
 
    // Have to do as outlined in datasheet pg 102

    // Write the transmit command into the transmit command request register
    NdisRawWritePortUshort( (unsigned long)&(g_pCS8900Reg->CS8900_TX_CMD), TX_CMD_START_1021 );

    // Get the packet size of the packet from the head of the queue
    NdisQueryPacket(pEthernet->HeadPacket, NULL, NULL, NULL, &PacketSize);

    // Write the packet length into the Transmit Length I/O register of CS8900A
    NdisRawWritePortUshort( (unsigned long)&(g_pCS8900Reg->CS8900_TX_LENGTH), (WORD)PacketSize );


    Data = ReadCs8900Register(PKTPG_BUS_ST);

    if(Data & BUS_ST_TX_BID_ERR)
    {
        pEthernet->StartTX = TRUE;      // Better start another TX at end of next interrupt
                                        // Assumes Receives are cause of bid failure
        return FALSE;
    }

    if(Data & BUS_ST_RDY4TXNOW) 
    {
        return TRUE;
    }
    else
    {
        pEthernet->TransmitBidPending = TRUE;
    }
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -CheckReadyForTransmit\r\n")));
    return FALSE;
}

//------------------------------------------------------------------------------
//
// Function: TransferPacketToChip
//
// This function transfer the packet to CS8900 chip.
//
// Parameters:
//      pEthernet
//          [in] pointer to the CS8900 structure.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void TransferPacketToChip(pCs8900_t pEthernet)
{
    // Packet size of the packet
    UINT PacketSize;
    PNDIS_BUFFER pNDISBuffer;

    // Current counter for number of bytes copying
    DWORD CurrentBytes = 0;

    // This flag indicates that an odd byte is to be transferred in the previous
    // fragment which is to be transferred with a byte from next fragment

    WORD OddWordFlag   = FALSE;

    // The variable to store the odd byte to be transferred with the next
    // fragment.

    WORD OddWordValue   = 0;

    // Holds the virtual address of the current buffer.
    PUCHAR CurrentBufAddress;


    // Holds the length of the current buffer of the packet.
    DWORD BufferLength;
    // temporary location for odd starting address data
    WORD TmpWord, i;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: +TransferPacketToChip\r\n")));
    
    // check whether the first packet is NULL 
    if(pEthernet->HeadPacket==NULL)
    {
        return;
    }
    // Get the length of the packet and the pointer to NDIS Buffer
    NdisQueryPacket(pEthernet->HeadPacket, NULL, NULL, &pNDISBuffer, &PacketSize);

    NdisQueryBuffer(pNDISBuffer,(PVOID *)&CurrentBufAddress,&BufferLength);

    while (pNDISBuffer && (BufferLength == 0 || CurrentBufAddress == NULL)) 
    {
        NdisGetNextBuffer(pNDISBuffer, &pNDISBuffer);
        NdisQueryBuffer(pNDISBuffer, (PVOID *)&CurrentBufAddress, &BufferLength);
    }


    if(CurrentBufAddress)
    {

        do{ // do while there is valid pNDISBuffer pointer

            // check for OddWordFlag 
            if(OddWordFlag) 
            {
                OddWordValue |= ((USHORT)(*CurrentBufAddress)) << 8;
                NdisRawWritePortUshort((unsigned long)&(g_pCS8900Reg->CS8900_RX_TX_DATA_0), OddWordValue);
                BufferLength--;
                OddWordFlag = FALSE;
                OddWordValue=0;
                CurrentBufAddress++;    
            }

            // check for starting odd address
            if ( ((ULONG)CurrentBufAddress & 0x1) != 0)
            {
                for (i=0; i < BufferLength/2; i++) 
                {
                    // for ARM 16 bit data-write alignment
                    // CurrentBufAddress may not point to a 16 bit boundary address.  Use 
                    // memcpy() to move data from unaligned memory to aligned memory.
                    // It works since memcpy() casts pointers it copies to char*
                    memcpy(&TmpWord, (WORD*)CurrentBufAddress, min(BufferLength,sizeof(WORD)));
                    NdisRawWritePortUshort((unsigned long)&(g_pCS8900Reg->CS8900_RX_TX_DATA_0), TmpWord);
                    ((WORD*)CurrentBufAddress)++;

                } // end for
            } // end if
            else 
            {
                for (i=0; i < BufferLength/2; i++)
                {
                   NdisRawWritePortUshort((unsigned long)&(g_pCS8900Reg->CS8900_RX_TX_DATA_0), *((PWORD)CurrentBufAddress)++);
                } // end for
            }// end else

            // check for odd buffer length
            if ( BufferLength % 2 == 1 ) 
            {

                // Store the byte from the current fragment to be transmitted
                // with the next fragment and set the odd_bytes flag.
                OddWordValue = *((PUCHAR)CurrentBufAddress);
                OddWordFlag  = TRUE;
            }

            // Move to the next buffer
            NdisGetNextBuffer(pNDISBuffer, &pNDISBuffer);

            if (pNDISBuffer)
            {
                NdisQueryBuffer(pNDISBuffer, (PVOID *)&CurrentBufAddress, &BufferLength);
            }

            // Get address and length of the next buffer
            while (pNDISBuffer && (BufferLength == 0 || CurrentBufAddress == NULL)) 
            {
                NdisGetNextBuffer(pNDISBuffer, &pNDISBuffer);
                if (pNDISBuffer)
                {
                    NdisQueryBuffer(pNDISBuffer, (PVOID *)&CurrentBufAddress, &BufferLength);
                }
            }
        }while(pNDISBuffer);

        // check for extra odd byte
        if(OddWordFlag) 
        {
           NdisRawWritePortUshort((unsigned long)&(g_pCS8900Reg->CS8900_RX_TX_DATA_0), OddWordValue );
        }

    }
    DEBUGMSG(ZONE_FUNCTION, (TEXT("CS8900A: -TransferPacketToChip\r\n")));
}

⌨️ 快捷键说明

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