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

📄 card.c

📁 Wince4.2 BSP for SH4 engineering development board
💻 C
📖 第 1 页 / 共 2 页
字号:
    The 32-bit CRC value.

Note:

    This is adapted from the comments in the assembly language
    version in _GENREQ.ASM of the DWB NE1000/2000 driver.

--*/

{
    ULONG Crc, Carry;
    UINT i, j;
    UCHAR CurByte;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("+CELAN:CardComputeCrc\r\n")));

    Crc = 0xffffffff;

    for (i = 0; i < Length; i++) {

        CurByte = Buffer[i];

        for (j = 0; j < 8; j++) {

            Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);

            Crc <<= 1;

            CurByte >>= 1;

            if (Carry) {

                Crc = (Crc ^ 0x04c11db6) | Carry;

            }

        }

    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("-CELAN:CardComputeCrc\r\n")));

    return Crc;
}


VOID
CardGetMulticastBit(
    IN UCHAR Address[CELAN_LENGTH_OF_ADDRESS],
    OUT UCHAR * Byte,
    OUT UCHAR * Value
    )

/*++

Routine Description:

    For a given multicast address, returns the byte and bit in
    the card multicast registers that it hashes to. Calls
    CardComputeCrc() to determine the CRC value.

Arguments:

    Address - the address

    Byte - the byte that it hashes to

    Value - will have a 1 in the relevant bit

Return Value:

    None.

--*/

{
    ULONG Crc;
    UINT BitNumber;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("91C94:+CardGetMulticastBit\r\n")));

    //
    // First compute the CRC.
    //

    Crc = CardComputeCrc(Address, CELAN_LENGTH_OF_ADDRESS);


    //
    // The bit number is now in the 6 most significant bits of CRC.
    //

    BitNumber = (UINT)((Crc >> 26) & 0x3f);

    *Byte = (UCHAR)(BitNumber / 8);
    *Value = (UCHAR)((UCHAR)1 << (BitNumber % 8));

    DEBUGMSG(ZONE_FUNCTION, (TEXT("91C94:-CardGetMulticastBit\r\n")));
}

VOID
CardFillMulticastRegs(
    IN PCELAN_ADAPTER Adapter
    )

/*++

Routine Description:

    Erases and refills the card multicast registers. Used when
    an address has been deleted and all bits must be recomputed.

Arguments:

    Adapter - pointer to the adapter block

Return Value:

    None.

--*/

{
    UINT i;
    UCHAR Byte, Bit;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("91C94:+CardFillMulticastRegs\r\n")));

    //
    // First turn all bits off.
    //

    for (i=0; i<8; i++) {

        Adapter->NicMulticastRegs[i] = 0;

    }

    //
    // Now turn on the bit for each address in the multicast list.
    //

    for ( ; i > 0; ) {

        i--;

        CardGetMulticastBit(Adapter->Addresses[i], &Byte, &Bit);

        Adapter->NicMulticastRegs[Byte] |= Bit;

    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("91C94:-CardFillMulticastRegs\r\n")));

}

BOOLEAN
SyncCardCopyMulticastRegs(
    IN PVOID SynchronizeContext
    )

/*++

Routine Description:

    Sets the eight bytes in the card multicast registers.

Arguments:

    SynchronizeContext - pointer to the adapter block

Return Value:

    None.

--*/

{
    PCELAN_ADAPTER Adapter = ((PCELAN_ADAPTER)SynchronizeContext);
    UINT i;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("91C94:+CardCopyMulticastRegs\r\n")));

    SelectBank(BANK3);

    for (i=0; i<8; i+=2) {
        WriteWord(MULTICAST1+i, Adapter->NicMulticastRegs[i] |
                    Adapter->NicMulticastRegs[i+1]<<8 );
    }
    DEBUGMSG(ZONE_FUNCTION, (TEXT("Multicast bits\r\n")));
    for (i=0; i<8; i++) {
        DEBUGMSG(ZONE_FUNCTION, (TEXT("%02x "),Adapter->NicMulticastRegs[i]));
    }
    DEBUGMSG(ZONE_FUNCTION, (TEXT("\r\n")));

    PrintRegs;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("91C94:-CardCopyMulticastRegs\r\n")));
    return FALSE;
}


//++
//
// VOID
// CardStart(
//    IN PCELAN_ADAPTER Adapter
//    )
//
//
// Routine Description:
//
//    Starts the card.
//
// Arguments:
//
//    Adapter - pointer to the adapter block
//
// Return Value:
//
//    None.
//
//--
#pragma NDIS_PAGEABLE_FUNCTION(CardStart)
VOID CardStart(IN PCELAN_ADAPTER Adapter)
{
    DEBUGMSG(ZONE_FUNCTION, (TEXT("+CELAN:CardStart\r\n")));

    // Initialize trasmit control register
    DEBUGMSG(ZONE_INIT, (TEXT("91C94:CardStart\r\n")));
    SelectBank(BANK0);
    WriteWord(TCR,TCR_PAD_ENABLE|TCR_ENABLE);

    //
    // Set Receive Mode
    //
    DEBUGMSG(ZONE_INIT, (TEXT("91C94:Init Receive config register\r\n")));
    SelectBank(BANK0);
    WriteWord(RCR,Adapter->NicReceiveConfig);

    LAN91C111Init();
    RETAILMSG(1,(TEXT("CELAN : Initialze LAN91C111 Done\r\n")));

    // PrintRegs;
    DEBUGMSG(ZONE_FUNCTION, (TEXT("-CELAN:CardStart\r\n")));
}

#pragma NDIS_PAGEABLE_FUNCTION(CardBlockInterrupts)
VOID CardBlockInterrupts(IN PCELAN_ADAPTER Adapter)
{
    WORD    Bank;
    DEBUGMSG(ZONE_INTR,(TEXT("CardBlockInterrupt INT_REG : %04x\r\n"),Adapter->NicInterruptMask));
    Bank = ReadWord(BANK_SELECT);
    SelectBank(BANK2);
    WriteWord(INT_REG,0);

    WRITE_PHY(19,0xFFFF);
    DEBUGMSG(ZONE_INTR,(TEXT("Set Link detect interrupt to Phy regs.\r\n")));
    
    SelectBank(Bank);
}

#pragma NDIS_PAGEABLE_FUNCTION(CardUnblockInterrupts)
VOID CardUnblockInterrupts(IN PCELAN_ADAPTER Adapter)
{
    WORD    Bank;
    DEBUGMSG(ZONE_INTR,(TEXT("CardUnblockInterrupt INT_REG : %04x\r\n"),Adapter->NicInterruptMask));
    Bank = ReadWord(BANK_SELECT);
    SelectBank(BANK2);
    WriteWord(INT_REG,Adapter->NicInterruptMask);

    WRITE_PHY(19,0x3FC0);
    DEBUGMSG(ZONE_INTR,(TEXT("Set Link detect interrupt to Phy regs.\r\n")));

    SelectBank(Bank);
}

#pragma NDIS_PAGEABLE_FUNCTION(CardGetInterruptStatus)
VOID CardGetInterruptStatus(
    IN PCELAN_ADAPTER Adapter,
    OUT PUCHAR pInterruptStatus
            )
{
    SelectBank(BANK2);
    *pInterruptStatus = (UCHAR)ReadWord(INT_REG);
}


BOOLEAN
SyncCardSetReceiveConfig(
    IN PVOID SynchronizeContext
    )

/*++

Routine Description:

    Sets the value of the "receive configuration" NIC register to
    the value of Adapter->NicReceiveConfig.

Arguments:

    SynchronizeContext - pointer to the adapter block

Return Value:

    None.

--*/

{
    PCELAN_ADAPTER Adapter = ((PCELAN_ADAPTER)SynchronizeContext);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("91C94:+SyncCardSetReceiveConfig\r\n")));

    SelectBank(BANK0);
    WriteWord(RCR,Adapter->NicReceiveConfig);

    DEBUGMSG(ZONE_FUNCTION, (TEXT("91C94:-SyncCardSetReceiveConfig\r\n")));

    return FALSE;

}

BOOLEAN
SyncCardSetAllMulticast(
    IN PVOID SynchronizeContext
    )

/*++

Routine Description:

    Turns on all the bits in the multicast register. Used when
    the card must receive all multicast packets.

Arguments:

    SynchronizeContext - pointer to the adapter block

Return Value:

    None.

--*/

{
    PCELAN_ADAPTER Adapter = ((PCELAN_ADAPTER)SynchronizeContext);
    UINT i;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("91C94:+CardSetAllMulticast\r\n")));

    SelectBank(BANK3);
    for (i=0; i<8; i+=2) {
        WriteWord(MULTICAST1+i, 0xffff);
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("91C94:-CardSetAllMulticast\r\n")));

    return FALSE;

}


void LAN91C111Init()
{
    unsigned short capability;
    unsigned long AutoNegotiationTimeOver;

    WriteWord(0x0e,0x3301);
    WriteWord(0x00,0xB0B1);
    WriteWord(0x0e,0x3303);

    RETAILMSG(1,(TEXT("+Product Ethernet Driver Initialize\r\n")));

    PHYDiag();

    RETAILMSG(1,(TEXT("Try Auto Negotiation.......\r\n")));
    
    WriteWord(0x0e,0x3300);
    WriteWord(0x00,0x0081);
    WriteWord(0x0a,0x0800);

    AutoNegotiationTimeOver = 0;
    capability =0;

    WRITE_PHY(0,0x1000);

    while ( !(READ_PHY(1)&0x0020)) {
        if( AutoNegotiationTimeOver == 0x8000 ) {
            RETAILMSG(1,(TEXT("time out.\r\n")));
            WRITE_PHY(19,0x3FC0);
            capability = 1;
            break;
        }
        WRITE_PHY(0,0x1000);
        AutoNegotiationTimeOver++;
    }

    if ( capability !=1 )
        RETAILMSG(1,(TEXT("completed.\r\n")));
    
    if (!(capability))
        capability = READ_PHY(5);


    WRITE_PHY(0,0x0000);

        if( capability & 0x0200) {
            RETAILMSG(1,(TEXT("100Base-T4 capable.\r\n")));
            RETAILMSG(1,(TEXT("We will not support 100Base-T4.\r\n")));
        }
        if( capability & 0x0100) {
            RETAILMSG(1,(TEXT("100Base-TX Full Duplex capable.\r\n")));

            WRITE_PHY(0,0x3100);
            WriteWord(0x0e,0x3300);
            WriteWord(0x00,0x8881);
            WriteWord(0x0a,0x38C0);
        }
        else if( capability & 0x0080) {
            RETAILMSG(1,(TEXT("100Base-TX Half Duplex capable.\r\n")));

            WRITE_PHY(0,0x3000);
            WriteWord(0x0e,0x3300);
            WriteWord(0x00,0x0081);
            WriteWord(0x0a,0x28C0);
        }
        else if( capability & 0x0040) {
            RETAILMSG(1,(TEXT("10Base-T Full Duplex capable.\r\n")));

            WRITE_PHY(0,0x1100);
            WriteWord(0x0e,0x3300);
            WriteWord(0x00,0x8881);
            WriteWord(0x0a,0x18C0);
        }
        else if( capability & 0x0020) {
            RETAILMSG(1,(TEXT("10Base-T Half Duplex capable.\r\n")));

            WRITE_PHY(0,0x1000);
            WriteWord(0x0e,0x3300);
            WriteWord(0x00,0x0081);
            WriteWord(0x0a,0x08C0);
        }
        else {
            RETAILMSG(1,(TEXT("Wait for partner in the state of AutoNegotiaton.\r\n")));
            READ_PHY(18);
        }
}

void PHYDiag()
{
    //Reset Phy module.
    WRITE_PHY(0,0x8000);
    while ((READ_PHY(0)&0x8000));

    RETAILMSG(1,(TEXT("LAN91C111 diagnostic testing...\r\n")));

    if( (0x16 == READ_PHY(2)) && (0xF840 == READ_PHY(3))) {
        RETAILMSG(1,(TEXT("completed.\r\n")));
    } else {
        RETAILMSG(1,(TEXT("failed.\r\n")));
        while(1);
    }

}

void WRITE_PHY(unsigned char address, unsigned short data)
{
    int i;
    unsigned char adr;
    unsigned short dat;

    adr = address;
    dat = data;

        for ( i=0; i<32; i++) SendData1();
        //start bits
        SendData0();
        SendData1();
        //write command
        SendData0();
        SendData1();
        //PHY address
        for ( i=0; i<5; i++) SendData0();
        //PHY reg.
        for ( i=0; i<5; i++) {
        if(adr & (0x10>>i))
            SendData1();
        else
            SendData0();
        }
        
        // TA
        SendData1();
        SendData0();
        //write data
        for ( i=0; i<16; i++) {
        if(dat & (0x8000>>i))
            SendData1();
        else
            SendData0();
        }
}

unsigned short READ_PHY(unsigned char address)
{
    unsigned short ret,temp;
    int i;
    unsigned char adr;

    adr = address;

        for ( i=0; i<32; i++) SendData1();
        //start bits
        SendData0();
        SendData1();
        //read command
        SendData1();
        SendData0();
        //PHY address
        for ( i=0; i<5; i++) SendData0();

        //PHY reg.
        for ( i=0; i<5; i++) {
        if(adr & (0x10>>i))
            SendData1();
        else
            SendData0();
        }

    // TA Z0h
        SendDataZ();
        SendData0();

    // Read data
        temp=0;
        ret=0;
        for ( i=0; i<16; i++) {
            WriteWord(0x08,0x3330);
            temp = ReadWord(0x08);
            temp = (temp & 0x0002)>>1;
            ret |= (temp <<(15-i));
            WriteWord(0x08,0x3334);
        }
    return ret;
}


void SendData0()
{
    WriteWord(0x0e,0x3303);
    WriteWord(0x08,0x3338);
    WriteWord(0x08,0x333C);
    WriteWord(0x08,0x3338);
}

void SendData1()
{
    WriteWord(0x0e,0x3303);
    WriteWord(0x08,0x3339);
    WriteWord(0x08,0x333D);
    WriteWord(0x08,0x3339);
}

void SendDataZ()
{
    WriteWord(0x0e,0x3303);
    WriteWord(0x08,0x3330);
    WriteWord(0x08,0x3334);
    WriteWord(0x08,0x3330);
}

⌨️ 快捷键说明

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