?? cssysend.c
字號:
/* csSysEnd.c - PCx86 or ARM system-dependent module for CS8900 Ethernet driver */
/* */
/* Copyright 2000 Crystal Semiconductor Corp. */
/* */
/* Last release: v3.05a */
/* Mod level for last release: 05a */
/*
MODIFICATION HISTORY
--------------------
v3.05a,06/26/01, kml - Added Support for Interrupt Level and Interrupt Vector for
Non-Ix86 processors.
- Added CS8900_INTERRUPT_REQUEST_PIN_NUM for Non-Ix86 processors to
write their interrupt pin number to InterruptNumber Register.
- Modified the code so that logMsg is used only when CS_DEBUG_ENABLE is
defined. Thus, compiler warning mesages can be avoided if
CS_DEBUG_ENABLE is not defined.
- Added "Define your BSP Type" for users to define their
CS_BSP_TYPE string.
v3.03a,10/02/00, kml -Merged for PCx86 and ARM.
June 20000 -Modified for ARM 940 by Conexant Systems, Inc.
v3.02a,24Sep99, kml -Set offset 2 to the receiving buffer pointer when copying received frames from chip
so that the IP header stars from the 17th bytes for 32-bits-Alignment.
-Change receiving buffer size from 32 to 64.
-Correction: If the memory address parameter is zero, the CS8900 operates in the
mode specified by EEPROM or the Config Flag parameter.
v3.01a,07May, kml ported to the Enhanced Network Driver (END) model
to support the MUX interface:
10f,11apr97,rks Added variables for "early tx" support to CS_END_DEVICE structure
(TxUnderruns, TotalTxUnderruns, TxStartCMD, and TxLenght.
10e,05apr97,rks Added CS_MAX_NET_JOBS and STRESS_TESTING defines.
10d,11mar97,rks Moved some typedefs to this file so "config.h" could include
"if_cs.h" easily.
01c,25feb97,rks Changed SysEnetAddrGet parameters to Unit, IA addr pointer
01b,31jan97,rks Modified sysEnetAddrGet to take Ethernet address from EEPROM
or from the csEnetAddr array based on the value of the
GET_ENET_ADDR_FROM_BOARD flag.
01a,16dec96,rks Written (using routines originally written by q_s in "if_cs.c".
*/
/*
DESCRIPTION
This module provides PCx86 and ARM board-specific routines and data types require
by the Crystal Semiconductor CS8900 Ethernet VxWorks END network interface driver.
It implements five routines called from the "csEnd.c" main driver module:
* sysEnetGetConfig( CS_END_DEVICE *pCS )
This routine takes configuration parameters not specifed to csLoad(), if any,
from non-volatile storage (e.g. an attached EEPROM) and puts them in the
CS_END_DEVICE structure. If all the parameters were specified to csLoad(), then
this routine does not attempt to read the EEPROM.
* sysEnetAddrGet( CS_END_DEVICE pCS, unsigned char *pAddr )
This routine obtains the Ethernet MAC address from non-volatile storage or from
the "csEnetAddr" array defined in csSysEnd.c and saves it in the CS_END_DEVICE
structure.
* sysEnetHWInit( CS_END_DEVICE *pCS )
This routine uses global variables in the CS_END_DEVICE structure to configure the
adapter for the board-specific IO circuitry and supported media types.
* sysEnetIntEnable( CS_END_DEVICE *pCS )
This routine enables the interrupt used by the CS8900 at the system level.
* sysEnetIntDisable( CS_END_DEVICE *pCS )
This routine disables the interrupt used by the CS8900 at the system level.
*/
/* DEFINES */
#ifdef CPU_FAMILY
#undef CPU_FAMILY
#endif
#ifdef _BYTE_ORDER
#undef _BYTE_ORDER
#endif
#define CPU_FAMILY ARM
#define _BYTE_ORDER _LITTLE_ENDIAN
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* Driver Configuration Defines *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* Maximum number of CS8900 chips supported */
#define CS_MAX_NUM_UNITS 1
/* Maximum number of receive buffers */
#define CS_NUM_RX_BUFFERS 64
/* Minimum bytes of first buffer for chain used by scattered transmission. */
#define CS_MIN_FBUF 5
/* Number of elements held by TX and RX queues */
#define CS_QUEUE_SIZE 200 /* @kml */
/* Initial TXStartCMD (number of bytes to buffer before CS8900 starts the TX */
/* Select one of: [TX_CMD_START_5 | TX_CMD_START_381 | TX_CMD_START_1021 |
* TX_CMD_START_ALL ] */
#define CS_INITIAL_START_CMD TX_CMD_START_5
/* Number of underruns with current TXStartCMD before TXStartCMD is set to next value */
#define CS_TX_UNDRUN_TRHSHOLD 2
/* BSP type supported by this driver */
#if CPU_FAMILY == ARM
#define CS_BSP_TYPE "ARM"
#elif CPU_FAMILY == MIPS
#define CS_BSP_TYPE "MIPS"
#elif CPU_FAMILY == I80X86
#define CS_BSP_TYPE "i[3|4]86"
#else
#define CS_BSP_TYPE "Unknown BSP Type"
#endif
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* Miscellaneous and BSP-specific defines *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* Define a unique cluster type */
/*
This flag determines if the Ethernet address is taked from EEPROM or from
the csEnetAddr array defined below. Define as 0 to take the Ethernet address
from csEnetAddr. WARNING! The Ethernet address must be unique for each Ethernet
device on the network.
*/
#define GET_ENET_ADDR_FROM_BOARD 1
/*
These macros are used to communicate with the CS8900. These functions need to be supplied
by syslib.c
*/
/* Macros used to provide platform independence for IO accesses */
#if CPU_FAMILY == ARM
#define SYS_ENET_OUT_WORD(port, value) sysOutWord((int)(port), (value))
#define SYS_ENET_IN_WORD(port) sysInWord((int)(port))
#define SYS_ENET_IN_BYTE(port) sysInByte((int)(port))
#else
#define SYS_ENET_OUT_WORD(port, value) sysOutWord(port, value)
#define SYS_ENET_IN_WORD(port) sysInWord(port)
#define SYS_ENET_IN_BYTE(port) sysInByte(port)
#endif
/*add by syx*/
#define EXTINT1 0x5600008C
#define GPGCON 0x56000060
#define BWSCON 0x48000000
#define BANKCON2 0x4800000C
/*end add*/
/* TYPEDEFS */
/* Individual Address (Ethernet Address) */
typedef struct
{
USHORT word[3];
} IA, *PIA;
typedef struct
{
void *Queue[CS_QUEUE_SIZE+1];
int Head;
int Tail;
} CIR_QUEUE;
#if CPU_FAMILY == ARM
typedef unsigned long IOADDR; /* IO space address is 32-bit */
#else
typedef unsigned short IOADDR; /* IO space address is 16-bit */
IMPORT UINT sysVectorIRQ0; /* vector for IRQ0 */
#endif
/* Driver control structure for a single unit */
typedef struct
{
END_OBJ end;
int unit;
UCHAR enetAddr[6];
IOADDR IOAddr;
USHORT IntLevel;
USHORT IntVector;
unsigned short *pPacketPage;
USHORT MediaType;
USHORT ConfigFlags;
BOOL InMemoryMode;
BOOL Resetting;
USHORT MaxTxDepth;
USHORT TxQueueDepth;
USHORT MaxTxQueueDepth;
UINT Rdy4TxInts;
M_BLK_ID pTxFrameChain;
BOOL TxInProgress;
BOOL InISR;
CIR_QUEUE *pTxBuffFreeList;
CIR_QUEUE *pRxBuffProcessList;
CIR_QUEUE *pTxQueue;
UINT NetJobDepth;
USHORT TxStartCMD;
USHORT TxUnderruns;
UINT TotalTxUnderruns;
UINT TxLength;
UINT Collisions;
CL_POOL_ID pClPoolId;
USHORT MulticastTable[4];
} CS_END_DEVICE;
/* Define GET_ENET_ADDR_FROM_BOARD as 0 to take the Ethernet address
from csEnetAddr. */
/* LOCALS */
unsigned char csEnetAddr [6] = { 0x08, 0x00, 0x20, 0x74, 0x80, 0xa7 };
/* Instance variables */
LOCAL CS_END_DEVICE cs_end[CS_MAX_NUM_UNITS];
CIR_QUEUE TxBuffFreeList;
CIR_QUEUE RxBuffProcessList;
CIR_QUEUE TxQueue;
/* For ARM user only: */
/* The following code is specific for Conexant IRD, ARM 940. You can take it as an
example or ignore it. */
/* @Conexant ARM 940 specific code */
/*
#include "basetype.h"
#include "sabine.h"
#include "hwconfig.h"
#include "hwlib.h"
#include "retcodes.h"
extern PFNISR ethernetChainNode; // ISR linked list node storage
extern void csIntr(CS_END_DEVICE *arg);
CS_END_DEVICE *EndObject;
int ethernetIntHandler(unsigned int IntID, int FIQ, PFNISR *nextNode)
{
csIntr(EndObject);
*nextNode = ethernetChainNode;
return(RC_ISR_NOTHANDLED); // All PCI ints return this
}
void init_cs8900(void)
{
// Set the memory base address
SYS_ENET_OUT_WORD(0x3150030a, 0x002c);
SYS_ENET_OUT_WORD(0x3150030c, 0x0000);
SYS_ENET_OUT_WORD(0x3150030a, 0x002e);
SYS_ENET_OUT_WORD(0x3150030c, 0x0000);
int_register_isr(INT_GPIO68, (PFNISR)ethernetIntHandler, FALSE, FALSE,
ðernetChainNode);
set_gpio_int_edge(68, POS_EDGE);
}
int sysCsIntAck(void)
{
clear_pic_interrupt(PIC_GPIO, INT_GPIO68);
return 1;
}
*/
/* end of Conexant IRD, ARM 940 */
/* Crystal Semiconductor supplied code */
/* FORWARD DECLARATIONS */
LOCAL STATUS sysEnetGetConfig( CS_END_DEVICE *pCS );
LOCAL STATUS sysEnetAddrGet( CS_END_DEVICE *pCS, unsigned char *pAddr ); /*@kml*/
LOCAL void sysEnetHWInit( CS_END_DEVICE *pCS );
LOCAL STATUS sysEnetIntEnable( CS_END_DEVICE *pCS );
LOCAL STATUS sysEnetIntDisable( CS_END_DEVICE *pCS ); /*@kml*/
/* sub-routines for above functions */
LOCAL STATUS csGetUnspecifiedParms( CS_END_DEVICE *pCS );
LOCAL STATUS csValidateParms( CS_END_DEVICE *pCS );
LOCAL STATUS csReadEEPROM( CS_END_DEVICE *pCS, USHORT Offset, USHORT *pValue );
#ifdef TRUE
/* These routines defined in csEnd.c but available for use here. */
/* Ifdef FALSE if none are called from this module */
#define DECLARED_IN_SYS_ENET
LOCAL USHORT csReadPacketPage( CS_END_DEVICE *pCS, USHORT Offset );
LOCAL void csWritePacketPage( CS_END_DEVICE *pCS, USHORT Offset, USHORT Value );
#endif
#define MAXLOOP 0x8888 /* Delay loop counter */
/******************************************************************************
*
* sysEnetGetConfig - Get any CS8900 parameters not specifed to csLoad
*
* This routine gets parameters that were not specifed to csAttach() from an
* EEPROM, if used, and puts them in the CS_END_DEVICE structure. If all the
* parameters were specified to csAttach(), then this routine does not attempt
* to read the EEPROM.
*
* RETURNS: OK or ERROR
*
*/
LOCAL STATUS sysEnetGetConfig( CS_END_DEVICE *pCS )
{
/* Get parameters, which were not specified, from the EEPROM */
if ( csGetUnspecifiedParms(pCS) == ERROR )
return ERROR;
/* Verify that parameters are valid */
if ( csValidateParms(pCS) == ERROR )
return ERROR;
/* If memory address was specified but configuration flags were not */
if ( pCS->pPacketPage != 0 )
pCS->ConfigFlags |= CFGFLG_MEM_MODE; /* Implictly set memory mode */
/* If the interrupt vector was not specified then derive it */
if ( pCS->IntVector == 0 ) {
#if CPU_FAMILY == I80X86
pCS->IntVector = sysVectorIRQ0 + pCS->IntLevel;
#else
pCS->IntVector = pCS->IntLevel;
#endif
}
return OK;
}
/*******************************************************************************
*
* sysEnetAddrGet - saves the Ethernet address to the CS_END_DEVICE structure
*
* The Ethernet address is taked from EEPROM or from the csEnetAddr array
* then the Ethernet address was saved in the CS_END_DEVICE structure.
*
* pAddr: the pointer points to the array holding Ethernet Addr in CA_END_DEVICE
*
* RETURNS: OK or ERROR
*/
LOCAL STATUS sysEnetAddrGet( CS_END_DEVICE *pCS, unsigned char *pAddr )
{
USHORT SelfStatus;
PIA pIA;
/* Setup pointer for the Ethernet address */
pIA = (PIA)pAddr;
/* If the Ethernet address in EEPROM */
if ( GET_ENET_ADDR_FROM_BOARD ) /* defined in config.h */
{
/* Verify that the EEPROM is present and OK */
SelfStatus = csReadPacketPage( pCS, PKTPG_SELF_ST );
if ( !((SelfStatus & SELF_ST_EEP_PRES) && (SelfStatus & SELF_ST_EEP_OK)))
{
#ifdef CS_DEBUG_ENABLE
logMsg("\ncs0 - EEPROM is missing or bad\n",0,0,0,0,0,0);
#endif
return ERROR;
}
/* Get Ethernet address from the EEPROM */
if ( csReadEEPROM(pCS,EEPROM_IND_ADDR_H,&pIA->word[0]) == ERROR )
return ERROR;
if ( csReadEEPROM(pCS,EEPROM_IND_ADDR_M,&pIA->word[1]) == ERROR )
return ERROR;
if ( csReadEEPROM(pCS,EEPROM_IND_ADDR_L,&pIA->word[2]) == ERROR )
return ERROR;
}
else /* Use Ethernet Address defined in csEnetAddr */
bcopyBytes ((char *) csEnetAddr, (char *) pIA, 6);
return OK;
}
/*******************************************************************************
*
* sysEnetHWInit - configure the adapter for board-specific IO and media support
*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -