common: Adding common library for sample vnf
[samplevnf.git] / common / VIL / l2l3_stack / interface.c
diff --git a/common/VIL/l2l3_stack/interface.c b/common/VIL/l2l3_stack/interface.c
new file mode 100644 (file)
index 0000000..84c390d
--- /dev/null
@@ -0,0 +1,1478 @@
+/*
+// Copyright (c) 2017 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#include <interface.h>
+#include <rte_byteorder.h>
+#include <lib_arp.h>
+#include <tsx.h>
+
+interface_main_t ifm;
+int USE_RTM_LOCKS = 0;
+rte_rwlock_t rwlock;
+uint8_t ifm_debug;
+static int prev_state;
+
+void config_ifm_debug(int dbg, int flag)
+{
+       switch (dbg) {
+       case IFM_DEBUG_CONFIG:
+               if (flag) {
+                       ifm_debug |= IFM_DEBUG_CONFIG;
+               } else {
+                       ifm_debug &= ~IFM_DEBUG_CONFIG;
+               }
+               break;
+       case IFM_DEBUG_RXTX:
+               if (flag) {
+                       ifm_debug |= IFM_DEBUG_RXTX;
+               } else {
+                       ifm_debug &= ~IFM_DEBUG_RXTX;
+               }
+               break;
+       case IFM_DEBUG_LOCKS:
+               if (flag) {
+                       ifm_debug |= IFM_DEBUG_LOCKS;
+               } else {
+                       ifm_debug &= ~IFM_DEBUG_LOCKS;
+               }
+               break;
+       case IFM_DEBUG:
+               if (flag) {
+                       ifm_debug |= IFM_DEBUG;
+               } else {
+                       ifm_debug &= ~IFM_DEBUG;
+               }
+               break;
+       }
+}
+
+void ifm_init(void)
+{
+       int i = 0;
+       config_ifm_debug(IFM_DEBUG_CONFIG, 1);
+       if (can_use_intel_core_4th_gen_features()) {
+               if (ifm_debug & IFM_DEBUG_CONFIG)
+                       RTE_LOG(INFO, IFM, "TSX not currently supported...\n\r");
+               USE_RTM_LOCKS = 0;
+       } else {
+               if (ifm_debug & IFM_DEBUG_CONFIG)
+                       RTE_LOG(INFO, IFM, "TSX not supported\n\r");
+               USE_RTM_LOCKS = 0;
+       }
+       if (USE_RTM_LOCKS)
+               rtm_init();
+       else
+               rte_rwlock_init(&rwlock);
+
+       for (i = 0; i < IFM_MAX_PORTARR_SZ; i++) {
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_lock();
+               else
+                       rte_rwlock_write_lock(&rwlock);
+
+               ifm.port_list[i] = NULL;
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_write_unlock(&rwlock);
+       }
+       ifm.nport_intialized = rte_eth_dev_count();
+       ifm.nport_configured = 0;
+       RTE_LOG(INFO, IFM, "IFM_INIT: Number of ports initialized during "
+               "PCI probing %u.\n\r", ifm.nport_intialized);
+}
+
+void ifm_remove_port_details(uint8_t portid)
+{
+       if (ifm.port_list[portid] != NULL) {
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Acquiring lock %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_lock();
+               else
+                       rte_rwlock_write_lock(&rwlock);
+               l2_phy_interface_t *port = ifm.port_list[portid];
+               ifm.port_list[portid] = NULL;
+               if (ifm_debug & IFM_DEBUG_CONFIG)
+                       RTE_LOG(INFO, IFM, "%s: NULL set for port %u\n\r",
+                               __FUNCTION__, portid);
+               rte_free(port);
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_write_unlock(&rwlock);
+       } else {
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM,
+                               "%s: Failed to remove port details.Port %u info"
+                               " is already Null.\n\r", __FUNCTION__, portid);
+       }
+}
+
+l2_phy_interface_t *ifm_get_port(uint8_t port_id)
+{
+       l2_phy_interface_t *port = NULL;
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_read_lock(&rwlock);
+
+       port = ifm.port_list[port_id];
+
+       if (port == NULL) {
+               /*RTE_LOG(ERR, IFM, "%s: Port %u info not found... configure it first.\n\r",
+                        __FUNCTION__, port_id);
+                */
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_read_unlock(&rwlock);
+               return NULL;
+       }
+       if (port->pmdid == port_id) {
+               /*RTE_LOG(INFO, IFM, "%s: Port %u found....\n\r",
+                        __FUNCTION__, port_id); */
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_read_unlock(&rwlock);
+               return port;
+       } else {
+
+/*             RTE_LOG(INFO, IFM,"%s: Mismatch given port %u port in loc %u\n\r",__FUNCTION__,port_id,
+                               ifm.port_list[port_id]->pmdid);
+*/
+       }
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_unlock();
+       else
+               rte_rwlock_read_unlock(&rwlock);
+       return NULL;
+}
+
+l2_phy_interface_t *ifm_get_first_port(void)
+{
+       l2_phy_interface_t *port = NULL;
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_read_lock(&rwlock);
+       port = ifm.port_list[0];
+       if (port == NULL) {
+               /*RTE_LOG(ERR, IFM, "%s: Port info not found... configure it first.\n\r",
+                        __FUNCTION__); */
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_read_unlock(&rwlock);
+               return NULL;
+       }
+       /*RTE_LOG(ERR, IFM, "%s: Port  %u info is found...%p\n\r",
+                __FUNCTION__, port->pmdid, port); */
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_unlock();
+       else
+               rte_rwlock_read_unlock(&rwlock);
+       return port;
+}
+
+l2_phy_interface_t *ifm_get_next_port(uint8_t port_id)
+{
+       l2_phy_interface_t *port = NULL;
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_read_lock(&rwlock);
+       port = ifm.port_list[port_id + 1];
+       if (port == NULL) {
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_read_unlock(&rwlock);
+               return NULL;
+       }
+       /*RTE_LOG(ERR, IFM, "%s: Port  %u info is found...\n\r",
+                __FUNCTION__, port_id); */
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS)
+               rtm_unlock();
+       else
+               rte_rwlock_read_unlock(&rwlock);
+       return port;
+}
+
+l2_phy_interface_t *ifm_get_port_by_name(const char *name)
+{
+       l2_phy_interface_t *port = NULL;
+       int i;
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_read_lock(&rwlock);
+       for (i = 0; i < RTE_MAX_ETHPORTS && ifm.port_list[i]; i++) {
+               port = ifm.port_list[i];
+               if (strcmp(name, port->ifname) == 0) {
+                       if (ifm_debug & IFM_DEBUG_CONFIG)
+                               RTE_LOG(INFO, IFM, "FOUND! port %u %s\n\r",
+                                       port->pmdid, port->ifname);
+                       if (ifm_debug & IFM_DEBUG_LOCKS)
+                               RTE_LOG(INFO, IFM,
+                                       "%s: Releasing lock @ %d\n\r",
+                                       __FUNCTION__, __LINE__);
+                       if (USE_RTM_LOCKS)
+                               rtm_unlock();
+                       else
+                               rte_rwlock_read_unlock(&rwlock);
+                       return port;
+               }
+       }
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_unlock();
+       else
+               rte_rwlock_read_unlock(&rwlock);
+       return NULL;
+}
+
+void lsi_event_callback(uint8_t port_id, enum rte_eth_event_type type,
+                       void *param)
+{
+       struct rte_eth_link link;
+       l2_phy_interface_t *port;
+       int nclients = ifm.nclient;
+       int i;
+
+       RTE_SET_USED(param);
+       RTE_SET_USED(type);
+
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS) {
+               rtm_lock();
+       } else {
+               rte_rwlock_write_lock(&rwlock);
+       }
+       rte_eth_link_get(port_id, &link);
+       for (i = 0; i < nclients; i++)
+               ifm.if_client[i].cb_linkupdate(port_id, link.link_status);
+       port = ifm.port_list[port_id];
+       if (port == NULL) {
+               RTE_LOG(ERR, IFM,
+                       "%s: Port %u info not found... configure it first.\n\r",
+                       __FUNCTION__, port_id);
+       }
+       if (port != NULL && port->pmdid == port_id) {
+               if (link.link_status) {
+                       port->link_status = IFM_ETH_LINK_UP;
+                       port->link_speed = link.link_speed;
+                       port->link_duplex = link.link_duplex;
+                       RTE_LOG(INFO, IFM,
+                               "EVENT-- PORT %u Link UP - Speed %u Mbps - %s.\n",
+                               port_id, (unsigned)link.link_speed,
+                               (link.link_duplex ==
+                                ETH_LINK_FULL_DUPLEX) ? ("full-duplex")
+                               : ("half-duplex"));
+                       if (port->flags & IFM_MASTER) {
+                               port->flags |= IFM_BONDED;
+                               port->bond_config->active_slave_count =
+                                               rte_eth_bond_active_slaves_get(port->pmdid,
+                                                                        port->
+                                                                        bond_config->
+                                                                        active_slaves,
+                                                                        RTE_MAX_ETHPORTS);
+                               struct ether_addr new_mac;
+                               rte_eth_macaddr_get(port->pmdid,
+                                                               (struct ether_addr *)
+                                                               &new_mac);
+                               if (memcmp
+                                               (&new_mac, port->macaddr,
+                                                sizeof(struct ether_addr))) {
+                                       RTE_LOG(INFO, IFM,
+                                               "Bond port %u MAC has changed.\n\r",
+                                               port->pmdid);
+                               } else {
+                                       RTE_LOG(INFO, IFM,
+                                               "Bond port %u MAC remains same\n\r",
+                                               port->pmdid);
+                               }
+                       }
+                       if (port->flags & IFM_SLAVE) {
+                               uint8_t master_portid =
+                                               port->bond_config->bond_portid;
+                               struct rte_eth_link linkstatus;
+                               rte_eth_link_get(master_portid, &linkstatus);
+                               RTE_LOG(INFO, IFM, "Port %u 's Master(%u) status is %u\n\r", port_id,
+                                               master_portid, linkstatus.link_status);
+                       }
+                       if (ifm_debug & IFM_DEBUG_LOCKS)
+                               RTE_LOG(INFO, IFM,
+                                       "%s: Releasing WR lock @ %d\n\r",
+                                       __FUNCTION__, __LINE__);
+
+                       if (USE_RTM_LOCKS) {
+                               rtm_unlock();
+                       } else {
+                               rte_rwlock_write_unlock(&rwlock);
+                       }
+                       if (port->ipv4_list != NULL) {
+                               if (ifm_debug & IFM_DEBUG_CONFIG)
+                                       RTE_LOG(INFO, IFM,
+                                               "Sending garp on port %u\n\r",
+                                               port->pmdid);
+                               if (!prev_state) {
+                                       send_gratuitous_arp(port);
+                                       prev_state = 1;
+                               }
+                       }
+#if 0
+                       else {
+                               if (ifm_debug & IFM_DEBUG_CONFIG)
+                                       RTE_LOG(INFO, IFM,
+                                               "IP is not enabled on port %u, not sending GARP\n\r",
+                                               port->pmdid);
+                       }
+#endif
+               } else {
+                       if (port->flags & IFM_MASTER) {
+                               port->flags &= ~IFM_BONDED;
+                               //RTE_LOG(INFO, IFM, "IFM_MASTER port, resetting IFM_BONDED. %u\n\r", port->flags);
+                       }
+                       port->link_status = IFM_ETH_LINK_DOWN;
+                       RTE_LOG(INFO, IFM, "EVENT-- PORT %u is Link DOWN.\n",
+                               port_id);
+                       if (port->flags & IFM_SLAVE) {
+                               struct rte_eth_link linkstatus;
+                               uint8_t master_portid =
+                                               port->bond_config->bond_portid;
+                               rte_eth_link_get_nowait(master_portid,
+                                                       &linkstatus);
+                               RTE_LOG(INFO, IFM,
+                                       "Port %u 's Master(%u) status is %u\n\r",
+                                       port_id, master_portid,
+                                       linkstatus.link_status);
+                       }
+                       if (ifm_debug & IFM_DEBUG_LOCKS)
+                               RTE_LOG(INFO, IFM,
+                                       "%s: Releasing WR lock @ %d\n\r",
+                                       __FUNCTION__, __LINE__);
+                       if (USE_RTM_LOCKS) {
+                               rtm_unlock();
+                       } else {
+                               rte_rwlock_write_unlock(&rwlock);
+                       }
+                       prev_state = 0;
+               }
+       }
+       //print_interface_details();
+}
+
+void ifm_update_linkstatus(uint8_t port_id, uint16_t linkstatus)
+{
+       struct rte_eth_link link;
+       l2_phy_interface_t *port;
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_lock();
+       } else {
+               rte_rwlock_write_lock(&rwlock);
+       }
+       port = ifm.port_list[port_id];
+
+       if (port == NULL) {
+               RTE_LOG(ERR, IFM,
+                       "%s: Port %u info not found... configure it first.\n\r",
+                       __FUNCTION__, port_id);
+       }
+       if (port != NULL && port->pmdid == port_id) {
+               rte_eth_link_get(port_id, &link);
+               if (linkstatus == IFM_ETH_LINK_UP) {
+                       port->admin_status = IFM_ETH_LINK_UP;
+                       if(!link.link_status) {
+                               if (rte_eth_dev_set_link_up(port_id) < 0) {
+                                       RTE_LOG(INFO, IFM,
+                                                       "%s:Port %u admin up is unsuccessful\n\r",
+                                                       __FUNCTION__, port->pmdid);
+                               } else {
+                                       if (ifm_debug & IFM_DEBUG_LOCKS)
+                                               RTE_LOG(INFO, IFM,
+                                                               "%s: Releasing lock @ %d\n\r",
+                                                               __FUNCTION__, __LINE__);
+
+                                       if (USE_RTM_LOCKS) {
+                                               rtm_unlock();
+                                       } else {
+                                               rte_rwlock_write_unlock(&rwlock);
+                                       }
+                                       if (ifm_debug & IFM_DEBUG_CONFIG)
+                                               RTE_LOG(INFO, IFM,
+                                                               "%s:Port %u admin up...\n\r",
+                                                               __FUNCTION__, port->pmdid);
+                                       send_gratuitous_arp(port);
+                                       return;
+                               }
+                       }
+               } else if (linkstatus == IFM_ETH_LINK_DOWN)
+               {
+                       int status;
+                       port->admin_status = IFM_ETH_LINK_DOWN;
+                       /* need to check the following if */
+                       if(link.link_status) {
+                               status = rte_eth_dev_set_link_down(port_id);
+                               if (status < 0)
+                               {
+                                       rte_panic("(%" PRIu32 "): PMD set link down error %"
+                                                       PRId32 "\n", port_id, status);
+                               }
+                       }
+               }
+       }
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_unlock();
+       } else {
+               rte_rwlock_write_unlock(&rwlock);
+       }
+}
+
+void ifm_set_l2_interface_mtu(uint8_t port_id, uint16_t mtu)
+{
+       int ret;
+       l2_phy_interface_t *port;
+       port = ifm.port_list[port_id];
+       if (port == NULL) {
+               RTE_LOG(ERR, IFM,
+                       "%s: Port %u info not found... configure it first.\n\r",
+                       __FUNCTION__, port_id);
+       }
+
+       if (port != NULL && port->pmdid == port_id) {
+               ret = rte_eth_dev_set_mtu(port_id, mtu);
+               if (ret != 0)
+                       RTE_LOG(INFO, IFM,
+                               "set_l2_interface_mtu: Set MTU failed. ret=%d\n",
+                               ret);
+               else {
+                       if (ifm_debug & IFM_DEBUG_LOCKS)
+                               RTE_LOG(INFO, IFM,
+                                       "%s: Acquiring lock @ %d\n\r",
+                                       __FUNCTION__, __LINE__);
+
+                       if (USE_RTM_LOCKS) {
+                               rtm_lock();
+                       } else {
+                               rte_rwlock_write_lock(&rwlock);
+                       }
+                       port->mtu = mtu;
+                       if (ifm_debug & IFM_DEBUG_LOCKS)
+                               RTE_LOG(INFO, IFM,
+                                       "%s: Releasing lock @ %d\n\r",
+                                       __FUNCTION__, __LINE__);
+
+                       if (USE_RTM_LOCKS) {
+                               rtm_unlock();
+                       } else {
+                               rte_rwlock_write_unlock(&rwlock);
+                       }
+                       return;
+               }
+       }
+}
+
+void ifm_set_port_promisc(uint8_t port_id, uint8_t enable)
+{
+       l2_phy_interface_t *port;
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS) {
+               rtm_lock();
+       } else {
+               rte_rwlock_write_lock(&rwlock);
+       }
+       port = ifm.port_list[port_id];
+       if (port == NULL) {
+               RTE_LOG(ERR, IFM,
+                       "%s: Port %u info not found... configure it first.\n\r",
+                       __FUNCTION__, port_id);
+       }
+       if (port != NULL && port->pmdid == port_id) {
+               if (enable == 1) {
+                       rte_eth_promiscuous_enable(port_id);
+                       port->promisc = 1;
+               } else {
+                       rte_eth_promiscuous_disable(port_id);
+                       port->promisc = 0;
+               }
+       }
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS) {
+               rtm_unlock();
+       } else {
+               rte_rwlock_write_unlock(&rwlock);
+       }
+}
+
+int32_t ifm_get_nactive_ports(void)
+{
+       return ifm.nport_configured;
+}
+
+int32_t ifm_get_nports_initialized(void)
+{
+       return ifm.nport_intialized;
+}
+
+uint16_t ifm_receive_bulk_pkts(uint8_t port_id, uint16_t qid,
+                                                struct rte_mbuf **rx_pkts)
+{
+       uint64_t no_of_rcvd_pkt;
+       no_of_rcvd_pkt =
+                       rte_eth_rx_burst(port_id, qid, rx_pkts, IFM_BURST_SIZE);
+       if (ifm_debug & IFM_DEBUG_RXTX)
+               RTE_LOG(INFO, IFM,
+                       "ifm_receive_bulk_pkts: port_id %u no_of_rcvd_pkt %lu\n\r",
+                       port_id, no_of_rcvd_pkt);
+       return no_of_rcvd_pkt;
+}
+
+uint16_t ifm_transmit_bulk_pkts(l2_phy_interface_t *port,
+                               struct rte_mbuf **tx_pkts, uint64_t npkts)
+{
+       uint32_t burst_tx_delay_time = IFM_BURST_TX_WAIT_US;
+       uint32_t burst_tx_retry_num = IFM_BURST_TX_RETRIES;
+       uint32_t retry;
+       uint32_t no_of_tx_pkt;
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS) {
+               rtm_lock();
+       } else {
+               rte_rwlock_read_lock(&rwlock);
+       }
+       no_of_tx_pkt = rte_eth_tx_burst(port->pmdid, IFM_TX_DEFAULT_Q, tx_pkts,
+                                       npkts);
+       if (unlikely(no_of_tx_pkt < npkts)) {
+               retry = 0;
+               while (no_of_tx_pkt < IFM_BURST_SIZE
+                                        && retry++ < burst_tx_retry_num) {
+                       rte_delay_us(burst_tx_delay_time);
+                       no_of_tx_pkt =
+                                       rte_eth_tx_burst(port->pmdid, IFM_TX_DEFAULT_Q,
+                                                        &tx_pkts[no_of_tx_pkt],
+                                                        IFM_BURST_SIZE - no_of_tx_pkt);
+               }
+       }
+       if (ifm_debug & IFM_DEBUG_RXTX)
+               RTE_LOG(INFO, IFM,
+                       "ifm_transmit_bulk_pkts: no_of_tx_pkt %u\n\r",
+                       no_of_tx_pkt);
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS) {
+               rtm_unlock();
+       } else {
+               rte_rwlock_read_unlock(&rwlock);
+       }
+       return no_of_tx_pkt;
+}
+
+int ifm_transmit_single_pkt(l2_phy_interface_t *port, struct rte_mbuf *tx_pkts)
+{
+       uint64_t tx_npkts = 0;
+       if (tx_pkts == NULL || port == NULL) {
+               RTE_LOG(INFO, IFM,
+                       "ifm_transmit_single_pkt: tx_pkts and port are NULL ");
+               return IFM_FAILURE;
+       }
+       if (ifm_debug & IFM_DEBUG_RXTX)
+               RTE_LOG(INFO, IFM,
+                       "ifm_transmit_single_pkt: port->pmdid %u\n\r",
+                       port->pmdid);
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_lock();
+       } else {
+               rte_rwlock_read_lock(&rwlock);
+       }
+       tx_npkts =
+                       rte_eth_tx_buffer(port->pmdid, IFM_TX_DEFAULT_Q, port->tx_buffer,
+                                               tx_pkts);
+       if (ifm_debug & IFM_DEBUG_RXTX)
+               RTE_LOG(INFO, IFM,
+                       "ifm_transmit_single_pkt: port->pmdid %u No of packets buffered %lu\n\r",
+                       port->pmdid, tx_npkts);
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing RW lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_unlock();
+       } else {
+               rte_rwlock_read_unlock(&rwlock);
+       }
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_lock();
+       } else {
+               rte_rwlock_write_lock(&rwlock);
+       }
+       port->n_txpkts +=
+                       rte_eth_tx_buffer_flush(port->pmdid, IFM_TX_DEFAULT_Q,
+                                               port->tx_buffer);
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_unlock();
+       } else {
+               rte_rwlock_write_unlock(&rwlock);
+       }
+       if (ifm_debug & IFM_DEBUG_RXTX)
+               RTE_LOG(INFO, IFM,
+                       "ifm_transmit_single_pkt: no of pkts flushed %lu\n\r",
+                       port->n_txpkts);
+       return tx_npkts;
+}
+
+int16_t ifm_add_ipv4_port(uint8_t port_id, uint32_t ipaddr, uint32_t addrlen)
+{
+       l2_phy_interface_t *port;
+       ipv4list_t *ipconf;
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_lock();
+       } else {
+               rte_rwlock_write_lock(&rwlock);
+       }
+       port = ifm.port_list[port_id];
+       if (port == NULL) {
+               RTE_LOG(ERR, IFM,
+                       "%s: Port %u info not found... configure it first.\n\r",
+                       __FUNCTION__, port_id);
+       }
+       if (port != NULL && port->pmdid == port_id) {
+               ipconf = (ipv4list_t *) rte_zmalloc(NULL, sizeof(ipv4list_t),
+                                                               RTE_CACHE_LINE_SIZE);
+               if (ipconf != NULL) {
+                       ipconf->next = NULL;
+                       //ipconf->ipaddr = rte_bswap32(ipaddr);
+                       ipconf->ipaddr = ipaddr;
+                       ipconf->port = port;
+                       ipconf->addrlen = addrlen;
+                       if (port->ipv4_list == NULL)
+                               port->flags |= IFM_IPV4_ENABLED;
+                       ipconf->next = (ipv4list_t *) port->ipv4_list;
+                       port->ipv4_list = (ipv4list_t *) ipconf;
+                       if (ifm_debug & IFM_DEBUG_LOCKS)
+                               RTE_LOG(INFO, IFM,
+                                       "%s: Releasing lock @ %d\n\r",
+                                       __FUNCTION__, __LINE__);
+
+                       if (USE_RTM_LOCKS) {
+                               rtm_unlock();
+                       } else {
+                               rte_rwlock_write_unlock(&rwlock);
+                       }
+                       return 0;
+               }
+       }
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_unlock();
+       } else {
+               rte_rwlock_write_unlock(&rwlock);
+       }
+       return -1;
+}
+
+int16_t ifm_remove_ipv4_port(uint8_t port_id, uint32_t ipaddr,
+                                               uint32_t addrlen)
+{
+       l2_phy_interface_t *port;
+       ipv4list_t *iplist, *previplist = NULL;
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_lock();
+       } else {
+               rte_rwlock_write_lock(&rwlock);
+       }
+       port = ifm.port_list[port_id];
+       if (port == NULL) {
+               RTE_LOG(ERR, IFM,
+                       "%s: Port %u info not found... configure it first.\n\r",
+                       __FUNCTION__, port_id);
+       }
+       if (port != NULL && port->pmdid == port_id) {
+               if (port->ipv4_list == NULL) {
+                       if (ifm_debug & IFM_DEBUG_LOCKS)
+                               RTE_LOG(INFO, IFM,
+                                       "%s: Releasing lock @ %d\n\r",
+                                       __FUNCTION__, __LINE__);
+
+                       if (USE_RTM_LOCKS) {
+                               rtm_unlock();
+                       } else {
+                               rte_rwlock_write_unlock(&rwlock);
+                       }
+                       return -1;
+               }
+               iplist = (ipv4list_t *) port->ipv4_list;
+               while (iplist != NULL) {
+                       if (addrlen == iplist->addrlen &&
+                                       memcpy(&iplist->ipaddr, &ipaddr, addrlen)) {
+                               if (iplist == port->ipv4_list) {
+                                       port->ipv4_list = iplist->next;
+                               } else {
+                                       if (previplist != NULL)
+                                               previplist->next = iplist->next;
+                               }
+                               port->flags &= ~IFM_IPV4_ENABLED;
+                               rte_free(iplist);
+                               if (ifm_debug & IFM_DEBUG_LOCKS)
+                                       RTE_LOG(INFO, IFM,
+                                               "%s: Releasing lock @ %d\n\r",
+                                               __FUNCTION__, __LINE__);
+
+                               if (USE_RTM_LOCKS) {
+                                       rtm_unlock();
+                               } else {
+                                       rte_rwlock_write_unlock(&rwlock);
+                               }
+                               return 0;
+                       } else {
+                               previplist = iplist;
+                               iplist = iplist->next;
+                       }
+               }
+       }
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_unlock();
+       } else {
+               rte_rwlock_write_unlock(&rwlock);
+       }
+       return -1;
+}
+
+int8_t ifm_add_ipv6_port(uint8_t port_id, uint8_t ip6addr[], uint32_t addrlen)
+{
+       l2_phy_interface_t *port;
+       ipv6list_t *ip6conf;
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_lock();
+       } else {
+               rte_rwlock_write_lock(&rwlock);
+       }
+       port = ifm.port_list[port_id];
+       if (port == NULL) {
+               RTE_LOG(ERR, IFM,
+                       "%s: Port %u info not found... configure it first.\n\r",
+                       __FUNCTION__, port_id);
+       }
+       if (port != NULL && port->pmdid == port_id) {
+               ip6conf = (ipv6list_t *) rte_zmalloc(NULL, sizeof(ipv6list_t),
+                                                                RTE_CACHE_LINE_SIZE);
+               if (ip6conf != NULL) {
+                       ip6conf->next = NULL;
+                       memcpy(ip6conf->ipaddr, ip6addr, IFM_IPV6_ADDR_SIZE);
+                       ip6conf->port = port;
+                       ip6conf->addrlen = addrlen;
+
+                       if (port->ipv6_list == NULL) {
+                               port->flags |= IFM_IPV6_ENABLED;
+                       }
+                       ip6conf->next = (ipv6list_t *) port->ipv6_list;
+                       port->ipv6_list = (ipv6list_t *) ip6conf;
+                       if (ifm_debug & IFM_DEBUG_LOCKS)
+                               RTE_LOG(INFO, IFM,
+                                       "%s: Releasing lock @ %d\n\r",
+                                       __FUNCTION__, __LINE__);
+
+                       if (USE_RTM_LOCKS) {
+                               rtm_unlock();
+                       } else {
+                               rte_rwlock_write_unlock(&rwlock);
+                       }
+                       return 0;
+               }
+       }
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+
+       if (USE_RTM_LOCKS) {
+               rtm_unlock();
+       } else {
+               rte_rwlock_write_unlock(&rwlock);
+       }
+       return -1;
+}
+
+int16_t ifm_remove_ipv6_port(uint8_t port_id, uint32_t ip6addr,
+                                               uint32_t addrlen)
+{
+       l2_phy_interface_t *port;
+       ipv6list_t *ip6list, *previp6list = NULL;
+
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_write_lock(&rwlock);
+       port = ifm.port_list[port_id];
+       if (port == NULL) {
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS) {
+                       rtm_unlock();
+               } else {
+                       rte_rwlock_write_unlock(&rwlock);
+               }
+               RTE_LOG(ERR, IFM,
+                       "%s: Port %u info not found... configure it first.\n\r",
+                       __FUNCTION__, port_id);
+       }
+       if (port != NULL && port->pmdid == port_id) {
+               if (port->ipv6_list == NULL) {
+                       if (ifm_debug & IFM_DEBUG_LOCKS)
+                               RTE_LOG(INFO, IFM,
+                                       "%s: Releasing lock @ %d\n\r",
+                                       __FUNCTION__, __LINE__);
+
+                       if (USE_RTM_LOCKS) {
+                               rtm_unlock();
+                       } else {
+                               rte_rwlock_write_unlock(&rwlock);
+                       }
+                       return -1;
+               }
+               ip6list = (ipv6list_t *) port->ipv6_list;
+               while (ip6list != NULL) {
+                       if (addrlen == ip6list->addrlen &&
+                                       memcpy(&ip6list->ipaddr, &ip6addr, addrlen)) {
+                               if (ip6list == port->ipv6_list) {
+                                       port->ipv6_list = ip6list->next;
+                               } else {
+                                       if (previp6list != NULL)
+                                               previp6list->next =
+                                                               ip6list->next;
+                               }
+                               port->flags &= ~IFM_IPV6_ENABLED;
+                               rte_free(ip6list);
+                               if (ifm_debug & IFM_DEBUG_LOCKS)
+                                       RTE_LOG(INFO, IFM,
+                                               "%s: Releasing lock @ %d\n\r",
+                                               __FUNCTION__, __LINE__);
+
+                               if (USE_RTM_LOCKS) {
+                                       rtm_unlock();
+                               } else {
+                                       rte_rwlock_write_unlock(&rwlock);
+                               }
+                               return 0;
+                       } else {
+                               previp6list = ip6list;
+                               ip6list = ip6list->next;
+                       }
+               }
+       }
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_unlock();
+       else
+               rte_rwlock_write_unlock(&rwlock);
+       return -1;
+}
+
+int32_t ifm_chk_port_ipv4_enabled(uint8_t port_id)
+{
+       l2_phy_interface_t *port;
+
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_read_lock(&rwlock);
+       port = ifm.port_list[port_id];
+       if (port == NULL) {
+               RTE_LOG(ERR, IFM,
+                       "%s: Port %u info not found... configure it first.\n\r",
+                       __FUNCTION__, port_id);
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_read_unlock(&rwlock);
+               return IFM_FAILURE;
+       }
+       if ((port->flags & IFM_IPV4_ENABLED) == 0) {
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_read_unlock(&rwlock);
+               return 0;
+       } else {
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_read_unlock(&rwlock);
+               return 1;
+       }
+}
+
+int32_t ifm_chk_port_ipv6_enabled(uint8_t port_id)
+{
+       l2_phy_interface_t *port;
+
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_read_lock(&rwlock);
+
+       port = ifm.port_list[port_id];
+       if (port == NULL) {
+               if (ifm_debug & IFM_DEBUG)
+                       RTE_LOG(ERR, IFM, "%s: Port %u info not found..."
+                               " configure it first.\n\r",
+                               __FUNCTION__, port_id);
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_read_unlock(&rwlock);
+               return IFM_FAILURE;
+       }
+       if ((port->flags & IFM_IPV6_ENABLED) == 0) {
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_read_unlock(&rwlock);
+               return 0;
+       } else {
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_read_unlock(&rwlock);
+               return 1;
+       }
+}
+
+void ifm_register_for_linkupdate(uint32_t clientid,
+                                void (*cb_linkupdate) (uint8_t, unsigned int))
+{
+       ifm.if_client[ifm.nclient].cb_linkupdate = cb_linkupdate;
+       ifm.if_client[ifm.nclient].clientid = clientid;
+       ifm.nclient++;
+}
+
+int ifm_port_setup(uint8_t port_id, port_config_t *pconfig)
+{
+       int status, sock;
+       char buf[12];
+       struct rte_eth_dev_info dev_info;
+       struct rte_eth_link linkstatus;
+       l2_phy_interface_t *port = NULL;
+
+       if (!ifm.nport_intialized) {
+               RTE_LOG(ERR, IFM, "%s: Failed to configure port %u. 0 ports"
+                       "were intialized during PCI probe...\n\r",
+                       __FUNCTION__, port_id);
+               return IFM_FAILURE;
+       }
+       if (ifm_debug & IFM_DEBUG_CONFIG)
+               RTE_LOG(INFO, IFM, "%s: Configuring port %u with "
+                       "nrxq: %u, ntxq: %u\n\r", __FUNCTION__,
+                       port_id, pconfig->nrx_queue, pconfig->ntx_queue);
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring WR lock1 @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_write_lock(&rwlock);
+
+       if (ifm.port_list[port_id] == NULL) {
+               ifm.port_list[port_id] =
+                               (l2_phy_interface_t *) rte_zmalloc(NULL,
+                                                                        sizeof
+                                                                        (l2_phy_interface_t),
+                                                                        RTE_CACHE_LINE_SIZE);
+               ifm.port_list[port_id]->pmdid = port_id;
+       }
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing WR lock1 @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_unlock();
+       else
+               rte_rwlock_write_unlock(&rwlock);
+
+       rte_eth_link_get(port_id, &linkstatus);
+       if (linkstatus.link_status) {
+               if (ifm_debug & IFM_DEBUG_CONFIG) {
+                       RTE_LOG(INFO, IFM, "%s: %u is up.Stop it before"
+                               " reconfiguring.\n\r", __FUNCTION__, port_id);
+               }
+               rte_eth_dev_stop(port_id);
+       }
+       /*Configure an Ethernet device. rets 0 on success queue */
+       status = rte_eth_dev_configure(port_id, pconfig->nrx_queue,
+                                                        pconfig->ntx_queue, &pconfig->port_conf);
+       if (status < 0) {
+               ifm_remove_port_details(port_id);
+               RTE_LOG(ERR, IFM, "%s: rte_eth_dev_configure is failed"
+                       "for port %u.\n\r", __FUNCTION__, port_id);
+               return IFM_FAILURE;
+       }
+       status = rte_eth_dev_callback_register(port_id,
+                                                                RTE_ETH_EVENT_INTR_LSC,
+                                                                lsi_event_callback, NULL);
+       if (status < 0) {
+               ifm_remove_port_details(port_id);
+               RTE_LOG(ERR, IFM, "%s: rte_eth_dev_callback_register()"
+                       " failed for port %u.\n\r", __FUNCTION__, port_id);
+               return IFM_FAILURE;
+       }
+       /*promiscuous mode is enabled set it */
+       if (pconfig->promisc)
+               rte_eth_promiscuous_enable(port_id);
+
+       sock = rte_eth_dev_socket_id(port_id);
+       if (sock == -1)
+               RTE_LOG(ERR, IFM, "%s: Warning: rte_eth_dev_socket_id,"
+                       " port_id value is"
+                       "out of range %u\n\r", __FUNCTION__, port_id);
+       /*Port initialization */
+       int ntxqs;
+       for (ntxqs = 0; ntxqs < pconfig->ntx_queue; ntxqs++) {
+               status = rte_eth_tx_queue_setup(port_id, ntxqs,
+                                               IFM_TX_DESC_DEFAULT, sock,
+                                               &(pconfig->tx_conf));
+               if (status < 0) {
+                       ifm_remove_port_details(port_id);
+                       RTE_LOG(ERR, IFM, "%s: rte_eth_tx_queue_setup failed"
+                               " for port %u\n\r", __FUNCTION__, port_id);
+                       return IFM_FAILURE;
+               }
+       }
+       port = ifm_get_port(port_id);
+       if (port == NULL) {
+               RTE_LOG(INFO, IFM, "%s: Port is NULL @ %d\n\r", __FUNCTION__,
+                       __LINE__);
+               return IFM_FAILURE;
+       }
+
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring WR lock 2 @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_write_lock(&rwlock);
+
+       if (port->tx_buf_len == 0) {
+               port->tx_buf_len = RTE_ETH_TX_BUFFER_SIZE(IFM_BURST_SIZE);
+       }
+       port->tx_buffer = rte_zmalloc_socket("tx_buffer", port->tx_buf_len, 0,
+                                                        rte_eth_dev_socket_id(port_id));
+
+       if (port->tx_buffer == NULL) {
+               ifm_remove_port_details(port_id);
+               RTE_LOG(ERR, IFM, "%s: Failed to allocate tx buffers for"
+                       " port %u\n\r", __FUNCTION__, port_id);
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing WR lock2 %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_write_unlock(&rwlock);
+               return IFM_FAILURE;
+       }
+       rte_eth_tx_buffer_init(port->tx_buffer, IFM_BURST_SIZE);
+
+       sprintf(buf, "MEMPOOL%d", port_id);
+       port->mempool = rte_mempool_create(buf,
+                                                pconfig->mempool.pool_size,
+                                                pconfig->mempool.buffer_size,
+                                                pconfig->mempool.cache_size,
+                                                sizeof(struct
+                                                       rte_pktmbuf_pool_private),
+                                                rte_pktmbuf_pool_init, NULL,
+                                                rte_pktmbuf_init, NULL, sock, 0);
+       if (port->mempool == NULL) {
+               ifm_remove_port_details(port_id);
+               RTE_LOG(ERR, IFM, "%s: rte_mempool_create is failed for port"
+                       " %u. Error: %s\n\r",
+                       __FUNCTION__, port_id, rte_strerror(rte_errno));
+               if (ifm_debug & IFM_DEBUG_LOCKS)
+                       RTE_LOG(INFO, IFM, "%s: Releasing WR lock2 %d\n\r",
+                               __FUNCTION__, __LINE__);
+               if (USE_RTM_LOCKS)
+                       rtm_unlock();
+               else
+                       rte_rwlock_write_unlock(&rwlock);
+               return IFM_FAILURE;
+       }
+       int nrxqs;
+       for (nrxqs = 0; nrxqs < pconfig->nrx_queue; nrxqs++) {
+               status = rte_eth_rx_queue_setup(port_id, nrxqs,
+                                               IFM_RX_DESC_DEFAULT, sock,
+                                               &(pconfig->rx_conf),
+                                               port->mempool);
+               if (status < 0) {
+                       ifm_remove_port_details(port_id);
+                       RTE_LOG(ERR, IFM,
+                               "%s: rte_eth_rx_queue_setup is failed "
+                               "for port %u queue %u. Error: %s\n\r",
+                               __FUNCTION__, port_id, nrxqs,
+                               rte_strerror(rte_errno));
+                       if (ifm_debug & IFM_DEBUG_LOCKS)
+                               RTE_LOG(INFO, IFM,
+                                       "%s: Releasing WR lock2 %d\n\r",
+                                       __FUNCTION__, __LINE__);
+                       if (USE_RTM_LOCKS)
+                               rtm_unlock();
+                       else
+                               rte_rwlock_write_unlock(&rwlock);
+                       return IFM_FAILURE;
+               }
+       }
+       /*Start link */
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing WR lock2  @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_unlock();
+       else
+               rte_rwlock_write_unlock(&rwlock);
+       status = rte_eth_dev_start(port_id);
+       if (status < 0) {
+               ifm_remove_port_details(port_id);
+               RTE_LOG(ERR, IFM, "%s: rte_eth_dev_start is failed for"
+                       " port %u.\n\r", __FUNCTION__, port_id);
+               return IFM_FAILURE;
+       }
+       rte_delay_ms(5000);
+       /*Get device info and populate interface structure */
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring WR lock3 @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_write_lock(&rwlock);
+       rte_eth_macaddr_get(port_id, (struct ether_addr *)port->macaddr);
+       if (pconfig->promisc)
+               port->promisc = 1;
+       rte_eth_link_get(port_id, &linkstatus);
+       /*Link status */
+       port->link_duplex = linkstatus.link_duplex;
+       port->link_autoneg = linkstatus.link_autoneg;
+       port->link_speed = linkstatus.link_speed;
+       port->admin_status = pconfig->state;
+
+       /*Get dev_info */
+       memset(&dev_info, 0, sizeof(dev_info));
+       rte_eth_dev_info_get(port_id, &dev_info);
+       port->min_rx_bufsize = dev_info.min_rx_bufsize;
+       port->max_rx_pktlen = dev_info.max_rx_pktlen;
+       port->max_rx_queues = dev_info.max_rx_queues;
+       port->max_tx_queues = dev_info.max_tx_queues;
+       rte_eth_dev_get_mtu(port_id, &(port->mtu));
+
+       /*Add rx and tx packet function ptrs */
+       port->retrieve_bulk_pkts = &ifm_receive_bulk_pkts;
+       port->transmit_bulk_pkts = &ifm_transmit_bulk_pkts;
+       port->transmit_single_pkt = &ifm_transmit_single_pkt;
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing WR3 lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_unlock();
+       else
+               rte_rwlock_write_unlock(&rwlock);
+       RTE_LOG(INFO, IFM, "%s: Port %u is successfully configured.\n\r",
+               __FUNCTION__, port_id);
+       return IFM_SUCCESS;
+}
+
+int ifm_configure_ports(port_config_t *pconfig)
+{
+       uint8_t port_id;
+       int status = 0;
+       if (!ifm.nport_intialized) {
+               RTE_LOG(ERR, IFM, "%s, Configuring ports failed. Zero ports "
+                       "are intialized during PCI probe", __FUNCTION__);
+               return IFM_FAILURE;
+       }
+       if (pconfig == NULL) {
+               RTE_LOG(ERR, IFM, "%s, Configuring ports failed. "
+                       "Param pconfig is NULL\n\r", __FUNCTION__);
+               return IFM_FAILURE;
+       }
+
+       /*Initialize all ports */
+       for (port_id = 0; port_id < ifm.nport_intialized; port_id++) {
+               if (ifm_debug & IFM_DEBUG_CONFIG)
+                       RTE_LOG(INFO, IFM, "Call ifm_port_setup %u\n\r",
+                               port_id);
+               status =
+                               ifm_port_setup(pconfig[port_id].port_id, &pconfig[port_id]);
+               if (status == IFM_SUCCESS)
+                       ifm.nport_configured++;
+       }
+       if (!ifm.nport_configured) {
+               RTE_LOG(ERR, IFM, "%s: Zero ports are configured\n\r",
+                       __FUNCTION__);
+               return IFM_FAILURE;
+       }
+       RTE_LOG(INFO, IFM, "%s: Number of ports sucessfully configured:"
+               " %d\n\r", __FUNCTION__, ifm.nport_configured);
+       return IFM_SUCCESS;
+}
+
+void print_interface_details(void)
+{
+       l2_phy_interface_t *port;
+       int i = 0;
+       struct sockaddr_in ip;
+       printf("\n\r");
+
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Acquiring RW lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_lock();
+       else
+               rte_rwlock_read_lock(&rwlock);
+
+       for (i = 0; i < RTE_MAX_ETHPORTS && ifm.port_list[i]; i++) {
+               port = ifm.port_list[i];
+               printf(" %u", port->pmdid);
+               if (port->ifname && strlen(port->ifname)) {
+                       printf(" (%s)\t", port->ifname);
+               } else
+                       printf("\t\t");
+               printf("MAC:%02x:%02x:%02x:%02x:%02x:%02x Adminstate:%s"
+                                        " Operstate:%s \n\r",
+                                        port->macaddr[0], port->macaddr[1],
+                                        port->macaddr[2], port->macaddr[3],
+                                        port->macaddr[4], port->macaddr[5],
+                                        port->admin_status ? "UP" : "DOWN",
+                                        port->link_status ? "UP" : "DOWN");
+               printf("\t\t");
+               printf("Speed: %u, %s-duplex\n\r", port->link_speed,
+                                        port->link_duplex ? "full" : "half");
+               printf("\t\t");
+
+               if (port->ipv4_list != NULL) {
+                       ip.sin_addr.s_addr =
+                                       (unsigned long)((ipv4list_t *) (port->ipv4_list))->
+                                       ipaddr;
+                       printf("IP: %s/%d", inet_ntoa(ip.sin_addr),
+                                                ((ipv4list_t *) (port->ipv4_list))->addrlen);
+               } else {
+                       printf("IP: NA");
+               }
+
+               printf("\r\n");
+               printf("\t\t");
+               if (port->ipv6_list != NULL) {
+                       uint8_t *addr =
+                                       ((ipv6list_t *) (port->ipv6_list))->ipaddr;
+                       printf
+                                       ("IPv6: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+                                        addr[0], addr[1], addr[2], addr[3], addr[4],
+                                        addr[5], addr[6], addr[7], addr[8], addr[9],
+                                        addr[10], addr[11], addr[12], addr[13], addr[14],
+                                        addr[15]);
+               } else {
+                       printf("IPv6: NA");
+               }
+
+               if (port->flags & IFM_SLAVE) {
+                       printf("  IFM_SLAVE ");
+                       printf(" MasterPort: %u",
+                                                port->bond_config->bond_portid);
+               }
+               if (port->flags & IFM_MASTER) {
+                       printf("  IFM_MASTER ");
+                       printf("  Mode: %u", port->bond_config->mode);
+                       printf("  PrimaryPort: %u", port->bond_config->primary);
+                       printf("\n\r");
+                       printf("\t\tSlavePortCount: %u",
+                                                port->bond_config->slave_count);
+                       printf(" SlavePorts:");
+                       int i;
+                       for (i = 0; i < port->bond_config->slave_count; i++) {
+                               printf(" %u ", port->bond_config->slaves[i]);
+                       }
+                       printf(" ActivePortCount: %u",
+                                                port->bond_config->active_slave_count);
+                       printf(" ActivePorts:");
+                       for (i = 0; i < port->bond_config->active_slave_count;
+                                        i++) {
+                               printf(" %u ",
+                                                        port->bond_config->active_slaves[i]);
+                       }
+                       printf("\n\r");
+                       printf("\t\t");
+                       printf("Link_monitor_freq: %u ms ",
+                                                port->bond_config->internal_ms);
+                       printf(" Link_up_prop_delay: %u ms ",
+                                                port->bond_config->link_up_delay_ms);
+                       printf(" Link_down_prop_delay: %u ms ",
+                                                port->bond_config->link_down_delay_ms);
+                       printf("\n\r");
+                       printf("\t\t");
+                       printf("Xmit_policy: %u",
+                                                port->bond_config->xmit_policy);
+               }
+               printf("\n\r");
+               printf("\t\t");
+               printf("n_rxpkts: %" PRIu64 " ,n_txpkts: %" PRIu64 " ,",
+                                        port->n_rxpkts, port->n_txpkts);
+               struct rte_eth_stats eth_stats;
+               rte_eth_stats_get(port->pmdid, &eth_stats);
+               printf("pkts_in: %" PRIu64 " ,", eth_stats.ipackets);
+               printf("pkts_out: %" PRIu64 " ", eth_stats.opackets);
+               printf("\n\r");
+               printf("\t\t");
+               printf("in_errs: %" PRIu64 " ,", eth_stats.ierrors);
+               printf("in_missed: %" PRIu64 " ,", eth_stats.imissed);
+               printf("out_errs: %" PRIu64 " ,", eth_stats.oerrors);
+               printf("mbuf_errs: %" PRIu64 " ", eth_stats.rx_nombuf);
+               printf("\n\r");
+               printf("\n\r");
+       }
+       if (ifm_debug & IFM_DEBUG_LOCKS)
+               RTE_LOG(INFO, IFM, "%s: Releasing RW lock @ %d\n\r",
+                       __FUNCTION__, __LINE__);
+       if (USE_RTM_LOCKS)
+               rtm_unlock();
+       else
+               rte_rwlock_read_unlock(&rwlock);
+}