⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net_nic.c

📁 DM9000A的网卡驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
*                                        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 + -