summaryrefslogtreecommitdiffstats
path: root/common/VIL/l2l3_stack/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/VIL/l2l3_stack/interface.c')
-rw-r--r--common/VIL/l2l3_stack/interface.c1478
1 files changed, 1478 insertions, 0 deletions
diff --git a/common/VIL/l2l3_stack/interface.c b/common/VIL/l2l3_stack/interface.c
new file mode 100644
index 00000000..84c390da
--- /dev/null
+++ b/common/VIL/l2l3_stack/interface.c
@@ -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);
+}