📄 csend.c
字号:
/* csEnd.c - Crystal Semiconductor CS8900 network interface driver */
/* */
/* Copyright 2000 Crystal Semiconductor Corp. */
/* */
/* Last release: v3.05a */
/* Mod level for last release: 05a */
/*
modification history
--------------------
v3.06a,11/02/01, kml
- Added BYTE_SWAP() in writting to the multicast filter register.
- remove if (END_MULTI_LST_CNT(&pCS->end) > 0) {} in csConfig() so that
csAddrFilterSet() is always called. csAddrFilterSet() will zero the
MulticastTable and return if the last one in END_MULTI_LST has been deleted.
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.
- Pass ETHERMTU to END_MIB_INIT() instead of
ETHERMTU+SIZEOF_ETHERHEADER to fix the bug that pinging the
target with a packet size larger than the MTU size would fail.
- Added INT_LOCK and INTUNLOCK in csTxNextFrame() to fixed the bug
that CS8900 stops Tx after Tx underrun errors occurs.
v3.04a,09May01, kml
-Added support for SH3. ALIGMENT_32BIT needs to be defined for
SH3, ARM, MIPS.
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,07May99, kml ported to the Enhanced Network Driver (END) model
to support the MUX interface.
01g.25nov97.jla Added defs to help a page fault with hard resets.
HARD_RESET does hard chip resets
SOFT_RESET does a softer, kinder sort of reset
The routine csResetChip does one or the other based
on the define set in if_cs.h
01q,11apr97,rks Implementd "early tx" support. Required mods to csLoad
(initialization), csInitChip (early tx int enable),
csTxNextFrame, and csBufferEvent.
01p,09apr97,rks Replaced common TX code in csStartOutput and csTransmitEvent
with a new routine csTxNextFrame().
Added conditional compile for a Tx Queue depth and max TX
Queue depth counter if CS_DEBUG_ENABLE defined.
01o,07apr97,rks Changed queue routines (enqueue and deueue) to make the data
update prior to pointer update. Removed the int lock/unlock
around the queue accesses in csEventHandler (no longer needed
with the new queue routines).
Moved the m_freem call to after the intUnlock in csStartOutput.
01n,01apr97,rks Implemented a local queue for TX frames. On csStartOuput call,
the interface's queue is drained. Frames are then taken from
the local queue in csStartOutput and at ISR level for transmit
to ensure the interface's queue is manipulated only by routines
at the same context (csStartOuput and ether_output).
01m,30mar97,rks Modified the csIntHandler. Removed the chip int disables and
replaced with CLI/STI pairs only around queue manipulations.
Also, now use a "NetJobDepth" counter instead of an active flag
to determine if another csIntHandler needs to be queued.
Moved the netJobAdd logic to the bottom of the ISR and removed
it from all the ISR sub-routines.
01l,27mar97,rks Bracketed mbuff routines in csProcessReceive with splnet/splx.
01k,28feb97,rks Added circular queue manipulation routines to handle TX mbufs
to be freed and RX frames to be handled at the task level.
Created generic event handler (csEventHandler) to processe RX
frame processing and TX mbuff freeing at the task level.
Added a counter to ensure never more than 2 instances of the
event handler are queued for tNetTask processing.
01j,27feb97,rks Added support for the collision counter. Moved support for Rx
miss counter to ISR (saves a function call).
01h,25feb97,rks Modifications for MIPS suppport (prevent word reads from odd
addresses in csCopyTXFrame. Debug macro to replace csError
routine. (Greg Rasche)
01g,07jan97,rks Modified csLoad to remove parameter for specifying
Ethernet address.
01f,16dec96,rks Divided the driver into two files, this file for
system-indendent routines and "sysEnet.c" containing
target-specific routines and macros for "IO mode" operations.
Added BYTE_SWAP macro for all non-constant io values
to the CS8900. Replace pcX86-specific io routine
calls with SYS_IN/OUT macros.
01e,12dec96,rks Moved the pTxFrameChain variable to the CS_END_DEVICE structure.
Moved the int disable in csStartOutput to immediately
before the Rdy4TxNow poll. Mutex'd the call to
IF_DEQUEUE in csStartOutput with splnet/splx.
01d,05dec96,rks Removed the processing of every RX miss and implemented
support for RX miss statistics using the RX miss counter
with RX Miss Counter Overflow interrupts instead.
01c,25nov96,rks Added version number to statistics reported by csShow(),
Added support for TX on Rdy4Tx interrupts, Created
routine csFreeTxFrame() to move call of m_freem()
to task level Added statistic reported by csShow for
Rdy4Tx events
01b,16nov96,rks Removed support for collision counter (AnyColliE) to
improve system perf.
01a,12jul96,q_s Written.
*/
/*
DESCRIPTION
This module implements the Crystal Semiconductor CS8900 Ethernet network
interface driver.
This driver's structure is designed to facilitate porting to any architecture
supported by VxWorks. The routines in this file are system independent. A
library of system-dependent routines in the file "csSysEnd.c" must be provided
for the target system. This driver supports only one CS8900 device per system
board.
SYSTEM DEPENDENT SUPPORT ROUTINES
This driver requires five system-dependent support routines. These five
routines are defined in sysEnet.c.
* sysEnetGetConfig( CS_END_DEVICE *pCS )
This routine takes configuration parameters not specifed to csEndLoad(), if
any, from non-volatile storage (e.g. an attached EEPROM) and puts them in
the CS_END_DEVICE structure.
* sysEnetAddrGet( CS_END_DEVICE *pCS, unsigned char *pAddr )
This routine obtains the Ethernet MAC address from non-volatile storage or
from the "csEnetAddr" array in csSysEnd.c dependent on the
CS8900_ENET_ADDR_FROM_BOARD flag defined in csSysEnd.c and saves the
Ethernet address to 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.
INCLUDE FILES: csEnd.h, csSysEnd.c
*/
/* INCLUDES */
#include "vxWorks.h"
#include "sysLib.h"
#include "intLib.h"
#include "logLib.h"
#include "netLib.h"
#include "etherLib.h"
#include "stdio.h"
#include "iv.h"
#include "ioctl.h"
#include "taskLib.h"
#include "net/if_subr.h"
#include "etherMultiLib.h"
#include "end.h"
#include "endLib.h"
#include "lstLib.h"
#include "csEnd.h"
/* ALIGMENT_32BIT needs to be defined for the processors that perform 32-bit
read/write, such as ARM, Strong ARM, SH3, SH4, and MIPS.
If the data buffer for transmission starts on an odd address boundary, copy it
to a temporary buffer that starts on an even address boundary, and write the
temporary buffer to the CS8900 Chip. */
/* #define ALIGMENT_32BIT */
/*********************** User Defines *******************************/
/* this flag is used to turn DEBUG on or off */
#define CS_DEBUG_ENABLE
/*CS8900_INTERRUPT_REQUEST_PIN_NUM is used for non-Ix86 processors.
For the users of the Intel x86 processors, this define will NOT be used. You can ignore it.
For the users of the non-Ix86 processors (eg. SHx, ARM, MIPS...), this define must be defined.
The CS8900 has four interrupt request output pins that can be connected directly
to Processor. Only one interrupt output pin is connected to your processor.
CS8900_INTERRUPT_PIN_NUM defines which interrupt pin is used.
0: INTRQ0
1: INTRQ1
2: INTRQ2
3: INTRQ3
*/
#define CS8900_INTERRUPT_REQUEST_PIN_NUM 0 /* or other number: 0-3 */
/*********************** End of User Defines *******************************/
/*************************************************************************************/
#ifdef CS_DEBUG_ENABLE
#undef LOCAL
#define LOCAL
#endif
#include "csSysEnd.c" /* lib of BSP specific routines used by CS8900 driver */
/* DEFINES */
#define CS_DRIVER_VER "3.06a" /* Driver revsion number */
#define CS_NAME "cs" /* the device name used to locate the END driver*/
#define CS_NAME_LEN 3 /* the length of the CS_NAME + 1 */
/* Configuration items */
#define END_BUFSIZE (SIZEOF_ETHERHEADER+ETHERMTU+6)/* 4-byte alignment*/
#define END_SPEED 10000000
/* A shortcut for getting the hardware address from the MIB II stuff. */
#define END_HADDR(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
#define END_HADDR_LEN(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
/*********************** end debug macro *******************************/
/* FORWARD DECLARATIONS */
/* This is the only externally visible interface. */
END_OBJ* csEndLoad (char* initString);
void csShow(void); /* may be called from WindSh */
/*********** END required routines ****************/
LOCAL STATUS csStart(END_OBJ * pV);
LOCAL STATUS csStop(END_OBJ * pV);
LOCAL STATUS csUnload(END_OBJ * pV);
LOCAL int csIoctl( END_OBJ * pV, int Command, caddr_t data );
LOCAL STATUS csSend (END_OBJ * pV, M_BLK_ID pMBufChain);
LOCAL STATUS csMCastAdd (END_OBJ * pV, char* pAddress);
LOCAL STATUS csMCastDel (END_OBJ * pV, char* pAddress);
LOCAL STATUS csMCastGet (END_OBJ * pV, MULTI_TABLE* pTable);
LOCAL STATUS csPollSend (END_OBJ * pV, M_BLK_ID pMblk);
LOCAL STATUS csPollRcv (END_OBJ * pV, M_BLK_ID pMblk);
LOCAL STATUS csPollStart (END_OBJ * pV);
LOCAL STATUS csPollStop (END_OBJ * pV);
LOCAL CS_END_DEVICE *csParse( char *initString);
LOCAL STATUS csInitRxBuff( CS_END_DEVICE *pCS );
LOCAL STATUS csVerifyChip( CS_END_DEVICE *pCS );
STATUS csInit( CS_END_DEVICE *pCS);
LOCAL void csInitChip( CS_END_DEVICE *pCS );
void csReset( CS_END_DEVICE *pCS);
LOCAL void csConfig( CS_END_DEVICE *pCS);
LOCAL STATUS csResetChip( CS_END_DEVICE *pCS );
LOCAL void csStartOutput( CS_END_DEVICE *pCS, M_BLK_ID pMbuf);
LOCAL void csCopyTxFrame( CS_END_DEVICE *pCS, M_BLK_ID pMbufChain );
LOCAL void csIntr( CS_END_DEVICE *pCS);
LOCAL void csEventHandler( CS_END_DEVICE *pCS );
LOCAL void csBufferEvent( CS_END_DEVICE *pCS, USHORT BuffEvent );
LOCAL void csTransmitEvent( CS_END_DEVICE *pCS, USHORT TxEvent );
LOCAL void csTxNextFrame( CS_END_DEVICE *pCS );
LOCAL void csReceiveEvent( CS_END_DEVICE *pCS, USHORT RxEvent );
LOCAL int csCopyRxFrame( CS_END_DEVICE *pCS,char *pRxBuff );
LOCAL void csProcessReceive( CS_END_DEVICE *pCS, M_BLK_ID pRxBuff );
LOCAL USHORT csReadPacketPage( CS_END_DEVICE *pCS, USHORT Offset );
LOCAL void csWritePacketPage( CS_END_DEVICE *pCS, USHORT Offset, USHORT Value );
LOCAL void csInitQueue( CIR_QUEUE *Q );
LOCAL void *csDequeue( CIR_QUEUE *Q );
LOCAL STATUS csEnqueue( CIR_QUEUE *Q, void *pBuff );
LOCAL BOOL csQueueEmpty( CIR_QUEUE *Q );
UCHAR calculateHashIndex(UCHAR *pMulticastAddr);
LOCAL void updateCrc( USHORT bit );
LOCAL void csAddrFilterSet(CS_END_DEVICE *pCS);
LOCAL void csPurgeQs(CS_END_DEVICE *pCS);
extern void * cacheDmaMalloc (size_t bytes);
extern int endMultiLstCnt( END_OBJ* pEnd);
/* used to calculate multicast hash index */
int CRC_Poly[] = {1,1,1,0, 1,1,0,1,
1,0,1,1, 1,0,0,0,
1,0,0,0, 0,0,1,1,
0,0,1,0, 0,0,0,0 };
int CRC[33];
/*
* Declare our function table. This is static across all driver
* instances.
*/
LOCAL NET_FUNCS endFuncTable =
{
(FUNCPTR) csStart, /* Function to start the device. */
(FUNCPTR) csStop, /* Function to stop the device. */
(FUNCPTR) csUnload, /* Unloading function for the driver. */
(FUNCPTR) csIoctl, /* Ioctl function for the driver. */
(FUNCPTR) csSend, /* Send function for the driver. */
(FUNCPTR) csMCastAdd, /* Multicast address add function for the */
/* driver. */
(FUNCPTR) csMCastDel, /* Multicast address delete function for */
/* the driver. */
(FUNCPTR) csMCastGet, /* Multicast table retrieve function for */
/* the driver. */
(FUNCPTR) csPollSend, /* Polling send function for the driver. */
(FUNCPTR) csPollRcv, /* Polling receive function for the driver. */
endEtherAddressForm, /* Put address info into a packet. */
endEtherPacketDataGet, /* Get a pointer to packet data. */
endEtherPacketAddrGet /* Get packet addresses. */
};
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
* OS Entry-point Routines *
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/*******************************************************************************
*
* csEndLoad - initialize the driver and device
*
* This routine initializes the driver and the device to the operational state.
* All of the device specific parameters are passed in the initString.
*
* The string contains the target specific parameters like this:
*
* "Unit:IOAddr:IntLevel:MemAddr:MediaType:ConfigFlags"
*
* RETURNS: An END object pointer or NULL on error.
*/
END_OBJ* csEndLoad (
char* initString /* String to be parsed by the driver. */
)
{
FAST CS_END_DEVICE *pCS;
STATUS status1, status2;
if (initString == NULL)
return (NULL);
/*OS wants to get the END Ethernet device name if a null string is passed.*/
if (initString[0] == NULL)
{
bcopy((char *)CS_NAME, initString, CS_NAME_LEN);
#ifdef CS_DEBUG_ENABLE
logMsg("csEndLoad(): Returning CS8900 Device Name string...\n", 0, 0, 0,0, 0,0);
#endif
return ((END_OBJ *)OK);
}
/* parse the init string, filling in the device structure */
pCS=csParse (initString);
if (pCS == NULL)
{
#ifdef CS_DEBUG_ENABLE
logMsg("csEndLoad(): Parser Error in initString.\n", 0, 0, 0 ,0, 0 ,0);
#endif
return NULL;
}
/* Start out in IO mode */
pCS->InMemoryMode = FALSE;
/* Init TX in progress flag */
pCS->TxInProgress = FALSE;
/* Init the TX start command */
pCS->TxStartCMD = CS_INITIAL_START_CMD;
/* Set counters to zero */
pCS->TxUnderruns = 0;
pCS->TotalTxUnderruns = 0;
pCS->Collisions = 0;
pCS->MaxTxDepth = 0;
pCS->Rdy4TxInts = 0;
pCS->NetJobDepth = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -