📄 cs8900a.c
字号:
/* */
/* CS8900A_Open */
/* */
/* DESCRIPTION */
/* */
/* 该函数负责以太网网路芯片的初始化,以便进行通信,同时注册一个LISR, */
/* 处理所有网络芯片产生的中断。 */
/* */
/* CALLED BY */
/* */
/* CS8900A_Init */
/* */
/* CALLS */
/* */
/* CS8900A_Delay */
/* CS8900A_Set_Address */
/* CS8900A_Set_RXCFG */
/* NU_Register_LISR */
/* NU_Create_HISR */
/* */
/* INPUTS */
/* */
/* uint8 * : pointer to the hardware address. */
/* uint16 : The IRQ number. */
/* ulint : Shared memory buffer for TCP/IP packets, not used. */
/* ulint : I/O base address of the board. */
/* */
/* OUTPUTS */
/* */
/* NU_SUCCESS is returned if no errors occur, otherwise -1 is returned. */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/****************************************************************************/
STATUS CS8900A_Open (uint8 *ether_addr, DV_DEVICE_ENTRY *device)
{
STATUS status;
void *pointer;
int regval;
CS8900A_XDATA *n_data;
void (*CS8900A_old_vect_routine)(LONG);
static int open_count = 0;
unsigned long val;
NU_Sleep(20);
if((val=CS8900A_VerifyChip() ) != SUCCESS)
{
#ifdef DBGNET
UART_Printf("Cann't detect chip \n");
#endif
return -1;
};
#ifdef DBGNET
UART_Printf("Chip Verify ok!\n");
#endif
/* Point at the CS8900A xtended data. */
n_data = (CS8900A_XDATA *)device->user_defined_1;
/* Note that 1 is added to the unit number because the unit number has a
base of 0. However, RFC 1213 specifies that the interface Index has a
base of 1. */
SNMP_ifDescr(device->dev_unit + 1, "CS8900A Ethernet: Software revision 0.91");
SNMP_ifType(device->dev_unit + 1, 6);
SNMP_ifMtu(device->dev_unit + 1, device->dev_mtu);
SNMP_ifSpeed(device->dev_unit + 1, 10000000); /* 10 Mbps */
/* Get rid of those annoying compiler warnings. */
regval = (int) device -> dev_sm_addr;
/* Reset the chip */
if ( CS8900A_Reset(device) == FAILURE )
return (-1);
#ifdef DBGNET
UART_Printf("Reset CS8900A ok ! \n");
#endif
device->dev_vect = device->dev_irq;
/* read old, load new */
// NU_Register_LISR (device->dev_vect, CS8900A_LISR,
// &CS8900A_old_vect_routine);
XW_RegisterLISR(device->dev_vect, CS8900A_LISR,
&CS8900A_old_vect_routine);
Xos_sys_lisr_int_enable[XDRV_NET_RVECTOR] = 1;
/* The HISR can be shared by all CS8900A devices. So only create one. */
if (open_count++ == 0)
{
/* create the HISR for handling the interrupt from the Ethernet card */
status = NU_Allocate_Memory (&System_Memory, &pointer, 2048,
NU_NO_SUSPEND);
if (status != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_SESS_MEM, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
pointer = (void *)normalize_ptr(pointer);
status = NU_Create_HISR (&CS8900A_Ether_inter_Control, "ETHRHISR",
CS8900A_Recv_HISR,
0, pointer, 2048);
if (status != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_HRDWR_INIT, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
/* create the HISR for transmitting packets */
if (NU_Allocate_Memory (&System_Memory, &pointer, 2048,
NU_NO_SUSPEND) != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_SESS_MEM, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
pointer = (void *)normalize_ptr(pointer);
if (NU_Create_HISR (&CS8900A_inter_Trans, "TRANHISR",
CS8900A_Transmit, 0, pointer, 2048) != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_HRDWR_INIT, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
/* 产生用于Buffer事件中断的HISR */
if (NU_Allocate_Memory (&System_Memory, &pointer, 2048,
NU_NO_SUSPEND) != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_SESS_MEM, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
pointer = (void *)normalize_ptr(pointer);
if (NU_Create_HISR (&CS8900A_inter_BufferE, "BUFFEREVENT",
CS8900A_BufferEvent, 0, pointer, 2048) != NU_SUCCESS)
{
NU_Tcp_Log_Error (TCP_HRDWR_INIT, TCP_FATAL, __FILE__, __LINE__);
return (-1);
}
}
/* Set the current status to operational. */
SNMP_ifAdminStatus(device->dev_unit + 1, 1);
SNMP_ifOperStatus(device->dev_unit + 1, 1);
/* Initialize the ring buffer pointers. */
CS8900A_Read = CS8900A_Write = 0;
Host_Data_Write=Host_Data_Read=0;
/********************************************************************************/
// 杨天池,修改于2003.11.2
/********************************************************************************/
#ifdef DBGNET
UART_Printf("CS8900A init controler \n");
#endif
/*配置Eint9为中断*/
// rGPGCON |= 0xff95ffba;
rGPGCON = (rGPGCON & 0xfffffff3)|0x8;
/*不使用上拉*/
rGPGUP = 0xffff;
// Set the interrupt pin in the chip
CS8900AWritePacketPage( PKTPG_INT_NUM, 0x0 );
/* 使能片上中断功能 */
CS8900AWritePacketPage( PKTPG_BUS_CTL,
CS8900AReadPacketPage(PKTPG_BUS_CTL) | BUS_CTL_int_ENBL );
/* 使能接收的发送 */
CS8900AWritePacketPage( PKTPG_LINE_CTL,
CS8900AReadPacketPage(PKTPG_LINE_CTL) | LINE_CTL_RX_ON | LINE_CTL_TX_ON );
rEINTPEND = 0xffffff;
rSRCPND = BIT_EINT8_23; //to clear the previous pending states
rINTPND = BIT_EINT8_23;
rEXTINT1 =( rEXTINT1 & 0xFFFFFF0F ) | 0X40; // config EINT9 as assert
rEINTMASK = rEINTMASK & 0xfffffDff;// enable EINT9
rINTMSK= rINTMSK&(~BIT_EINT8_23);
/********************************************************************************/
// 修改结束
/********************************************************************************/
return NU_SUCCESS;
} /* end CS8900A_Open */
/****************************************************************************/
/* FUNCTION */
/* */
/* CS8900A_Recv_Packet */
/* */
/* DESCRIPTION */
/* */
/* This function will handle the incomming data packets to the Ehternet */
/* board. It is called from the LISR whenever a receive interrupt */
/* occurrs. It will handle the parsing and storing of the current packet */
/* from the wire. */
/* */
/* AUTHOR */
/* */
/* */
/* CALLED BY */
/* */
/* CS8900A_LISR */
/* */
/* CALLS */
/* */
/* OUTB */
/* INB */
/* INW */
/* */
/* INPUTS */
/* */
/* No inputs to this function. */
/* */
/* OUTPUTS */
/* */
/* sshort : Returns status as to buffer processing NU_TRUE if ok */
/* NU_FALSE if an error. */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Glen Johnson 02/17/96 Created initilal version. */
/* Glen Johnson 10/14/96 Fixed bug. The last byte of odd sized */
/* packets was not being copied. */
/* */
/****************************************************************************/
STATUS CS8900A_Recv_Packet (DV_DEVICE_ENTRY *device, unsigned short RxEvent)
{
uint16 pkt_size;
NET_BUFFER *buf_ptr, *work_buf;
int bytes_left;
CS8900A_XDATA *n_data;
unsigned short *pFrame;
unsigned short Length;
unsigned short value;
STATUS previous_int_value;
/* Verify that it is an RxOK event */
if (RxEvent & RX_EVENT_RX_OK)
// return;
{
/* Lock out interrupts. */
previous_int_value = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* Read the header from the frame buffer */
if ( CS8900AInMemoryMode )
{
// pFrame = CS8900A_pPacketPage + (PKTPG_RX_LENGTH/2);
// Length = *pFrame++;// - HEADER_LENGTH;
}
else /* In IO mode */
{
value=*((unsigned short *)PORT_RXTX_DATA); /* Discard RxStatus */
Length = *((unsigned short*)PORT_RXTX_DATA);// - HEADER_LENGTH;
}
/* If there is an extra byte at the end of the frame */
/* Point at the CS8900A xtended data. */
n_data = (CS8900A_XDATA *)device->user_defined_1;
/* Compute the packet size. */
pkt_size = Length;
/* Allocate a chain of buffers into which the received packet can
be copied. */
buf_ptr = MEM_Buffer_Chain_Dequeue(&MEM_Buffer_Freelist, pkt_size);
/* Only get the packet out of the buffer if we have somewhere to
put it. If we do not have anywhere to put it, then we will
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -