📄 net_nic.c
字号:
* DM9000A_EMAC_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 DM9000.
* (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.
* DM9000_EMAC_ERR_RX_BUSY Receiver not ready.
*
* Return(s) : none.
*
* Caller(s) : NetNIC_RxPkt().
*
* Note(s) : (1) See 'DM9000 EMAC RECEIVE BUFFER DESCRIPTOR' for packet frame format.
*
* (2) Four extra bytes are read to remove the FCS from the DM9000A SRAM.
*
* (3) Because only one packet can be "received" at a time (meaning, essentially, that the
* DM9000A's read pointer can only point at one location), an read interrupt will not be
* generated for a packet received while one is already waiting in the buffer.
* Consequently, the byte after the read packet is consulted to determine if another
* packet is waiting and, if so, NetOS_IF_RxTaskSignal() is called.
*********************************************************************************************************
*/
static void DM9000A_EMAC_RxPkt (void *ppkt,
CPU_INT16U size,
NET_ERR *perr)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
volatile CPU_INT16U w_data;
CPU_INT08U *p8;
CPU_INT16U *p16;
CPU_INT08U status;
DM9000A_ENTER();
p8 = (CPU_INT08U *)ppkt;
p16 = (CPU_INT16U *)ppkt;
NetNIC_WrIx_8(DM9000A_MRCMD); /* Prepare to read memory with auto-increment (0xF2) */
#if DM9000A_IO_MODE == DM9000A_IO_8_BITS
(void)p16;
while (size > 0) {
*p8 = NetNIC_RdData_8(); /* Read byte of data from register (0xF2) */
p8++; /* Increment packet pointer */
size--; /* Decrement number of packets left to receive */
}
/* Discard four-byte FCS: */
w_data = NetNIC_RdData_8(); /* read/discard first byte, */
w_data = NetNIC_RdData_8(); /* read/discard second byte, */
w_data = NetNIC_RdData_8(); /* read/discard third byte, and */
w_data = NetNIC_RdData_8(); /* read/discard fourth byte. */
#elif DM9000A_IO_MODE == DM9000A_IO_16_BITS
(void)p8;
while (size >= 2) {
*p16 = NetNIC_RdData_16(); /* Read word of data from register (0xF2) */
p16++; /* Increment packet pointer */
size -= 2; /* Decrement number of packets left to receive */
}
if (size == 1) { /* If an odd number of packets need be received */
*(CPU_INT08U *)p16 = (CPU_INT08U)NetNIC_RdData_16(); /* Read final word of data from register */
}
/* Discard four-byte FCS: */
w_data = NetNIC_RdData_16(); /* read/discard first & second bytes, and */
w_data = NetNIC_RdData_16(); /* read/discard third & fourth bytes. */
#endif
/* Check to see if another packet is in the buffer . . . */
/* . . .for which no interrupt was generated because . . . */
/* . . .a packet was already being received. */
status = NetNIC_RdReg_8(DM9000A_MRCMDX); /* Dummy read to determine if packet is ready (0xF0) */
status = NetNIC_RdData_8() & 0xFF; /* Read status byte (0xF0) */
/* If first byte of status is 0x00, no packet is in SRAM. */
/* If first byte of status is neither 0x00 or 0x01 . . . */
/* . . .then an error has occurred; this will be . . . */
/* . . .handled when the next receive interrupt occurs. */
/* If first byte of status is 0x01 */
if (status == 0x01) { /* . . .then a packet has been received and is in SRAM */
NetOS_IF_RxTaskSignal(perr); /* . . .so signal Net IF Rx Task of NIC rx pkt. */
}
DM9000A_EXIT();
*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 (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;
}
if (size > 0) {
DM9000A_EMAC_RxPktDiscard(size);
}
NET_CTR_ERR_INC(NetNIC_ErrRxPktDiscardedCtr);
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* DM9000A_EMAC_RxPktDiscard()
*
* Description : Discard network packet from NIC to free NIC packet frames for new receive packets.
*
* Argument(s) : RxDescNum The first index in the Rx descriptor list containing the SOF flag that
* corresponds to the buffer(s) to be released.
*
* Return(s) : none.
*
* Caller(s) : NetNIC_RxPktDiscard().
*********************************************************************************************************
*/
static void DM9000A_EMAC_RxPktDiscard (CPU_INT16U size)
{
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
volatile CPU_INT16U w_data;
volatile CPU_INT08U b_data;
DM9000A_ENTER();
NetNIC_WrIx_8(DM9000A_MRCMD); /* Prepare to read memory with auto-increment */
#if DM9000A_IO_MODE == DM9000A_IO_8_BITS
while (size > 0) {
b_data = NetNIC_RdData_8(); /* Read byte from NIC */
size--;
}
b_data = NetNIC_RdData_8();
b_data = NetNIC_RdData_8();
b_data = NetNIC_RdData_8();
b_data = NetNIC_RdData_8();
#elif DM9000A_IO_MODE == DM9000A_IO_16_BITS
while (size >= 2) {
w_data = NetNIC_RdData_16(); /* Read two bytes from NIC */
size -= 2;
}
if (size == 1) {
w_data = NetNIC_RdData_16();
}
w_data = NetNIC_RdData_16();
w_data = NetNIC_RdData_16();
#endif
DM9000A_EXIT();
}
/*
*********************************************************************************************************
* 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
DM9000A_EMAC_TxPkt(ppkt, size, perr); /* Tx pkt to DM9000. */
if (*perr != NET_NIC_ERR_NONE) {
NetNIC_TxPktDiscard(perr);
return;
}
NET_CTR_STAT_INC(NetNIC_StatTxPktCtr);
*perr = NET_NIC_ERR_NONE;
}
/*
*********************************************************************************************************
* DM9000A_EMAC_TxPkt()
*
* Description : (1) Instruct DM9000 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.
* DM9000_EMAC_ERR_TX_BUSY Transmitter not ready.
* Return(s) : none.
*
* Caller(s) : NetNIC_TxPkt().
*
* Note(s) : (1) The DM9000A has two transmit buffers. This function, as written, will not issue
* the transmit command on the second buffer while the data from the first is still
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -