bd4c4e92453613f68c7a46457b47f48a3a3c34c5
[samplevnf.git] / common / VIL / l2l3_stack / interface.c
1 /*
2 // Copyright (c) 2017 Intel Corporation
3 //
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
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
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.
15 */
16 #include <interface.h>
17 #include <rte_byteorder.h>
18 #include <lib_arp.h>
19 #include <tsx.h>
20
21 interface_main_t ifm;
22 int USE_RTM_LOCKS = 0;
23 rte_rwlock_t rwlock;
24 uint8_t ifm_debug;
25 static int prev_state;
26
27 void config_ifm_debug(int dbg, int flag)
28 {
29         switch (dbg) {
30         case IFM_DEBUG_CONFIG:
31                 if (flag) {
32                         ifm_debug |= IFM_DEBUG_CONFIG;
33                 } else {
34                         ifm_debug &= ~IFM_DEBUG_CONFIG;
35                 }
36                 break;
37         case IFM_DEBUG_RXTX:
38                 if (flag) {
39                         ifm_debug |= IFM_DEBUG_RXTX;
40                 } else {
41                         ifm_debug &= ~IFM_DEBUG_RXTX;
42                 }
43                 break;
44         case IFM_DEBUG_LOCKS:
45                 if (flag) {
46                         ifm_debug |= IFM_DEBUG_LOCKS;
47                 } else {
48                         ifm_debug &= ~IFM_DEBUG_LOCKS;
49                 }
50                 break;
51         case IFM_DEBUG:
52                 if (flag) {
53                         ifm_debug |= IFM_DEBUG;
54                 } else {
55                         ifm_debug &= ~IFM_DEBUG;
56                 }
57                 break;
58         }
59 }
60
61 void ifm_init(void)
62 {
63         int i = 0;
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");
68                 USE_RTM_LOCKS = 0;
69         } else {
70                 if (ifm_debug & IFM_DEBUG_CONFIG)
71                         RTE_LOG(INFO, IFM, "TSX not supported\n\r");
72                 USE_RTM_LOCKS = 0;
73         }
74         if (USE_RTM_LOCKS)
75                 rtm_init();
76         else
77                 rte_rwlock_init(&rwlock);
78
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__);
83                 if (USE_RTM_LOCKS)
84                         rtm_lock();
85                 else
86                         rte_rwlock_write_lock(&rwlock);
87
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__);
92                 if (USE_RTM_LOCKS)
93                         rtm_unlock();
94                 else
95                         rte_rwlock_write_unlock(&rwlock);
96         }
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);
101 }
102
103 void ifm_remove_port_details(uint8_t portid)
104 {
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__);
109                 if (USE_RTM_LOCKS)
110                         rtm_lock();
111                 else
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);
118                 rte_free(port);
119                 if (ifm_debug & IFM_DEBUG_LOCKS)
120                         RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
121                                 __FUNCTION__, __LINE__);
122
123                 if (USE_RTM_LOCKS)
124                         rtm_unlock();
125                 else
126                         rte_rwlock_write_unlock(&rwlock);
127         } else {
128                 if (ifm_debug & IFM_DEBUG_LOCKS)
129                         RTE_LOG(INFO, IFM,
130                                 "%s: Failed to remove port details.Port %u info"
131                                 " is already Null.\n\r", __FUNCTION__, portid);
132         }
133 }
134
135 l2_phy_interface_t *ifm_get_port(uint8_t port_id)
136 {
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__,
140                         __LINE__);
141
142         if (USE_RTM_LOCKS)
143                 rtm_lock();
144         else
145                 rte_rwlock_read_lock(&rwlock);
146
147         port = ifm.port_list[port_id];
148
149         if (port == NULL) {
150                 /*RTE_LOG(ERR, IFM, "%s: Port %u info not found... configure it first.\n\r",
151                          __FUNCTION__, port_id);
152                  */
153                 if (ifm_debug & IFM_DEBUG_LOCKS)
154                         RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
155                                 __FUNCTION__, __LINE__);
156                 if (USE_RTM_LOCKS)
157                         rtm_unlock();
158                 else
159                         rte_rwlock_read_unlock(&rwlock);
160                 return NULL;
161         }
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__);
168
169                 if (USE_RTM_LOCKS)
170                         rtm_unlock();
171                 else
172                         rte_rwlock_read_unlock(&rwlock);
173                 return port;
174         } else {
175
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);
178 */
179         }
180         if (ifm_debug & IFM_DEBUG_LOCKS)
181                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
182                         __LINE__);
183         if (USE_RTM_LOCKS)
184                 rtm_unlock();
185         else
186                 rte_rwlock_read_unlock(&rwlock);
187         return NULL;
188 }
189
190 l2_phy_interface_t *ifm_get_first_port(void)
191 {
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__,
195                         __LINE__);
196
197         if (USE_RTM_LOCKS)
198                 rtm_lock();
199         else
200                 rte_rwlock_read_lock(&rwlock);
201         port = ifm.port_list[0];
202         if (port == NULL) {
203                 /*RTE_LOG(ERR, IFM, "%s: Port info not found... configure it first.\n\r",
204                          __FUNCTION__); */
205                 if (ifm_debug & IFM_DEBUG_LOCKS)
206                         RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
207                                 __FUNCTION__, __LINE__);
208                 if (USE_RTM_LOCKS)
209                         rtm_unlock();
210                 else
211                         rte_rwlock_read_unlock(&rwlock);
212                 return NULL;
213         }
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__,
218                         __LINE__);
219         if (USE_RTM_LOCKS)
220                 rtm_unlock();
221         else
222                 rte_rwlock_read_unlock(&rwlock);
223         return port;
224 }
225
226 l2_phy_interface_t *ifm_get_next_port(uint8_t port_id)
227 {
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__,
231                         __LINE__);
232         if (USE_RTM_LOCKS)
233                 rtm_lock();
234         else
235                 rte_rwlock_read_lock(&rwlock);
236         port = ifm.port_list[port_id + 1];
237         if (port == NULL) {
238                 if (ifm_debug & IFM_DEBUG_LOCKS)
239                         RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
240                                 __FUNCTION__, __LINE__);
241                 if (USE_RTM_LOCKS)
242                         rtm_unlock();
243                 else
244                         rte_rwlock_read_unlock(&rwlock);
245                 return NULL;
246         }
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__,
251                         __LINE__);
252
253         if (USE_RTM_LOCKS)
254                 rtm_unlock();
255         else
256                 rte_rwlock_read_unlock(&rwlock);
257         return port;
258 }
259
260 l2_phy_interface_t *ifm_get_port_by_name(const char *name)
261 {
262         l2_phy_interface_t *port = NULL;
263         int i;
264         if (ifm_debug & IFM_DEBUG_LOCKS)
265                 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
266                         __LINE__);
267
268         if (USE_RTM_LOCKS)
269                 rtm_lock();
270         else
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)
279                                 RTE_LOG(INFO, IFM,
280                                         "%s: Releasing lock @ %d\n\r",
281                                         __FUNCTION__, __LINE__);
282                         if (USE_RTM_LOCKS)
283                                 rtm_unlock();
284                         else
285                                 rte_rwlock_read_unlock(&rwlock);
286                         return port;
287                 }
288         }
289         if (ifm_debug & IFM_DEBUG_LOCKS)
290                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
291                         __LINE__);
292         if (USE_RTM_LOCKS)
293                 rtm_unlock();
294         else
295                 rte_rwlock_read_unlock(&rwlock);
296         return NULL;
297 }
298
299 void lsi_event_callback(uint8_t port_id, enum rte_eth_event_type type,
300                         void *param)
301 {
302         struct rte_eth_link link;
303         l2_phy_interface_t *port;
304         int nclients = ifm.nclient;
305         int i;
306
307         RTE_SET_USED(param);
308         RTE_SET_USED(type);
309
310         if (ifm_debug & IFM_DEBUG_LOCKS)
311                 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
312                         __FUNCTION__, __LINE__);
313         if (USE_RTM_LOCKS) {
314                 rtm_lock();
315         } else {
316                 rte_rwlock_write_lock(&rwlock);
317         }
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];
322         if (port == NULL) {
323                 RTE_LOG(ERR, IFM,
324                         "%s: Port %u info not found... configure it first.\n\r",
325                         __FUNCTION__, port_id);
326         }
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;
332                         RTE_LOG(INFO, IFM,
333                                 "EVENT-- PORT %u Link UP - Speed %u Mbps - %s.\n",
334                                 port_id, (unsigned)link.link_speed,
335                                 (link.link_duplex ==
336                                  ETH_LINK_FULL_DUPLEX) ? ("full-duplex")
337                                 : ("half-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,
342                                                                          port->
343                                                                          bond_config->
344                                                                          active_slaves,
345                                                                          RTE_MAX_ETHPORTS);
346                                 struct ether_addr new_mac;
347                                 rte_eth_macaddr_get(port->pmdid,
348                                                                 (struct ether_addr *)
349                                                                 &new_mac);
350                                 if (memcmp
351                                                 (&new_mac, port->macaddr,
352                                                  sizeof(struct ether_addr))) {
353                                         RTE_LOG(INFO, IFM,
354                                                 "Bond port %u MAC has changed.\n\r",
355                                                 port->pmdid);
356                                 } else {
357                                         RTE_LOG(INFO, IFM,
358                                                 "Bond port %u MAC remains same\n\r",
359                                                 port->pmdid);
360                                 }
361                         }
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);
369                         }
370                         if (ifm_debug & IFM_DEBUG_LOCKS)
371                                 RTE_LOG(INFO, IFM,
372                                         "%s: Releasing WR lock @ %d\n\r",
373                                         __FUNCTION__, __LINE__);
374
375                         if (USE_RTM_LOCKS) {
376                                 rtm_unlock();
377                         } else {
378                                 rte_rwlock_write_unlock(&rwlock);
379                         }
380                         if (port->ipv4_list != NULL) {
381                                 if (ifm_debug & IFM_DEBUG_CONFIG)
382                                         RTE_LOG(INFO, IFM,
383                                                 "Sending garp on port %u\n\r",
384                                                 port->pmdid);
385                                 if (!prev_state) {
386                                         send_gratuitous_arp(port);
387                                         prev_state = 1;
388                                 }
389                         }
390 #if 0
391                         else {
392                                 if (ifm_debug & IFM_DEBUG_CONFIG)
393                                         RTE_LOG(INFO, IFM,
394                                                 "IP is not enabled on port %u, not sending GARP\n\r",
395                                                 port->pmdid);
396                         }
397 #endif
398                 } else {
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);
402                         }
403                         port->link_status = IFM_ETH_LINK_DOWN;
404                         RTE_LOG(INFO, IFM, "EVENT-- PORT %u is Link DOWN.\n",
405                                 port_id);
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,
411                                                         &linkstatus);
412                                 RTE_LOG(INFO, IFM,
413                                         "Port %u 's Master(%u) status is %u\n\r",
414                                         port_id, master_portid,
415                                         linkstatus.link_status);
416                         }
417                         if (ifm_debug & IFM_DEBUG_LOCKS)
418                                 RTE_LOG(INFO, IFM,
419                                         "%s: Releasing WR lock @ %d\n\r",
420                                         __FUNCTION__, __LINE__);
421                         if (USE_RTM_LOCKS) {
422                                 rtm_unlock();
423                         } else {
424                                 rte_rwlock_write_unlock(&rwlock);
425                         }
426                         prev_state = 0;
427                 }
428         }
429         //print_interface_details();
430 }
431
432 void ifm_update_linkstatus(uint8_t port_id, uint16_t linkstatus)
433 {
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__,
438                         __LINE__);
439
440         if (USE_RTM_LOCKS) {
441                 rtm_lock();
442         } else {
443                 rte_rwlock_write_lock(&rwlock);
444         }
445         port = ifm.port_list[port_id];
446
447         if (port == NULL) {
448                 RTE_LOG(ERR, IFM,
449                         "%s: Port %u info not found... configure it first.\n\r",
450                         __FUNCTION__, port_id);
451         }
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) {
458                                         RTE_LOG(INFO, IFM,
459                                                         "%s:Port %u admin up is unsuccessful\n\r",
460                                                         __FUNCTION__, port->pmdid);
461                                 } else {
462                                         if (ifm_debug & IFM_DEBUG_LOCKS)
463                                                 RTE_LOG(INFO, IFM,
464                                                                 "%s: Releasing lock @ %d\n\r",
465                                                                 __FUNCTION__, __LINE__);
466
467                                         if (USE_RTM_LOCKS) {
468                                                 rtm_unlock();
469                                         } else {
470                                                 rte_rwlock_write_unlock(&rwlock);
471                                         }
472                                         if (ifm_debug & IFM_DEBUG_CONFIG)
473                                                 RTE_LOG(INFO, IFM,
474                                                                 "%s:Port %u admin up...\n\r",
475                                                                 __FUNCTION__, port->pmdid);
476                                         send_gratuitous_arp(port);
477                                         return;
478                                 }
479                         }
480                 } else if (linkstatus == IFM_ETH_LINK_DOWN)
481                 {
482                         int status;
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);
487                                 if (status < 0)
488                                 {
489                                         printf("(%" PRIu32 "): PMD set link down... continuing...%"
490                                                         PRId32 "\n", port_id, status);
491                                 }
492                         }
493                 }
494         }
495         if (ifm_debug & IFM_DEBUG_LOCKS)
496                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
497                         __LINE__);
498
499         if (USE_RTM_LOCKS) {
500                 rtm_unlock();
501         } else {
502                 rte_rwlock_write_unlock(&rwlock);
503         }
504 }
505
506 void ifm_set_l2_interface_mtu(uint8_t port_id, uint16_t mtu)
507 {
508         int ret;
509         l2_phy_interface_t *port;
510         port = ifm.port_list[port_id];
511         if (port == NULL) {
512                 RTE_LOG(ERR, IFM,
513                         "%s: Port %u info not found... configure it first.\n\r",
514                         __FUNCTION__, port_id);
515         }
516
517         if (port != NULL && port->pmdid == port_id) {
518                 ret = rte_eth_dev_set_mtu(port_id, mtu);
519                 if (ret != 0)
520                         RTE_LOG(INFO, IFM,
521                                 "set_l2_interface_mtu: Set MTU failed. ret=%d\n",
522                                 ret);
523                 else {
524                         if (ifm_debug & IFM_DEBUG_LOCKS)
525                                 RTE_LOG(INFO, IFM,
526                                         "%s: Acquiring lock @ %d\n\r",
527                                         __FUNCTION__, __LINE__);
528
529                         if (USE_RTM_LOCKS) {
530                                 rtm_lock();
531                         } else {
532                                 rte_rwlock_write_lock(&rwlock);
533                         }
534                         port->mtu = mtu;
535                         if (ifm_debug & IFM_DEBUG_LOCKS)
536                                 RTE_LOG(INFO, IFM,
537                                         "%s: Releasing lock @ %d\n\r",
538                                         __FUNCTION__, __LINE__);
539
540                         if (USE_RTM_LOCKS) {
541                                 rtm_unlock();
542                         } else {
543                                 rte_rwlock_write_unlock(&rwlock);
544                         }
545                         return;
546                 }
547         }
548 }
549
550 void ifm_set_port_promisc(uint8_t port_id, uint8_t enable)
551 {
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__);
556         if (USE_RTM_LOCKS) {
557                 rtm_lock();
558         } else {
559                 rte_rwlock_write_lock(&rwlock);
560         }
561         port = ifm.port_list[port_id];
562         if (port == NULL) {
563                 RTE_LOG(ERR, IFM,
564                         "%s: Port %u info not found... configure it first.\n\r",
565                         __FUNCTION__, port_id);
566         }
567         if (port != NULL && port->pmdid == port_id) {
568                 if (enable == 1) {
569                         rte_eth_promiscuous_enable(port_id);
570                         port->promisc = 1;
571                 } else {
572                         rte_eth_promiscuous_disable(port_id);
573                         port->promisc = 0;
574                 }
575         }
576         if (ifm_debug & IFM_DEBUG_LOCKS)
577                 RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
578                         __FUNCTION__, __LINE__);
579         if (USE_RTM_LOCKS) {
580                 rtm_unlock();
581         } else {
582                 rte_rwlock_write_unlock(&rwlock);
583         }
584 }
585
586 int32_t ifm_get_nactive_ports(void)
587 {
588         return ifm.nport_configured;
589 }
590
591 int32_t ifm_get_nports_initialized(void)
592 {
593         return ifm.nport_intialized;
594 }
595
596 uint16_t ifm_receive_bulk_pkts(uint8_t port_id, uint16_t qid,
597                                                  struct rte_mbuf **rx_pkts)
598 {
599         uint64_t no_of_rcvd_pkt;
600         no_of_rcvd_pkt =
601                         rte_eth_rx_burst(port_id, qid, rx_pkts, IFM_BURST_SIZE);
602         if (ifm_debug & IFM_DEBUG_RXTX)
603                 RTE_LOG(INFO, IFM,
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;
607 }
608
609 uint16_t ifm_transmit_bulk_pkts(l2_phy_interface_t *port,
610                                 struct rte_mbuf **tx_pkts, uint64_t npkts)
611 {
612         uint32_t burst_tx_delay_time = IFM_BURST_TX_WAIT_US;
613         uint32_t burst_tx_retry_num = IFM_BURST_TX_RETRIES;
614         uint32_t retry;
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__);
619         if (USE_RTM_LOCKS) {
620                 rtm_lock();
621         } else {
622                 rte_rwlock_read_lock(&rwlock);
623         }
624         no_of_tx_pkt = rte_eth_tx_burst(port->pmdid, IFM_TX_DEFAULT_Q, tx_pkts,
625                                         npkts);
626         if (unlikely(no_of_tx_pkt < npkts)) {
627                 retry = 0;
628                 while (no_of_tx_pkt < IFM_BURST_SIZE
629                                          && retry++ < burst_tx_retry_num) {
630                         rte_delay_us(burst_tx_delay_time);
631                         no_of_tx_pkt =
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);
635                 }
636         }
637         if (ifm_debug & IFM_DEBUG_RXTX)
638                 RTE_LOG(INFO, IFM,
639                         "ifm_transmit_bulk_pkts: no_of_tx_pkt %u\n\r",
640                         no_of_tx_pkt);
641         if (ifm_debug & IFM_DEBUG_LOCKS)
642                 RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
643                         __FUNCTION__, __LINE__);
644         if (USE_RTM_LOCKS) {
645                 rtm_unlock();
646         } else {
647                 rte_rwlock_read_unlock(&rwlock);
648         }
649         return no_of_tx_pkt;
650 }
651
652 int ifm_transmit_single_pkt(l2_phy_interface_t *port, struct rte_mbuf *tx_pkts)
653 {
654         uint64_t tx_npkts = 0;
655         if (tx_pkts == NULL || port == NULL) {
656                 RTE_LOG(INFO, IFM,
657                         "ifm_transmit_single_pkt: tx_pkts and port are NULL ");
658                 return IFM_FAILURE;
659         }
660         if (ifm_debug & IFM_DEBUG_RXTX)
661                 RTE_LOG(INFO, IFM,
662                         "ifm_transmit_single_pkt: port->pmdid %u\n\r",
663                         port->pmdid);
664         if (ifm_debug & IFM_DEBUG_LOCKS)
665                 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
666                         __FUNCTION__, __LINE__);
667
668         if (USE_RTM_LOCKS) {
669                 rtm_lock();
670         } else {
671                 rte_rwlock_read_lock(&rwlock);
672         }
673         tx_npkts =
674                         rte_eth_tx_buffer(port->pmdid, IFM_TX_DEFAULT_Q, port->tx_buffer,
675                                                 tx_pkts);
676         if (ifm_debug & IFM_DEBUG_RXTX)
677                 RTE_LOG(INFO, IFM,
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__);
683
684         if (USE_RTM_LOCKS) {
685                 rtm_unlock();
686         } else {
687                 rte_rwlock_read_unlock(&rwlock);
688         }
689         if (ifm_debug & IFM_DEBUG_LOCKS)
690                 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
691                         __FUNCTION__, __LINE__);
692
693         if (USE_RTM_LOCKS) {
694                 rtm_lock();
695         } else {
696                 rte_rwlock_write_lock(&rwlock);
697         }
698         port->n_txpkts +=
699                         rte_eth_tx_buffer_flush(port->pmdid, IFM_TX_DEFAULT_Q,
700                                                 port->tx_buffer);
701         if (ifm_debug & IFM_DEBUG_LOCKS)
702                 RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
703                         __FUNCTION__, __LINE__);
704
705         if (USE_RTM_LOCKS) {
706                 rtm_unlock();
707         } else {
708                 rte_rwlock_write_unlock(&rwlock);
709         }
710         if (ifm_debug & IFM_DEBUG_RXTX)
711                 RTE_LOG(INFO, IFM,
712                         "ifm_transmit_single_pkt: no of pkts flushed %lu\n\r",
713                         port->n_txpkts);
714         return tx_npkts;
715 }
716
717 int16_t ifm_add_ipv4_port(uint8_t port_id, uint32_t ipaddr, uint32_t addrlen)
718 {
719         l2_phy_interface_t *port;
720         ipv4list_t *ipconf;
721         if (ifm_debug & IFM_DEBUG_LOCKS)
722                 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
723                         __LINE__);
724
725         if (USE_RTM_LOCKS) {
726                 rtm_lock();
727         } else {
728                 rte_rwlock_write_lock(&rwlock);
729         }
730         port = ifm.port_list[port_id];
731         if (port == NULL) {
732                 RTE_LOG(ERR, IFM,
733                         "%s: Port %u info not found... configure it first.\n\r",
734                         __FUNCTION__, port_id);
735         }
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) {
740                         ipconf->next = NULL;
741                         //ipconf->ipaddr = rte_bswap32(ipaddr);
742                         ipconf->ipaddr = ipaddr;
743                         ipconf->port = port;
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)
750                                 RTE_LOG(INFO, IFM,
751                                         "%s: Releasing lock @ %d\n\r",
752                                         __FUNCTION__, __LINE__);
753
754                         if (USE_RTM_LOCKS) {
755                                 rtm_unlock();
756                         } else {
757                                 rte_rwlock_write_unlock(&rwlock);
758                         }
759                         return 0;
760                 }
761         }
762         if (ifm_debug & IFM_DEBUG_LOCKS)
763                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
764                         __LINE__);
765
766         if (USE_RTM_LOCKS) {
767                 rtm_unlock();
768         } else {
769                 rte_rwlock_write_unlock(&rwlock);
770         }
771         return -1;
772 }
773
774 int16_t ifm_remove_ipv4_port(uint8_t port_id, uint32_t ipaddr,
775                                                 uint32_t addrlen)
776 {
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__,
781                         __LINE__);
782
783         if (USE_RTM_LOCKS) {
784                 rtm_lock();
785         } else {
786                 rte_rwlock_write_lock(&rwlock);
787         }
788         port = ifm.port_list[port_id];
789         if (port == NULL) {
790                 RTE_LOG(ERR, IFM,
791                         "%s: Port %u info not found... configure it first.\n\r",
792                         __FUNCTION__, port_id);
793         }
794         if (port != NULL && port->pmdid == port_id) {
795                 if (port->ipv4_list == NULL) {
796                         if (ifm_debug & IFM_DEBUG_LOCKS)
797                                 RTE_LOG(INFO, IFM,
798                                         "%s: Releasing lock @ %d\n\r",
799                                         __FUNCTION__, __LINE__);
800
801                         if (USE_RTM_LOCKS) {
802                                 rtm_unlock();
803                         } else {
804                                 rte_rwlock_write_unlock(&rwlock);
805                         }
806                         return -1;
807                 }
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;
814                                 } else {
815                                         if (previplist != NULL)
816                                                 previplist->next = iplist->next;
817                                 }
818                                 port->flags &= ~IFM_IPV4_ENABLED;
819                                 rte_free(iplist);
820                                 if (ifm_debug & IFM_DEBUG_LOCKS)
821                                         RTE_LOG(INFO, IFM,
822                                                 "%s: Releasing lock @ %d\n\r",
823                                                 __FUNCTION__, __LINE__);
824
825                                 if (USE_RTM_LOCKS) {
826                                         rtm_unlock();
827                                 } else {
828                                         rte_rwlock_write_unlock(&rwlock);
829                                 }
830                                 return 0;
831                         } else {
832                                 previplist = iplist;
833                                 iplist = iplist->next;
834                         }
835                 }
836         }
837         if (ifm_debug & IFM_DEBUG_LOCKS)
838                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
839                         __LINE__);
840
841         if (USE_RTM_LOCKS) {
842                 rtm_unlock();
843         } else {
844                 rte_rwlock_write_unlock(&rwlock);
845         }
846         return -1;
847 }
848
849 int8_t ifm_add_ipv6_port(uint8_t port_id, uint8_t ip6addr[], uint32_t addrlen)
850 {
851         l2_phy_interface_t *port;
852         ipv6list_t *ip6conf;
853         if (ifm_debug & IFM_DEBUG_LOCKS)
854                 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
855                         __LINE__);
856
857         if (USE_RTM_LOCKS) {
858                 rtm_lock();
859         } else {
860                 rte_rwlock_write_lock(&rwlock);
861         }
862         port = ifm.port_list[port_id];
863         if (port == NULL) {
864                 RTE_LOG(ERR, IFM,
865                         "%s: Port %u info not found... configure it first.\n\r",
866                         __FUNCTION__, port_id);
867         }
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;
876
877                         if (port->ipv6_list == NULL) {
878                                 port->flags |= IFM_IPV6_ENABLED;
879                         }
880                         ip6conf->next = (ipv6list_t *) port->ipv6_list;
881                         port->ipv6_list = (ipv6list_t *) ip6conf;
882                         if (ifm_debug & IFM_DEBUG_LOCKS)
883                                 RTE_LOG(INFO, IFM,
884                                         "%s: Releasing lock @ %d\n\r",
885                                         __FUNCTION__, __LINE__);
886
887                         if (USE_RTM_LOCKS) {
888                                 rtm_unlock();
889                         } else {
890                                 rte_rwlock_write_unlock(&rwlock);
891                         }
892                         return 0;
893                 }
894         }
895         if (ifm_debug & IFM_DEBUG_LOCKS)
896                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
897                         __LINE__);
898
899         if (USE_RTM_LOCKS) {
900                 rtm_unlock();
901         } else {
902                 rte_rwlock_write_unlock(&rwlock);
903         }
904         return -1;
905 }
906
907 int16_t ifm_remove_ipv6_port(uint8_t port_id, uint32_t ip6addr,
908                                                 uint32_t addrlen)
909 {
910         l2_phy_interface_t *port;
911         ipv6list_t *ip6list, *previp6list = NULL;
912
913         if (ifm_debug & IFM_DEBUG_LOCKS)
914                 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
915                         __LINE__);
916         if (USE_RTM_LOCKS)
917                 rtm_lock();
918         else
919                 rte_rwlock_write_lock(&rwlock);
920         port = ifm.port_list[port_id];
921         if (port == NULL) {
922                 if (ifm_debug & IFM_DEBUG_LOCKS)
923                         RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
924                                 __FUNCTION__, __LINE__);
925                 if (USE_RTM_LOCKS) {
926                         rtm_unlock();
927                 } else {
928                         rte_rwlock_write_unlock(&rwlock);
929                 }
930                 RTE_LOG(ERR, IFM,
931                         "%s: Port %u info not found... configure it first.\n\r",
932                         __FUNCTION__, port_id);
933         }
934         if (port != NULL && port->pmdid == port_id) {
935                 if (port->ipv6_list == NULL) {
936                         if (ifm_debug & IFM_DEBUG_LOCKS)
937                                 RTE_LOG(INFO, IFM,
938                                         "%s: Releasing lock @ %d\n\r",
939                                         __FUNCTION__, __LINE__);
940
941                         if (USE_RTM_LOCKS) {
942                                 rtm_unlock();
943                         } else {
944                                 rte_rwlock_write_unlock(&rwlock);
945                         }
946                         return -1;
947                 }
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;
954                                 } else {
955                                         if (previp6list != NULL)
956                                                 previp6list->next =
957                                                                 ip6list->next;
958                                 }
959                                 port->flags &= ~IFM_IPV6_ENABLED;
960                                 rte_free(ip6list);
961                                 if (ifm_debug & IFM_DEBUG_LOCKS)
962                                         RTE_LOG(INFO, IFM,
963                                                 "%s: Releasing lock @ %d\n\r",
964                                                 __FUNCTION__, __LINE__);
965
966                                 if (USE_RTM_LOCKS) {
967                                         rtm_unlock();
968                                 } else {
969                                         rte_rwlock_write_unlock(&rwlock);
970                                 }
971                                 return 0;
972                         } else {
973                                 previp6list = ip6list;
974                                 ip6list = ip6list->next;
975                         }
976                 }
977         }
978         if (ifm_debug & IFM_DEBUG_LOCKS)
979                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
980                         __LINE__);
981         if (USE_RTM_LOCKS)
982                 rtm_unlock();
983         else
984                 rte_rwlock_write_unlock(&rwlock);
985         return -1;
986 }
987
988 int32_t ifm_chk_port_ipv4_enabled(uint8_t port_id)
989 {
990         l2_phy_interface_t *port;
991
992         if (ifm_debug & IFM_DEBUG_LOCKS)
993                 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
994                         __FUNCTION__, __LINE__);
995         if (USE_RTM_LOCKS)
996                 rtm_lock();
997         else
998                 rte_rwlock_read_lock(&rwlock);
999         port = ifm.port_list[port_id];
1000         if (port == NULL) {
1001                 RTE_LOG(ERR, IFM,
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__);
1007                 if (USE_RTM_LOCKS)
1008                         rtm_unlock();
1009                 else
1010                         rte_rwlock_read_unlock(&rwlock);
1011                 return IFM_FAILURE;
1012         }
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__);
1017                 if (USE_RTM_LOCKS)
1018                         rtm_unlock();
1019                 else
1020                         rte_rwlock_read_unlock(&rwlock);
1021                 return 0;
1022         } else {
1023                 if (ifm_debug & IFM_DEBUG_LOCKS)
1024                         RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
1025                                 __FUNCTION__, __LINE__);
1026                 if (USE_RTM_LOCKS)
1027                         rtm_unlock();
1028                 else
1029                         rte_rwlock_read_unlock(&rwlock);
1030                 return 1;
1031         }
1032 }
1033
1034 int32_t ifm_chk_port_ipv6_enabled(uint8_t port_id)
1035 {
1036         l2_phy_interface_t *port;
1037
1038         if (ifm_debug & IFM_DEBUG_LOCKS)
1039                 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
1040                         __FUNCTION__, __LINE__);
1041         if (USE_RTM_LOCKS)
1042                 rtm_lock();
1043         else
1044                 rte_rwlock_read_lock(&rwlock);
1045
1046         port = ifm.port_list[port_id];
1047         if (port == NULL) {
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__);
1055                 if (USE_RTM_LOCKS)
1056                         rtm_unlock();
1057                 else
1058                         rte_rwlock_read_unlock(&rwlock);
1059                 return IFM_FAILURE;
1060         }
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__);
1065                 if (USE_RTM_LOCKS)
1066                         rtm_unlock();
1067                 else
1068                         rte_rwlock_read_unlock(&rwlock);
1069                 return 0;
1070         } else {
1071                 if (ifm_debug & IFM_DEBUG_LOCKS)
1072                         RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
1073                                 __FUNCTION__, __LINE__);
1074                 if (USE_RTM_LOCKS)
1075                         rtm_unlock();
1076                 else
1077                         rte_rwlock_read_unlock(&rwlock);
1078                 return 1;
1079         }
1080 }
1081
1082 void ifm_register_for_linkupdate(uint32_t clientid,
1083                                  void (*cb_linkupdate) (uint8_t, unsigned int))
1084 {
1085         ifm.if_client[ifm.nclient].cb_linkupdate = cb_linkupdate;
1086         ifm.if_client[ifm.nclient].clientid = clientid;
1087         ifm.nclient++;
1088 }
1089
1090 int ifm_port_setup(uint8_t port_id, port_config_t *pconfig)
1091 {
1092         int status, sock;
1093         char buf[12];
1094         struct rte_eth_dev_info dev_info;
1095         struct rte_eth_link linkstatus;
1096         l2_phy_interface_t *port = NULL;
1097
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);
1102                 return IFM_FAILURE;
1103         }
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__);
1111         if (USE_RTM_LOCKS)
1112                 rtm_lock();
1113         else
1114                 rte_rwlock_write_lock(&rwlock);
1115
1116         if (ifm.port_list[port_id] == NULL) {
1117                 ifm.port_list[port_id] =
1118                                 (l2_phy_interface_t *) rte_zmalloc(NULL,
1119                                                                          sizeof
1120                                                                          (l2_phy_interface_t),
1121                                                                          RTE_CACHE_LINE_SIZE);
1122                 ifm.port_list[port_id]->pmdid = port_id;
1123         }
1124         if (ifm_debug & IFM_DEBUG_LOCKS)
1125                 RTE_LOG(INFO, IFM, "%s: Releasing WR lock1 @ %d\n\r",
1126                         __FUNCTION__, __LINE__);
1127         if (USE_RTM_LOCKS)
1128                 rtm_unlock();
1129         else
1130                 rte_rwlock_write_unlock(&rwlock);
1131
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);
1137                 }
1138                 rte_eth_dev_stop(port_id);
1139         }
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);
1143         if (status < 0) {
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);
1147                 return IFM_FAILURE;
1148         }
1149         status = rte_eth_dev_callback_register(port_id,
1150                                                                  RTE_ETH_EVENT_INTR_LSC,
1151                                                                  lsi_event_callback, NULL);
1152         if (status < 0) {
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);
1156                 return IFM_FAILURE;
1157         }
1158         /*promiscuous mode is enabled set it */
1159         if (pconfig->promisc)
1160                 rte_eth_promiscuous_enable(port_id);
1161
1162         sock = rte_eth_dev_socket_id(port_id);
1163         if (sock == -1)
1164                 RTE_LOG(ERR, IFM, "%s: Warning: rte_eth_dev_socket_id,"
1165                         " port_id value is"
1166                         "out of range %u\n\r", __FUNCTION__, port_id);
1167         /*Port initialization */
1168         int ntxqs;
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));
1173                 if (status < 0) {
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);
1177                         return IFM_FAILURE;
1178                 }
1179         }
1180         port = ifm_get_port(port_id);
1181         if (port == NULL) {
1182                 RTE_LOG(INFO, IFM, "%s: Port is NULL @ %d\n\r", __FUNCTION__,
1183                         __LINE__);
1184                 return IFM_FAILURE;
1185         }
1186
1187         if (ifm_debug & IFM_DEBUG_LOCKS)
1188                 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock 2 @ %d\n\r",
1189                         __FUNCTION__, __LINE__);
1190         if (USE_RTM_LOCKS)
1191                 rtm_lock();
1192         else
1193                 rte_rwlock_write_lock(&rwlock);
1194
1195         if (port->tx_buf_len == 0) {
1196                 port->tx_buf_len = RTE_ETH_TX_BUFFER_SIZE(IFM_BURST_SIZE);
1197         }
1198         port->tx_buffer = rte_zmalloc_socket("tx_buffer", port->tx_buf_len, 0,
1199                                                          rte_eth_dev_socket_id(port_id));
1200
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__);
1208                 if (USE_RTM_LOCKS)
1209                         rtm_unlock();
1210                 else
1211                         rte_rwlock_write_unlock(&rwlock);
1212                 return IFM_FAILURE;
1213         }
1214         rte_eth_tx_buffer_init(port->tx_buffer, IFM_BURST_SIZE);
1215
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,
1221                                                  sizeof(struct
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__);
1233                 if (USE_RTM_LOCKS)
1234                         rtm_unlock();
1235                 else
1236                         rte_rwlock_write_unlock(&rwlock);
1237                 return IFM_FAILURE;
1238         }
1239         int nrxqs;
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),
1244                                                 port->mempool);
1245                 if (status < 0) {
1246                         ifm_remove_port_details(port_id);
1247                         RTE_LOG(ERR, IFM,
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)
1253                                 RTE_LOG(INFO, IFM,
1254                                         "%s: Releasing WR lock2 %d\n\r",
1255                                         __FUNCTION__, __LINE__);
1256                         if (USE_RTM_LOCKS)
1257                                 rtm_unlock();
1258                         else
1259                                 rte_rwlock_write_unlock(&rwlock);
1260                         return IFM_FAILURE;
1261                 }
1262         }
1263         /*Start link */
1264         if (ifm_debug & IFM_DEBUG_LOCKS)
1265                 RTE_LOG(INFO, IFM, "%s: Releasing WR lock2  @ %d\n\r",
1266                         __FUNCTION__, __LINE__);
1267         if (USE_RTM_LOCKS)
1268                 rtm_unlock();
1269         else
1270                 rte_rwlock_write_unlock(&rwlock);
1271         status = rte_eth_dev_start(port_id);
1272         if (status < 0) {
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);
1276                 return IFM_FAILURE;
1277         }
1278         rte_delay_ms(5000);
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__);
1283         if (USE_RTM_LOCKS)
1284                 rtm_lock();
1285         else
1286                 rte_rwlock_write_lock(&rwlock);
1287         rte_eth_macaddr_get(port_id, (struct ether_addr *)port->macaddr);
1288         if (pconfig->promisc)
1289                 port->promisc = 1;
1290         rte_eth_link_get(port_id, &linkstatus);
1291         /*Link status */
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;
1296
1297         /*Get dev_info */
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));
1305
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__);
1313         if (USE_RTM_LOCKS)
1314                 rtm_unlock();
1315         else
1316                 rte_rwlock_write_unlock(&rwlock);
1317         RTE_LOG(INFO, IFM, "%s: Port %u is successfully configured.\n\r",
1318                 __FUNCTION__, port_id);
1319         return IFM_SUCCESS;
1320 }
1321
1322 int ifm_configure_ports(port_config_t *pconfig)
1323 {
1324         uint8_t port_id;
1325         int status = 0;
1326         if (!ifm.nport_intialized) {
1327                 RTE_LOG(ERR, IFM, "%s, Configuring ports failed. Zero ports "
1328                         "are intialized during PCI probe", __FUNCTION__);
1329                 return IFM_FAILURE;
1330         }
1331         if (pconfig == NULL) {
1332                 RTE_LOG(ERR, IFM, "%s, Configuring ports failed. "
1333                         "Param pconfig is NULL\n\r", __FUNCTION__);
1334                 return IFM_FAILURE;
1335         }
1336
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",
1341                                 port_id);
1342                 status =
1343                                 ifm_port_setup(pconfig[port_id].port_id, &pconfig[port_id]);
1344                 if (status == IFM_SUCCESS)
1345                         ifm.nport_configured++;
1346         }
1347         if (!ifm.nport_configured) {
1348                 RTE_LOG(ERR, IFM, "%s: Zero ports are configured\n\r",
1349                         __FUNCTION__);
1350                 return IFM_FAILURE;
1351         }
1352         RTE_LOG(INFO, IFM, "%s: Number of ports sucessfully configured:"
1353                 " %d\n\r", __FUNCTION__, ifm.nport_configured);
1354         return IFM_SUCCESS;
1355 }
1356
1357 void print_interface_details(void)
1358 {
1359         l2_phy_interface_t *port;
1360         int i = 0;
1361         struct sockaddr_in ip;
1362         printf("\n\r");
1363
1364         if (ifm_debug & IFM_DEBUG_LOCKS)
1365                 RTE_LOG(INFO, IFM, "%s: Acquiring RW lock @ %d\n\r",
1366                         __FUNCTION__, __LINE__);
1367         if (USE_RTM_LOCKS)
1368                 rtm_lock();
1369         else
1370                 rte_rwlock_read_lock(&rwlock);
1371
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);
1377                 } else
1378                         printf("\t\t");
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");
1386                 printf("\t\t");
1387                 printf("Speed: %u, %s-duplex\n\r", port->link_speed,
1388                                          port->link_duplex ? "full" : "half");
1389                 printf("\t\t");
1390
1391                 if (port->ipv4_list != NULL) {
1392                         ip.sin_addr.s_addr =
1393                                         (unsigned long)((ipv4list_t *) (port->ipv4_list))->
1394                                         ipaddr;
1395                         printf("IP: %s/%d", inet_ntoa(ip.sin_addr),
1396                                                  ((ipv4list_t *) (port->ipv4_list))->addrlen);
1397                 } else {
1398                         printf("IP: NA");
1399                 }
1400
1401                 printf("\r\n");
1402                 printf("\t\t");
1403                 if (port->ipv6_list != NULL) {
1404                         uint8_t *addr =
1405                                         ((ipv6list_t *) (port->ipv6_list))->ipaddr;
1406                         printf
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],
1411                                          addr[15]);
1412                 } else {
1413                         printf("IPv6: NA");
1414                 }
1415
1416                 if (port->flags & IFM_SLAVE) {
1417                         printf("  IFM_SLAVE ");
1418                         printf(" MasterPort: %u",
1419                                                  port->bond_config->bond_portid);
1420                 }
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);
1425                         printf("\n\r");
1426                         printf("\t\tSlavePortCount: %u",
1427                                                  port->bond_config->slave_count);
1428                         printf(" SlavePorts:");
1429                         int i;
1430                         for (i = 0; i < port->bond_config->slave_count; i++) {
1431                                 printf(" %u ", port->bond_config->slaves[i]);
1432                         }
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;
1437                                          i++) {
1438                                 printf(" %u ",
1439                                                          port->bond_config->active_slaves[i]);
1440                         }
1441                         printf("\n\r");
1442                         printf("\t\t");
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);
1449                         printf("\n\r");
1450                         printf("\t\t");
1451                         printf("Xmit_policy: %u",
1452                                                  port->bond_config->xmit_policy);
1453                 }
1454                 printf("\n\r");
1455                 printf("\t\t");
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, &eth_stats);
1460                 printf("pkts_in: %" PRIu64 " ,", eth_stats.ipackets);
1461                 printf("pkts_out: %" PRIu64 " ", eth_stats.opackets);
1462                 printf("\n\r");
1463                 printf("\t\t");
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);
1468                 printf("\n\r");
1469                 printf("\n\r");
1470         }
1471         if (ifm_debug & IFM_DEBUG_LOCKS)
1472                 RTE_LOG(INFO, IFM, "%s: Releasing RW lock @ %d\n\r",
1473                         __FUNCTION__, __LINE__);
1474         if (USE_RTM_LOCKS)
1475                 rtm_unlock();
1476         else
1477                 rte_rwlock_read_unlock(&rwlock);
1478 }