This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS570LC4357: tms570lc4357-dp83869

Part Number: TMS570LC4357
Other Parts Discussed in Thread: HALCOGEN, DP83869HM, DP83640, DP83869

Tool/software:

hii,

I am using  tms570lc4357  with ethernet phy dp83869hm, i am not able  to establish ethernet connectivity with tms, as halcogen is genrating drivers for 83860, please suggest solution to this

  • Hi Gourav,

    The driver code generated from HALCoGen is for DP83640

    You can follow the below procedure to make this DP83640 driver to work with DP83869.

    1. First you need to identify the API's that are using in DP83640 in application code.

    on my verification they are using the below highlighted four API's in the code:

    2. Now you should need to verify the PHY registers and corresponding bits that are using in these API's

    On my verification i found they are using below highlighted registers.

    On my verification i found they are using below highlighted bits:

    3. Now we should need to compare whether the above highlighted register addresses are same or not in both PHY IC's (DP83640 and DP83869).

    On my verification they look same in the the PHY IC's.

    So, my suggestion would be either take an existing example for DP83640 or else create one example. And do the test on the DP83869, most probably it should work.

    You can find ethernet examples in below link:

    (3) [FAQ] TMS570LC4357: Examples and Demos available for Hercules Controllers (E.g. TMS570x, RM57x and RM46x etc) - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    --
    Thanks & regards,
    Jagadish.

  • hii jagadish, I tried same, and run emac loopback example my code stuck in emac transmit function, please find the images.
    i have uploaded table of pin configuration with dp83869 and tms470, pin ball U8, R1, T2 and G4 AS MII_TX_D0-D3, E4 TXEN, T9 not found in data sheet as well as in halcogen, how do i configure it for transmission

  • hi Jagadish sir, requesting for solution for the above

  • Hi Gourav,

    I got similar issue thread:

    (2) while(((EMACSwizzleData(curr_bd->flags_pktlen)) & EMAC_BUF_DESC_OWNER) == EMAC_BUF_DESC_OWNER); - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    Here customer got the issue due to using of old HALCoGen code. So, verify whether you are using new HALCoGen only (4.7.1).

    And also make sure your pinmux settings to be correct.

    Just make sure your pinmux settings are as per below project:

    8865.LwIP (1).zip

    In the above project also, we are using same MII pins as yours. So please make sure your pinmux settings are as per the above project.

    --
    Thanks & regards,
    Jagadish.

  • I am able to successfully run emac loopback and data is coming in pbuf_array, Thanks for the support, does it mean my controller is able to communicate with phy, I am new to it 

  • Hi Gourav,

    It is successfully communicating with PHY.

    If it is not communicating with PHY then the code must be stuck with in the EMACHWInit API at below part of the code where we are reading the PHY ID.

    --
    Thanks & regards,
    Jagadish.

  • next I have to use mqtt over lwip stack, any reference for this

  • Hi jagadish, I used the lwip library in my project,,not able to autoassign ip from network, also, I try to  assign static ip, it is not pinging, what may be the possible reasons.

  • Hi Jagadish Sir,

    I'm using VS Code to build the application as part of the project. I followed the steps outlined above, but I'm still unable to establish a connection.

  • Hi Gourav,

    What about static IP? are you able to communicate properly with static IP?

    PHY wise no issues, right? I mean is your code getting through with PHY ID and PHY link status?

    And can verify and let me know that where exactly your code getting stuck in debug?

    --
    Thanks & regards,
    Jagadish.

  •  here it stucks for 12- 15 seconds

  • Hi Gourav,

    How you designed this custom board, did you take any reference of our Lauchpad or HDK.

    The reason for asking is because, both lauchpad and HDK have different designs.

    If you verify PHY CLK in put in both Launchpad and our HDK:

    Launchpad:

    HDK:

    As you can see in our launchpad we are providing PHY clock using ECLK from the controller, but in HDK we are providing clock using external clock generator.

    So, if you followed launchpad design then you should need to generate the 25Mhz ECLK on ECLK1 pin.

    For more details about configuration, just refer below link once:

    Minimal lwIP Project for Hercules LaunchPad - Hackster.io

    --
    Thanks & Regards,
    Jagadish.

  • Hi Jagadish,

    Please find the schematic in the attachment. We are using open-source tools for research purposes. An external clock of 25 MHz is provided.enet (2).zip

  • Hi Jagadish,

    Please find the schematic in the attachment. We are using open-source tools for research purposes. An external clock of 25 MHz is provided.

    1.do the clock configurations are same for both dp83869 and dp83640, because here we are using 83869,

     

    2. pins marked are not able to configure using halcogen, neither found in data sheet,

    I am worried more about pin T9 MDC PIN, code also stuck when mdio is reading th phy register,

    1512.enet (2).zip

  • We hve got pins in the privous version data sheet, they are not available in technical refernce mannual, will you please guide how to configure it mannually

  • Hi Gourav,

    I verified your schematic, and it is exactly same as our launchpad PHY connectivity like as shown below:

    LAUNCHXL2-570LC43 Development kit | TI.com

    So, i am suggesting you download the Launchpad LwIP example code in the below link:

    (+) [FAQ] TMS570LC4357: Step-by-Step process to execute the LwIP demo on the TMS570LC4357 HDK board using Dynamic IP (DHCP) - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    And make sure you are exactly using same pin configurations as per the above example.

    --
    Thanks & regards,
    Jagadish.

  • Hi Jagadish, I had tries with the above configurations, it still stuck in that area, do the Vclock configurations are same for both 83640 and 83869, for 83640 vclk 4 is 37.5

  • Hi Gourav,

    VCLK4 doesn't have any dependency over PHY:

    This clock is only used for internal EMAC logic.

    Can you do one testing, can you try to increase MDC clock frequency to 2.5Mhz.

    Previously this value is 1Mhz, can you test with 2.5Mhz?

    This 1Mhz MDIO clock is working with DP83640 but not sure on DP83869

    Try with 2.5Mhz and let me know the result.

    --
    Thanks & regards,
    Jagadish.

  •   I change the mdc configuration,also i had given static ip, same result dp83640 also having same clock configurations,
    Do, you have example code with freertos. 

  • Hi Gourav,

    I change the mdc configuration,also i had given static ip, same result dp83640 also having same clock configurations,

    You are correct.

    Can you setup one live debugging session on this, so that i can verify your code and test results directly.

    Do, you have example code with freertos. 

    We have only one FreeRTOS example on LwIP and you can find it in below link:

    (+) [FAQ] TMS570LC4357: Examples and Demos available for Hercules Controllers (E.g. TMS570x, RM57x and RM46x etc) - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    --
    Thanks & regards,
    Jagadish.

  • Sure, Please share availability, where to share meeting link

  • Sure, Please share availability, where to share meeting link

    I will be available from 10AM to 7PM Indian Standard Time (IST)

  • Shall we schedule for tomorrow 19-july-2024 at 1330 hrs as per IST, 

  • Hi Gourav,

    I am on sick leave yesterday and i have lot of issues to work on today.

    If possible, schedule at today evening after 6PM IST or else Monday.

    --
    Thanks & regards,
    Jagadish.

  • are you available at 6:40 pm

  • Sure,

    Please share the meeting link.

  •  below is the link

    Meeting_tms570lc4357_dp83869

  • or, (No title)
    Friday, July 19 · 1:30 – 2:30pm
    Time zone: Asia/Kolkata
    Google Meet joining info
    Video call link: meet.google.com/kjf-nkez-hvr

  • Friday, July 19 · 1:30 – 2:30pm

    It is at 6:40 right?

  • (No title)
    Friday, July 19 · 6:40 – 7:40pm
    Time zone: Asia/Kolkata
    Google Meet joining info
    Video call link: https://meet.google.com/dkg-qovr-oie

  • please excuse, 
    kindly follow the above link

  • Thanks for the meeting link gourav, i will join at 6:40PM today.

  •      HERE WE STUCK DURING DHCP IP,

  •     ABLE TO ASSIGN STATIC IP BUT NOT ABLE TO PING

  • Hi Jagadish I have found diffrences in the schematic, do these  the reason, here in our schematic TXD[3:0] are connected invertly

  • Hi Gourav,

    I think this could create a problem:

    As there were two names in your schematic, i also confused in my verification for the first time, the red color names at PHY side looks correct but the blue color names looks wrong on the PHY side.

    However, i think the connections between PHY and controller made using blue names. So, the real connectivity between PHY and controller will look as below:

    As you can see TXD0 at controller finally connected to the TXD3 at PHY, similarly TXD1 at controller to the TXD2 at PHY, TXD2 at controller to the TXD1 at PHY and TXD3 at controller to the TXD0 at PHY.

    This will may not affect the MDIO communication between PHY and controller as this communication takes on other lines MDC and MDIO, that is the reason maybe we don't have any issues for PHY ID receiving and PHY link status etc. However, this might create issues for ethernet data communication, here the bits might be shuffle and the data might be received wrongly by other end device like router or PC.

    --
    Thanks & regards,
    Jagadish.

  • How to rectify this,using pinmux settings, or any configuration in software

  • Hi Gourav,

    I think firmware wise we can't rectify this issue as it is related to hardware pin connectivity. 

    I am thinking of two ways:

    1. I think we should somehow need to disconnect these pins connectivity between controller and PHY IC and should need to connect them correctly using external wires.

    Maybe we should need to identify these four tracks on PCB and need to cut them and need to make right connectivity using external wires. Maybe this is not an easy process.

    2. I hope this PCB is a prototype PCB, so maybe you need to design another PCB with right connectivity.

    I don't know any other possible ways.

    --
    Thanks & regards,
    Jagadish.

  • Ae you sure, this is the reason, it is very difficult for us to go for design a new hardware at this stage, please suggest any alternative solution if exist, i am also finding.

    Thank you, for very good support

    gourav

  • Sure gourav, if i have any alternative solution then i will suggest you.

    --
    Thanks,
    Jagadish.

  • Hi Gourav,

    I don't know any other easy alternative than changing the hardware.

    There could be one possible way, but it involves lot of effort and not sure whether it work also.

    That is changing the order of the data bits for every nibble (4 bits) which will get transmitted out through EMAC. This is very hard process and involves lot of effort to understand complete data which will get transmitted, and we should need to change the order of every nibble that will transmit out from EMAC.

    This is because end of the day the data from MAC will be transmitted in the parallel through four lines, right? I mean TXD_3, TXD_2, TXD_1 and TXD_0. So, if we consider one byte transmission it will get transmit in terms of two nibbles, right? 

    In our case the order of the nibble from MSB to LSB should be TXD0, TXD1, TXD2 and TXD3, so we need to change each nibble data order as this. I can't do this at my end because it involves lot of effort and time consuming. If you want to try it out, you need to build your own application.

    But my suggestion would be better to go for my previous two suggestions only.

    --
    Thanks & regards,
    Jagadish.

  • Hi we have changed the pin configuration in the hardware, now while assigning dhcp it is showing error for phy alive status, whie autoassign ip ip will be assigned but not ping.


       

  • Hi Gourav,

    whie autoassign ip ip will be assigned but not ping.

    You mean static ip?

    dhcp it is showing error for phy alive status,

    If for static ip PHY alive status success means for DHCP also it should be success only. After PHY alive status only we will assign the ip address, so for static ip if the PHY alive status success means for DHCP it should not stuck at PHY alive status?

    Are you using same code for static and DHCP? We should just change the lwIPInit argument as IPADDR_USE_DHCP right?

    --
    Thanks & regards,
    Jagadish.

    • Yes, I have changed that, and also using same code, 
  • Hi Gourav,

    Also, can you please try to increase the below DHCP try "count" value from 10 to 100

    --
    Thanks & regards,
    Jagadish.

  • is there any other example available like tcp client or tcp echo server


  • 1067.hdkif.c
    /**
     * @file - hdkif.c
     * lwIP Ethernet interface for Hercules Devices
     *
     */
    
    /**
     * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice,
     *    this list of conditions and the following disclaimer.
     * 2. Redistributions in binary form must reproduce the above copyright notice,
     *    this list of conditions and the following disclaimer in the documentation
     *    and/or other materials provided with the distribution.
     * 3. The name of the author may not be used to endorse or promote products
     *    derived from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
     * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
     * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
     * OF SUCH DAMAGE.
     *
     * This file is part of the lwIP TCP/IP stack.
     *
     * Author: Adam Dunkels <adam@sics.se>
     *
     */
    
    /**
     * Copyright (c) 2010 Texas Instruments Incorporated
     *
     * This file is dervied from the "ethernetif.c" skeleton Ethernet network
     * interface driver for lwIP.
     *
     */
    #include "hdkif.h"
    
    #include "cc.h"
    #include "def.h"
    #include "err.h"
    #include "etharp.h"
    #include "lwip_sys.h"
    #include "mem.h"
    #include "opt.h"
    #include "pbuf.h"
    #include "ppp_oe.h"
    #include "snmp.h"
    #include "stats.h"
    
    /* HALCoGen DriverLib Header & PHY files required for this interface driver. */
    
    #include "HL_emac.h"
    #include "HL_mdio.h"
    #include "HL_phy_dp83640.h"
    #include "HL_sci.h"
    
    #ifndef TRUE
    #define TRUE 1
    #endif
    
    /* EMAC Control RAM size in bytes */
    #ifndef SIZE_EMAC_CTRL_RAM
    #define SIZE_EMAC_CTRL_RAM 0x2000
    #endif
    
    #define PBUF_LEN_MAX MAX_TRANSFER_UNIT
    
    /* Define those to better describe the network interface. */
    #define IFNAME0 'e'
    #define IFNAME1 'n'
    
    /* Choosing the SCI module used depending upon the device HDK */
    
    #define sciREGx sciREG3
    
    /* EMAC TX Buffer descriptor data structure */
    struct emac_tx_bdp {
        volatile struct emac_tx_bdp *next;
        volatile uint32 bufptr;
        volatile uint32 bufoff_len;
        volatile uint32 flags_pktlen;
    
        /* helper to know which pbuf this tx bd corresponds to */
        volatile struct pbuf *pbuf;
    } emac_tx_bdp;
    
    /* EMAC RX Buffer descriptor data structure */
    struct emac_rx_bdp {
        volatile struct emac_rx_bdp *next;
        volatile uint32 bufptr;
        volatile uint32 bufoff_len;
        volatile uint32 flags_pktlen;
    
        /* helper to know which pbuf this rx bd corresponds to */
        volatile struct pbuf *pbuf;
    } emac_rx_bdp;
    
    /**
     * Helper struct to hold the data used to operate on a particular
     * receive channel
     */
    struct rxch {
        volatile struct emac_rx_bdp *free_head;
        volatile struct emac_rx_bdp *active_head;
        volatile struct emac_rx_bdp *active_tail;
        uint32 freed_pbuf_len;
    } rxch;
    
    /**
     * Helper struct to hold the data used to operate on a particular
     * transmit channel
     */
    struct txch {
        volatile struct emac_tx_bdp *free_head;
        volatile struct emac_tx_bdp *active_tail;
        volatile struct emac_tx_bdp *next_bd_to_process;
    } txch;
    
    /**
     * Helper struct to hold private data used to operate the ethernet interface.
     */
    struct hdkif {
        /* emac instance number */
        uint32 inst_num;
    
        uint8 mac_addr[6];
    
        /* emac base address */
        uint32 emac_base;
    
        /* emac controller base address */
        volatile uint32 emac_ctrl_base;
        volatile uint32 emac_ctrl_ram;
    
        /* mdio base address */
        volatile uint32 mdio_base;
    
        /* phy parameters for this instance - for future use */
        uint32 phy_addr;
        boolean (*phy_autoneg)(uint32, uint32, uint16);
        boolean (*phy_partnerability)(uint32, uint32, uint16 *);
    
        /* The tx/rx channels for the interface */
        struct txch txch;
        struct rxch rxch;
    } hdkif;
    
    /* Defining interface for all the emac instances */
    static struct hdkif hdkif_data[MAX_EMAC_INSTANCE];
    
    uint32 hdkif_swizzle_data(uint32 word) {
    // #if ((__little_endian__ == 0) || (__LITTLE_ENDIAN__ == 0))
    //     return word;
    
    // #else
    //     return (
    //         ((word << 24) & 0xFF000000) | ((word << 8) & 0x00FF0000) | ((word >> 8) & 0x0000FF00) |
    //         ((word >> 24) & 0x000000FF));
    // #endif
    #if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))
        //return word;
        return __rev(word);
    #else
        return (word);
        // return __rev(word);
    #endif
    }
    
    struct emac_tx_bdp *hdkif_swizzle_txp(volatile struct emac_tx_bdp *p) {
        return (struct emac_tx_bdp *)hdkif_swizzle_data((uint32)p);
    }
    
    struct emac_rx_bdp *hdkif_swizzle_rxp(volatile struct emac_rx_bdp *p) {
        return (struct emac_rx_bdp *)hdkif_swizzle_data((uint32)p);
    }
    /**
    * Function to set the MAC address to the interface
    * @param   inst_num the instance number
    * @return  none.
    */
    void hdkif_macaddrset(uint32 inst_num, uint8 *mac_addr) {
        struct hdkif *hdkif;
        uint32 temp;
    
        hdkif = &hdkif_data[inst_num];
    
        /* set MAC hardware address */
        for (temp = 0; temp < ETHARP_HWADDR_LEN; temp++) {
            hdkif->mac_addr[temp] = mac_addr[(ETHARP_HWADDR_LEN - 1) - temp];
        }
    }
    
    /**
    * Function to setup the instance parameters inside the interface
    * @param   hdkif
    * @return  none.
    */
    static void hdkif_inst_config(struct hdkif *hdkif) {
        hdkif->emac_base          = EMAC_0_BASE;
        hdkif->emac_ctrl_base     = EMAC_CTRL_0_BASE;
        hdkif->emac_ctrl_ram      = EMAC_CTRL_RAM_0_BASE;
        hdkif->mdio_base          = MDIO_0_BASE;
        hdkif->phy_addr           = 0;
        hdkif->phy_autoneg        = Dp83640AutoNegotiate;
        hdkif->phy_partnerability = Dp83640PartnerAbilityGet;
    }
    
    /**
    * Function to setup the link. AutoNegotiates with the phy for link
    * setup and set the EMAC with the result of autonegotiation.
    * @param  hdkif
    * @return ERR_OK if everything passed
    *         others if not passed
    */
    static err_t hdkif_link_setup(struct hdkif *hdkif) {
        err_t linkstat              = ERR_CONN;
        uint16 partnr_ablty         = 0U;
        uint32 phyduplex            = EMAC_DUPLEX_HALF;
        volatile unsigned int delay = 0xFFFFFU;
        if (hdkif->inst_num == 0) {
            if (Dp83640AutoNegotiate(
                    (uint32)hdkif->mdio_base,
                    (uint32)hdkif->phy_addr,
                    (uint16)((uint16)DP83640_100BTX | (uint16)DP83640_100BTX_FD | (uint16)DP83640_10BT | (uint16)DP83640_10BT_FD)) ==
                TRUE) {
                linkstat = ERR_OK;
    
                Dp83640PartnerAbilityGet(hdkif->mdio_base, hdkif->phy_addr, &partnr_ablty);
    
                /* Check for 100 Mbps and duplex capability */
                if ((partnr_ablty & DP83640_100BTX_FD) != 0U) {
                    phyduplex = EMAC_DUPLEX_FULL;
                }
            } else {
                linkstat = ERR_CONN;
            }
        } else {
            linkstat = ERR_CONN;
        }
    
        /* Set the EMAC with the negotiation results if it is successful */
        if (linkstat == ERR_OK) {
            EMACDuplexSet(hdkif->emac_base, phyduplex);
        }
    
        /* Wait for the MII to settle down */
        while (delay != 0U) {
            delay--;
        }
        return linkstat;
    }
    
    /**
     * This function should do the actual transmission of the packet. The packet is
     * contained in the pbuf that is passed to the function. This pbuf might be
     * chained. That is, one pbuf can span more than one tx buffer descriptors
     *
     * @param hdkif the network interface state for this ethernetif
     * @param pbuf  the pbuf which is to be sent over EMAC
     * @return None
     */
    static void hdkif_transmit(struct hdkif *hdkif, struct pbuf *pbuf) {
        struct pbuf *q;
        struct txch *txch;
        volatile struct emac_tx_bdp *curr_bd, *active_head, *bd_end;
        //uint16 qLen;
        txch = &(hdkif->txch);
    
        /* Get the buffer descriptor which is free to transmit */
        curr_bd     = txch->free_head;
        bd_end      = curr_bd;
        active_head = curr_bd;
    
        /* Update the total packet length */
        uint32 flags_pktlen = pbuf->tot_len;
        flags_pktlen |= (EMAC_BUF_DESC_SOP | EMAC_BUF_DESC_OWNER);
        curr_bd->flags_pktlen = hdkif_swizzle_data(flags_pktlen);
    
        /* Copy pbuf information into TX buffer descriptors */
        for (q = pbuf; q != NULL; q = q->next) {
            /* Intialize the buffer pointer and length */
            curr_bd->bufptr = hdkif_swizzle_data((uint32)(q->payload));
            //  qLen                = (uint16)(q->len);
            curr_bd->bufoff_len = hdkif_swizzle_data((q->len) & 0xFFFF);
            bd_end              = curr_bd;
            curr_bd->pbuf       = pbuf;
            curr_bd             = hdkif_swizzle_txp(curr_bd->next);
            //if (curr_bd) curr_bd->flags_pktlen = 0;
        }
    
        /* Indicate the end of the packet */
        bd_end->next = NULL;
        bd_end->flags_pktlen |= hdkif_swizzle_data(EMAC_BUF_DESC_EOP);
    
        txch->free_head = curr_bd;
    
        /* For the first time, write the HDP with the filled bd */
        if (txch->active_tail == NULL) {
            EMACTxHdrDescPtrWrite(hdkif->emac_base, (unsigned int)(active_head), 0);
        }
    
        /*
       * Chain the bd's. If the DMA engine, already reached the end of the chain,
       * the EOQ will be set. In that case, the HDP shall be written again.
       */
        else {
            curr_bd = txch->active_tail;
            /* TODO: (This is a workaround) Wait for the EOQ bit is set */
            while (EMAC_BUF_DESC_EOQ != (hdkif_swizzle_data(curr_bd->flags_pktlen) & EMAC_BUF_DESC_EOQ))
                ;
            /* TODO: (This is a workaround) Don't write to TXHDP0 until it turns to zero */
            while (0 != *((uint32 *)0xFCF78600))
                ;
            curr_bd->next = hdkif_swizzle_txp(active_head);
            if (EMAC_BUF_DESC_EOQ == (hdkif_swizzle_data(curr_bd->flags_pktlen) & EMAC_BUF_DESC_EOQ)) {
                /* Write the Header Descriptor Pointer and start DMA */
                EMACTxHdrDescPtrWrite(hdkif->emac_base, (unsigned int)(active_head), 0);
            }
        }
    
        txch->active_tail = bd_end;
    }
    
    /**
     * This function will send a packet through the emac if the channel is
     * available. Otherwise, the packet will be queued in a pbuf queue.
     *
     * @param netif the lwip network interface structure for this ethernetif
     * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
     * @return ERR_OK if the packet could be sent
     *         an err_t value if the packet couldn't be sent
     *
     */
    static err_t hdkif_output(struct netif *netif, struct pbuf *p) {
        SYS_ARCH_DECL_PROTECT(lev);
    
        /**
       * This entire function must run within a "critical section" to preserve
       * the integrity of the transmit pbuf queue.
       *
       */
        SYS_ARCH_PROTECT(lev);
    
        /* adjust the packet length if less than minimum required */
        if (p->tot_len < MIN_PKT_LEN) {
            p->tot_len = MIN_PKT_LEN;
            p->len     = MIN_PKT_LEN;
        }
    
        /**
       * Bump the reference count on the pbuf to prevent it from being
       * freed till we are done with it.
       *
       */
        pbuf_ref(p);
    
        /* call the actual transmit function */
        hdkif_transmit(netif->state, p);
    
        /* Return to prior interrupt state and return. */
        SYS_ARCH_UNPROTECT(lev);
    
        return ERR_OK;
    }
    
    extern void sciDisplayText(sciBASE_t *sci, uint8_t *text, uint32_t length);
    static uint8_t txtCRLF2[]        = {'\r', '\n'};
    static uint8_t txtSuccess[]      = {"SUCCESS"};
    static uint8_t txtProgress[]     = {"."};
    static uint8_t txtError[]        = {"!!! ERROR !!!"};
    static uint8_t txtPhyGetId[]     = {"	DEBUG - Getting PHY ID..."};
    static uint8_t txtPhyGetAlSts[]  = {"	DEBUG - Getting PHY Alive Status..."};
    static uint8_t txtPhyGetLnkSts[] = {"	DEBUG - Getting PHY Link Status..."};
    static uint8_t txtPhySetupLink[] = {"	DEBUG - Setting up Link..."};
    /* End of DEBUG BLOCK - 1 */
    
    /**
     * In this function, the hardware should be initialized.
     * Called from hdkif_init().
     *
     * @param netif the already initialized lwip network interface structure
     *        for this ethernetif
     */
    static err_t hdkif_hw_init(struct netif *netif) {
        uint32 temp, channel;
        uint32 num_bd, pbuf_cnt = 0U;
        volatile uint32 phyID          = 0U;
        volatile uint32 delay          = 0xFFFU;
        volatile uint32 phyIdReadCount = 0xFFFFU;
        volatile struct emac_tx_bdp *curr_txbd, *last_txbd;
        volatile struct emac_rx_bdp *curr_bd, *last_bd;
        uint32 retVal = EMAC_ERR_OK;
        struct hdkif *hdkif;
        struct txch *txch;
        struct rxch *rxch;
        struct pbuf *p, *q;
        hdkif = &hdkif_data[0U];
        hdkif_inst_config(hdkif);
        hdkif = netif->state;
    
        /* set MAC hardware address length */
        netif->hwaddr_len = ETHARP_HWADDR_LEN;
    
        /* set MAC hardware address */
        for (temp = 0; temp < ETHARP_HWADDR_LEN; temp++) {
            netif->hwaddr[temp] = hdkif->mac_addr[(ETHARP_HWADDR_LEN - 1) - temp];
        }
    
        /* maximum transfer unit */
        netif->mtu = MAX_TRANSFER_UNIT;
    
        /* device capabilities */
        /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
        netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
    
        EMACInit(hdkif->emac_ctrl_base, hdkif->emac_base);
    
        MDIOInit(hdkif->mdio_base, MDIO_FREQ_INPUT, MDIO_FREQ_OUTPUT);
        while (delay--)
            ;
        EMACRxBroadCastEnable(hdkif->emac_base, 0);
        /* Set the MAC Addresses in EMAC hardware */
        EMACMACSrcAddrSet(hdkif->emac_base, hdkif->mac_addr);
    
        for (channel = 0; channel < 8; channel++) {
            EMACMACAddrSet(hdkif->emac_base, channel, hdkif->mac_addr, EMAC_MACADDR_MATCH);
        }
    
        // Dp83640Reset(hdkif->mdio_base, hdkif->phy_addr);
        gen_cfg(hdkif->mdio_base, hdkif->phy_addr);
    
        phy_status_read(hdkif->mdio_base, hdkif->phy_addr);
        led_cfg_reg(hdkif->mdio_base, hdkif->phy_addr);
        dp83869_SwStrap(hdkif->mdio_base, hdkif->phy_addr);
        sciDisplayText(sciREGx, txtCRLF2, sizeof(txtCRLF2));
        sciDisplayText(sciREGx, txtPhyGetId, sizeof(txtPhyGetId));
    
        while ((phyID == 0) && (phyIdReadCount > 0)) {
            phyID = Dp83640IDGet(hdkif->mdio_base, hdkif->phy_addr);
            phyIdReadCount--;
            sciDisplayText(sciREGx, txtProgress, sizeof(txtProgress));
        }
    
        if (0 != phyID) {
            sciDisplayText(sciREGx, txtSuccess, sizeof(txtSuccess));
        } else {
            sciDisplayText(sciREGx, txtError, sizeof(txtError));
            retVal = EMAC_ERR_CONNECT;
        }
        sciDisplayText(sciREGx, txtCRLF2, sizeof(txtCRLF2));
    
        sciDisplayText(sciREGx, txtPhyGetAlSts, sizeof(txtPhyGetAlSts));
        // if (!((MDIOPhyAliveStatusGet(hdkif->mdio_base) >> hdkif->phy_addr) & 0x01))
        if ((uint32)0U == ((MDIOPhyAliveStatusGet(hdkif->mdio_base) >> hdkif->phy_addr) & (uint32)0x01U)) {
            sciDisplayText(sciREGx, txtError, sizeof(txtError));
            return ERR_CONN;
        } else {
            sciDisplayText(sciREGx, txtSuccess, sizeof(txtSuccess));
        }
        sciDisplayText(sciREGx, txtCRLF2, sizeof(txtCRLF2));
    
        // if ((uint32)0U == ((MDIOPhyAliveStatusGet(hdkif->mdio_base) >> hdkif->phy_addr) & (uint32)0x01U)) {
        //     retVal = EMAC_ERR_CONNECT;
        // } else {
        // }
    
        sciDisplayText(sciREGx, txtPhyGetLnkSts, sizeof(txtPhyGetLnkSts));
    
        if (!Dp83640LinkStatusGet(hdkif->mdio_base, hdkif->phy_addr, 0xFFFFFU)) {
            sciDisplayText(sciREGx, txtError, sizeof(txtError));
            return EMAC_ERR_CONNECT;
        } else {
            sciDisplayText(sciREGx, txtSuccess, sizeof(txtSuccess));
        }
        sciDisplayText(sciREGx, txtCRLF2, sizeof(txtCRLF2));
    
        sciDisplayText(sciREGx, txtPhySetupLink, sizeof(txtPhySetupLink));
        if (hdkif_link_setup(hdkif) != ERR_OK) {
            sciDisplayText(sciREGx, txtError, sizeof(txtError));
            return ERR_CONN;
        } else {
            sciDisplayText(sciREGx, txtSuccess, sizeof(txtSuccess));
        }
        sciDisplayText(sciREGx, txtCRLF2, sizeof(txtCRLF2));
        // EMACDMAInit(hdkif);
    
        txch = &(hdkif->txch);
    
        /**
      * Initialize the Descriptor Memory For TX and RX
      * Only Channel 0 is supported for both TX and RX
      */
        txch->free_head          = (volatile struct emac_tx_bdp *)(hdkif->emac_ctrl_ram);
        txch->next_bd_to_process = txch->free_head;
        txch->active_tail        = NULL;
    
        /* Set the number of descriptors for the channel */
        num_bd = (SIZE_EMAC_CTRL_RAM >> 1) / sizeof(emac_tx_bdp);
    
        curr_txbd = txch->free_head;
    
        /* Initialize all the TX buffer Descriptors */
        while (num_bd--) {
            curr_txbd->next         = hdkif_swizzle_txp(curr_txbd + 1);
            curr_txbd->flags_pktlen = 0;
            last_txbd               = curr_txbd;
            curr_txbd               = hdkif_swizzle_txp(curr_txbd->next);
        }
        last_txbd->next = hdkif_swizzle_txp(txch->free_head);
    
        /* Initialize the descriptors for the RX channel */
        rxch              = &(hdkif->rxch);
        rxch->active_head = (volatile struct emac_rx_bdp *)(curr_txbd + 1);
    
        rxch->free_head      = NULL;
        rxch->freed_pbuf_len = 0;
        num_bd               = ((SIZE_EMAC_CTRL_RAM >> 1) / sizeof(emac_rx_bdp) - 1);
        curr_bd              = rxch->active_head;
        last_bd              = curr_bd;
    
        /*
      ** Allocate the pbufs for the maximum count permitted or till the
      ** number of buffer desceriptors expire, which ever is earlier.
      */
        while (pbuf_cnt < MAX_RX_PBUF_ALLOC) {
            p = pbuf_alloc(PBUF_RAW, PBUF_LEN_MAX, PBUF_POOL);
            pbuf_cnt++;
    
            if (p != NULL) {
                /* write the descriptors if there are enough numbers to hold the pbuf*/
                if (((uint32)pbuf_clen(p)) <= num_bd) {
                    for (q = p; q != NULL; q = q->next) {
                        curr_bd->bufptr       = hdkif_swizzle_data((uint32)(q->payload));
                        curr_bd->bufoff_len   = hdkif_swizzle_data(q->len);
                        curr_bd->next         = hdkif_swizzle_rxp(curr_bd + 1);
                        curr_bd->flags_pktlen = hdkif_swizzle_data(EMAC_BUF_DESC_OWNER);
    
                        /* Save the pbuf */
                        curr_bd->pbuf = q;
                        last_bd       = curr_bd;
                        curr_bd       = hdkif_swizzle_rxp(curr_bd->next);
                        num_bd--;
                    }
                }
    
                /* free the allocated pbuf if no free descriptors are left */
                else {
                    pbuf_free(p);
                    break;
                }
            } else {
                break;
            }
        }
    
        last_bd->next     = NULL;
        rxch->active_tail = last_bd;
    
        /* Acknowledge receive and transmit interrupts for proper interrupt pulsing*/
        EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX);
        EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_TX);
    
    #if (EMAC_BROADCAST_ENABLE)
        EMACRxBroadCastEnable(hdkif->emac_base, (uint32)EMAC_CHANNELNUMBER);
    #else
        /*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
        /*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
        EMACRxBroadCastDisable(hdkif->emac_base, (uint32)EMAC_CHANNELNUMBER);
    #endif
    
    #if (EMAC_UNICAST_ENABLE)
        EMACRxUnicastSet(hdkif->emac_base, (uint32)EMAC_CHANNELNUMBER);
    #else
        /*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
        EMACRxUnicastClear(hdkif->emac_base, (uint32)EMAC_CHANNELNUMBER);
    #endif
    
        // EMACNumFreeBufSet(hdkif->emac_base, 0, 10);
    
    #if (EMAC_FULL_DUPLEX_ENABLE)
        EMACDuplexSet(EMAC_0_BASE, (uint32)EMAC_DUPLEX_FULL);
    #else
        /*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition arameter is taken as input from GUI." */
        EMACDuplexSet(EMAC_0_BASE, (uint32)EMAC_DUPLEX_HALF);
    #endif
        // EMACDMAInit(hdkif);
        EMACMIIEnable(hdkif->emac_base);
    #if (EMAC_TX_ENABLE)
        EMACTxEnable(hdkif->emac_base);
        EMACTxIntPulseEnable(
            hdkif->emac_base, hdkif->emac_ctrl_base, (uint32)EMAC_CHANNELNUMBER, (uint32)EMAC_CHANNELNUMBER);
    #else
        /*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
        /*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
        EMACTxDisable(hdkif->emac_base);
        EMACTxIntPulseDisable(
            hdkif->emac_base, hdkif->emac_ctrl_base, (uint32)EMAC_CHANNELNUMBER, (uint32)EMAC_CHANNELNUMBER);
    #endif
    //EMACRxEnable(hdkif->emac_base);
    #if (EMAC_RX_ENABLE)
        EMACNumFreeBufSet(hdkif->emac_base, (uint32)EMAC_CHANNELNUMBER, (uint32)MAX_RX_PBUF_ALLOC);
        EMACRxEnable(hdkif->emac_base);
        EMACRxIntPulseEnable(
            hdkif->emac_base, hdkif->emac_ctrl_base, (uint32)EMAC_CHANNELNUMBER, (uint32)EMAC_CHANNELNUMBER);
        rxch = &(hdkif->rxch);
        /* Write to the RX HDP for channel 0 */
        /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> "Valid non NULL input parameters are assigned in this driver" */
        EMACRxHdrDescPtrWrite(hdkif->emac_base, (uint32)rxch->active_head, (uint32)EMAC_CHANNELNUMBER);
    #else
        /*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
        /*SAFETYMCUSW 1 J MR:14.1 <APPROVED> "If condition parameter is taken as input from GUI." */
        EMACRxDisable(hdkif->emac_base);
        EMACRxIntPulseDisable(
            hdkif->emac_base, hdkif->emac_ctrl_base, (uint32)EMAC_CHANNELNUMBER, (uint32)EMAC_CHANNELNUMBER);
    #endif
    
        /* Write the RX HDP for channel 0 */
        //EMACRxHdrDescPtrWrite(hdkif->emac_base, (uint32)rxch->active_head, 0);
    
        /**
      * Enable the Transmission and reception, enable the interrupts for
      * channel 0 and for control core 0
      */
        // EMACTxIntPulseEnable(hdkif->emac_base, hdkif->emac_ctrl_base, 0, 0);
        // EMACRxIntPulseEnable(hdkif->emac_base, hdkif->emac_ctrl_base, 0, 0);
    
        return retVal;
    }
    
    /**
     * Should be called at the beginning of the program to set up the
     * network interface. It calls the function hdkif_hw_init() to do the
     * low level initializations.
     *
     * @param netif the lwip network interface structure for this ethernetif
     * @return ERR_OK if the loopif is initialized
     *         ERR_MEM if private data couldn't be allocated
     *         any other err_t on error
     */
    err_t hdkif_init(struct netif *netif) {
        /* Get the instance number first */
        unsigned int inst_num = *(unsigned int *)(netif->state);
        struct hdkif *hdkif;
    
    #if LWIP_NETIF_HOSTNAME
        /* Initialize interface hostname */
        netif->hostname = "lwip";
    #endif /* LWIP_NETIF_HOSTNAME */
    
        hdkif = &hdkif_data[inst_num];
    
        netif->state = hdkif;
    
        /*
       * Initialize the snmp variables and counters inside the struct netif.
       * The last argument should be replaced with your link speed, in units
       * of bits per second.
      */
        NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000);
    
        hdkif->inst_num = inst_num;
    
        netif->name[0] = IFNAME0;
        netif->name[1] = IFNAME1;
    
        netif->num = (uint8)inst_num;
    
        /* We directly use etharp_output() here to save a function call.
       * You can instead declare your own function an call etharp_output()
       * from it if you have to do some checks before sending (e.g. if link
       * is available...)
       */
        netif->output     = etharp_output;
        netif->linkoutput = hdkif_output;
       // EMACInit(hdkif->emac_ctrl_base, hdkif->emac_base);
        /* initialize the hardware */
        hdkif_inst_config(hdkif);
    
        return (hdkif_hw_init(netif));
    }
    
    /**
     * Handler for Receive interrupt. Packet processing is done in this
     * interrupt handler itself.
     *
     * @param netif the lwip network interface structure for this ethernetif
     * @return none
     */
    void hdkif_rx_inthandler(struct netif *netif) {
        struct hdkif *hdkif;
        struct rxch *rxch;
        volatile struct emac_rx_bdp *curr_bd, *processed_bd, *curr_tail, *last_bd;
        volatile struct pbuf *pbuf, *q, *new_pbuf;
        uint32 ex_len = 0, len_to_alloc = 0;
        uint16 tot_len;
    
        hdkif = netif->state;
        rxch  = &(hdkif->rxch);
    
        /* Get the bd which contains the earliest filled data */
        curr_bd = rxch->active_head;
        last_bd = rxch->active_tail;
    
        /**
       * Process the descriptors as long as data is available
       * when the DMA is receiving data, SOP flag will be set
      */
        while (hdkif_swizzle_data(curr_bd->flags_pktlen) & EMAC_BUF_DESC_SOP) {
            ex_len       = 0;
            len_to_alloc = 0;
    
            /* Start processing once the packet is loaded */
            if ((hdkif_swizzle_data(curr_bd->flags_pktlen) & EMAC_BUF_DESC_OWNER) != EMAC_BUF_DESC_OWNER) {
                if (rxch->free_head == NULL) {
                    /* this bd chain will be freed after processing */
                    rxch->free_head = curr_bd;
                }
    
                /* Get the total length of the packet. curr_bd points to the start
           * of the packet.
           */
                tot_len = hdkif_swizzle_data(curr_bd->flags_pktlen) & 0xFFFF;
    
                /* Get the start of the pbuf queue */
                q = curr_bd->pbuf;
    
                do {
                    /* Get the pbuf pointer which is associated with the current bd */
                    pbuf = curr_bd->pbuf;
    
                    /* If the earlier pbuf ended, update the chain */
                    if (pbuf->next == NULL) {
                        pbuf->next = (struct pbuf *)hdkif_swizzle_rxp(curr_bd->next)->pbuf;
                    }
    
                    len_to_alloc += pbuf->len;
                    /* Update the len and tot_len fields for the pbuf in the chain*/
                    pbuf->len     = hdkif_swizzle_data(curr_bd->bufoff_len) & 0xFFFF;
                    pbuf->tot_len = tot_len - ex_len;
                    processed_bd  = curr_bd;
                    ex_len += pbuf->len;
                    curr_bd = hdkif_swizzle_rxp(curr_bd->next);
                } while ((hdkif_swizzle_data(processed_bd->flags_pktlen) & EMAC_BUF_DESC_EOP) != EMAC_BUF_DESC_EOP);
    
                /**
           * Close the chain for this pbuf. A full packet is received in
           * this pbuf chain. Now this pbuf can be given to upper layers for
           * processing. The start of the pbuf chain is now 'q'.
          */
                pbuf->next = NULL;
    
                /* Adjust the link statistics */
                LINK_STATS_INC(link.recv);
    
                /* Process the packet */
                if (ethernet_input((struct pbuf *)q, netif) != ERR_OK) {
                    /* Adjust the link statistics */
                    LINK_STATS_INC(link.memerr);
                    LINK_STATS_INC(link.drop);
                }
    
                /* Acknowledge that this packet is processed */
                EMACRxCPWrite(hdkif->emac_base, 0, (unsigned int)processed_bd);
    
                rxch->active_head = curr_bd;
    
                /**
           * The earlier pbuf chain is freed from the upper layer. So, we need to
           * allocate a new pbuf chain and update the descriptors with the pbuf info.
           * To support chaining, the total length freed by the upper layer is tracked.
           * Care should be taken even if the allocation fails.
           */
                /**
           * now len_to_alloc will contain the length of the pbuf which was freed
           * from the upper layer
           */
                rxch->freed_pbuf_len += len_to_alloc;
                new_pbuf = pbuf_alloc(PBUF_RAW, (rxch->freed_pbuf_len), PBUF_POOL);
    
                /* Write the descriptors with the pbuf info till either of them expires */
                if (new_pbuf != NULL) {
                    curr_bd = rxch->free_head;
    
                    for (q = new_pbuf; (q != NULL) && (curr_bd != rxch->active_head); q = q->next) {
                        curr_bd->bufptr = hdkif_swizzle_data((uint32)(q->payload));
    
                        /* no support for buf_offset. RXBUFFEROFFEST register is 0 */
                        curr_bd->bufoff_len   = hdkif_swizzle_data((q->len) & 0xFFFF);
                        curr_bd->flags_pktlen = hdkif_swizzle_data(EMAC_BUF_DESC_OWNER);
    
                        rxch->freed_pbuf_len -= q->len;
    
                        /* Save the pbuf */
                        curr_bd->pbuf = q;
                        last_bd       = curr_bd;
                        curr_bd       = hdkif_swizzle_rxp(curr_bd->next);
                    }
    
                    /**
             * At this point either pbuf expired or no rxbd to allocate. If
             * there are no, enough rx bds to allocate all pbufs in the chain,
             * free the rest of the pbuf
             */
                    if (q != NULL) {
                        pbuf_free((struct pbuf *)q);
                    }
    
                    curr_tail     = rxch->active_tail;
                    last_bd->next = NULL;
    
                    curr_tail->next = hdkif_swizzle_rxp(rxch->free_head);
    
                    /**
             * Check if the reception has ended. If the EOQ flag is set, the NULL
             * Pointer is taken by the DMA engine. So we need to write the RX HDP
             * with the next descriptor.
             */
                    if (hdkif_swizzle_data(curr_tail->flags_pktlen) & EMAC_BUF_DESC_EOQ) {
                        EMACRxHdrDescPtrWrite(hdkif->emac_base, (uint32)(rxch->free_head), 0);
                    }
    
                    rxch->free_head   = curr_bd;
                    rxch->active_tail = last_bd;
                }
            }
            curr_bd = rxch->active_head;
        }
    
        EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX);
        EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_TX);
    }
    
    /**
     * Handler for EMAC Transmit interrupt
     *
     * @param netif the lwip network interface structure for this ethernetif
     * @return none
     */
    void hdkif_tx_inthandler(struct netif *netif) {
        struct txch *txch;
        struct hdkif *hdkif;
        volatile struct emac_tx_bdp *curr_bd, *next_bd_to_process;
    
        hdkif = netif->state;
        txch  = &(hdkif->txch);
    
        next_bd_to_process = txch->next_bd_to_process;
    
        curr_bd = next_bd_to_process;
    
        /* Check for correct start of packet */
        while (hdkif_swizzle_data(curr_bd->flags_pktlen) & EMAC_BUF_DESC_SOP) {
            /* Make sure that the transmission is over */
            while ((hdkif_swizzle_data(curr_bd->flags_pktlen) & EMAC_BUF_DESC_OWNER) == EMAC_BUF_DESC_OWNER)
                ;
    
            /* Traverse till the end of packet is reached */
            while ((hdkif_swizzle_data(curr_bd->flags_pktlen) & EMAC_BUF_DESC_EOP) != EMAC_BUF_DESC_EOP) {
                curr_bd = hdkif_swizzle_txp(curr_bd->next);
            }
    
            next_bd_to_process->flags_pktlen &= hdkif_swizzle_data(~(EMAC_BUF_DESC_SOP));
            curr_bd->flags_pktlen &= hdkif_swizzle_data(~(EMAC_BUF_DESC_EOP));
    
            /**
         * If there are no more data transmitted, the next interrupt
         * shall happen with the pbuf associated with the free_head
         */
            if (curr_bd->next == NULL) {
                txch->next_bd_to_process = txch->free_head;
            }
    
            else {
                txch->next_bd_to_process = hdkif_swizzle_txp(curr_bd->next);
            }
    
            /* Acknowledge the EMAC and free the corresponding pbuf */
            EMACTxCPWrite(hdkif->emac_base, 0, (uint32)curr_bd);
    
            pbuf_free((struct pbuf *)curr_bd->pbuf);
    
            LINK_STATS_INC(link.xmit);
    
            next_bd_to_process = txch->next_bd_to_process;
            curr_bd            = next_bd_to_process;
        }
    
        EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_RX);
        EMACCoreIntAck(hdkif->emac_base, EMAC_INT_CORE0_TX);
    }
    
    /**
     * Gets the netif status
     *
     * @param   the netif whoes status to be checked
     * @return  the status
     */
    uint32 hdkif_netif_status(struct netif *netif) {
        return (netif_is_up(netif));
    }
    
    /**
     * returns the link status
     *
     * @param   the netif whoes link to be checked
     * @return  the status
     */
    uint32 hdkif_link_status(struct netif *netif) {
        struct hdkif *hdkif = netif->state;
    
        return (Dp83640LinkStatusGet(hdkif->mdio_base, hdkif->phy_addr, 100000));
    }
    
    HL_phy_dp83640.c
    /**
     *  \file   phy_dp83640.c
     *
     *  \brief  APIs for configuring DP83640.
     *
     *   This file contains the device abstraction APIs for PHY DP83640.
     */
    
    /*
    * Copyright (C) 2009-2018 Texas Instruments Incorporated - www.ti.com
    *
    *
    *  Redistribution and use in source and binary forms, with or without
    *  modification, are permitted provided that the following conditions
    *  are met:
    *
    *    Redistributions of source code must retain the above copyright
    *    notice, this list of conditions and the following disclaimer.
    *
    *    Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the
    *    documentation and/or other materials provided with the
    *    distribution.
    *
    *    Neither the name of Texas Instruments Incorporated nor the names of
    *    its contributors may be used to endorse or promote products derived
    *    from this software without specific prior written permission.
    *
    *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    */
    
    
    /* USER CODE BEGIN (0) */
    /* USER CODE END */
    
    #include "HL_sys_common.h"
    #include "HL_mdio.h"
    #include "HL_phy_dp83640.h"
    
    /* USER CODE BEGIN (1) */
    /* USER CODE END */
    
    /*******************************************************************************
    *                        API FUNCTION DEFINITIONS
    *******************************************************************************/
    /**
     * \brief   Reads the PHY ID.
     *
     * \param   mdioBaseAddr  Base Address of the MDIO Module Registers.
     * \param   phyAddr       PHY Adress.
     *
     * \return  32 bit PHY ID (ID1:ID2)
     *
     **/
    /* SourceId : ETH_SourceId_063 */
    /* DesignId : ETH_DesignId_063*/
    /* Requirements : HL_CONQ_EMAC_SR69 */
    uint32 Dp83640IDGet(uint32 mdioBaseAddr, uint32 phyAddr)
    {
        uint32 id = 0U;
        uint16 data = 0U;
    
        /* read the ID1 register */
        (void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_ID1, &data);
    
        /* update the ID1 value */
    	id = (uint32)data;
    	id = (uint32)((uint32)id << PHY_ID_SHIFT);
    
        /* read the ID2 register */
        (void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_ID2, &data);
    
        /* update the ID2 value */
        id |= data;
    
        /* return the ID in ID1:ID2 format */
        return id;
    }
    
    /**
     * \brief   Reads the link status of the PHY.
     *
     * \param   mdioBaseAddr  Base Address of the MDIO Module Registers.
     * \param   phyAddr       PHY Adress.
     * \param   retries       The number of retries before indicating down status
     *
     * \return  link status after reading \n
     *          TRUE if link is up
     *          FALSE if link is down \n
     *
     * \note    This reads both the basic status register of the PHY and the
     *          link register of MDIO for double check
     **/
    /* SourceId : ETH_SourceId_067 */
    /* DesignId : ETH_DesignId_067*/
    /* Requirements : HL_CONQ_EMAC_SR67 */
    boolean Dp83640LinkStatusGet(uint32 mdioBaseAddr,
                                       uint32 phyAddr,
                                       volatile uint32 retries)
    {
        volatile uint16 linkStatus = 0U;
        boolean retVal = TRUE;
    
        while (retVal == TRUE)
        {
            /* First read the BSR of the PHY */
            (void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_BSR, &linkStatus);
    
    		/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
            if((linkStatus & PHY_LINK_STATUS) != 0U)
            {
                /* Check if MDIO LINK register is updated */
                linkStatus = (uint16)MDIOPhyLinkStatusGet(mdioBaseAddr);
    
    			/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
                if((linkStatus & (uint16)((uint16)1U << phyAddr)) != 0U)
                {
                   break;
                }
                else
                {
    			    /*SAFETYMCUSW 9 S MR:12.2 <APPROVED> "Ternary Operator Expression" */
    				/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
    				/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
    				if(retries != 0U)
    				{
    					retries--;
    				}
    				else
    				{
    					retVal = FALSE;
    				}
                }
            }
            else
            {
    			/*SAFETYMCUSW 9 S MR:12.2 <APPROVED> "Ternary Operator Expression" */
             	/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
             	/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
    				if(retries != 0U)
    				{
    					retries--;
    				}
    				else
    				{
    					retVal = FALSE;
    				}
            }
        }
    
        return retVal;
    }
    
    /**
     * \brief   This function does Autonegotiates with the EMAC device connected
     *          to the PHY. It will wait till the autonegotiation completes.
     *
     * \param   mdioBaseAddr  Base Address of the MDIO Module Registers.
     * \param   phyAddr       PHY Adress.
     * \param   advVal        Autonegotiation advertisement value
     *          advVal can take the following any OR combination of the values \n
     *               DP83640_100BTX - 100BaseTX
     *               DP83640_100BTX_FD - Full duplex capabilty for 100BaseTX
     *               DP83640_10BT - 10BaseT
     *               DP83640_10BT_FD - Full duplex capability for 10BaseT
     *
     * \return  status after autonegotiation \n
     *          TRUE if autonegotiation successful
     *          FALSE if autonegotiation failed
     *
     **/
    /* SourceId : ETH_SourceId_065 */
    /* DesignId : ETH_DesignId_065*/
    /* Requirements : HL_CONQ_EMAC_SR66 */
    boolean Dp83640AutoNegotiate(uint32 mdioBaseAddr,
                                       uint32 phyAddr, uint16 advVal)
    {
        volatile uint16 data = 0U, anar = 0U;
    	boolean retVal = TRUE;
    	uint32 phyNegTries = 0xFFFFU;
        if(MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_BCR, &data) != TRUE )
        {
            retVal = FALSE;
        }
    
        data |= PHY_AUTONEG_ENABLE;
    
        /* Enable Auto Negotiation */
        MDIOPhyRegWrite(mdioBaseAddr, phyAddr, (uint32)PHY_BCR, data);
    
        if(MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_BCR, &data) != TRUE )
        {
            retVal = FALSE;
        }
    
        /* Write Auto Negotiation capabilities */
        (void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_AUTONEG_ADV, &anar);
        anar &= (uint16)(~0xff10U);
    	/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
        MDIOPhyRegWrite(mdioBaseAddr, phyAddr, (uint32)PHY_AUTONEG_ADV, (anar |advVal));
    
        data |= PHY_AUTONEG_RESTART;
    
        /* Start Auto Negotiation */
        MDIOPhyRegWrite(mdioBaseAddr, phyAddr, (uint32)PHY_BCR, data);
    
        /* Get the auto negotiation status*/
        if(MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_BSR, &data) != TRUE)
        {
             retVal = FALSE;
        }
    
        /* Wait till auto negotiation is complete */
    	/*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
        /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
        while((((uint16)(PHY_AUTONEG_INCOMPLETE)) == (data & (uint16)(PHY_AUTONEG_STATUS))) && (retVal == TRUE) && (phyNegTries > 0U))
        {
             (void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_BSR, &data);
    		 phyNegTries--;
        }
    
        /* Check if the PHY is able to perform auto negotiation */
        /*SAFETYMCUSW 134 S MR:12.2 <APPROVED> "LDRA Tool issue" */
    	if((data & PHY_AUTONEG_ABLE) != 0U)
        {
             retVal = TRUE;
        }
    	else
    	{
             retVal = FALSE;
    	}
    
    	return retVal;
    }
    
    
    /**
     * \brief   Reads the Link Partner Ability register of the PHY.
     *
     * \param   mdioBaseAddr  Base Address of the MDIO Module Registers.
     * \param   phyAddr       PHY Adress.
     * \param   ptnerAblty    The partner abilities of the EMAC
     *
     * \return  status after reading \n
     *          TRUE if reading successful
     *          FALSE if reading failed
     **/
    /* SourceId : ETH_SourceId_066 */
    /* DesignId : ETH_DesignId_066*/
    /* Requirements : HL_CONQ_EMAC_SR68 */
    boolean Dp83640PartnerAbilityGet(uint32 mdioBaseAddr,
                                           uint32 phyAddr,
                                           uint16 *ptnerAblty)
    {
        return (MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_LINK_PARTNER_ABLTY,
                               ptnerAblty));
    }
    
    
    /**
     * \brief   Resets the PHY.
     *
     * \param   mdioBaseAddr  Base Address of the MDIO Module Registers.
     * \param   phyAddr       PHY Adress.
     *
     * \return  No return value.
     **/
    /* SourceId : ETH_SourceId_064 */
    /* DesignId : ETH_DesignId_064*/
    /* Requirements : HL_CONQ_EMAC_SR65 */
    void Dp83640Reset(uint32 mdioBaseAddr, uint32 phyAddr)
    {
    	uint16 regVal = 0U;
    	uint16 *regPtr = &regVal;
    	MDIOPhyRegWrite(mdioBaseAddr, phyAddr, PHY_BCR, PHY_SOFTRESET);
    
    	(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BCR, regPtr);
    	/* : This bit is self-clearing and returns 1 until the reset process is complete. */
    	while((regVal & PHY_SOFTRESET) != 0U)
    	{
    		(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_BCR, regPtr);
    	}
    }
    
    /**
     * \brief   Enables PHY Loopback.
     *
     * \param   mdioBaseAddr  Base Address of the MDIO Module Registers.
     * \param   phyAddr       PHY Adress.
     *
     * \return  No return value.
     **/
    /* SourceId : ETH_SourceId_069 */
    /* DesignId : ETH_DesignId_069*/
    /* Requirements : HL_CONQ_EMAC_SR72 */
    void Dp83640EnableLoopback(uint32 mdioBaseAddr, uint32 phyAddr)
    {
    	uint32 delay = 0x1FFFU;
    	uint16 regVal = 0x0000U;
    	uint16 *regPtr = &regVal;
    	(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_BCR, regPtr);
    	/* Disabling Auto Negotiate. */
    	/*SAFETYMCUSW 334 S MR:10.5 <APPROVED> "Only unsigned short values are used." */
    	regVal &= (uint16)(~((uint16)PHY_AUTONEG_ENABLE));
    	/* Enabling Loopback. */
    	regVal |= PHY_LPBK_ENABLE;
    
    	MDIOPhyRegWrite(mdioBaseAddr, phyAddr, (uint32)PHY_BCR, regVal);
    
    	while(delay > 0U)
    	{
    		delay--;
    	}
    }
    
    /**
     * \brief   Disable PHY Loopback.
     *
     * \param   mdioBaseAddr  Base Address of the MDIO Module Registers.
     * \param   phyAddr       PHY Adress.
     *
     * \return  No return value.
     **/
    /* SourceId : ETH_SourceId_070 */
    /* DesignId : ETH_DesignId_070*/
    /* Requirements : HL_CONQ_EMAC_SR73 */
    void Dp83640DisableLoopback(uint32 mdioBaseAddr, uint32 phyAddr)
    {
    	uint32 delay = 0x1FFFU;
    	uint16 regVal = 0x0000U;
    	uint16 *regPtr = &regVal;
    	(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_BCR, regPtr);
    
    	/* Enabling Loopback. */
    	/*SAFETYMCUSW 334 S MR:10.5 <APPROVED> "Only unsigned short values are used." */
    	regVal &= (uint16)(~((uint16)PHY_LPBK_ENABLE));
    
    	MDIOPhyRegWrite(mdioBaseAddr, phyAddr, (uint32)PHY_BCR, regVal);
    
    	while(delay > 0U)
    	{
    		delay--;
    	}
    }
    /**
     * \brief   Reads the Transmit/Receive Timestamp
     *
     * \param   mdioBaseAddr  Base Address of the MDIO Module Registers.
     * \param   phyAddr       PHY Adress.
     * \param   type	      1- Transmit Timetamp
     * 						  2- Receive Timestamp
     * \param   timestamp     The read value that is returned to the user.
     *
     * \return  The timestamp is returned in 4 16-bit reads. They are stored in the following order:
     * 			Timestamp_ns [63:49]
     *			Overflow_cnt[48:47], Timestamp_ns[46:33]
     *			Timestamp_sec[32:16]
     *			Timestamp_sec[15:0]
     *			This is returned as a 64 bit value.
     *
     **/
    /* SourceId : ETH_SourceId_068 */
    /* DesignId : ETH_DesignId_068*/
    /* Requirements : HL_CONQ_EMAC_SR75 */
    uint64 Dp83640GetTimeStamp(uint32 mdioBaseAddr, uint32 phyAddr, phyTimeStamp_t type)
    {
    	uint16 ts = 0U;
    	/* (MISRA-C:2004 10.1/R) MISRA error reported with Code Composer Studio MISRA checker (due to use of & ?) */
    	uint16 *tsptr = &ts;
    	uint64 timeStamp = 0u;
    	if(type == 1U)
    	{
    	(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_TXTS, tsptr);
    	timeStamp |= (uint64)ts;
    	(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_TXTS, tsptr);
    	timeStamp = timeStamp << 16U ;
    	timeStamp |= (uint64)ts;
    	(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_TXTS, tsptr);
    	timeStamp = timeStamp << 16U ;
    	timeStamp |= (uint64)ts;
    	(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_TXTS, tsptr);
    	timeStamp = timeStamp << 16U ;
    	timeStamp |= (uint64)ts;
    	}
    	else
    	{
    	(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_RXTS, tsptr);
    	timeStamp |= (uint64)ts;
    	(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_RXTS, tsptr);
    	timeStamp = timeStamp << 16U ;
    	timeStamp |= (uint64)ts;
    	(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_RXTS, tsptr);
    	timeStamp = timeStamp << 16U ;
    	timeStamp |= (uint64)ts;
    	(void)MDIOPhyRegRead(mdioBaseAddr, phyAddr, (uint32)PHY_RXTS, tsptr);
    	timeStamp = timeStamp << 16U ;
    	timeStamp |= (uint64)ts;
    	}
    
    	return timeStamp;
    }
    
    /**
     * \brief   Reads the Speed info from Status register of the PHY.
     *
     * \param   mdioBaseAddr  Base Address of the MDIO Module Registers.
     * \param   phyAddr       PHY Adress.
     * \param   ptnerAblty    The partner abilities of the EMAC
     *
     * \return  status after reading \n
     *          TRUE if reading successful
     *          FALSE if reading failed
     **/
    boolean Dp83640PartnerSpdGet(uint32 mdioBaseAddr,
                                uint32 phyAddr,
                                uint16 *ptnerAblty)
    {
        return (MDIOPhyRegRead(mdioBaseAddr, phyAddr, PHY_LINK_PARTNER_SPD,
                               ptnerAblty));
    }
    
    /* USER CODE BEGIN (2) */
    void gen_cfg(uint32 mdioBaseAddr, uint32 phyAddr)
    {
    	uint16 gen_status_data =0x0000u;
    	uint16 *gen_status_ptr = &gen_status_data;
    
    		MDIOPhyRegWrite(mdioBaseAddr,phyAddr,Phy_gen_cfg1,disable_1000_advt);
    		MDIOPhyRegWrite(mdioBaseAddr,phyAddr, opmode_decode, opmode);
    		MDIOPhyRegWrite(mdioBaseAddr,phyAddr,gen_cfg_2,0x0000||0x0010);
    		MDIOPhyRegWrite(mdioBaseAddr,phyAddr,gen_cfg4,gencfgh_val);
    
    		MDIOPhyRegRead(mdioBaseAddr,phyAddr, gen_status, gen_status_ptr);
    
    
    }
    void dp83869_SwStrap(uint32 mdioBaseAddr, uint32 phyAddr ) {
    	uint16 status=0x0000u;
    
       uint16 *status_ptr=&status;
    	MDIOPhyRegRead(mdioBaseAddr, phyAddr, Sw_strap_status, status_ptr);
    
    }
    
    void phy_status_read(uint32 mdioBaseAddr, uint32 phyAddr){
    	uint16 phy_status_data =0x0000u;
    	uint16 *phy_status_ptr = &phy_status_data;
    	 MDIOPhyRegRead(mdioBaseAddr,phyAddr, Phy_status, phy_status_ptr)	;
    }
    void led_cfg_reg(uint32 mdioBaseAddr, uint32 phyAddr){
    	MDIOPhyRegWrite(mdioBaseAddr,phyAddr, led_cfg, led_sel);
    }
    /* USER CODE END */
    /**************************** End Of File ***********************************/
    
    HL_phy_dp83640.hHii, Jagadish as we have discussed regarding wrong pin configuration, we have inverted pins, also, I try making changes in hdkif.c, now every time my code is stuck in hardware initialisation error, I'm both cases DHCP and static IP, what may be the possible reasons.

    I am able to read all register value correctly, advertise 1000bps disable,as per data shéet, linkstatus also correct value receiving but at the end it is showing hardware initialisation error