2 // Copyright (c) 2017 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
16 #include <interface.h>
17 #include <rte_byteorder.h>
22 int USE_RTM_LOCKS = 0;
25 static int prev_state;
27 void config_ifm_debug(int dbg, int flag)
30 case IFM_DEBUG_CONFIG:
32 ifm_debug |= IFM_DEBUG_CONFIG;
34 ifm_debug &= ~IFM_DEBUG_CONFIG;
39 ifm_debug |= IFM_DEBUG_RXTX;
41 ifm_debug &= ~IFM_DEBUG_RXTX;
46 ifm_debug |= IFM_DEBUG_LOCKS;
48 ifm_debug &= ~IFM_DEBUG_LOCKS;
53 ifm_debug |= IFM_DEBUG;
55 ifm_debug &= ~IFM_DEBUG;
64 config_ifm_debug(IFM_DEBUG_CONFIG, 1);
65 if (can_use_intel_core_4th_gen_features()) {
66 if (ifm_debug & IFM_DEBUG_CONFIG)
67 RTE_LOG(INFO, IFM, "TSX not currently supported...\n\r");
70 if (ifm_debug & IFM_DEBUG_CONFIG)
71 RTE_LOG(INFO, IFM, "TSX not supported\n\r");
77 rte_rwlock_init(&rwlock);
79 for (i = 0; i < IFM_MAX_PORTARR_SZ; i++) {
80 if (ifm_debug & IFM_DEBUG_LOCKS)
81 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
82 __FUNCTION__, __LINE__);
86 rte_rwlock_write_lock(&rwlock);
88 ifm.port_list[i] = NULL;
89 if (ifm_debug & IFM_DEBUG_LOCKS)
90 RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
91 __FUNCTION__, __LINE__);
95 rte_rwlock_write_unlock(&rwlock);
97 ifm.nport_intialized = rte_eth_dev_count();
98 ifm.nport_configured = 0;
99 RTE_LOG(INFO, IFM, "IFM_INIT: Number of ports initialized during "
100 "PCI probing %u.\n\r", ifm.nport_intialized);
103 void ifm_remove_port_details(uint8_t portid)
105 if (ifm.port_list[portid] != NULL) {
106 if (ifm_debug & IFM_DEBUG_LOCKS)
107 RTE_LOG(INFO, IFM, "%s: Acquiring lock %d\n\r",
108 __FUNCTION__, __LINE__);
112 rte_rwlock_write_lock(&rwlock);
113 l2_phy_interface_t *port = ifm.port_list[portid];
114 ifm.port_list[portid] = NULL;
115 if (ifm_debug & IFM_DEBUG_CONFIG)
116 RTE_LOG(INFO, IFM, "%s: NULL set for port %u\n\r",
117 __FUNCTION__, portid);
119 if (ifm_debug & IFM_DEBUG_LOCKS)
120 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
121 __FUNCTION__, __LINE__);
126 rte_rwlock_write_unlock(&rwlock);
128 if (ifm_debug & IFM_DEBUG_LOCKS)
130 "%s: Failed to remove port details.Port %u info"
131 " is already Null.\n\r", __FUNCTION__, portid);
135 l2_phy_interface_t *ifm_get_port(uint8_t port_id)
137 l2_phy_interface_t *port = NULL;
138 if (ifm_debug & IFM_DEBUG_LOCKS)
139 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
145 rte_rwlock_read_lock(&rwlock);
147 port = ifm.port_list[port_id];
150 /*RTE_LOG(ERR, IFM, "%s: Port %u info not found... configure it first.\n\r",
151 __FUNCTION__, port_id);
153 if (ifm_debug & IFM_DEBUG_LOCKS)
154 RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
155 __FUNCTION__, __LINE__);
159 rte_rwlock_read_unlock(&rwlock);
162 if (port->pmdid == port_id) {
163 /*RTE_LOG(INFO, IFM, "%s: Port %u found....\n\r",
164 __FUNCTION__, port_id); */
165 if (ifm_debug & IFM_DEBUG_LOCKS)
166 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
167 __FUNCTION__, __LINE__);
172 rte_rwlock_read_unlock(&rwlock);
176 /* RTE_LOG(INFO, IFM,"%s: Mismatch given port %u port in loc %u\n\r",__FUNCTION__,port_id,
177 ifm.port_list[port_id]->pmdid);
180 if (ifm_debug & IFM_DEBUG_LOCKS)
181 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
186 rte_rwlock_read_unlock(&rwlock);
190 l2_phy_interface_t *ifm_get_first_port(void)
192 l2_phy_interface_t *port = NULL;
193 if (ifm_debug & IFM_DEBUG_LOCKS)
194 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
200 rte_rwlock_read_lock(&rwlock);
201 port = ifm.port_list[0];
203 /*RTE_LOG(ERR, IFM, "%s: Port info not found... configure it first.\n\r",
205 if (ifm_debug & IFM_DEBUG_LOCKS)
206 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
207 __FUNCTION__, __LINE__);
211 rte_rwlock_read_unlock(&rwlock);
214 /*RTE_LOG(ERR, IFM, "%s: Port %u info is found...%p\n\r",
215 __FUNCTION__, port->pmdid, port); */
216 if (ifm_debug & IFM_DEBUG_LOCKS)
217 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
222 rte_rwlock_read_unlock(&rwlock);
226 l2_phy_interface_t *ifm_get_next_port(uint8_t port_id)
228 l2_phy_interface_t *port = NULL;
229 if (ifm_debug & IFM_DEBUG_LOCKS)
230 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
235 rte_rwlock_read_lock(&rwlock);
236 port = ifm.port_list[port_id + 1];
238 if (ifm_debug & IFM_DEBUG_LOCKS)
239 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
240 __FUNCTION__, __LINE__);
244 rte_rwlock_read_unlock(&rwlock);
247 /*RTE_LOG(ERR, IFM, "%s: Port %u info is found...\n\r",
248 __FUNCTION__, port_id); */
249 if (ifm_debug & IFM_DEBUG_LOCKS)
250 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
256 rte_rwlock_read_unlock(&rwlock);
260 l2_phy_interface_t *ifm_get_port_by_name(const char *name)
262 l2_phy_interface_t *port = NULL;
264 if (ifm_debug & IFM_DEBUG_LOCKS)
265 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
271 rte_rwlock_read_lock(&rwlock);
272 for (i = 0; i < RTE_MAX_ETHPORTS && ifm.port_list[i]; i++) {
273 port = ifm.port_list[i];
274 if (strcmp(name, port->ifname) == 0) {
275 if (ifm_debug & IFM_DEBUG_CONFIG)
276 RTE_LOG(INFO, IFM, "FOUND! port %u %s\n\r",
277 port->pmdid, port->ifname);
278 if (ifm_debug & IFM_DEBUG_LOCKS)
280 "%s: Releasing lock @ %d\n\r",
281 __FUNCTION__, __LINE__);
285 rte_rwlock_read_unlock(&rwlock);
289 if (ifm_debug & IFM_DEBUG_LOCKS)
290 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
295 rte_rwlock_read_unlock(&rwlock);
299 void lsi_event_callback(uint8_t port_id, enum rte_eth_event_type type,
302 struct rte_eth_link link;
303 l2_phy_interface_t *port;
304 int nclients = ifm.nclient;
310 if (ifm_debug & IFM_DEBUG_LOCKS)
311 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
312 __FUNCTION__, __LINE__);
316 rte_rwlock_write_lock(&rwlock);
318 rte_eth_link_get(port_id, &link);
319 for (i = 0; i < nclients; i++)
320 ifm.if_client[i].cb_linkupdate(port_id, link.link_status);
321 port = ifm.port_list[port_id];
324 "%s: Port %u info not found... configure it first.\n\r",
325 __FUNCTION__, port_id);
327 if (port != NULL && port->pmdid == port_id) {
328 if (link.link_status) {
329 port->link_status = IFM_ETH_LINK_UP;
330 port->link_speed = link.link_speed;
331 port->link_duplex = link.link_duplex;
333 "EVENT-- PORT %u Link UP - Speed %u Mbps - %s.\n",
334 port_id, (unsigned)link.link_speed,
336 ETH_LINK_FULL_DUPLEX) ? ("full-duplex")
338 if (port->flags & IFM_MASTER) {
339 port->flags |= IFM_BONDED;
340 port->bond_config->active_slave_count =
341 rte_eth_bond_active_slaves_get(port->pmdid,
346 struct ether_addr new_mac;
347 rte_eth_macaddr_get(port->pmdid,
348 (struct ether_addr *)
351 (&new_mac, port->macaddr,
352 sizeof(struct ether_addr))) {
354 "Bond port %u MAC has changed.\n\r",
358 "Bond port %u MAC remains same\n\r",
362 if (port->flags & IFM_SLAVE) {
363 uint8_t master_portid =
364 port->bond_config->bond_portid;
365 struct rte_eth_link linkstatus;
366 rte_eth_link_get(master_portid, &linkstatus);
367 RTE_LOG(INFO, IFM, "Port %u 's Master(%u) status is %u\n\r", port_id,
368 master_portid, linkstatus.link_status);
370 if (ifm_debug & IFM_DEBUG_LOCKS)
372 "%s: Releasing WR lock @ %d\n\r",
373 __FUNCTION__, __LINE__);
378 rte_rwlock_write_unlock(&rwlock);
380 if (port->ipv4_list != NULL) {
381 if (ifm_debug & IFM_DEBUG_CONFIG)
383 "Sending garp on port %u\n\r",
386 send_gratuitous_arp(port);
392 if (ifm_debug & IFM_DEBUG_CONFIG)
394 "IP is not enabled on port %u, not sending GARP\n\r",
399 if (port->flags & IFM_MASTER) {
400 port->flags &= ~IFM_BONDED;
401 //RTE_LOG(INFO, IFM, "IFM_MASTER port, resetting IFM_BONDED. %u\n\r", port->flags);
403 port->link_status = IFM_ETH_LINK_DOWN;
404 RTE_LOG(INFO, IFM, "EVENT-- PORT %u is Link DOWN.\n",
406 if (port->flags & IFM_SLAVE) {
407 struct rte_eth_link linkstatus;
408 uint8_t master_portid =
409 port->bond_config->bond_portid;
410 rte_eth_link_get_nowait(master_portid,
413 "Port %u 's Master(%u) status is %u\n\r",
414 port_id, master_portid,
415 linkstatus.link_status);
417 if (ifm_debug & IFM_DEBUG_LOCKS)
419 "%s: Releasing WR lock @ %d\n\r",
420 __FUNCTION__, __LINE__);
424 rte_rwlock_write_unlock(&rwlock);
429 //print_interface_details();
432 void ifm_update_linkstatus(uint8_t port_id, uint16_t linkstatus)
434 struct rte_eth_link link;
435 l2_phy_interface_t *port;
436 if (ifm_debug & IFM_DEBUG_LOCKS)
437 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
443 rte_rwlock_write_lock(&rwlock);
445 port = ifm.port_list[port_id];
449 "%s: Port %u info not found... configure it first.\n\r",
450 __FUNCTION__, port_id);
452 if (port != NULL && port->pmdid == port_id) {
453 rte_eth_link_get(port_id, &link);
454 if (linkstatus == IFM_ETH_LINK_UP) {
455 port->admin_status = IFM_ETH_LINK_UP;
456 port->link_status = IFM_ETH_LINK_UP;
457 if(!link.link_status) {
458 if (rte_eth_dev_set_link_up(port_id) < 0) {
460 "%s:Port %u admin up is unsuccessful\n\r",
461 __FUNCTION__, port->pmdid);
463 if (ifm_debug & IFM_DEBUG_LOCKS)
465 "%s: Releasing lock @ %d\n\r",
466 __FUNCTION__, __LINE__);
471 rte_rwlock_write_unlock(&rwlock);
473 if (ifm_debug & IFM_DEBUG_CONFIG)
475 "%s:Port %u admin up...\n\r",
476 __FUNCTION__, port->pmdid);
477 send_gratuitous_arp(port);
481 } else if (linkstatus == IFM_ETH_LINK_DOWN)
484 port->admin_status = IFM_ETH_LINK_DOWN;
485 port->link_status = IFM_ETH_LINK_DOWN;
486 /* need to check the following if */
487 if(link.link_status) {
488 status = rte_eth_dev_set_link_down(port_id);
491 printf("(%" PRIu32 "): PMD set link down... continuing...%"
492 PRId32 "\n", port_id, status);
497 if (ifm_debug & IFM_DEBUG_LOCKS)
498 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
504 rte_rwlock_write_unlock(&rwlock);
508 void ifm_set_l2_interface_mtu(uint8_t port_id, uint16_t mtu)
511 l2_phy_interface_t *port;
512 port = ifm.port_list[port_id];
515 "%s: Port %u info not found... configure it first.\n\r",
516 __FUNCTION__, port_id);
519 if (port != NULL && port->pmdid == port_id) {
520 ret = rte_eth_dev_set_mtu(port_id, mtu);
523 "set_l2_interface_mtu: Set MTU failed. ret=%d\n",
526 if (ifm_debug & IFM_DEBUG_LOCKS)
528 "%s: Acquiring lock @ %d\n\r",
529 __FUNCTION__, __LINE__);
534 rte_rwlock_write_lock(&rwlock);
537 if (ifm_debug & IFM_DEBUG_LOCKS)
539 "%s: Releasing lock @ %d\n\r",
540 __FUNCTION__, __LINE__);
545 rte_rwlock_write_unlock(&rwlock);
552 void ifm_set_port_promisc(uint8_t port_id, uint8_t enable)
554 l2_phy_interface_t *port;
555 if (ifm_debug & IFM_DEBUG_LOCKS)
556 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
557 __FUNCTION__, __LINE__);
561 rte_rwlock_write_lock(&rwlock);
563 port = ifm.port_list[port_id];
566 "%s: Port %u info not found... configure it first.\n\r",
567 __FUNCTION__, port_id);
569 if (port != NULL && port->pmdid == port_id) {
571 rte_eth_promiscuous_enable(port_id);
574 rte_eth_promiscuous_disable(port_id);
578 if (ifm_debug & IFM_DEBUG_LOCKS)
579 RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
580 __FUNCTION__, __LINE__);
584 rte_rwlock_write_unlock(&rwlock);
588 int32_t ifm_get_nactive_ports(void)
590 return ifm.nport_configured;
593 int32_t ifm_get_nports_initialized(void)
595 return ifm.nport_intialized;
598 uint16_t ifm_receive_bulk_pkts(uint8_t port_id, uint16_t qid,
599 struct rte_mbuf **rx_pkts)
601 uint64_t no_of_rcvd_pkt;
603 rte_eth_rx_burst(port_id, qid, rx_pkts, IFM_BURST_SIZE);
604 if (ifm_debug & IFM_DEBUG_RXTX)
606 "ifm_receive_bulk_pkts: port_id %u no_of_rcvd_pkt %lu\n\r",
607 port_id, no_of_rcvd_pkt);
608 return no_of_rcvd_pkt;
611 uint16_t ifm_transmit_bulk_pkts(l2_phy_interface_t *port,
612 struct rte_mbuf **tx_pkts, uint64_t npkts)
614 uint32_t burst_tx_delay_time = IFM_BURST_TX_WAIT_US;
615 uint32_t burst_tx_retry_num = IFM_BURST_TX_RETRIES;
617 uint32_t no_of_tx_pkt;
618 if (ifm_debug & IFM_DEBUG_LOCKS)
619 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
620 __FUNCTION__, __LINE__);
624 rte_rwlock_read_lock(&rwlock);
626 no_of_tx_pkt = rte_eth_tx_burst(port->pmdid, IFM_TX_DEFAULT_Q, tx_pkts,
628 if (unlikely(no_of_tx_pkt < npkts)) {
630 while (no_of_tx_pkt < IFM_BURST_SIZE
631 && retry++ < burst_tx_retry_num) {
632 rte_delay_us(burst_tx_delay_time);
634 rte_eth_tx_burst(port->pmdid, IFM_TX_DEFAULT_Q,
635 &tx_pkts[no_of_tx_pkt],
636 IFM_BURST_SIZE - no_of_tx_pkt);
639 if (ifm_debug & IFM_DEBUG_RXTX)
641 "ifm_transmit_bulk_pkts: no_of_tx_pkt %u\n\r",
643 if (ifm_debug & IFM_DEBUG_LOCKS)
644 RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
645 __FUNCTION__, __LINE__);
649 rte_rwlock_read_unlock(&rwlock);
654 int ifm_transmit_single_pkt(l2_phy_interface_t *port, struct rte_mbuf *tx_pkts)
656 uint64_t tx_npkts = 0;
657 if (tx_pkts == NULL || port == NULL) {
659 "ifm_transmit_single_pkt: tx_pkts and port are NULL ");
662 if (ifm_debug & IFM_DEBUG_RXTX)
664 "ifm_transmit_single_pkt: port->pmdid %u\n\r",
666 if (ifm_debug & IFM_DEBUG_LOCKS)
667 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
668 __FUNCTION__, __LINE__);
673 rte_rwlock_read_lock(&rwlock);
676 rte_eth_tx_buffer(port->pmdid, IFM_TX_DEFAULT_Q, port->tx_buffer,
678 if (ifm_debug & IFM_DEBUG_RXTX)
680 "ifm_transmit_single_pkt: port->pmdid %u No of packets buffered %lu\n\r",
681 port->pmdid, tx_npkts);
682 if (ifm_debug & IFM_DEBUG_LOCKS)
683 RTE_LOG(INFO, IFM, "%s: Releasing RW lock @ %d\n\r",
684 __FUNCTION__, __LINE__);
689 rte_rwlock_read_unlock(&rwlock);
691 if (ifm_debug & IFM_DEBUG_LOCKS)
692 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
693 __FUNCTION__, __LINE__);
698 rte_rwlock_write_lock(&rwlock);
701 rte_eth_tx_buffer_flush(port->pmdid, IFM_TX_DEFAULT_Q,
703 if (ifm_debug & IFM_DEBUG_LOCKS)
704 RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
705 __FUNCTION__, __LINE__);
710 rte_rwlock_write_unlock(&rwlock);
712 if (ifm_debug & IFM_DEBUG_RXTX)
714 "ifm_transmit_single_pkt: no of pkts flushed %lu\n\r",
719 int16_t ifm_add_ipv4_port(uint8_t port_id, uint32_t ipaddr, uint32_t addrlen)
721 l2_phy_interface_t *port;
723 if (ifm_debug & IFM_DEBUG_LOCKS)
724 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
730 rte_rwlock_write_lock(&rwlock);
732 port = ifm.port_list[port_id];
735 "%s: Port %u info not found... configure it first.\n\r",
736 __FUNCTION__, port_id);
738 if (port != NULL && port->pmdid == port_id) {
739 ipconf = (ipv4list_t *) rte_zmalloc(NULL, sizeof(ipv4list_t),
740 RTE_CACHE_LINE_SIZE);
741 if (ipconf != NULL) {
743 //ipconf->ipaddr = rte_bswap32(ipaddr);
744 ipconf->ipaddr = ipaddr;
746 ipconf->addrlen = addrlen;
747 if (port->ipv4_list == NULL)
748 port->flags |= IFM_IPV4_ENABLED;
749 ipconf->next = (ipv4list_t *) port->ipv4_list;
750 port->ipv4_list = (ipv4list_t *) ipconf;
751 if (ifm_debug & IFM_DEBUG_LOCKS)
753 "%s: Releasing lock @ %d\n\r",
754 __FUNCTION__, __LINE__);
759 rte_rwlock_write_unlock(&rwlock);
764 if (ifm_debug & IFM_DEBUG_LOCKS)
765 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
771 rte_rwlock_write_unlock(&rwlock);
776 int16_t ifm_remove_ipv4_port(uint8_t port_id, uint32_t ipaddr,
779 l2_phy_interface_t *port;
780 ipv4list_t *iplist, *previplist = NULL;
781 if (ifm_debug & IFM_DEBUG_LOCKS)
782 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
788 rte_rwlock_write_lock(&rwlock);
790 port = ifm.port_list[port_id];
793 "%s: Port %u info not found... configure it first.\n\r",
794 __FUNCTION__, port_id);
796 if (port != NULL && port->pmdid == port_id) {
797 if (port->ipv4_list == NULL) {
798 if (ifm_debug & IFM_DEBUG_LOCKS)
800 "%s: Releasing lock @ %d\n\r",
801 __FUNCTION__, __LINE__);
806 rte_rwlock_write_unlock(&rwlock);
810 iplist = (ipv4list_t *) port->ipv4_list;
811 while (iplist != NULL) {
812 if (addrlen == iplist->addrlen &&
813 memcpy(&iplist->ipaddr, &ipaddr, addrlen)) {
814 if (iplist == port->ipv4_list) {
815 port->ipv4_list = iplist->next;
817 if (previplist != NULL)
818 previplist->next = iplist->next;
820 port->flags &= ~IFM_IPV4_ENABLED;
822 if (ifm_debug & IFM_DEBUG_LOCKS)
824 "%s: Releasing lock @ %d\n\r",
825 __FUNCTION__, __LINE__);
830 rte_rwlock_write_unlock(&rwlock);
835 iplist = iplist->next;
839 if (ifm_debug & IFM_DEBUG_LOCKS)
840 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
846 rte_rwlock_write_unlock(&rwlock);
851 int8_t ifm_add_ipv6_port(uint8_t port_id, uint8_t ip6addr[], uint32_t addrlen)
853 l2_phy_interface_t *port;
855 if (ifm_debug & IFM_DEBUG_LOCKS)
856 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
862 rte_rwlock_write_lock(&rwlock);
864 port = ifm.port_list[port_id];
867 "%s: Port %u info not found... configure it first.\n\r",
868 __FUNCTION__, port_id);
870 if (port != NULL && port->pmdid == port_id) {
871 ip6conf = (ipv6list_t *) rte_zmalloc(NULL, sizeof(ipv6list_t),
872 RTE_CACHE_LINE_SIZE);
873 if (ip6conf != NULL) {
874 ip6conf->next = NULL;
875 memcpy(ip6conf->ipaddr, ip6addr, IFM_IPV6_ADDR_SIZE);
876 ip6conf->port = port;
877 ip6conf->addrlen = addrlen;
879 if (port->ipv6_list == NULL) {
880 port->flags |= IFM_IPV6_ENABLED;
882 ip6conf->next = (ipv6list_t *) port->ipv6_list;
883 port->ipv6_list = (ipv6list_t *) ip6conf;
884 if (ifm_debug & IFM_DEBUG_LOCKS)
886 "%s: Releasing lock @ %d\n\r",
887 __FUNCTION__, __LINE__);
892 rte_rwlock_write_unlock(&rwlock);
897 if (ifm_debug & IFM_DEBUG_LOCKS)
898 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
904 rte_rwlock_write_unlock(&rwlock);
909 int16_t ifm_remove_ipv6_port(uint8_t port_id, uint32_t ip6addr,
912 l2_phy_interface_t *port;
913 ipv6list_t *ip6list, *previp6list = NULL;
915 if (ifm_debug & IFM_DEBUG_LOCKS)
916 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
921 rte_rwlock_write_lock(&rwlock);
922 port = ifm.port_list[port_id];
924 if (ifm_debug & IFM_DEBUG_LOCKS)
925 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
926 __FUNCTION__, __LINE__);
930 rte_rwlock_write_unlock(&rwlock);
933 "%s: Port %u info not found... configure it first.\n\r",
934 __FUNCTION__, port_id);
936 if (port != NULL && port->pmdid == port_id) {
937 if (port->ipv6_list == NULL) {
938 if (ifm_debug & IFM_DEBUG_LOCKS)
940 "%s: Releasing lock @ %d\n\r",
941 __FUNCTION__, __LINE__);
946 rte_rwlock_write_unlock(&rwlock);
950 ip6list = (ipv6list_t *) port->ipv6_list;
951 while (ip6list != NULL) {
952 if (addrlen == ip6list->addrlen &&
953 memcpy(&ip6list->ipaddr, &ip6addr, addrlen)) {
954 if (ip6list == port->ipv6_list) {
955 port->ipv6_list = ip6list->next;
957 if (previp6list != NULL)
961 port->flags &= ~IFM_IPV6_ENABLED;
963 if (ifm_debug & IFM_DEBUG_LOCKS)
965 "%s: Releasing lock @ %d\n\r",
966 __FUNCTION__, __LINE__);
971 rte_rwlock_write_unlock(&rwlock);
975 previp6list = ip6list;
976 ip6list = ip6list->next;
980 if (ifm_debug & IFM_DEBUG_LOCKS)
981 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
986 rte_rwlock_write_unlock(&rwlock);
990 int32_t ifm_chk_port_ipv4_enabled(uint8_t port_id)
992 l2_phy_interface_t *port;
994 if (ifm_debug & IFM_DEBUG_LOCKS)
995 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
996 __FUNCTION__, __LINE__);
1000 rte_rwlock_read_lock(&rwlock);
1001 port = ifm.port_list[port_id];
1004 "%s: Port %u info not found... configure it first.\n\r",
1005 __FUNCTION__, port_id);
1006 if (ifm_debug & IFM_DEBUG_LOCKS)
1007 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
1008 __FUNCTION__, __LINE__);
1012 rte_rwlock_read_unlock(&rwlock);
1015 if ((port->flags & IFM_IPV4_ENABLED) == 0) {
1016 if (ifm_debug & IFM_DEBUG_LOCKS)
1017 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
1018 __FUNCTION__, __LINE__);
1022 rte_rwlock_read_unlock(&rwlock);
1025 if (ifm_debug & IFM_DEBUG_LOCKS)
1026 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
1027 __FUNCTION__, __LINE__);
1031 rte_rwlock_read_unlock(&rwlock);
1036 int32_t ifm_chk_port_ipv6_enabled(uint8_t port_id)
1038 l2_phy_interface_t *port;
1040 if (ifm_debug & IFM_DEBUG_LOCKS)
1041 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
1042 __FUNCTION__, __LINE__);
1046 rte_rwlock_read_lock(&rwlock);
1048 port = ifm.port_list[port_id];
1050 if (ifm_debug & IFM_DEBUG)
1051 RTE_LOG(ERR, IFM, "%s: Port %u info not found..."
1052 " configure it first.\n\r",
1053 __FUNCTION__, port_id);
1054 if (ifm_debug & IFM_DEBUG_LOCKS)
1055 RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
1056 __FUNCTION__, __LINE__);
1060 rte_rwlock_read_unlock(&rwlock);
1063 if ((port->flags & IFM_IPV6_ENABLED) == 0) {
1064 if (ifm_debug & IFM_DEBUG_LOCKS)
1065 RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
1066 __FUNCTION__, __LINE__);
1070 rte_rwlock_read_unlock(&rwlock);
1073 if (ifm_debug & IFM_DEBUG_LOCKS)
1074 RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
1075 __FUNCTION__, __LINE__);
1079 rte_rwlock_read_unlock(&rwlock);
1084 void ifm_register_for_linkupdate(uint32_t clientid,
1085 void (*cb_linkupdate) (uint8_t, unsigned int))
1087 ifm.if_client[ifm.nclient].cb_linkupdate = cb_linkupdate;
1088 ifm.if_client[ifm.nclient].clientid = clientid;
1092 int ifm_port_setup(uint8_t port_id, port_config_t *pconfig)
1096 struct rte_eth_dev_info dev_info;
1097 struct rte_eth_link linkstatus;
1098 l2_phy_interface_t *port = NULL;
1100 if (!ifm.nport_intialized) {
1101 RTE_LOG(ERR, IFM, "%s: Failed to configure port %u. 0 ports"
1102 "were intialized during PCI probe...\n\r",
1103 __FUNCTION__, port_id);
1106 if (ifm_debug & IFM_DEBUG_CONFIG)
1107 RTE_LOG(INFO, IFM, "%s: Configuring port %u with "
1108 "nrxq: %u, ntxq: %u\n\r", __FUNCTION__,
1109 port_id, pconfig->nrx_queue, pconfig->ntx_queue);
1110 if (ifm_debug & IFM_DEBUG_LOCKS)
1111 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock1 @ %d\n\r",
1112 __FUNCTION__, __LINE__);
1116 rte_rwlock_write_lock(&rwlock);
1118 if (ifm.port_list[port_id] == NULL) {
1119 ifm.port_list[port_id] =
1120 (l2_phy_interface_t *) rte_zmalloc(NULL,
1122 (l2_phy_interface_t),
1123 RTE_CACHE_LINE_SIZE);
1124 ifm.port_list[port_id]->pmdid = port_id;
1126 if (ifm_debug & IFM_DEBUG_LOCKS)
1127 RTE_LOG(INFO, IFM, "%s: Releasing WR lock1 @ %d\n\r",
1128 __FUNCTION__, __LINE__);
1132 rte_rwlock_write_unlock(&rwlock);
1134 rte_eth_link_get(port_id, &linkstatus);
1135 if (linkstatus.link_status) {
1136 if (ifm_debug & IFM_DEBUG_CONFIG) {
1137 RTE_LOG(INFO, IFM, "%s: %u is up.Stop it before"
1138 " reconfiguring.\n\r", __FUNCTION__, port_id);
1140 rte_eth_dev_stop(port_id);
1142 /*Configure an Ethernet device. rets 0 on success queue */
1143 status = rte_eth_dev_configure(port_id, pconfig->nrx_queue,
1144 pconfig->ntx_queue, &pconfig->port_conf);
1146 ifm_remove_port_details(port_id);
1147 RTE_LOG(ERR, IFM, "%s: rte_eth_dev_configure is failed"
1148 "for port %u.\n\r", __FUNCTION__, port_id);
1151 status = rte_eth_dev_callback_register(port_id,
1152 RTE_ETH_EVENT_INTR_LSC,
1153 lsi_event_callback, NULL);
1155 ifm_remove_port_details(port_id);
1156 RTE_LOG(ERR, IFM, "%s: rte_eth_dev_callback_register()"
1157 " failed for port %u.\n\r", __FUNCTION__, port_id);
1160 /*promiscuous mode is enabled set it */
1161 if (pconfig->promisc)
1162 rte_eth_promiscuous_enable(port_id);
1164 sock = rte_eth_dev_socket_id(port_id);
1166 RTE_LOG(ERR, IFM, "%s: Warning: rte_eth_dev_socket_id,"
1168 "out of range %u\n\r", __FUNCTION__, port_id);
1169 /*Port initialization */
1171 for (ntxqs = 0; ntxqs < pconfig->ntx_queue; ntxqs++) {
1172 status = rte_eth_tx_queue_setup(port_id, ntxqs,
1173 IFM_TX_DESC_DEFAULT, sock,
1174 &(pconfig->tx_conf));
1176 ifm_remove_port_details(port_id);
1177 RTE_LOG(ERR, IFM, "%s: rte_eth_tx_queue_setup failed"
1178 " for port %u\n\r", __FUNCTION__, port_id);
1182 port = ifm_get_port(port_id);
1184 RTE_LOG(INFO, IFM, "%s: Port is NULL @ %d\n\r", __FUNCTION__,
1189 if (ifm_debug & IFM_DEBUG_LOCKS)
1190 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock 2 @ %d\n\r",
1191 __FUNCTION__, __LINE__);
1195 rte_rwlock_write_lock(&rwlock);
1197 if (port->tx_buf_len == 0) {
1198 port->tx_buf_len = RTE_ETH_TX_BUFFER_SIZE(IFM_BURST_SIZE);
1200 port->tx_buffer = rte_zmalloc_socket("tx_buffer", port->tx_buf_len, 0,
1201 rte_eth_dev_socket_id(port_id));
1203 if (port->tx_buffer == NULL) {
1204 ifm_remove_port_details(port_id);
1205 RTE_LOG(ERR, IFM, "%s: Failed to allocate tx buffers for"
1206 " port %u\n\r", __FUNCTION__, port_id);
1207 if (ifm_debug & IFM_DEBUG_LOCKS)
1208 RTE_LOG(INFO, IFM, "%s: Releasing WR lock2 %d\n\r",
1209 __FUNCTION__, __LINE__);
1213 rte_rwlock_write_unlock(&rwlock);
1216 rte_eth_tx_buffer_init(port->tx_buffer, IFM_BURST_SIZE);
1218 sprintf(buf, "MEMPOOL%d", port_id);
1219 port->mempool = rte_mempool_create(buf,
1220 pconfig->mempool.pool_size,
1221 pconfig->mempool.buffer_size,
1222 pconfig->mempool.cache_size,
1224 rte_pktmbuf_pool_private),
1225 rte_pktmbuf_pool_init, NULL,
1226 rte_pktmbuf_init, NULL, sock, 0);
1227 if (port->mempool == NULL) {
1228 ifm_remove_port_details(port_id);
1229 RTE_LOG(ERR, IFM, "%s: rte_mempool_create is failed for port"
1230 " %u. Error: %s\n\r",
1231 __FUNCTION__, port_id, rte_strerror(rte_errno));
1232 if (ifm_debug & IFM_DEBUG_LOCKS)
1233 RTE_LOG(INFO, IFM, "%s: Releasing WR lock2 %d\n\r",
1234 __FUNCTION__, __LINE__);
1238 rte_rwlock_write_unlock(&rwlock);
1242 for (nrxqs = 0; nrxqs < pconfig->nrx_queue; nrxqs++) {
1243 status = rte_eth_rx_queue_setup(port_id, nrxqs,
1244 IFM_RX_DESC_DEFAULT, sock,
1245 &(pconfig->rx_conf),
1248 ifm_remove_port_details(port_id);
1250 "%s: rte_eth_rx_queue_setup is failed "
1251 "for port %u queue %u. Error: %s\n\r",
1252 __FUNCTION__, port_id, nrxqs,
1253 rte_strerror(rte_errno));
1254 if (ifm_debug & IFM_DEBUG_LOCKS)
1256 "%s: Releasing WR lock2 %d\n\r",
1257 __FUNCTION__, __LINE__);
1261 rte_rwlock_write_unlock(&rwlock);
1266 if (ifm_debug & IFM_DEBUG_LOCKS)
1267 RTE_LOG(INFO, IFM, "%s: Releasing WR lock2 @ %d\n\r",
1268 __FUNCTION__, __LINE__);
1272 rte_rwlock_write_unlock(&rwlock);
1273 status = rte_eth_dev_start(port_id);
1275 ifm_remove_port_details(port_id);
1276 RTE_LOG(ERR, IFM, "%s: rte_eth_dev_start is failed for"
1277 " port %u.\n\r", __FUNCTION__, port_id);
1281 /*Get device info and populate interface structure */
1282 if (ifm_debug & IFM_DEBUG_LOCKS)
1283 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock3 @ %d\n\r",
1284 __FUNCTION__, __LINE__);
1288 rte_rwlock_write_lock(&rwlock);
1289 rte_eth_macaddr_get(port_id, (struct ether_addr *)port->macaddr);
1290 if (pconfig->promisc)
1292 rte_eth_link_get(port_id, &linkstatus);
1294 port->link_duplex = linkstatus.link_duplex;
1295 port->link_autoneg = linkstatus.link_autoneg;
1296 port->link_speed = linkstatus.link_speed;
1297 port->admin_status = pconfig->state;
1300 memset(&dev_info, 0, sizeof(dev_info));
1301 rte_eth_dev_info_get(port_id, &dev_info);
1302 port->min_rx_bufsize = dev_info.min_rx_bufsize;
1303 port->max_rx_pktlen = dev_info.max_rx_pktlen;
1304 port->max_rx_queues = dev_info.max_rx_queues;
1305 port->max_tx_queues = dev_info.max_tx_queues;
1306 rte_eth_dev_get_mtu(port_id, &(port->mtu));
1308 /*Add rx and tx packet function ptrs */
1309 port->retrieve_bulk_pkts = &ifm_receive_bulk_pkts;
1310 port->transmit_bulk_pkts = &ifm_transmit_bulk_pkts;
1311 port->transmit_single_pkt = &ifm_transmit_single_pkt;
1312 if (ifm_debug & IFM_DEBUG_LOCKS)
1313 RTE_LOG(INFO, IFM, "%s: Releasing WR3 lock @ %d\n\r",
1314 __FUNCTION__, __LINE__);
1318 rte_rwlock_write_unlock(&rwlock);
1319 RTE_LOG(INFO, IFM, "%s: Port %u is successfully configured.\n\r",
1320 __FUNCTION__, port_id);
1324 int ifm_configure_ports(port_config_t *pconfig)
1328 if (!ifm.nport_intialized) {
1329 RTE_LOG(ERR, IFM, "%s, Configuring ports failed. Zero ports "
1330 "are intialized during PCI probe", __FUNCTION__);
1333 if (pconfig == NULL) {
1334 RTE_LOG(ERR, IFM, "%s, Configuring ports failed. "
1335 "Param pconfig is NULL\n\r", __FUNCTION__);
1339 /*Initialize all ports */
1340 for (port_id = 0; port_id < ifm.nport_intialized; port_id++) {
1341 if (ifm_debug & IFM_DEBUG_CONFIG)
1342 RTE_LOG(INFO, IFM, "Call ifm_port_setup %u\n\r",
1345 ifm_port_setup(pconfig[port_id].port_id, &pconfig[port_id]);
1346 if (status == IFM_SUCCESS)
1347 ifm.nport_configured++;
1349 if (!ifm.nport_configured) {
1350 RTE_LOG(ERR, IFM, "%s: Zero ports are configured\n\r",
1354 RTE_LOG(INFO, IFM, "%s: Number of ports sucessfully configured:"
1355 " %d\n\r", __FUNCTION__, ifm.nport_configured);
1359 void print_interface_details(void)
1361 l2_phy_interface_t *port;
1363 struct sockaddr_in ip;
1366 if (ifm_debug & IFM_DEBUG_LOCKS)
1367 RTE_LOG(INFO, IFM, "%s: Acquiring RW lock @ %d\n\r",
1368 __FUNCTION__, __LINE__);
1372 rte_rwlock_read_lock(&rwlock);
1374 for (i = 0; i < RTE_MAX_ETHPORTS && ifm.port_list[i]; i++) {
1375 port = ifm.port_list[i];
1376 printf(" %u", port->pmdid);
1377 if (port->ifname && strlen(port->ifname)) {
1378 printf(" (%s)\t", port->ifname);
1381 printf("MAC:%02x:%02x:%02x:%02x:%02x:%02x Adminstate:%s"
1382 " Operstate:%s \n\r",
1383 port->macaddr[0], port->macaddr[1],
1384 port->macaddr[2], port->macaddr[3],
1385 port->macaddr[4], port->macaddr[5],
1386 port->admin_status ? "UP" : "DOWN",
1387 port->link_status ? "UP" : "DOWN");
1389 printf("Speed: %u, %s-duplex\n\r", port->link_speed,
1390 port->link_duplex ? "full" : "half");
1393 if (port->ipv4_list != NULL) {
1394 ip.sin_addr.s_addr =
1395 (unsigned long)((ipv4list_t *) (port->ipv4_list))->
1397 printf("IP: %s/%d", inet_ntoa(ip.sin_addr),
1398 ((ipv4list_t *) (port->ipv4_list))->addrlen);
1405 if (port->ipv6_list != NULL) {
1407 ((ipv6list_t *) (port->ipv6_list))->ipaddr;
1409 ("IPv6: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
1410 addr[0], addr[1], addr[2], addr[3], addr[4],
1411 addr[5], addr[6], addr[7], addr[8], addr[9],
1412 addr[10], addr[11], addr[12], addr[13], addr[14],
1418 if (port->flags & IFM_SLAVE) {
1419 printf(" IFM_SLAVE ");
1420 printf(" MasterPort: %u",
1421 port->bond_config->bond_portid);
1423 if (port->flags & IFM_MASTER) {
1424 printf(" IFM_MASTER ");
1425 printf(" Mode: %u", port->bond_config->mode);
1426 printf(" PrimaryPort: %u", port->bond_config->primary);
1428 printf("\t\tSlavePortCount: %u",
1429 port->bond_config->slave_count);
1430 printf(" SlavePorts:");
1432 for (i = 0; i < port->bond_config->slave_count; i++) {
1433 printf(" %u ", port->bond_config->slaves[i]);
1435 printf(" ActivePortCount: %u",
1436 port->bond_config->active_slave_count);
1437 printf(" ActivePorts:");
1438 for (i = 0; i < port->bond_config->active_slave_count;
1441 port->bond_config->active_slaves[i]);
1445 printf("Link_monitor_freq: %u ms ",
1446 port->bond_config->internal_ms);
1447 printf(" Link_up_prop_delay: %u ms ",
1448 port->bond_config->link_up_delay_ms);
1449 printf(" Link_down_prop_delay: %u ms ",
1450 port->bond_config->link_down_delay_ms);
1453 printf("Xmit_policy: %u",
1454 port->bond_config->xmit_policy);
1458 printf("n_rxpkts: %" PRIu64 " ,n_txpkts: %" PRIu64 " ,",
1459 port->n_rxpkts, port->n_txpkts);
1460 struct rte_eth_stats eth_stats;
1461 rte_eth_stats_get(port->pmdid, ð_stats);
1462 printf("pkts_in: %" PRIu64 " ,", eth_stats.ipackets);
1463 printf("pkts_out: %" PRIu64 " ", eth_stats.opackets);
1466 printf("in_errs: %" PRIu64 " ,", eth_stats.ierrors);
1467 printf("in_missed: %" PRIu64 " ,", eth_stats.imissed);
1468 printf("out_errs: %" PRIu64 " ,", eth_stats.oerrors);
1469 printf("mbuf_errs: %" PRIu64 " ", eth_stats.rx_nombuf);
1473 if (ifm_debug & IFM_DEBUG_LOCKS)
1474 RTE_LOG(INFO, IFM, "%s: Releasing RW lock @ %d\n\r",
1475 __FUNCTION__, __LINE__);
1479 rte_rwlock_read_unlock(&rwlock);