📄 cs8900a.c
字号:
fall through and tell the device that we got it even though
we didn't. That is, the packet is dropped. */
if (buf_ptr != NU_NULL)
{
/* Put the head of the chain onto the incoming packet buffer list */
MEM_Buffer_Enqueue (&MEM_Buffer_List, buf_ptr);
/* Compute the total number of bytes that must be copied. */
bytes_left = pkt_size;
/* Preserve a pointer to the interface on which this packet was
received. */
buf_ptr->mem_buf_device = device;
/* Clear the flags field. */
buf_ptr->mem_flags = 0;
/* Get a work pointer to the buffer chain */
work_buf = buf_ptr;
/* This while loop cycles through each of the buffers in the chain.
The data_ptr and data_len are initialized for each of these
buffers. This information is required by the CS8900A_Chip_Read
function that is called below. CS8900A_Chip_Read uses DMA to copy
the received packet into the buffer chain. */
while (bytes_left && work_buf)
{
/* The first buffer in the chain is a special case. Becase there
is management overhead in the first buffer it can not hold as
much data as succeding buffers. */
if (work_buf == buf_ptr)
{
/* Initialize the data_ptr and data_len for the first buffer
in the chain. */
work_buf->data_len = (bytes_left <= NET_PARENT_BUFFER_SIZE) ?
bytes_left : NET_PARENT_BUFFER_SIZE;
work_buf->data_ptr = work_buf->mem_parent_packet;
}
else
{
/* Initialize the data_ptr and data_len for the 2nd and
succedding buffers. */
work_buf->data_len = (bytes_left <= NET_MAX_BUFFER_SIZE) ?
bytes_left : NET_MAX_BUFFER_SIZE;
work_buf->data_ptr = work_buf->mem_packet;
}
/* Update a count of the bytes that still must have a home. */
bytes_left -= work_buf->data_len;
/* Move to the next buffer in the chain */
work_buf = (NET_BUFFER *)work_buf->next_buffer;
}
/* Initialize the total data length for this buffer chain. */
buf_ptr->mem_total_data_len = pkt_size;
/* Now perform the actual copy.
此处需要执行调用从网络芯片拷贝数据到系统内存的函数。*/
CS8900A_Chip_Read ( device->dev_io_addr, buf_ptr, pFrame );
/* Update the total number of octets received. */
// SNMP_ifInOctets(device->dev_unit + 1, (RBUF_HDR_LEN + header[1]));
return NU_SUCCESS;
}
else
{
SNMP_ifInDiscards_Inc(device->dev_unit + 1)
return(-1);
}
/* Re-enable interrupts. */
NU_Local_Control_Interrupts(previous_int_value);
}//end of if ((RxEvent & RX_EVENT_RX_OK))
else
return(-1);
} /* end CS8900A_Recv_Packet */
/******************************************************************************/
/* FUNCTION */
/* */
/* CS8900A_Xmit_Packet */
/* */
/* DESCRIPTION */
/* */
/* This function will handle placing the passed in packet onto the actual */
/* wire. This routine will make sure that each packet is at least 60 */
/* bytes long. */
/* */
/* AUTHOR */
/* */
/* CALLED BY */
/* */
/* NET_Ether_Send */
/* */
/* CALLS */
/* */
/* OUTB */
/* INB */
/* CS8900A_Chip_Write */
/* */
/* INPUTS */
/* */
/* uint8 : pointer to the packet to be sent. */
/* uiint16 : size of the packet in bytes. */
/* */
/* OUTPUTS */
/* */
/* sshort : Returns NU_SUCCESS (0) if ok, else -1 due to wait for trans */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Glen Johnson 02/17/96 Initial version */
/* Glen Johnson 10/14/96 Replaced call to NU_Control_interrupts */
/* with masking of interrupts on the NIC. */
/* */
/******************************************************************************/
STATUS CS8900A_Xmit_Packet (DV_DEVICE_ENTRY *device, NET_BUFFER *buf_ptr)
{
int n_sent;
int pktlen = buf_ptr->mem_total_data_len;
//#if SNMP_INCLUDED
#if (INCLUDE_SNMP == NU_TRUE)
/* Is this a unicast or a non-unicast packet. */
if ( (buf_ptr->mem_flags & NET_BCAST) || (buf_ptr->mem_flags & NET_MCAST) )
SNMP_ifOutNUcastPkts_Inc(device->dev_unit + 1);
else
SNMP_ifOutUcastPkts_Inc(device->dev_unit + 1);
#endif
/*
* 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_Chip_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);
} /* end CS8900A_Xmit */
/****************************************************************************/
/* FUNCTION */
/* */
/* CS8900A_Transmit */
/* */
/* DESCRIPTION */
/* */
/* This function will transmit any packets that are waiting in the */
/* transmit queue. This is the entry point for the transmit HISR. */
/* */
/* AUTHOR */
/* */
/* */
/* CALLED BY */
/* */
/* Activated by the LISR */
/* */
/* CALLS */
/* */
/* NU_Control_interrupts */
/* dll_dequeue */
/* dll_enqueue */
/* CS8900A_Xmit_Packet */
/* */
/* INPUTS */
/* */
/* No inputs to the function */
/* */
/* OUTPUTS */
/* */
/* No outputs from this function */
/* */
/* HISTORY */
/* */
/* NAME DATE REMARKS */
/* */
/* Glen Johnson 02/17/96 Initial version. */
/* */
/****************************************************************************/
void CS8900A_Transmit (void)
{
STATUS previous_int_value;
NET_BUFFER *buf_ptr;
DV_DEVICE_ENTRY *device;
/* Get a pointer to the device. */
device = CS8900A_RBuffer[CS8900A_Read];
/* Update the read index. */
if(CS8900A_Read >= (MAX_CS8900A_DEVICES -1))
CS8900A_Read = 0;
else
CS8900A_Read++;
if (device == NU_NULL)
return;
/* Lock out interrupts. */
previous_int_value = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* If there is an item on the transmit list (there should be everytime we
* 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_Xmit_Packet(device, device->dev_transq.head);
return; //because has enabled interrupt
}
}
/* Re-enable interrupts. */
NU_Local_Control_Interrupts(previous_int_value);
} /* CS8900A_Transmit */
/*缓冲区事件的高级中断处理程序。*/
void CS8900A_BufferEvent(void)
{
STATUS previous_int_value;
NET_BUFFER *buf_ptr;
DV_DEVICE_ENTRY *device;
/* Get a pointer to the device. */
device = CS8900A_THOSTBuffer[Host_Data_Read];
/* Update the read index. */
if(Host_Data_Read >= (MAX_CS8900A_DEVICES -1))
Host_Data_Read = 0;
else
Host_Data_Read++;
if (device == NU_NULL)
return;
/* Lock out interrupts. */
previous_int_value = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/* If there is an item on the transmit list (there should be everytime we
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -