📄 net_nic.c
字号:
/* ----------------- INIT INT CTRL'R ------------------ */
#if (NET_NIC_CFG_INT_CTRL_EN == DEF_ENABLED)
NetNIC_IntInit(); /* See Note #5. (Enable CPU interrupts to accept CS8900 int */
#endif
CS8900_DBG_PRINT("8900 init done\r\n");
}
/*
*********************************************************************************************************
* CS8900_RxPkt()
*
* Description : (1) Read network packet from NIC into buffer :
*
* (a) Clear all receiver errors
* (b) Find the first buffer marked 'software-owned'
* 'software owned' means that the NIC has copied a packet frame into it
* (c) Read received packet frame from CS8900
* (d) Release received packet
*
*
* Argument(s) : ppkt Pointer to memory buffer to receive NIC packet.
* ---- Argument checked in NetNIC_RxPkt().
*
* size Number of packet frame octets to read into buffer.
* ---- Argument checked in NetNIC_RxPkt().
*
* perr Pointer to variable that will hold the return error code from this function :
*
* NET_NIC_ERR_NONE Packet successfully transmitted.
* CS8900_ERR_RX_BUSY Receiver not ready.
*
* Return(s) : none.
*
* Caller(s) : NetNIC_RxPkt().
*
* Note(s) : (2) See 'CS8900 RECEIVE BUFFER DESCRIPTOR' for packet frame format.
*********************************************************************************************************
*/
NET_LOCAL void CS8900_RxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
char *ptr;
*perr = NET_NIC_ERR_NONE;
CPU_CRITICAL_ENTER();
if (frame_bff_num == 0) {
CS8900_DBG_PRINT("Frame buffer underflow\r\n");
CPU_CRITICAL_EXIT();
return;
}
ptr = (char *)&frame_bff[frame_bff_tail].Frame;
frame_bff_tail++;
if (frame_bff_tail >= (CS8900_NUM_ETH_FRAME_BUF - 1)) {
frame_bff_tail = 0;
}
frame_bff_num--;
CPU_CRITICAL_EXIT();
Mem_Copy((char *)ppkt, (char *)ptr,size);
}
/*
*********************************************************************************************************
* CS8900_RxPktDiscard()
*
* Description : Discard network packet from NIC to free NIC packet frames for new receive packets.
*
* Argument(s) : size Number of packet frame octets.
*
* Return(s) : none.
*
* Caller(s) : NetNIC_RxPktDiscard().
*
* Note(s) : (1) 'size' NOT required for CS8900 packet discard.
*********************************************************************************************************
*/
NET_LOCAL void CS8900_RxPktDiscard (CPU_INT16U size)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
(void)size;
CPU_CRITICAL_ENTER();
CPU_CRITICAL_EXIT();
}
/*
*********************************************************************************************************
* CS8900_TxPkt()
*
* Description : (1) Instruct CS8900 NIC to send network packet :
*
* (a) Check is transmitter ready.
* (b) Copy packet info transmitter buffer
* (c) Clear all transmitter errors.
* (d) Inform transmitter about buffer address and size.
* This starts actual transmission of the packet.
*
*
* Argument(s) : ppkt Pointer to memory buffer to transmit NIC packet.
* ---- Argument checked in NetNIC_TxPkt().
*
* size Number of packet frame octets to write to frame.
*
* perr Pointer to variable that will hold the return error code from this function :
*
* NET_NIC_ERR_NONE Packet successfully transmitted.
* CS8900_ERR_TX_BUSY Transmitter not ready.
*
* Return(s) : none.
*
* Caller(s) : NetNIC_TxPkt().
*
* Note(s) : (2) See 'CS8900 RECEIVE BUFFER DESCRIPTOR' for packet frame format.
*********************************************************************************************************
*/
NET_LOCAL void CS8900_TxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
CPU_INT16U stat;
CPU_INT16U *sdata;
*perr = NET_NIC_ERR_NONE;
CPU_CRITICAL_ENTER();
CS8900_RegWr(CS8900_TxCMD_OFFSET, PP_TxCmd_TxStart_Full); /* Step 1: Write the TX command */
CS8900_RegWr(CS8900_TxLEN_OFFSET, size); /* Step 2: Bid for Tx */
/* Write the frame length (number of bytes to TX) */
/* Note: After the frame length has been written, CS8900 */
/* reserves Tx bufferfor this bid no matter PP_BusStat_TxRDY */
/* is set or not. */
stat = CS8900_PPRegRd(PP_BusStat); /* Read BusST to verify it is set as Rdy4TxNow. */
if ((stat & PP_BusStat_TxBid) != 0) { /* Step 3: check if TxBidErr happens */
CS8900_DBG_PRINT("Tx Bid Error!\r\n");
CPU_CRITICAL_EXIT(); /* Step 3.1: enable interrupts at processor level. */
*perr = NET_NIC_ERR_NONE;
return;
}
if ((stat & PP_BusStat_TxRDY) == 0) { /* Step 4: check if chip is ready for Tx */
/* If Bid4Tx not ready, return immediately and wait */
/* for ReadyForTx Interrupt. */
CPU_CRITICAL_EXIT(); /* Step 4.1: enable interrupts at processor level. */
*perr = NET_NIC_ERR_NONE;
return;
}
sdata = (CPU_INT16U *)ppkt; /* Step 5: copy Tx data into CS8900's buffer */
if (size > 0) { /* This actually starts the Txmit */
while (size > 1) { /* Output contiguous words, two bytes at a time. */
CS8900_RegWr(CS8900_RTDATA_OFFSET, *sdata);
sdata++;
size -= 2;
}
if (size == 1) { /* If Odd bytes, copy the last one byte to chip. */
CS8900_RegWr(CS8900_RTDATA_OFFSET, (*sdata) & 0x00FF);
}
}
CPU_CRITICAL_EXIT(); /* Enable interrupts at processor level */
}
/*
*********************************************************************************************************
* CS8900_Reset()
*
* Description : (1) Reset the CS8900 by writing to the Self Control Register
*
* Argument(s) : none.
* Return(s) : 0, -1 (Pass / Fail
* Caller(s) : CS8900_Init()
*
* Note(s) : none.
*********************************************************************************************************
*/
NET_LOCAL CPU_INT32S CS8900_Reset (void)
{
CPU_INT16U i;
CPU_INT16U status;
CS8900_PPRegWr(PP_SelfCtl, PP_SelfCtl_Reset); /* Reset chip */
NET_BSP_CS8900A_Reset_Delay(); /* Wait for the chip to come out of reset 10ms minimum */
for (i = 0; i < 3000; i++) { /* check PP_SelfStat_InitD bit if the chip successflly reset */
status = (CS8900_PPRegRd(PP_SelfStat)&PP_SelfStat_InitD);
if (status != 0) {
return (0);
}
}
return (-1);
}
/*
*********************************************************************************************************
* CS8900_Int_Receive()
*
* Description : (1) Process Receive Interrupts
*
* Argument(s) : none.
* Return(s) : none.
* Caller(s) : NetNIC_ISR_Handler()
*
* Note(s) : none.
*********************************************************************************************************
*/
NET_LOCAL CPU_INT32S CS8900_Int_Receive (CS8900_ETH_FRAME *pframe, CPU_INT16U RxEventStatus)
{
CPU_INT16U val;
CPU_INT16U leftLen;
CPU_INT16U *pdata;
CPU_INT08U *cp;
/* Step 1: Determine if there is Rx Error. */
if ((RxEventStatus & PP_RER_RxOK) == 0) { /* If RxOk bit is not set, Rx Error occurred */
if ( RxEventStatus & PP_RER_CRC) {
CS8900_DBG_PRINT("CRC error.\r\n");
} else if (RxEventStatus & PP_RER_RUNT) {
CS8900_DBG_PRINT("RUNT error.\r\n");
} else if (RxEventStatus & PP_RER_EXTRA) {
CS8900_DBG_PRINT("EXTRA error.\r\n");
} else {
CS8900_DBG_PRINT("Unknown Error.\r\n");
}
CS8900_PPRegRd(PP_Rx_LENGTH); /* Step 2: skip this received error frame. */
/* Note: Must skip this received error frame. */
/* Otherwise, CS8900 hangs here. */
/* Read the length of Rx frame */
val = CS8900_PPRegRd(PP_RxCFG); /* Write Skip to RxCfg Register and also keep the */
/* current configuration. */
val |= PP_RxCFG_Skip1;
CS8900_PPRegWr(PP_RxCFG, val);
return (-1); /* return failed */
}
if (frame_bff_num >= CS8900_NUM_ETH_FRAME_BUF) {
CS8900_DBG_PRINT("Frame buffer overflow\r\n");
return (-1);
}
frame_bff_num++;
pframe->size = CS8900_PPRegRd(PP_Rx_LENGTH); /* Step 3: Read the length of Rx frame */
pdata = (CPU_INT16U *)pframe->Frame; /* Step 4: Read the Rx data from Chip and store it to */
/* the stacks buffer */
leftLen = pframe->size;
while (leftLen >= 2) { /* read 2 bytes at a time */
*pdata++ = CS8900_RegRd(CS8900_RTDATA_OFFSET);
leftLen -= 2;
}
if (leftLen == 1) { /* if odd bytes, read the last byte from chip */
val = CS8900_RegRd(CS8900_RTDATA_OFFSET); /* Read the last byte from chip */
cp = (CPU_INT08U *)pdata; /* point to the last one byte of the user buffer */
*cp = (CPU_INT08U)(val & 0xFF); /* truncate the word (2-bytes) read from chip to one byte */
}
return (pframe->size);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -