📄 cs8900a.c
字号:
* get here) then remove it because it has just been successfully
* transmitted. */
if(device -> dev_transq.head)
{
buf_ptr = MEM_Buffer_Dequeue(&device->dev_transq);
MEM_One_Buffer_Chain_Free (buf_ptr, buf_ptr->mem_dlist);
/* If there is another item on the list, transmit it. */
if(device -> dev_transq.head)
{
/* Re-enable interrupts. */
NU_Local_Control_Interrupts(previous_int_value);
/* Transmit the next packet. */
CS8900A_Buffer_Packet(device, device->dev_transq.head);
return;
}
}
/* Re-enable interrupts. */
NU_Local_Control_Interrupts(previous_int_value);
}
STATUS CS8900A_Buffer_Packet (DV_DEVICE_ENTRY *device, NET_BUFFER *buf_ptr)
{
int pktlen = buf_ptr->mem_total_data_len;
int n_sent;
/*
* Check to make sure that the message has the minimum of at least 60
* bytes long. If not just set the new length, since hardware will do
* the checksum for the whole block.
*/
if (pktlen < 60)
{
pktlen = 60;
} /* end check for message is to small */
/* Mask all network interrupts. */
// CS8900AWritePacketPage(PKTPG_BUS_CTL,
// CS8900AReadPacketPage(PKTPG_BUS_CTL) & ~BUS_CTL_int_ENBL );
n_sent = CS8900A_Buffer_Write(device->dev_io_addr, buf_ptr);
/* Re-enable network interrupts. */
// CS8900AWritePacketPage( PKTPG_BUS_CTL,
// CS8900AReadPacketPage(PKTPG_BUS_CTL) | BUS_CTL_int_ENBL );
// if (n_sent < 60)
// return (-1);
SNMP_ifOutOctets(device->dev_unit + 1, n_sent);
return (NU_SUCCESS);
}
int CS8900A_Buffer_Write(int16 io_addr, NET_BUFFER *buf_ptr)
{
STATUS previous_int_value;
uint16 i;
uint16 *pack_addr;
uint16 pktlen = buf_ptr->mem_total_data_len;
uint16 len;
uint16 total_sent;
unsigned short *pFrame;
total_sent=0;
/* Lock out interrupts. */
previous_int_value = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
len = buf_ptr->data_len + (buf_ptr->data_len & 1);
pack_addr = (uint16 *)buf_ptr->data_ptr;
if ( CS8900AInMemoryMode )
{
for(i=0; i<len/2; i++)
*pFrame++ = *pack_addr++;
}
else
{
for(i=0; i<len/2; i++)
*((unsigned short *)PORT_RXTX_DATA)=*pack_addr++;
}
total_sent = i;
/* Point to the next buffer in the chain. */
buf_ptr = (NET_BUFFER *)buf_ptr->next_buffer;
/* While there are more buffers in the chain transfer the data therin to
the chip. */
while (buf_ptr)
{
/* Guarentee the length is divisible by two. This should only be a
problem when the last buffer in the chain is encountered. */
len = buf_ptr->data_len + (buf_ptr->data_len & 1);
/* Get a pointer to the data. */
pack_addr = (uint16 *)buf_ptr->data_ptr;
/* Transfer the data to the chip. */
if ( CS8900AInMemoryMode )
{
for(i=0; i<len/2; i++)
*pFrame++ = *pack_addr++;
}
else
{
for(i=0; i<len/2; i++)
*((unsigned short *)PORT_RXTX_DATA)=*pack_addr++;
}
total_sent += i;
buf_ptr = (NET_BUFFER *)buf_ptr->next_buffer;
}
/* This loop is only necessary when the packet to be sent is less than the
ethernet minimum of 60. In that case this loop will send the bytes
required to pad the whole length out to 60. */
while (total_sent++ < pktlen/2)
{
if ( CS8900AInMemoryMode )
{
*pFrame++ = *pack_addr++;
}
else
{
*((unsigned short *)PORT_RXTX_DATA)=*pack_addr++;
}
}
/* Re-enable interrupts. */
NU_Local_Control_Interrupts(previous_int_value);
return(total_sent);
}
/****************************************************************************/
/* FUNCTION */
/* */
/* CS8900A_LISR */
/* */
/* DESCRIPTION */
/* */
/* This function handles all interrupts generated by the CS8900A. If */
/* either a transmit or receive interrupt occurs a HISR is activated to */
/* complete processing of the packet. */
/* */
/* AUTHOR */
/* */
/* */
/* CALLED BY */
/* */
/* No functions call this function */
/* */
/* CALLS */
/* */
/* OUTB : Write a byte to the PC I/O buss. */
/* INB : Read a byte from the PC I/O buss. */
/* NU_Activte_HISR */
/* CS8900A_Recv_Packet */
/* */
/* INPUTS */
/* */
/* vector: The interrupt vector on which the interrupt was generated. */
/* This parameter is not used. */
/* */
/* OUTPUTS */
/* */
/* No outputs from this function */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Glen Johnson 02/17/96 Initial version. */
/* */
/****************************************************************************/
void CS8900A_LISR (LONG vector)
{
DV_DEVICE_ENTRY *device;
CS8900A_XDATA *n_data;
unsigned short Event;
//////////////////////////////////////////////////////////////////////////
// 杨天池,修改于2003.11.3
// 清楚EINTPEND SRCPND INTPND 三个寄存器的挂起位,避免开中断后,有进入中断
//////////////////////////////////////////////////////////////////////////
rEINTMASK |= 0x00000200; // 屏蔽 EINT9
rINTMSK |= (BIT_EINT8_23);
//清除EINTPEND的相应位
rEINTPEND |= 0x00000200;
//清除SRCPND的相应位
ClearPending(BIT_EINT8_23);
// add by ytc 2004.11.25 enable interrupt nest
// XW_EnableInterrupt(0,0);
//////////////////////////////////////////////////////////////////////////
// 杨天池,修改于2003.11.3 结束
//////////////////////////////////////////////////////////////////////////
/* Find the device for this interrupt. */
// device = DEV_Get_Dev_For_Vector(vector);
device = (DV_DEVICE_ENTRY *)Xos_Lisr_Driver[vector];
/* If the device is not correct then exit */
if (device == (DV_DEVICE_ENTRY *) 0)
return;
/* Point at the CS8900A xtended data. */
n_data = (CS8900A_XDATA *)device->user_defined_1;
/* Read an event from the interrupt Status Queue */
if ( CS8900AInMemoryMode )
Event = CS8900AReadPacketPage( PKTPG_ISQ );
else
Event =*((unsigned short *)PORT_ISQ);
/* Process all the events in the interrupt Status Queue */
while ( Event != 0 )
{
/* Dispatch to an event handler based on the register number */
switch ( Event & REG_NUM_MASK )
{
case REG_NUM_RX_EVENT:
if(CS8900A_Recv_Packet(device, Event)==NU_SUCCESS)
NU_Activate_HISR (&CS8900A_Ether_inter_Control);
break;
case REG_NUM_TX_EVENT:
/* The packet was successfully transmitted. */
/* Transmit the next packet. */
//#ifndef PACKET
/* Pass the device pointer to the HISR. */
CS8900A_RBuffer[CS8900A_Write] = device;
/* Point to the next location in the ring buffer. */
if(CS8900A_Write >= (MAX_CS8900A_DEVICES -1))
CS8900A_Write = 0;
else
CS8900A_Write++;
if(CS8900A_Write == CS8900A_Read)
{
CS8900A_Reset(device);
}
/* Activate the transmit HISR. */
NU_Activate_HISR (&CS8900A_inter_Trans);
//#endif
break;
case REG_NUM_BUF_EVENT:
/* The packet was successfully transmitted. */
/* Transmit the next packet. */
//#ifndef PACKET
/* Pass the device pointer to the HISR. */
CS8900A_THOSTBuffer[Host_Data_Write]=device;
/* Point to the next location in the ring buffer. */
if(Host_Data_Write >= (MAX_CS8900A_DEVICES -1))
Host_Data_Write = 0;
else
Host_Data_Write++;
if(Host_Data_Write == Host_Data_Read)
{
CS8900A_Reset(device);
}
if ( Event & BUF_EVENT_RDY4TX )
/* Activate the transmit HISR. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -