📄 net_nic.c
字号:
MAC2 &= ~MAC2_FULL_DUPLEX; /* Configure the EMAC to run in HALF duplex mode */
COMMAND &= ~COMMAND_FULL_DUPLEX; /* Configure the MII logic for a Half Duplex PHY Link */
IPGT = IPG_HALF_DUP; /* Set inter packet gap to the recommended Half Duplex */
break;
case NET_PHY_DUPLEX_FULL:
MAC2 |= MAC2_FULL_DUPLEX; /* Configure the EMAC to run in FULL duplex mode */
COMMAND |= COMMAND_FULL_DUPLEX; /* Configure the MII logic for a Full Duplex PHY Link */
IPGT = IPG_FULL_DUP; /* Set inter packet gap to the recommended Full Duplex */
break;
}
}
/*
*********************************************************************************************************
* NetNIC_ISR_Handler()
*
* Description : (1) Decode ISR & call appropriate ISR handler :
*
* (a) Receive Buffer Not Available ISR NetNIC_RxPktDiscard().
* (b) Receive ISR NetNIC_RxISR_Handler().
* (c) Transmit ISR NetNIC_TxISR_Handler().
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Caller(s) : This is an ISR
*
* Note(s) : 1) VIC interrupts do not need to be explicity acknowledged if the BSP exception
* handler writes a 0x00 to the VICAddress register after calling the ISR handler.
* User ISR handlers (such as this one) need only clear the local interrupt source.
*********************************************************************************************************
*/
void NetNIC_ISR_Handler (void)
{
CPU_INT32U intstatus;
CPU_INT16U n_new;
NET_ERR err;
intstatus = INTSTATUS; /* Read the interrupt status register */
if ((intstatus & INT_RX_DONE) > 0) { /* If a receiver event has occured */
n_new = NIC_RxGetNRdy() - NIC_RxNRdyCtr; /* Determine how many NEW franes have been received */
while (n_new > 0) {
NetOS_IF_RxTaskSignal(&err); /* Signal Net IF Rx Task that a new frame has arrived */
switch (err) { /* Each frame is processed sequentially from the Rx task */
case NET_IF_ERR_NONE:
if (NIC_RxNRdyCtr < EMAC_NUM_RX_DESC) {
NIC_RxNRdyCtr++;
}
break;
case NET_IF_ERR_RX_Q_FULL:
case NET_IF_ERR_RX_Q_POST_FAIL:
default:
NetNIC_RxPktDiscard(0, &err); /* If an error occured while signaling the task, discard */
break; /* the received frame */
}
n_new--;
}
INTCLEAR = (INT_RX_DONE); /* Clear the interrupt flags */
}
if ((intstatus & (INT_RX_OVERRUN)) > 0) { /* If a fator Overrun error has occured */
INTCLEAR = (INT_RX_OVERRUN); /* Clear the overrun interrupt flag */
COMMAND |= COMMAND_RESET_RX; /* Soft reset the Rx datapath, this disables the receiver */
COMMAND |= COMMAND_RX_EN; /* Re-enable the reciever */
MAC1 |= MAC1_RX_ENABLE; /* Re-enable the reciever */
}
}
/*
*********************************************************************************************************
* NetNIC_RxPktGetSize()
*
* Description : Get network packet size from NIC.
*
* Argument(s) : none.
*
* Return(s) : Size, in octets, of next frame to be read from the EMAC buffers
*
* Caller(s) : NetIF_RxTaskHandler()
*
* Notes : None.
*********************************************************************************************************
*/
CPU_INT16U NetNIC_RxPktGetSize (void)
{
CPU_INT16S size;
CPU_INT32U rxstatus;
rxstatus = RxStatus[RXCONSUMEINDEX].StatusInfo; /* Accquire the status word for this desciptor */
rxstatus &= (RX_DESC_STATUS_NODESC | /* Obtain the descriptor error bits */
RX_DESC_STATUS_OVERRUN |
RX_DESC_STATUS_ALGNERR |
RX_DESC_STATUS_LENERR |
RX_DESC_STATUS_SYMERR |
RX_DESC_STATUS_CRCERR |
RX_DESC_STATUS_FAILFLT);
if (rxstatus > 0) { /* If any receive errors (except range error) occured */
size = 0; /* then return 0 so upper layer call NetNIC_RxPktDiscard() */
} else {
size = RxStatus[RXCONSUMEINDEX].StatusInfo & 0x7FF; /* Obtain the fragment size from the status struct pointer */
size -= 3; /* +1 since the size is 0 based, -4 to ignore FCS */
}
if (size < 0) { /* Ensure that the subtraction didnt cause an underflow */
size = 0;
}
return (size); /* Return the size of the current frame */
}
/*
*********************************************************************************************************
* NetNIC_RxPkt()
*
* Description : Read network packet from NIC into buffer.
*
* Argument(s) : ppkt Pointer to memory buffer to receive NIC packet.
*
* size Number of packet frame octets to read into buffer.
*
* perr Pointer to variable that will hold the return error code from this function :
*
* NET_NIC_ERR_NONE Packet successfully read.
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
* NET_NIC_ERR_NULL_PTR Argument 'ppkt' passed a NULL pointer.
* NET_NIC_ERR_INVALID_SIZE Invalid size.
*
* Return(s) : none.
*
* Caller(s) : NetIF_RxTaskHandler().
*
* Note(s) : 1) NetNIC_RxPkt() blocked until network initialization completes; perform NO action.
*********************************************************************************************************
*/
void NetNIC_RxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr)
{
#if (NET_CTR_CFG_STAT_EN == DEF_ENABLED)
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
#endif
if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit rx (see Note #2). */
*perr = NET_ERR_INIT_INCOMPLETE;
return;
}
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------------- VALIDATE PTR ------------------ */
if (ppkt == (void *)0) {
*perr = NET_NIC_ERR_NULL_PTR;
return;
}
/* ------------------- VALIDATE SIZE ----------------- */
if (size < NET_IF_FRAME_MIN_SIZE) {
*perr = NET_NIC_ERR_INVALID_SIZE;
return;
}
#endif
EMAC_RxPkt(ppkt, size, perr); /* Read the received Frame from the EMAC buffers */
if (*perr != NET_NIC_ERR_NONE) {
return;
}
NET_CTR_STAT_INC(NetNIC_StatRxPktCtr);
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* NetNIC_RxPktDiscard()
*
* Description : Discard network packet from NIC to free NIC packet frames for new receive packets.
*
* Argument(s) : size Number of packet frame octets.
*
* perr Pointer to variable that will hold the return error code from this function :
*
* NET_NIC_ERR_NONE Packet successfully discarded.
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
*
* Return(s) : none.
*
* Caller(s) : NetIF_RxTaskHandler().
*
* Note(s) : (1) NetNIC_RxPktDiscard() blocked until network initialization completes; perform NO action.
*
* (2) #### 'perr' may NOT be necessary (remove before product release if unnecessary).
*********************************************************************************************************
*/
void NetNIC_RxPktDiscard (CPU_INT16U size,
NET_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit discard (see Note #1). */
*perr = NET_ERR_INIT_INCOMPLETE;
return;
}
EMAC_RxPktDiscard(size);
CPU_CRITICAL_ENTER(); /* This routine alters shared data. Disable interrupts! */
if (NIC_RxNRdyCtr > 0) { /* One less packet to process */
NIC_RxNRdyCtr--;
}
CPU_CRITICAL_EXIT(); /* Re-Enable interrupts */
NET_CTR_ERR_INC(NetNIC_ErrRxPktDiscardedCtr);
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* NetNIC_TxPkt()
*
* Description : Transmit data packets from network driver layer to network interface card.
*
* Argument(s) : ppkt Pointer to memory buffer to transmit NIC packet.
* ---- Argument validated in NetIF_Pkt_Tx().
*
* size Number of packet frame octets to write to frame.
* ---- Argument checked in NetIF_Tx().
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -