📄 net_nic.c
字号:
sizeLeftToCopy -= (NIC_RX_BUF_SIZE - dataOffset);
dataOffset = 0; /* Set the offset to zero since we processed the SOF */
} else {
sizeLeftToCopy = 0; /* An error occured! */
*perr = NET_ERR_RX; /* Return an error code! */
doMemCpy = FALSE; /* Disable mem copies, so we can free descriptors */
}
} else { /* If its not SOF, copy a full buffer to the stacks buf */
if (doMemCpy == TRUE) {
Mem_Copy((void *)(pStackBuf), (void *)(pEMACBuf), NIC_RX_BUF_SIZE);
pStackBuf += (NIC_RX_BUF_SIZE); /* Advance the pointer into the TCP/IP stacks buffer */
}
if ((sizeLeftToCopy - NIC_RX_BUF_SIZE) >= 0) { /* Subtract the amount copied from the total left */
sizeLeftToCopy -= (NIC_RX_BUF_SIZE);
} else {
sizeLeftToCopy = 0; /* An error occured! */
*perr = NET_ERR_RX; /* Return an error code! */
doMemCpy = FALSE; /* Disable mem copies, so we can free descriptors */
}
}
searchPtr->addr &= ~EMAC_RXBUF_SW_OWNED; /* Free the descriptor we just copied from */
searchPtr++; /* Go to the next descriptor */
if (searchPtr == NIC_RxBufDescPtrEnd) { /* If we have reached the end of the list, wrap around */
searchPtr = NIC_RxBufDescPtrStart; /* to the top of the list and continue searching */
}
}
/* COPY THE LAST DESCRIPTOR BUFFER DATA */
/* Get the address of the buffer we wish to copy */
pEMACBuf = (CPU_INT08U *)((searchPtr->addr & EMAC_RXBUF_ADDRESS_MASK));
if (doMemCpy == TRUE) { /* If no errors have occured, copy the remaining data */
if (dataOffset > 0) { /* If this is both the SOF and EOF descriptor */
Mem_Copy((void *)(pStackBuf), (void *)(pEMACBuf + dataOffset), sizeLeftToCopy - dataOffset);
} else { /* If this is the last descriptor, and NOT also SOF */
Mem_Copy((void *)(pStackBuf), (void *)(pEMACBuf), sizeLeftToCopy);
}
}
searchPtr->addr &= ~EMAC_RXBUF_SW_OWNED; /* Free the last descriptor */
CPU_CRITICAL_ENTER();
if (NIC_RxNRdyCtr > 0) { /* One less packet to process */
NIC_RxNRdyCtr--;
}
CPU_CRITICAL_EXIT();
}
/*
*********************************************************************************************************
* 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 (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 discard (see Note #1). */
*perr = NET_ERR_INIT_INCOMPLETE;
return;
}
EMAC_RxPktDiscard(size);
NET_CTR_ERR_INC(NetNIC_ErrRxPktDiscardedCtr);
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* EMAC_RxPktDiscard()
*
* Description : Discard network packet from NIC to free NIC packet frames for new receive packets.
*
* Argument(s) : Size: how much data to discard. However, we will discard an entire frame
* so this information is not necessary.
*
* Return(s) : none.
*
* Caller(s) : NetNIC_RxPktDiscard().
*********************************************************************************************************
*/
static void EMAC_RxPktDiscard (CPU_INT16U size)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr = 0;
#endif
NIC_BUF_DESC *searchPtr;
(void)size;
if ((NIC_CurrentFrameStart == NULL) || (NIC_CurrentFrameEnd == NULL)) {
CPU_CRITICAL_ENTER();
if (NIC_RxNRdyCtr > 0) { /* One less packet to process */
NIC_RxNRdyCtr--;
}
CPU_CRITICAL_EXIT();
return;
}
searchPtr = NIC_CurrentFrameStart; /* Point to the SOF descriptor. Start copy from here */
while (searchPtr != NIC_CurrentFrameEnd) { /* Copy from SOF to EOF descriptor (EOF not inclusive) */
searchPtr->addr &= ~EMAC_RXBUF_SW_OWNED; /* Free the descriptor */
searchPtr++; /* Go to the next descriptor */
if (searchPtr == NIC_RxBufDescPtrEnd) { /* If we have reached the end of the list, wrap around */
searchPtr = NIC_RxBufDescPtrStart; /* to the top of the list and continue searching */
}
}
searchPtr->addr &= ~EMAC_RXBUF_SW_OWNED; /* Free the last descriptor */
CPU_CRITICAL_ENTER();
if (NIC_RxNRdyCtr > 0) { /* One less packet to process */
NIC_RxNRdyCtr--;
}
CPU_CRITICAL_EXIT();
}
/*
---------------------------------------------------------------------------------------------------------
THE FOLLOWING FUNCTIONS ARE CALLED FROM THE TX TASK DURING THE PROCESSING OF A SINGLE TX FRAME
---------------------------------------------------------------------------------------------------------
*/
/*
*********************************************************************************************************
* 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.
*
* 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.
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
*
* - RETURNED BY NetNIC_TxPktDiscard() : -
* NET_ERR_TX Transmit error; packet discarded.
*
* Return(s) : none.
*
* Caller(s) : NetIF_Pkt_Tx().
*
* Note(s) : (1) NetNIC_TxPkt() blocked until network initialization completes; perform NO action.
*********************************************************************************************************
*/
void NetNIC_TxPkt (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 tx (see Note #1). */
*perr = NET_ERR_INIT_INCOMPLETE;
return;
}
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------------- VALIDATE PTR ------------------ */
if (ppkt == (void *)0) {
NetNIC_TxPktDiscard(perr);
return;
}
#endif
EMAC_TxPkt(ppkt, size, perr); /* Tx pkt to AT91SAM7X256. */
if (*perr != NET_NIC_ERR_NONE) {
NetNIC_TxPktDiscard(perr);
return;
}
NET_CTR_STAT_INC(NetNIC_StatTxPktCtr);
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* EMAC_TxPkt()
*
* Description : (1) Instruct AT91SAM7X256 EMAC to send network packet :
* (a) Check is transmitter ready.
* (b) Clear all transmitter errors.
* (c) 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.
* AT91SAM7X256_EMAC_ERR_TX_BUSY Transmitter not ready.
* Return(s) : none.
*
* Caller(s) : NetNIC_TxPkt().
*
* Notes : 1) If the Tx descriptor is NOT available, a BUSY return code will be sent to the stack
* and retransmission will be attemped at a later time. - Transmitting the descriptor
* content is VERY fast, therefore, the descriptor should always be available.
*********************************************************************************************************
*/
static void EMAC_TxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr)
{
CPU_INT32U reg_val;
/* Check if transmitter ready. */
reg_val = AT91C_BASE_EMAC->EMAC_TSR;
if ((reg_val & AT91C_EMAC_TGO) == AT91C_EMAC_TGO) { /* If bit AT91C_EMAC_TGO == 1, then tranmitter is busy */
*perr = EMAC_ERR_TX_BUSY;
return;
}
/* Clear all transmitter errors. */
AT91C_BASE_EMAC->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -