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

📄 chip.c

📁 PXA255/270平台的 CS8900网卡驱动程序
💻 C
字号:
//---------------------------------------------------------------------------
//
//  Copyright (C) 1996-2003. Unpublished Work of Cirrus Logic Inc.
//  All Rights Reserved.
//
//  THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
//  PROPRIETARY AND TRADE SECRET INFORMATION OF CRYSTAL SEMICONDUCTOR.
//  ACCESS TO THIS WORK IS RESTRICTED TO (I) CRYSTAL SEMICONDUCTOR EMPLOYEES
//  WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR
//  ASSIGNMENTS  AND (II) ENTITIES OTHER THAN CRYSTAL SEMICONDUCTOR WHO
//  HAVE ENTERED INTO  APPROPRIATE LICENSE AGREEMENTS.  NO PART OF THIS
//  WORK MAY BE USED, PRACTICED, PERFORMED, COPIED, DISTRIBUTED, REVISED,
//  MODIFIED, TRANSLATED, ABRIDGED, CONDENSED, EXPANDED, COLLECTED,
//  COMPILED,LINKED,RECAST, TRANSFORMED, ADAPTED IN ANY FORM OR BY ANY
//  MEANS,MANUAL, MECHANICAL, CHEMICAL, ELECTRICAL, ELECTRONIC, OPTICAL,
//  BIOLOGICAL, OR OTHERWISE WITHOUT THE PRIOR WRITTEN PERMISSION AND
//  CONSENT OF CRYSTAL SEMICONDUCTOR . ANY USE OR EXPLOITATION OF THIS WORK
//  WITHOUT THE PRIOR WRITTEN CONSENT OF CRYSTAL SEMICONDUCTOR  COULD
//  SUBJECT THE PERPETRATOR TO CRIMINAL AND CIVIL LIABILITY.
//
//---------------------------------------------------------------------------

/* chip.c  - CS8900A VChip Initialization */


#include "cs8900a.h"
#include "cshrd.h"
//#include "bvd1bd.h"
#include "Ind.h"

extern volatile CS8900_REGS *v_pCS8900Regs;

/******************************************************************************
*
* VchipStartup()
*
******************************************************************************/

WORD VchipStartup( PCHIP pChip )
{
    PCD   pData;
    WORD  Result;
//	P_IND_CTRL pIndicatorLightAddr = (P_IND_CTRL)(INDICATOR_LIGHT_BASE_U_VIRTUAL);	//cs4

//	P_IND_CTRL pIndicatorLightAddr = (P_IND_CTRL)(ETHERNET_CS8900_BASE_U_VIRTUAL);	//cs2,dlp
	
    
    PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipStartup\r\n")));
    pData = pChip->pData;

    /* Initialize configuration flags to zero */
    pData->ConfigFlags = 0;

    PRINTDEBUGMSG(1, (TEXT("dlp#: ******001\r\n")));

//dlp	WAIT_FOR_WRITE_SIG( pIndicatorLightAddr );

	PRINTDEBUGMSG(1, (TEXT("dlp#: ******002\r\n")));
//	pIndicatorLightAddr->control |= LAN_ENABLE_BIT;

    Result = VchipReset( pChip );             //@drsa
    if ( Result != CHIP_SUCCESS )             //@drsa
    {                                         //@drsa
        PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup 1 Result = 0x%x\r\n"), Result));
        return Result;                        //@drsa
    }                                         //@drsa   

    // @kml 6/30/99 Wait for the LinkOK bit in Line Control Reg.
    VominiDelay(100);

    PRINTDEBUGMSG(1, (TEXT("dlp#: ******003\r\n")));

    #if 0 
    DetectMedia( pChip );

    while ( pChip->Config.DetectedMediaType == MEDIA_PENDING )
    {
 	    if (pChip->Config.CurrentDuplexMode == DUPLEX_PENDING) 
        {
		    // @kml Auto Config Duplex mode
		    VominiDelay( 2500 ); 
        } 
        else 
        {   
            // @kml 6/30/99 quick init time when in Force Full or Half Duplex mode
            VominiDelay( 100 ); 
        }
        DetectMedia( pChip );
    }

    if ( pChip->Config.DetectedMediaType != MEDIA_NONE )
    {
        if ( pChip->Config.DetectedMediaType != MEDIA_BASE_T )
        {
            Result = VchipReset( pChip );             //@rosa avoids pending receives
            if ( Result != CHIP_SUCCESS )             //@rosa
            {
                PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup 2 Result = 0x%x\r\n"), Result));
                return Result;                         //@rosa
            }
        }

        /* Initialize the chip */
        Result = VchipInit( pChip );
        if ( Result != CHIP_SUCCESS )
        {
            PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup 3 Result = 0x%x\r\n"), Result));
            return Result;
        }
    }
    #else
    /* Initialize the chip */
    Result = VchipInit( pChip );
    if ( Result != CHIP_SUCCESS )
    {
        PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup 3 Result = 0x%x\r\n"), Result));
        return Result;
    }
    #endif

    /* Must start Timer routine to detect cable Status */
    Result = VominiStartTimer( pChip, VchipDetectMediaDaemon, 2500,
         &pData->DetectMediaTimer, NULL ); 

    if ( Result != CHIP_SUCCESS )
    {
        PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup 4 Result = 0x%x\r\n"), Result));
        return Result;
    }

    PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipStartup SUCCESS\r\n")));
    return CHIP_SUCCESS;
}


/******************************************************************************
*
* VchipInit()
*
* Note: This driver does not support memory mode.
*
******************************************************************************/

WORD VchipInit( PCHIP pChip )
{
    PCD  pData;

    PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipInit\r\n")));
    pData  = pChip->pData;

    /*
    if (( pChip->Config.DetectedMediaType == MEDIA_PENDING ) ||
        ( pChip->Config.DetectedMediaType == MEDIA_NONE ))
    {
        PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipInit 1 SUCCESS\r\n")));
        return CHIP_SUCCESS;
    }*/

    pData->TransmitBidPending = FALSE;
    pData->TransmitInProgress = FALSE;
    pData->TransmitThresholdCount = 0;
    pData->TransmitStarted = FALSE;
    pData->StartTX = FALSE;
    pData->TransmitCommand = CRYSTAL_TCR_TX_START_381_BYTES;
    pData->CurrentReceiveConfiguration = CRYSTAL_DEFAULT_RX_CONFIG_VALUE;

    InitQueues( pChip );

    WritePacketPage( CRYSTAL_LINE_CONTROL_REGISTER, CRYSTAL_LCR_DEFAULT_VALUE );

    /* Initialize the config and control registers */
    WritePacketPage( CRYSTAL_RX_CONFIG_REGISTER, CRYSTAL_DEFAULT_RX_CONFIG_VALUE );
    WritePacketPage( CRYSTAL_RX_CONTROL_REGISTER, CRYSTAL_RCR_DEFAULT_VALUE );
    WritePacketPage( CRYSTAL_TX_CONFIG_REGISTER, CRYSTAL_TCR_DEFAULT_VALUE);
    WritePacketPage( CRYSTAL_BUFFER_CONFIG_REGISTER, CRYSTAL_BCR_DEFAULT_VALUE);

    /* Setup initial filtering criteria */
    VchipChangeFiltering( pChip );

    /* The INTRQ pin number is independent from pChip->Config.IntLine. 
       Write the INTRQ pin number which is connected to Processor to CS8900's register.*/
    WritePacketPage( CRYSTAL_ISA_INTERRUPT_NUMBER, CS8900_INTERRUPT_REQUEST_PIN_NUM );

    /* Enable reception and transmission of frames */
    WritePacketPage( CRYSTAL_LINE_CONTROL_REGISTER,
                     (WORD)(ReadPacketPage( CRYSTAL_LINE_CONTROL_REGISTER) |
                     CRYSTAL_LCR_SERIAL_RX_ON | CRYSTAL_LCR_SERIAL_TX_ON) );

    /* Enable interrupt at the chip */
    VchipEnableInterrupts( pChip );

    PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipInit 2 SUCCESS\r\n")));
    return CHIP_SUCCESS;
}


/******************************************************************************
*
* InitQueues()
*
******************************************************************************/

void InitQueues( PCHIP pChip )
{
   PCD   pData = pChip->pData;
   PRINTDEBUGMSG(1, (TEXT("==>CS8900:InitQueues\r\n")));   

   pData->TransmitQueue.Head = pData->TransmitQueue.Tail = NULL;
   PRINTDEBUGMSG(1, (TEXT("<==CS8900:InitQueues\r\n")));   
}


/******************************************************************************
*
* VchipReset()
*
******************************************************************************/

WORD VchipReset( PCHIP pChip )
{
    PCD  pData;
    int  x;

    PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipReset\r\n")));
    pData  = pChip->pData;

    /* We are now resetting the chip */
    /* A spurious interrupt is generated by the chip when it is reset. */
    /* This variable informs the interrupt handler to ignore this interrupt. */
    pData->Resetting = TRUE;

    /* Issue a reset command to the chip */
    WritePacketPage( CRYSTAL_SELF_CONTROL_REGISTER, CRYSTAL_SCR_POWER_ON_RESET );

    /* Delay for 20 milliseconds */
    VominiDelay( 20 );

    /* Wait until the EEPROM is not busy */
    for ( x=0; x<MAXLOOP; x++ )
        if ( !(ReadPacketPage(CRYSTAL_SELF_STATUS_REGISTER) & CRYSTAL_SSR_SI_BUSY) )
            break;
    if ( x == MAXLOOP ) 
    {
        PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipReset CHIP_FAILURE 1\r\n")));
        return CHIP_FAILURE;
    }

    /* Wait until initialization is done */
    for ( x=0; x<MAXLOOP; x++ )
        if ( ReadPacketPage(CRYSTAL_SELF_STATUS_REGISTER) & CRYSTAL_SSR_INIT_DONE )
            break;
    if ( x == MAXLOOP ) 
    {
        PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipReset CHIP_FAILURE 2\r\n")));
        return CHIP_FAILURE;
    }

    /* Reset is no longer in progress */
    pData->Resetting = FALSE;

    PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipReset CHIP_SUCCESS\r\n")));
    return CHIP_SUCCESS;
}


/******************************************************************************
*
* VchipShutdown()
*
******************************************************************************/

void VchipShutdown( PCHIP pChip )
{
   PCD  pData;
   WORD SelfStatus;

   PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipShutdown\r\n")));   
   pData    = pChip->pData;

   VominiStopTimer( pChip, pData->DetectMediaTimer );

   VchipReset( pChip );

   /* Read the self status register */
   SelfStatus = ReadPacketPage( CRYSTAL_SELF_STATUS_REGISTER );
   PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipShutdown\r\n")));   
}


/******************************************************************************
*
* VchipTest()
*
******************************************************************************/
void VchipTest( PCHIP pChip )
{
   WORD BuffConfig;

   PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipTest\r\n")));   
   /* Generate a software initiated interrupt */
   BuffConfig = ReadPacketPage( CRYSTAL_BUFFER_CONFIG_REGISTER );
   BuffConfig |= CRYSTAL_BCR_GENERATE_SW_INTERRUPT;
   WritePacketPage( CRYSTAL_BUFFER_CONFIG_REGISTER, BuffConfig );
   PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipTest\r\n")));   
}

/******************************************************************************
*
* ReadPacketPage()
*
******************************************************************************/
WORD ReadPacketPage( WORD Offset )
{
   v_pCS8900Regs->PAGEIX = Offset;
   return v_pCS8900Regs->PAGE0;
}

/******************************************************************************
*
* WritePacketPage()
*
******************************************************************************/
void WritePacketPage( WORD Offset, WORD Value )
{
    v_pCS8900Regs->PAGEIX = Offset;
    v_pCS8900Regs->PAGE0  = Value;
}

NDIS_STATUS VchipFindIOBase( PCHIP pChip)
{
    WORD Result;
    WORD SelfStatus;

    PRINTDEBUGMSG(1, (TEXT("==>CS8900:VchipFindIOBase\r\n")));

    /* Read the EISA ID from the packet page */
    Result = ReadPacketPage( CRYSTAL_CHIPEISA_ID );
    PRINTDEBUGMSG(1, (TEXT("EISA ID = 0x%04x\r\n"), Result));
    
    /* If the EISA ID is for Crystal Semiconductor */
    if ( Result == CS89XX_ID )
    {
        /* Read the product ID from the packet page */
        Result = ReadPacketPage( CRYSTAL_PRODUCT_ID );
        pChip->Config.ChipType = Result & PRODUCT_ID_MASK;
        pChip->Config.ChipRev  = Result & REVISION_ID_MASK;    
        PRINTDEBUGMSG(1, (TEXT("Product ID = 0x%04x\r\n"), Result));
    }
    else
    {
        PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipFindIOBase, FAILURE\r\n")));
        return NDIS_STATUS_FAILURE;
    }

    /* Read the self status register */
    SelfStatus = ReadPacketPage( CRYSTAL_SELF_STATUS_REGISTER );
    
	/* If the EEPROM is not present or the EEPROM is not OK,
	   then sofeware reset the chip. */
	pChip->Config.IOBase = ETHERNET_CS8900_BASE_U_VIRTUAL;
    pChip->Config.MemoryBase = ETHERNET_CS8900_BASE_U_VIRTUAL;
    pChip->Config.IOSize = CRYSTAL_IO_SIZE;

    PRINTDEBUGMSG(1, (TEXT("<==CS8900:VchipFindIOBase\r\n")));
    return NDIS_STATUS_SUCCESS;
}

extern NDIS_STATUS GetNetworkAddress(IN NDIS_HANDLE ConfigHandle,
                                     OUT PUCHAR CurrentNetworkAddress)
{
	USHORT MacAddr[3];
    
    PRINTRETAILMSG(1, (TEXT("==>CS8900:GetNetworkAddress\r\n")));   
///important by marsahal
    WritePacketPage( CRYSTAL_INDIVIDUAL_ADDRESS + 0, 0x0000 );
    WritePacketPage( CRYSTAL_INDIVIDUAL_ADDRESS + 2, 0x5577 );
    WritePacketPage( CRYSTAL_INDIVIDUAL_ADDRESS + 4, 0x9bad );

    MacAddr[0] = ReadPacketPage(CRYSTAL_INDIVIDUAL_ADDRESS + 0);
    MacAddr[1] = ReadPacketPage(CRYSTAL_INDIVIDUAL_ADDRESS + 2);
    MacAddr[2] = ReadPacketPage(CRYSTAL_INDIVIDUAL_ADDRESS + 4);
    
	/* MAcAddr=0000:0000:0000 means to use EEPROM setting, so return Failure.*/
	if ( MacAddr[0] == 0 && 
         MacAddr[1] == 0 && 
         MacAddr[2] == 0) 
    {
        return NDIS_STATUS_FAILURE;
	}

    NdisMoveMemory(CurrentNetworkAddress,
                   (unsigned char *)MacAddr,
                   (ULONG) ETH_LENGTH_OF_ADDRESS);
    PRINTRETAILMSG(1, (TEXT("<==CS8900:GetNetworkAddress\r\n")));   
    return NDIS_STATUS_SUCCESS;
}

⌨️ 快捷键说明

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