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 if(!link.link_status) {
457 if (rte_eth_dev_set_link_up(port_id) < 0) {
459 "%s:Port %u admin up is unsuccessful\n\r",
460 __FUNCTION__, port->pmdid);
462 if (ifm_debug & IFM_DEBUG_LOCKS)
464 "%s: Releasing lock @ %d\n\r",
465 __FUNCTION__, __LINE__);
470 rte_rwlock_write_unlock(&rwlock);
472 if (ifm_debug & IFM_DEBUG_CONFIG)
474 "%s:Port %u admin up...\n\r",
475 __FUNCTION__, port->pmdid);
476 send_gratuitous_arp(port);
480 } else if (linkstatus == IFM_ETH_LINK_DOWN)
483 port->admin_status = IFM_ETH_LINK_DOWN;
484 /* need to check the following if */
485 if(link.link_status) {
486 status = rte_eth_dev_set_link_down(port_id);
489 printf("(%" PRIu32 "): PMD set link down... continuing...%"
490 PRId32 "\n", port_id, status);
495 if (ifm_debug & IFM_DEBUG_LOCKS)
496 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
502 rte_rwlock_write_unlock(&rwlock);
506 void ifm_set_l2_interface_mtu(uint8_t port_id, uint16_t mtu)
509 l2_phy_interface_t *port;
510 port = ifm.port_list[port_id];
513 "%s: Port %u info not found... configure it first.\n\r",
514 __FUNCTION__, port_id);
517 if (port != NULL && port->pmdid == port_id) {
518 ret = rte_eth_dev_set_mtu(port_id, mtu);
521 "set_l2_interface_mtu: Set MTU failed. ret=%d\n",
524 if (ifm_debug & IFM_DEBUG_LOCKS)
526 "%s: Acquiring lock @ %d\n\r",
527 __FUNCTION__, __LINE__);
532 rte_rwlock_write_lock(&rwlock);
535 if (ifm_debug & IFM_DEBUG_LOCKS)
537 "%s: Releasing lock @ %d\n\r",
538 __FUNCTION__, __LINE__);
543 rte_rwlock_write_unlock(&rwlock);
550 void ifm_set_port_promisc(uint8_t port_id, uint8_t enable)
552 l2_phy_interface_t *port;
553 if (ifm_debug & IFM_DEBUG_LOCKS)
554 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
555 __FUNCTION__, __LINE__);
559 rte_rwlock_write_lock(&rwlock);
561 port = ifm.port_list[port_id];
564 "%s: Port %u info not found... configure it first.\n\r",
565 __FUNCTION__, port_id);
567 if (port != NULL && port->pmdid == port_id) {
569 rte_eth_promiscuous_enable(port_id);
572 rte_eth_promiscuous_disable(port_id);
576 if (ifm_debug & IFM_DEBUG_LOCKS)
577 RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
578 __FUNCTION__, __LINE__);
582 rte_rwlock_write_unlock(&rwlock);
586 int32_t ifm_get_nactive_ports(void)
588 return ifm.nport_configured;
591 int32_t ifm_get_nports_initialized(void)
593 return ifm.nport_intialized;
596 uint16_t ifm_receive_bulk_pkts(uint8_t port_id, uint16_t qid,
597 struct rte_mbuf **rx_pkts)
599 uint64_t no_of_rcvd_pkt;
601 rte_eth_rx_burst(port_id, qid, rx_pkts, IFM_BURST_SIZE);
602 if (ifm_debug & IFM_DEBUG_RXTX)
604 "ifm_receive_bulk_pkts: port_id %u no_of_rcvd_pkt %lu\n\r",
605 port_id, no_of_rcvd_pkt);
606 return no_of_rcvd_pkt;
609 uint16_t ifm_transmit_bulk_pkts(l2_phy_interface_t *port,
610 struct rte_mbuf **tx_pkts, uint64_t npkts)
612 uint32_t burst_tx_delay_time = IFM_BURST_TX_WAIT_US;
613 uint32_t burst_tx_retry_num = IFM_BURST_TX_RETRIES;
615 uint32_t no_of_tx_pkt;
616 if (ifm_debug & IFM_DEBUG_LOCKS)
617 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
618 __FUNCTION__, __LINE__);
622 rte_rwlock_read_lock(&rwlock);
624 no_of_tx_pkt = rte_eth_tx_burst(port->pmdid, IFM_TX_DEFAULT_Q, tx_pkts,
626 if (unlikely(no_of_tx_pkt < npkts)) {
628 while (no_of_tx_pkt < IFM_BURST_SIZE
629 && retry++ < burst_tx_retry_num) {
630 rte_delay_us(burst_tx_delay_time);
632 rte_eth_tx_burst(port->pmdid, IFM_TX_DEFAULT_Q,
633 &tx_pkts[no_of_tx_pkt],
634 IFM_BURST_SIZE - no_of_tx_pkt);
637 if (ifm_debug & IFM_DEBUG_RXTX)
639 "ifm_transmit_bulk_pkts: no_of_tx_pkt %u\n\r",
641 if (ifm_debug & IFM_DEBUG_LOCKS)
642 RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
643 __FUNCTION__, __LINE__);
647 rte_rwlock_read_unlock(&rwlock);
652 int ifm_transmit_single_pkt(l2_phy_interface_t *port, struct rte_mbuf *tx_pkts)
654 uint64_t tx_npkts = 0;
655 if (tx_pkts == NULL || port == NULL) {
657 "ifm_transmit_single_pkt: tx_pkts and port are NULL ");
660 if (ifm_debug & IFM_DEBUG_RXTX)
662 "ifm_transmit_single_pkt: port->pmdid %u\n\r",
664 if (ifm_debug & IFM_DEBUG_LOCKS)
665 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
666 __FUNCTION__, __LINE__);
671 rte_rwlock_read_lock(&rwlock);
674 rte_eth_tx_buffer(port->pmdid, IFM_TX_DEFAULT_Q, port->tx_buffer,
676 if (ifm_debug & IFM_DEBUG_RXTX)
678 "ifm_transmit_single_pkt: port->pmdid %u No of packets buffered %lu\n\r",
679 port->pmdid, tx_npkts);
680 if (ifm_debug & IFM_DEBUG_LOCKS)
681 RTE_LOG(INFO, IFM, "%s: Releasing RW lock @ %d\n\r",
682 __FUNCTION__, __LINE__);
687 rte_rwlock_read_unlock(&rwlock);
689 if (ifm_debug & IFM_DEBUG_LOCKS)
690 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
691 __FUNCTION__, __LINE__);
696 rte_rwlock_write_lock(&rwlock);
699 rte_eth_tx_buffer_flush(port->pmdid, IFM_TX_DEFAULT_Q,
701 if (ifm_debug & IFM_DEBUG_LOCKS)
702 RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
703 __FUNCTION__, __LINE__);
708 rte_rwlock_write_unlock(&rwlock);
710 if (ifm_debug & IFM_DEBUG_RXTX)
712 "ifm_transmit_single_pkt: no of pkts flushed %lu\n\r",
717 int16_t ifm_add_ipv4_port(uint8_t port_id, uint32_t ipaddr, uint32_t addrlen)
719 l2_phy_interface_t *port;
721 if (ifm_debug & IFM_DEBUG_LOCKS)
722 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
728 rte_rwlock_write_lock(&rwlock);
730 port = ifm.port_list[port_id];
733 "%s: Port %u info not found... configure it first.\n\r",
734 __FUNCTION__, port_id);
736 if (port != NULL && port->pmdid == port_id) {
737 ipconf = (ipv4list_t *) rte_zmalloc(NULL, sizeof(ipv4list_t),
738 RTE_CACHE_LINE_SIZE);
739 if (ipconf != NULL) {
741 //ipconf->ipaddr = rte_bswap32(ipaddr);
742 ipconf->ipaddr = ipaddr;
744 ipconf->addrlen = addrlen;
745 if (port->ipv4_list == NULL)
746 port->flags |= IFM_IPV4_ENABLED;
747 ipconf->next = (ipv4list_t *) port->ipv4_list;
748 port->ipv4_list = (ipv4list_t *) ipconf;
749 if (ifm_debug & IFM_DEBUG_LOCKS)
751 "%s: Releasing lock @ %d\n\r",
752 __FUNCTION__, __LINE__);
757 rte_rwlock_write_unlock(&rwlock);
762 if (ifm_debug & IFM_DEBUG_LOCKS)
763 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
769 rte_rwlock_write_unlock(&rwlock);
774 int16_t ifm_remove_ipv4_port(uint8_t port_id, uint32_t ipaddr,
777 l2_phy_interface_t *port;
778 ipv4list_t *iplist, *previplist = NULL;
779 if (ifm_debug & IFM_DEBUG_LOCKS)
780 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
786 rte_rwlock_write_lock(&rwlock);
788 port = ifm.port_list[port_id];
791 "%s: Port %u info not found... configure it first.\n\r",
792 __FUNCTION__, port_id);
794 if (port != NULL && port->pmdid == port_id) {
795 if (port->ipv4_list == NULL) {
796 if (ifm_debug & IFM_DEBUG_LOCKS)
798 "%s: Releasing lock @ %d\n\r",
799 __FUNCTION__, __LINE__);
804 rte_rwlock_write_unlock(&rwlock);
808 iplist = (ipv4list_t *) port->ipv4_list;
809 while (iplist != NULL) {
810 if (addrlen == iplist->addrlen &&
811 memcpy(&iplist->ipaddr, &ipaddr, addrlen)) {
812 if (iplist == port->ipv4_list) {
813 port->ipv4_list = iplist->next;
815 if (previplist != NULL)
816 previplist->next = iplist->next;
818 port->flags &= ~IFM_IPV4_ENABLED;
820 if (ifm_debug & IFM_DEBUG_LOCKS)
822 "%s: Releasing lock @ %d\n\r",
823 __FUNCTION__, __LINE__);
828 rte_rwlock_write_unlock(&rwlock);
833 iplist = iplist->next;
837 if (ifm_debug & IFM_DEBUG_LOCKS)
838 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
844 rte_rwlock_write_unlock(&rwlock);
849 int8_t ifm_add_ipv6_port(uint8_t port_id, uint8_t ip6addr[], uint32_t addrlen)
851 l2_phy_interface_t *port;
853 if (ifm_debug & IFM_DEBUG_LOCKS)
854 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
860 rte_rwlock_write_lock(&rwlock);
862 port = ifm.port_list[port_id];
865 "%s: Port %u info not found... configure it first.\n\r",
866 __FUNCTION__, port_id);
868 if (port != NULL && port->pmdid == port_id) {
869 ip6conf = (ipv6list_t *) rte_zmalloc(NULL, sizeof(ipv6list_t),
870 RTE_CACHE_LINE_SIZE);
871 if (ip6conf != NULL) {
872 ip6conf->next = NULL;
873 memcpy(ip6conf->ipaddr, ip6addr, IFM_IPV6_ADDR_SIZE);
874 ip6conf->port = port;
875 ip6conf->addrlen = addrlen;
877 if (port->ipv6_list == NULL) {
878 port->flags |= IFM_IPV6_ENABLED;
880 ip6conf->next = (ipv6list_t *) port->ipv6_list;
881 port->ipv6_list = (ipv6list_t *) ip6conf;
882 if (ifm_debug & IFM_DEBUG_LOCKS)
884 "%s: Releasing lock @ %d\n\r",
885 __FUNCTION__, __LINE__);
890 rte_rwlock_write_unlock(&rwlock);
895 if (ifm_debug & IFM_DEBUG_LOCKS)
896 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
902 rte_rwlock_write_unlock(&rwlock);
907 int16_t ifm_remove_ipv6_port(uint8_t port_id, uint32_t ip6addr,
910 l2_phy_interface_t *port;
911 ipv6list_t *ip6list, *previp6list = NULL;
913 if (ifm_debug & IFM_DEBUG_LOCKS)
914 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
919 rte_rwlock_write_lock(&rwlock);
920 port = ifm.port_list[port_id];
922 if (ifm_debug & IFM_DEBUG_LOCKS)
923 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
924 __FUNCTION__, __LINE__);
928 rte_rwlock_write_unlock(&rwlock);
931 "%s: Port %u info not found... configure it first.\n\r",
932 __FUNCTION__, port_id);
934 if (port != NULL && port->pmdid == port_id) {
935 if (port->ipv6_list == NULL) {
936 if (ifm_debug & IFM_DEBUG_LOCKS)
938 "%s: Releasing lock @ %d\n\r",
939 __FUNCTION__, __LINE__);
944 rte_rwlock_write_unlock(&rwlock);
948 ip6list = (ipv6list_t *) port->ipv6_list;
949 while (ip6list != NULL) {
950 if (addrlen == ip6list->addrlen &&
951 memcpy(&ip6list->ipaddr, &ip6addr, addrlen)) {
952 if (ip6list == port->ipv6_list) {
953 port->ipv6_list = ip6list->next;
955 if (previp6list != NULL)
959 port->flags &= ~IFM_IPV6_ENABLED;
961 if (ifm_debug & IFM_DEBUG_LOCKS)
963 "%s: Releasing lock @ %d\n\r",
964 __FUNCTION__, __LINE__);
969 rte_rwlock_write_unlock(&rwlock);
973 previp6list = ip6list;
974 ip6list = ip6list->next;
978 if (ifm_debug & IFM_DEBUG_LOCKS)
979 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
984 rte_rwlock_write_unlock(&rwlock);
988 int32_t ifm_chk_port_ipv4_enabled(uint8_t port_id)
990 l2_phy_interface_t *port;
992 if (ifm_debug & IFM_DEBUG_LOCKS)
993 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
994 __FUNCTION__, __LINE__);
998 rte_rwlock_read_lock(&rwlock);
999 port = ifm.port_list[port_id];
1002 "%s: Port %u info not found... configure it first.\n\r",
1003 __FUNCTION__, port_id);
1004 if (ifm_debug & IFM_DEBUG_LOCKS)
1005 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
1006 __FUNCTION__, __LINE__);
1010 rte_rwlock_read_unlock(&rwlock);
1013 if ((port->flags & IFM_IPV4_ENABLED) == 0) {
1014 if (ifm_debug & IFM_DEBUG_LOCKS)
1015 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
1016 __FUNCTION__, __LINE__);
1020 rte_rwlock_read_unlock(&rwlock);
1023 if (ifm_debug & IFM_DEBUG_LOCKS)
1024 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
1025 __FUNCTION__, __LINE__);
1029 rte_rwlock_read_unlock(&rwlock);
1034 int32_t ifm_chk_port_ipv6_enabled(uint8_t port_id)
1036 l2_phy_interface_t *port;
1038 if (ifm_debug & IFM_DEBUG_LOCKS)
1039 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
1040 __FUNCTION__, __LINE__);
1044 rte_rwlock_read_lock(&rwlock);
1046 port = ifm.port_list[port_id];
1048 if (ifm_debug & IFM_DEBUG)
1049 RTE_LOG(ERR, IFM, "%s: Port %u info not found..."
1050 " configure it first.\n\r",
1051 __FUNCTION__, port_id);
1052 if (ifm_debug & IFM_DEBUG_LOCKS)
1053 RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
1054 __FUNCTION__, __LINE__);
1058 rte_rwlock_read_unlock(&rwlock);
1061 if ((port->flags & IFM_IPV6_ENABLED) == 0) {
1062 if (ifm_debug & IFM_DEBUG_LOCKS)
1063 RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
1064 __FUNCTION__, __LINE__);
1068 rte_rwlock_read_unlock(&rwlock);
1071 if (ifm_debug & IFM_DEBUG_LOCKS)
1072 RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
1073 __FUNCTION__, __LINE__);
1077 rte_rwlock_read_unlock(&rwlock);
1082 void ifm_register_for_linkupdate(uint32_t clientid,
1083 void (*cb_linkupdate) (uint8_t, unsigned int))
1085 ifm.if_client[ifm.nclient].cb_linkupdate = cb_linkupdate;
1086 ifm.if_client[ifm.nclient].clientid = clientid;
1090 int ifm_port_setup(uint8_t port_id, port_config_t *pconfig)
1094 struct rte_eth_dev_info dev_info;
1095 struct rte_eth_link linkstatus;
1096 l2_phy_interface_t *port = NULL;
1098 if (!ifm.nport_intialized) {
1099 RTE_LOG(ERR, IFM, "%s: Failed to configure port %u. 0 ports"
1100 "were intialized during PCI probe...\n\r",
1101 __FUNCTION__, port_id);
1104 if (ifm_debug & IFM_DEBUG_CONFIG)
1105 RTE_LOG(INFO, IFM, "%s: Configuring port %u with "
1106 "nrxq: %u, ntxq: %u\n\r", __FUNCTION__,
1107 port_id, pconfig->nrx_queue, pconfig->ntx_queue);
1108 if (ifm_debug & IFM_DEBUG_LOCKS)
1109 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock1 @ %d\n\r",
1110 __FUNCTION__, __LINE__);
1114 rte_rwlock_write_lock(&rwlock);
1116 if (ifm.port_list[port_id] == NULL) {
1117 ifm.port_list[port_id] =
1118 (l2_phy_interface_t *) rte_zmalloc(NULL,
1120 (l2_phy_interface_t),
1121 RTE_CACHE_LINE_SIZE);
1122 ifm.port_list[port_id]->pmdid = port_id;
1124 if (ifm_debug & IFM_DEBUG_LOCKS)
1125 RTE_LOG(INFO, IFM, "%s: Releasing WR lock1 @ %d\n\r",
1126 __FUNCTION__, __LINE__);
1130 rte_rwlock_write_unlock(&rwlock);
1132 rte_eth_link_get(port_id, &linkstatus);
1133 if (linkstatus.link_status) {
1134 if (ifm_debug & IFM_DEBUG_CONFIG) {
1135 RTE_LOG(INFO, IFM, "%s: %u is up.Stop it before"
1136 " reconfiguring.\n\r", __FUNCTION__, port_id);
1138 rte_eth_dev_stop(port_id);
1140 /*Configure an Ethernet device. rets 0 on success queue */
1141 status = rte_eth_dev_configure(port_id, pconfig->nrx_queue,
1142 pconfig->ntx_queue, &pconfig->port_conf);
1144 ifm_remove_port_details(port_id);
1145 RTE_LOG(ERR, IFM, "%s: rte_eth_dev_configure is failed"
1146 "for port %u.\n\r", __FUNCTION__, port_id);
1149 status = rte_eth_dev_callback_register(port_id,
1150 RTE_ETH_EVENT_INTR_LSC,
1151 lsi_event_callback, NULL);
1153 ifm_remove_port_details(port_id);
1154 RTE_LOG(ERR, IFM, "%s: rte_eth_dev_callback_register()"
1155 " failed for port %u.\n\r", __FUNCTION__, port_id);
1158 /*promiscuous mode is enabled set it */
1159 if (pconfig->promisc)
1160 rte_eth_promiscuous_enable(port_id);
1162 sock = rte_eth_dev_socket_id(port_id);
1164 RTE_LOG(ERR, IFM, "%s: Warning: rte_eth_dev_socket_id,"
1166 "out of range %u\n\r", __FUNCTION__, port_id);
1167 /*Port initialization */
1169 for (ntxqs = 0; ntxqs < pconfig->ntx_queue; ntxqs++) {
1170 status = rte_eth_tx_queue_setup(port_id, ntxqs,
1171 IFM_TX_DESC_DEFAULT, sock,
1172 &(pconfig->tx_conf));
1174 ifm_remove_port_details(port_id);
1175 RTE_LOG(ERR, IFM, "%s: rte_eth_tx_queue_setup failed"
1176 " for port %u\n\r", __FUNCTION__, port_id);
1180 port = ifm_get_port(port_id);
1182 RTE_LOG(INFO, IFM, "%s: Port is NULL @ %d\n\r", __FUNCTION__,
1187 if (ifm_debug & IFM_DEBUG_LOCKS)
1188 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock 2 @ %d\n\r",
1189 __FUNCTION__, __LINE__);
1193 rte_rwlock_write_lock(&rwlock);
1195 if (port->tx_buf_len == 0) {
1196 port->tx_buf_len = RTE_ETH_TX_BUFFER_SIZE(IFM_BURST_SIZE);
1198 port->tx_buffer = rte_zmalloc_socket("tx_buffer", port->tx_buf_len, 0,
1199 rte_eth_dev_socket_id(port_id));
1201 if (port->tx_buffer == NULL) {
1202 ifm_remove_port_details(port_id);
1203 RTE_LOG(ERR, IFM, "%s: Failed to allocate tx buffers for"
1204 " port %u\n\r", __FUNCTION__, port_id);
1205 if (ifm_debug & IFM_DEBUG_LOCKS)
1206 RTE_LOG(INFO, IFM, "%s: Releasing WR lock2 %d\n\r",
1207 __FUNCTION__, __LINE__);
1211 rte_rwlock_write_unlock(&rwlock);
1214 rte_eth_tx_buffer_init(port->tx_buffer, IFM_BURST_SIZE);
1216 sprintf(buf, "MEMPOOL%d", port_id);
1217 port->mempool = rte_mempool_create(buf,
1218 pconfig->mempool.pool_size,
1219 pconfig->mempool.buffer_size,
1220 pconfig->mempool.cache_size,
1222 rte_pktmbuf_pool_private),
1223 rte_pktmbuf_pool_init, NULL,
1224 rte_pktmbuf_init, NULL, sock, 0);
1225 if (port->mempool == NULL) {
1226 ifm_remove_port_details(port_id);
1227 RTE_LOG(ERR, IFM, "%s: rte_mempool_create is failed for port"
1228 " %u. Error: %s\n\r",
1229 __FUNCTION__, port_id, rte_strerror(rte_errno));
1230 if (ifm_debug & IFM_DEBUG_LOCKS)
1231 RTE_LOG(INFO, IFM, "%s: Releasing WR lock2 %d\n\r",
1232 __FUNCTION__, __LINE__);
1236 rte_rwlock_write_unlock(&rwlock);
1240 for (nrxqs = 0; nrxqs < pconfig->nrx_queue; nrxqs++) {
1241 status = rte_eth_rx_queue_setup(port_id, nrxqs,
1242 IFM_RX_DESC_DEFAULT, sock,
1243 &(pconfig->rx_conf),
1246 ifm_remove_port_details(port_id);
1248 "%s: rte_eth_rx_queue_setup is failed "
1249 "for port %u queue %u. Error: %s\n\r",
1250 __FUNCTION__, port_id, nrxqs,
1251 rte_strerror(rte_errno));
1252 if (ifm_debug & IFM_DEBUG_LOCKS)
1254 "%s: Releasing WR lock2 %d\n\r",
1255 __FUNCTION__, __LINE__);
1259 rte_rwlock_write_unlock(&rwlock);
1264 if (ifm_debug & IFM_DEBUG_LOCKS)
1265 RTE_LOG(INFO, IFM, "%s: Releasing WR lock2 @ %d\n\r",
1266 __FUNCTION__, __LINE__);
1270 rte_rwlock_write_unlock(&rwlock);
1271 status = rte_eth_dev_start(port_id);
1273 ifm_remove_port_details(port_id);
1274 RTE_LOG(ERR, IFM, "%s: rte_eth_dev_start is failed for"
1275 " port %u.\n\r", __FUNCTION__, port_id);
1279 /*Get device info and populate interface structure */
1280 if (ifm_debug & IFM_DEBUG_LOCKS)
1281 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock3 @ %d\n\r",
1282 __FUNCTION__, __LINE__);
1286 rte_rwlock_write_lock(&rwlock);
1287 rte_eth_macaddr_get(port_id, (struct ether_addr *)port->macaddr);
1288 if (pconfig->promisc)
1290 rte_eth_link_get(port_id, &linkstatus);
1292 port->link_duplex = linkstatus.link_duplex;
1293 port->link_autoneg = linkstatus.link_autoneg;
1294 port->link_speed = linkstatus.link_speed;
1295 port->admin_status = pconfig->state;
1298 memset(&dev_info, 0, sizeof(dev_info));
1299 rte_eth_dev_info_get(port_id, &dev_info);
1300 port->min_rx_bufsize = dev_info.min_rx_bufsize;
1301 port->max_rx_pktlen = dev_info.max_rx_pktlen;
1302 port->max_rx_queues = dev_info.max_rx_queues;
1303 port->max_tx_queues = dev_info.max_tx_queues;
1304 rte_eth_dev_get_mtu(port_id, &(port->mtu));
1306 /*Add rx and tx packet function ptrs */
1307 port->retrieve_bulk_pkts = &ifm_receive_bulk_pkts;
1308 port->transmit_bulk_pkts = &ifm_transmit_bulk_pkts;
1309 port->transmit_single_pkt = &ifm_transmit_single_pkt;
1310 if (ifm_debug & IFM_DEBUG_LOCKS)
1311 RTE_LOG(INFO, IFM, "%s: Releasing WR3 lock @ %d\n\r",
1312 __FUNCTION__, __LINE__);
1316 rte_rwlock_write_unlock(&rwlock);
1317 RTE_LOG(INFO, IFM, "%s: Port %u is successfully configured.\n\r",
1318 __FUNCTION__, port_id);
1322 int ifm_configure_ports(port_config_t *pconfig)
1326 if (!ifm.nport_intialized) {
1327 RTE_LOG(ERR, IFM, "%s, Configuring ports failed. Zero ports "
1328 "are intialized during PCI probe", __FUNCTION__);
1331 if (pconfig == NULL) {
1332 RTE_LOG(ERR, IFM, "%s, Configuring ports failed. "
1333 "Param pconfig is NULL\n\r", __FUNCTION__);
1337 /*Initialize all ports */
1338 for (port_id = 0; port_id < ifm.nport_intialized; port_id++) {
1339 if (ifm_debug & IFM_DEBUG_CONFIG)
1340 RTE_LOG(INFO, IFM, "Call ifm_port_setup %u\n\r",
1343 ifm_port_setup(pconfig[port_id].port_id, &pconfig[port_id]);
1344 if (status == IFM_SUCCESS)
1345 ifm.nport_configured++;
1347 if (!ifm.nport_configured) {
1348 RTE_LOG(ERR, IFM, "%s: Zero ports are configured\n\r",
1352 RTE_LOG(INFO, IFM, "%s: Number of ports sucessfully configured:"
1353 " %d\n\r", __FUNCTION__, ifm.nport_configured);
1357 void print_interface_details(void)
1359 l2_phy_interface_t *port;
1361 struct sockaddr_in ip;
1364 if (ifm_debug & IFM_DEBUG_LOCKS)
1365 RTE_LOG(INFO, IFM, "%s: Acquiring RW lock @ %d\n\r",
1366 __FUNCTION__, __LINE__);
1370 rte_rwlock_read_lock(&rwlock);
1372 for (i = 0; i < RTE_MAX_ETHPORTS && ifm.port_list[i]; i++) {
1373 port = ifm.port_list[i];
1374 printf(" %u", port->pmdid);
1375 if (port->ifname && strlen(port->ifname)) {
1376 printf(" (%s)\t", port->ifname);
1379 printf("MAC:%02x:%02x:%02x:%02x:%02x:%02x Adminstate:%s"
1380 " Operstate:%s \n\r",
1381 port->macaddr[0], port->macaddr[1],
1382 port->macaddr[2], port->macaddr[3],
1383 port->macaddr[4], port->macaddr[5],
1384 port->admin_status ? "UP" : "DOWN",
1385 port->link_status ? "UP" : "DOWN");
1387 printf("Speed: %u, %s-duplex\n\r", port->link_speed,
1388 port->link_duplex ? "full" : "half");
1391 if (port->ipv4_list != NULL) {
1392 ip.sin_addr.s_addr =
1393 (unsigned long)((ipv4list_t *) (port->ipv4_list))->
1395 printf("IP: %s/%d", inet_ntoa(ip.sin_addr),
1396 ((ipv4list_t *) (port->ipv4_list))->addrlen);
1403 if (port->ipv6_list != NULL) {
1405 ((ipv6list_t *) (port->ipv6_list))->ipaddr;
1407 ("IPv6: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
1408 addr[0], addr[1], addr[2], addr[3], addr[4],
1409 addr[5], addr[6], addr[7], addr[8], addr[9],
1410 addr[10], addr[11], addr[12], addr[13], addr[14],
1416 if (port->flags & IFM_SLAVE) {
1417 printf(" IFM_SLAVE ");
1418 printf(" MasterPort: %u",
1419 port->bond_config->bond_portid);
1421 if (port->flags & IFM_MASTER) {
1422 printf(" IFM_MASTER ");
1423 printf(" Mode: %u", port->bond_config->mode);
1424 printf(" PrimaryPort: %u", port->bond_config->primary);
1426 printf("\t\tSlavePortCount: %u",
1427 port->bond_config->slave_count);
1428 printf(" SlavePorts:");
1430 for (i = 0; i < port->bond_config->slave_count; i++) {
1431 printf(" %u ", port->bond_config->slaves[i]);
1433 printf(" ActivePortCount: %u",
1434 port->bond_config->active_slave_count);
1435 printf(" ActivePorts:");
1436 for (i = 0; i < port->bond_config->active_slave_count;
1439 port->bond_config->active_slaves[i]);
1443 printf("Link_monitor_freq: %u ms ",
1444 port->bond_config->internal_ms);
1445 printf(" Link_up_prop_delay: %u ms ",
1446 port->bond_config->link_up_delay_ms);
1447 printf(" Link_down_prop_delay: %u ms ",
1448 port->bond_config->link_down_delay_ms);
1451 printf("Xmit_policy: %u",
1452 port->bond_config->xmit_policy);
1456 printf("n_rxpkts: %" PRIu64 " ,n_txpkts: %" PRIu64 " ,",
1457 port->n_rxpkts, port->n_txpkts);
1458 struct rte_eth_stats eth_stats;
1459 rte_eth_stats_get(port->pmdid, ð_stats);
1460 printf("pkts_in: %" PRIu64 " ,", eth_stats.ipackets);
1461 printf("pkts_out: %" PRIu64 " ", eth_stats.opackets);
1464 printf("in_errs: %" PRIu64 " ,", eth_stats.ierrors);
1465 printf("in_missed: %" PRIu64 " ,", eth_stats.imissed);
1466 printf("out_errs: %" PRIu64 " ,", eth_stats.oerrors);
1467 printf("mbuf_errs: %" PRIu64 " ", eth_stats.rx_nombuf);
1471 if (ifm_debug & IFM_DEBUG_LOCKS)
1472 RTE_LOG(INFO, IFM, "%s: Releasing RW lock @ %d\n\r",
1473 __FUNCTION__, __LINE__);
1477 rte_rwlock_read_unlock(&rwlock);