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

📄 card.c

📁 Wince4.2 BSP for SH4 engineering development board
💻 C
📖 第 1 页 / 共 2 页
字号:

//
//      Copyright (c) Renesas Technology Corp. 1999-2003 All Rights Reserved.
//
//      LAN91C111 network hardware driver
//
//----------------------------------------------------------------------------
//
//  FILE      : CARD.C
//  CREATED   : 1998. 8.21 (for NE2000 driver)
//  MODIFIED  : 2003.08.06
//  AUTHOR    : Renesas Technology Corp.
//  HARDWARE  : RENESAS HS7751RSTC01H (S1-E, ITS-DS5)
//  TARGET OS : Microsoft(R) Windows(R) CE .NET 4.2
//  FUNCTION  : Card-specific driver functions
//  HISTORY   :
//              1999.04.26
//              - Released as SMSC LAN91C94 driver for PFM-DS6x by modifying
//               NE2000 driver in PB2.12 reference drivers.
//              (Detailed history for PFM-DS6x are omitted.)
//              2002.05.21
//              - Modified for HS7751RSTC01H. Target device is changed to
//               LAN91C111.
//              2002.09.05
//              - Header style is changed and file informations are added.
//              - Unreferenced header file inclusions are removed.

/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-1998 Microsoft Corporation.  All rights reserved.
--*/

#include "precomp.h"
#include "smc91c94.h"

PBYTE   EtherNetBase;
extern  PVOID   RegisterBase;
extern  WORD    MAC0,MAC1,MAC2;


void LAN91C111Init();
void PHYDiag();
void WRITE_PHY(unsigned char address, unsigned short data);
unsigned short READ_PHY(unsigned char address);
void SendData0();
void SendData1();
void SendDataZ();



//#ifdef    DEBUG
void    printregs(void)
{
    WORD    BankReg = ReadWord(BANK_SELECT);
    DEBUGMSG(1, (TEXT("SMSC91C94 Registers\r\n")));

    DEBUGMSG(1, (TEXT("  BANK0\r\n")));
    SelectBank(BANK0);
    DEBUGMSG(1, (TEXT("    TCR        : 0x%04X\r\n"),ReadWord(TCR)));
    DEBUGMSG(1, (TEXT("    EPH_STATUS : 0x%04X\r\n"),ReadWord(EPH_STATUS)));
    DEBUGMSG(1, (TEXT("    RCR        : 0x%04X\r\n"),ReadWord(RCR)));
    DEBUGMSG(1, (TEXT("    COUNTER    : 0x%04X\r\n"),ReadWord(COUNTER)));
    DEBUGMSG(1, (TEXT("    MIR        : 0x%04X\r\n"),ReadWord(MIR)));
    DEBUGMSG(1, (TEXT("    MCR        : 0x%04X\r\n"),ReadWord(MCR)));

    DEBUGMSG(1, (TEXT("  BANK1\r\n")));
    SelectBank(BANK1);
    DEBUGMSG(1, (TEXT("    CONFIG     : 0x%04X\r\n"),ReadWord(CONFIG)));
    DEBUGMSG(1, (TEXT("    BASE       : 0x%04X\r\n"),ReadWord(BASE)));
    DEBUGMSG(1, (TEXT("    ADDR0      : 0x%04X\r\n"),ReadWord(ADDR0)));
    DEBUGMSG(1, (TEXT("    ADDR1      : 0x%04X\r\n"),ReadWord(ADDR1)));
    DEBUGMSG(1, (TEXT("    ADDR2      : 0x%04X\r\n"),ReadWord(ADDR2)));
    DEBUGMSG(1, (TEXT("    GENERAL    : 0x%04X\r\n"),ReadWord(GENERAL)));
    DEBUGMSG(1, (TEXT("    CONTROL    : 0x%04X\r\n"),ReadWord(CONTROL)));

    DEBUGMSG(1, (TEXT("  BANK2\r\n")));
    SelectBank(BANK2);
    DEBUGMSG(1, (TEXT("    MMU_CMD    : 0x%04X\r\n"),ReadWord(MMU_CMD)));
    DEBUGMSG(1, (TEXT("    PNR_ARR    : 0x%04X\r\n"),ReadWord(PNR_ARR)));
    DEBUGMSG(1, (TEXT("    FIFO_PORTS : 0x%04X\r\n"),ReadWord(FIFO_PORTS)));
    DEBUGMSG(1, (TEXT("    POINTER    : 0x%04X\r\n"),ReadWord(POINTER)));
    DEBUGMSG(1, (TEXT("    DATA_1     : 0x%04X\r\n"),ReadWord(DATA_1)));
    DEBUGMSG(1, (TEXT("    DATA_2     : 0x%04X\r\n"),ReadWord(DATA_2)));
    DEBUGMSG(1, (TEXT("    INTERRUPT  : 0x%04X\r\n"),ReadWord(INT_REG)));

    DEBUGMSG(1, (TEXT("  BANK3\r\n")));
    SelectBank(BANK3);
    DEBUGMSG(1, (TEXT("    MULTICAST1 : 0x%04X\r\n"),ReadWord(MULTICAST1)));
    DEBUGMSG(1, (TEXT("    MULTICAST2 : 0x%04X\r\n"),ReadWord(MULTICAST2)));
    DEBUGMSG(1, (TEXT("    MULTICAST3 : 0x%04X\r\n"),ReadWord(MULTICAST3)));
    DEBUGMSG(1, (TEXT("    MULTICAST4 : 0x%04X\r\n"),ReadWord(MULTICAST4)));
    DEBUGMSG(1, (TEXT("    MGMT       : 0x%04X\r\n"),ReadWord(MGMT)));
    DEBUGMSG(1, (TEXT("    REVISION   : 0x%04X\r\n"),ReadWord(REVISION)));
    DEBUGMSG(1, (TEXT("    ERCV       : 0x%04X\r\n"),ReadWord(ERCV)));

    DEBUGMSG(1, (TEXT("  Bank select  : 0x%04X\r\n"),BankReg));

    WriteWord(BANK_SELECT,BankReg);
}
#define PrintRegs   printregs()
//#else 
//#define   PrintRegs
//#endif    DEBUG

BOOLEAN
CardSlotTest(
    IN PCELAN_ADAPTER Adapter
    );

BOOLEAN
CardRamTest(
    IN PCELAN_ADAPTER Adapter
    );


#pragma NDIS_PAGEABLE_FUNCTION(CardCheckParameters)

BOOLEAN CardCheckParameters(
    IN PCELAN_ADAPTER Adapter
)

/*++

Routine Description:

    Checks that the I/O base address is correct.

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    TRUE, if IoBaseAddress appears correct.

--*/

{
    return TRUE;
}

#pragma NDIS_PAGEABLE_FUNCTION(CardRamTest)

BOOLEAN
CardRamTest(
    IN PCELAN_ADAPTER Adapter
    )

/*++

Routine Description:

    Finds out how much RAM the adapter has.  It starts at 1K and checks thru
    60K.  It will set Adapter->RamSize to the appropriate value iff this
    function returns TRUE.

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    TRUE, if all goes well, else FALSE.

--*/

{
    return(TRUE);

}

#pragma NDIS_PAGEABLE_FUNCTION(CardInitialize)

BOOLEAN
CardInitialize(
    IN PCELAN_ADAPTER Adapter
    )

/*++

Routine Description:

    Initializes the card into a running state.

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    TRUE, if all goes well, else FALSE.

--*/

{

    DEBUGMSG(ZONE_INIT, (TEXT("91C94:CardInitialize - Entered.\r\n")));
    
    // VirtualAlloc Register Area for HS7751RSTC01H LAN Controller Base Address 
    EtherNetBase = (PBYTE)VirtualAlloc(0,0x20,MEM_RESERVE,PAGE_NOACCESS);
    DEBUGMSG(ZONE_INIT, (TEXT("91C94:VirtualAlloc at 0x%x.\r\n"),EtherNetBase));
    if(!VirtualCopy((PVOID)EtherNetBase,(PVOID)RegisterBase,0x20,PAGE_READWRITE|PAGE_NOCACHE)) {
            DEBUGMSG(ZONE_INIT, (TEXT("91C94:VirtualCopy failed.\r\n")));
        RETAILMSG(1,(TEXT("91C94:VirtualCopy failed.\r\n")));
    }
    
    // Reset the 91C94
    SelectBank(BANK0);
    WriteWord(RCR,RCR_SOFTRESET);
    Sleep(10);
    WriteWord(RCR,0);
    Sleep(10);
    
    // Initialize the control register
    SelectBank(BANK1);
    WriteWord(CONTROL,0x0020);

    // Reset MMU
    SelectBank(BANK2);
    WriteWord(MMU_CMD,MC_RESET);
    {
        int i;
        for (i=0;i<10000;i++) {
            if(!(ReadWord(MMU_CMD)&MC_BUSY)) {
                break;
            }
        }
        if (i==10000) {
                DEBUGMSG(ZONE_INIT, (TEXT("91C94:MMU reset failed.\r\n")));
                RETAILMSG(1, (TEXT("91C94:MMU reset failed.\r\n")));
            return(FALSE);
        }
    }

    DEBUGMSG(ZONE_INIT, (TEXT("91C94:CardInitialize - Finished.\r\n")));
    RETAILMSG(1, (TEXT("91C94:CardInitialize - Finished.\r\n")));

    return(TRUE);
}


#pragma NDIS_PAGEABLE_FUNCTION(CardReadEthernetAddress)

BOOLEAN CardReadEthernetAddress(
    IN PCELAN_ADAPTER Adapter
)

/*++

Routine Description:

    Reads in the Ethernet address from the LAN91C94.

Arguments:

    Adapter - pointer to the adapter block.

Return Value:

    The address is stored in Adapter->PermanentAddress, and StationAddress if it
    is currently zero.

--*/

{
    // Read MAC address registers
    SelectBank(BANK1);
    Adapter->PermanentAddress[0] = ReadWord(ADDR0) & 0xFF;
    Adapter->PermanentAddress[1] = ReadWord(ADDR0) >> 8;
    Adapter->PermanentAddress[2] = ReadWord(ADDR1) & 0xFF;
    Adapter->PermanentAddress[3] = ReadWord(ADDR1) >> 8;
    Adapter->PermanentAddress[4] = ReadWord(ADDR2) & 0xFF;
    Adapter->PermanentAddress[5] = ReadWord(ADDR2) >> 8;

#if 1   // for ROM
    if(
    ((Adapter->PermanentAddress[0] == 0) &&
     (Adapter->PermanentAddress[1] == 0) &&
     (Adapter->PermanentAddress[2] == 0) &&
     (Adapter->PermanentAddress[3] == 0) &&
     (Adapter->PermanentAddress[4] == 0) &&
     (Adapter->PermanentAddress[5] == 0) )
    ||
    ((Adapter->PermanentAddress[0] == 0xff) &&
     (Adapter->PermanentAddress[1] == 0xff) &&
     (Adapter->PermanentAddress[2] == 0xff) &&
     (Adapter->PermanentAddress[3] == 0xff) &&
     (Adapter->PermanentAddress[4] == 0xff) &&
     (Adapter->PermanentAddress[5] == 0xff) ) )
    {
       if (Adapter->PermanentAddress[0] == 0xff)
       RETAILMSG(1, (TEXT("CELAN: !!Warning!! EEPROM doesn't have MAC address. \r\n")));
       
       if ( (MAC0 == 0) && (MAC1 == 0) && (MAC2 == 0) )
       {
       RETAILMSG(1, (TEXT("CELAN: !!ERROR!! MAC address is not specified. \r\n")));
       return FALSE;    // Registry not set
       }
       else
       {
       // We do not have EEPROM, so let's set MAC address by software
       // MAC address is specified in the registry
#define SWAPB(Word) ((Word<<8)&0xff00 | (Word>>8)&0x00ff)
       SelectBank(BANK1);
       WriteWord(ADDR0,SWAPB(MAC0));
       WriteWord(ADDR1,SWAPB(MAC1));
       WriteWord(ADDR2,SWAPB(MAC2));

       }
   }
   // IP address save again
   Adapter->PermanentAddress[0] = ReadWord(ADDR0) & 0xFF;
   Adapter->PermanentAddress[1] = ReadWord(ADDR0) >> 8;
   Adapter->PermanentAddress[2] = ReadWord(ADDR1) & 0xFF;
   Adapter->PermanentAddress[3] = ReadWord(ADDR1) >> 8;
   Adapter->PermanentAddress[4] = ReadWord(ADDR2) & 0xFF;
   Adapter->PermanentAddress[5] = ReadWord(ADDR2) >> 8;
#endif  // for ROM
      
    RETAILMSG(1,
        (TEXT("CELAN: PermanentAddress [ %02x-%02x-%02x-%02x-%02x-%02x ]\r\n"),
            Adapter->PermanentAddress[0],
            Adapter->PermanentAddress[1],
            Adapter->PermanentAddress[2],
            Adapter->PermanentAddress[3],
            Adapter->PermanentAddress[4],
            Adapter->PermanentAddress[5]));

    //
    // Use the burned in address as the station address, unless the
    // registry specified an override value.
    //
    if ((Adapter->StationAddress[0] == 0x00) &&
        (Adapter->StationAddress[1] == 0x00) &&
        (Adapter->StationAddress[2] == 0x00) &&
        (Adapter->StationAddress[3] == 0x00) &&
        (Adapter->StationAddress[4] == 0x00) &&
        (Adapter->StationAddress[5] == 0x00)
    )
    {
        Adapter->StationAddress[0] = Adapter->PermanentAddress[0];
        Adapter->StationAddress[1] = Adapter->PermanentAddress[1];
        Adapter->StationAddress[2] = Adapter->PermanentAddress[2];
        Adapter->StationAddress[3] = Adapter->PermanentAddress[3];
        Adapter->StationAddress[4] = Adapter->PermanentAddress[4];
        Adapter->StationAddress[5] = Adapter->PermanentAddress[5];
    }

    return(TRUE);
}

BOOLEAN
CardSetup(
    IN PCELAN_ADAPTER Adapter
    )

/*++

Routine Description:

    Sets up the card.

Arguments:

    Adapter - pointer to the adapter block, which must be initialized.

Return Value:

    TRUE if successful.

--*/

{
    UINT i;
    UINT Filter;
    USHORT Tmp;

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

    //
    // Write to and read from RCR to make sure it is there.
    //
    DEBUGMSG(ZONE_INIT, (TEXT("91C94:Reset 91C94\r\n")));
    SelectBank(BANK0);
    WriteWord(RCR,RCR_SOFTRESET);
    Sleep(10);
    Tmp = ReadWord(RCR);

    if ((Tmp & RCR_SOFTRESET) != RCR_SOFTRESET) {
        DEBUGMSG(ZONE_INIT,
            (TEXT("91C94:CardSetup - Tmp = 0x%x, Expected 0x%x\r\n"),
            Tmp, (RCR_SOFTRESET)));
        return(FALSE);
    }
    WriteWord(RCR,0);
    Sleep(10);

    // Initialize the control register
    DEBUGMSG(ZONE_INIT, (TEXT("91C94:Init Control register\r\n")));
    SelectBank(BANK1);
    WriteWord(CONTROL,0x0920);

    //
    // Set Loopback Mode
    //
//  DEBUGMSG(ZONE_INIT, (TEXT("91C94:Set loopbacke mode\r\n")));
//  SelectBank(BANK0);
//  WriteWord(TCR,TCR_LOOP);

    //
    // Clear all pending interrupts
    //
    DEBUGMSG(ZONE_INIT, (TEXT("91C94:Cleare current pending interrupt\r\n")));
    SelectBank(BANK2);
    WriteWord(INT_REG,ReadWord(INT_REG));


    //
    // Set Interrupt Mask Register
    //
    DEBUGMSG(ZONE_INIT, (TEXT("91C94:Set interrupt mask reg %02x\r\n"),Adapter->NicInterruptMask));
    SelectBank(BANK2);
    WriteWord(INT_REG,Adapter->NicInterruptMask);


#if 0   // Station Address setting is in CardInitialize
    //
    // Set Station Address
    //
    DEBUGMSG(ZONE_INIT, (TEXT("91C94:Set station address regs\r\n")));
    SelectBank(BANK1);
    WriteWord(ADDR0,Adapter->StationAddress[0] | 
            Adapter->StationAddress[1]<<8);
    WriteWord(ADDR1,Adapter->StationAddress[2] | 
            Adapter->StationAddress[3]<<8);
    WriteWord(ADDR2,Adapter->StationAddress[4] | 
            Adapter->StationAddress[5]<<8);
#endif //#if 0

    Filter = Adapter->PacketFilter;

    //
    // Write out the multicast addresses
    //
    SelectBank(BANK3);
    for (i = 0; i < 8; i+=2)
    {
        WriteWord(MULTICAST1+i,
            (USHORT)((Filter & NDIS_PACKET_TYPE_ALL_MULTICAST) ?
            0xffff : Adapter->NicMulticastRegs[i] 
            | Adapter->NicMulticastRegs[i+1]<<8));
    }

    PrintRegs;

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

    //
    // ... but it is still in loopback mode.
    //
    return(TRUE);
}

VOID CardStop(
    IN PCELAN_ADAPTER Adapter
)

/*++

Routine Description:

    Stops the card.

Arguments:

    Adapter - pointer to the adapter block

Return Value:

    None.

--*/

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

    SelectBank(BANK0);
    WriteWord(RCR,0);

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

BOOLEAN CardReset(
    IN PCELAN_ADAPTER Adapter
)

/*++

Routine Description:

    Resets the card.

Arguments:

    Adapter - pointer to the adapter block

Return Value:

    TRUE if everything is OK.

--*/

{
    WORD Tmp;

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

    //
    // Stop the chip
    //
    CardStop(Adapter);

    //
    // Write to and read from RCR to make sure it is there.
    //
    DEBUGMSG(ZONE_INIT, (TEXT("91C94:Reset 91C94\r\n")));
    SelectBank(BANK0);
    WriteWord(RCR,RCR_SOFTRESET);
    Sleep(10);
    Tmp = ReadWord(RCR);

    if ((Tmp & RCR_SOFTRESET) != RCR_SOFTRESET) {
        DEBUGMSG(ZONE_ERROR,
            (TEXT("91C94:CardSetup - Tmp = 0x%x, Expected 0x%x\r\n"),
            Tmp, (RCR_SOFTRESET)));
        return(FALSE);
    }
    WriteWord(RCR,0);
    Sleep(10);

    //
    // Restart the chip
    //
    CardStart(Adapter);

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

    return TRUE;
}

ULONG
CardComputeCrc(
    IN PUCHAR Buffer,
    IN UINT Length
    )

/*++

Routine Description:

    Runs the AUTODIN II CRC algorithm on buffer Buffer of
    length Length.

Arguments:

    Buffer - the input buffer

    Length - the length of Buffer

Return Value:

⌨️ 快捷键说明

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