Fix compilation issue with older gcc
[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                         port->link_status = IFM_ETH_LINK_UP;
457                         if(!link.link_status) {
458                                 if (rte_eth_dev_set_link_up(port_id) < 0) {
459                                         RTE_LOG(INFO, IFM,
460                                                         "%s:Port %u admin up is unsuccessful\n\r",
461                                                         __FUNCTION__, port->pmdid);
462                                 } else {
463                                         if (ifm_debug & IFM_DEBUG_LOCKS)
464                                                 RTE_LOG(INFO, IFM,
465                                                                 "%s: Releasing lock @ %d\n\r",
466                                                                 __FUNCTION__, __LINE__);
467
468                                         if (USE_RTM_LOCKS) {
469                                                 rtm_unlock();
470                                         } else {
471                                                 rte_rwlock_write_unlock(&rwlock);
472                                         }
473                                         if (ifm_debug & IFM_DEBUG_CONFIG)
474                                                 RTE_LOG(INFO, IFM,
475                                                                 "%s:Port %u admin up...\n\r",
476                                                                 __FUNCTION__, port->pmdid);
477                                         send_gratuitous_arp(port);
478                                         return;
479                                 }
480                         }
481                 } else if (linkstatus == IFM_ETH_LINK_DOWN)
482                 {
483                         int status;
484                         port->admin_status = IFM_ETH_LINK_DOWN;
485                         port->link_status = IFM_ETH_LINK_DOWN;
486                         /* need to check the following if */
487                         if(link.link_status) {
488                                 status = rte_eth_dev_set_link_down(port_id);
489                                 if (status < 0)
490                                 {
491                                         printf("(%" PRIu32 "): PMD set link down... continuing...%"
492                                                         PRId32 "\n", port_id, status);
493                                 }
494                         }
495                 }
496         }
497         if (ifm_debug & IFM_DEBUG_LOCKS)
498                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
499                         __LINE__);
500
501         if (USE_RTM_LOCKS) {
502                 rtm_unlock();
503         } else {
504                 rte_rwlock_write_unlock(&rwlock);
505         }
506 }
507
508 void ifm_set_l2_interface_mtu(uint8_t port_id, uint16_t mtu)
509 {
510         int ret;
511         l2_phy_interface_t *port;
512         port = ifm.port_list[port_id];
513         if (port == NULL) {
514                 RTE_LOG(ERR, IFM,
515                         "%s: Port %u info not found... configure it first.\n\r",
516                         __FUNCTION__, port_id);
517         }
518
519         if (port != NULL && port->pmdid == port_id) {
520                 ret = rte_eth_dev_set_mtu(port_id, mtu);
521                 if (ret != 0)
522                         RTE_LOG(INFO, IFM,
523                                 "set_l2_interface_mtu: Set MTU failed. ret=%d\n",
524                                 ret);
525                 else {
526                         if (ifm_debug & IFM_DEBUG_LOCKS)
527                                 RTE_LOG(INFO, IFM,
528                                         "%s: Acquiring lock @ %d\n\r",
529                                         __FUNCTION__, __LINE__);
530
531                         if (USE_RTM_LOCKS) {
532                                 rtm_lock();
533                         } else {
534                                 rte_rwlock_write_lock(&rwlock);
535                         }
536                         port->mtu = mtu;
537                         if (ifm_debug & IFM_DEBUG_LOCKS)
538                                 RTE_LOG(INFO, IFM,
539                                         "%s: Releasing lock @ %d\n\r",
540                                         __FUNCTION__, __LINE__);
541
542                         if (USE_RTM_LOCKS) {
543                                 rtm_unlock();
544                         } else {
545                                 rte_rwlock_write_unlock(&rwlock);
546                         }
547                         return;
548                 }
549         }
550 }
551
552 void ifm_set_port_promisc(uint8_t port_id, uint8_t enable)
553 {
554         l2_phy_interface_t *port;
555         if (ifm_debug & IFM_DEBUG_LOCKS)
556                 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
557                         __FUNCTION__, __LINE__);
558         if (USE_RTM_LOCKS) {
559                 rtm_lock();
560         } else {
561                 rte_rwlock_write_lock(&rwlock);
562         }
563         port = ifm.port_list[port_id];
564         if (port == NULL) {
565                 RTE_LOG(ERR, IFM,
566                         "%s: Port %u info not found... configure it first.\n\r",
567                         __FUNCTION__, port_id);
568         }
569         if (port != NULL && port->pmdid == port_id) {
570                 if (enable == 1) {
571                         rte_eth_promiscuous_enable(port_id);
572                         port->promisc = 1;
573                 } else {
574                         rte_eth_promiscuous_disable(port_id);
575                         port->promisc = 0;
576                 }
577         }
578         if (ifm_debug & IFM_DEBUG_LOCKS)
579                 RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
580                         __FUNCTION__, __LINE__);
581         if (USE_RTM_LOCKS) {
582                 rtm_unlock();
583         } else {
584                 rte_rwlock_write_unlock(&rwlock);
585         }
586 }
587
588 int32_t ifm_get_nactive_ports(void)
589 {
590         return ifm.nport_configured;
591 }
592
593 int32_t ifm_get_nports_initialized(void)
594 {
595         return ifm.nport_intialized;
596 }
597
598 uint16_t ifm_receive_bulk_pkts(uint8_t port_id, uint16_t qid,
599                                                  struct rte_mbuf **rx_pkts)
600 {
601         uint64_t no_of_rcvd_pkt;
602         no_of_rcvd_pkt =
603                         rte_eth_rx_burst(port_id, qid, rx_pkts, IFM_BURST_SIZE);
604         if (ifm_debug & IFM_DEBUG_RXTX)
605                 RTE_LOG(INFO, IFM,
606                         "ifm_receive_bulk_pkts: port_id %u no_of_rcvd_pkt %lu\n\r",
607                         port_id, no_of_rcvd_pkt);
608         return no_of_rcvd_pkt;
609 }
610
611 uint16_t ifm_transmit_bulk_pkts(l2_phy_interface_t *port,
612                                 struct rte_mbuf **tx_pkts, uint64_t npkts)
613 {
614         uint32_t burst_tx_delay_time = IFM_BURST_TX_WAIT_US;
615         uint32_t burst_tx_retry_num = IFM_BURST_TX_RETRIES;
616         uint32_t retry;
617         uint32_t no_of_tx_pkt;
618         if (ifm_debug & IFM_DEBUG_LOCKS)
619                 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
620                         __FUNCTION__, __LINE__);
621         if (USE_RTM_LOCKS) {
622                 rtm_lock();
623         } else {
624                 rte_rwlock_read_lock(&rwlock);
625         }
626         no_of_tx_pkt = rte_eth_tx_burst(port->pmdid, IFM_TX_DEFAULT_Q, tx_pkts,
627                                         npkts);
628         if (unlikely(no_of_tx_pkt < npkts)) {
629                 retry = 0;
630                 while (no_of_tx_pkt < IFM_BURST_SIZE
631                                          && retry++ < burst_tx_retry_num) {
632                         rte_delay_us(burst_tx_delay_time);
633                         no_of_tx_pkt =
634                                         rte_eth_tx_burst(port->pmdid, IFM_TX_DEFAULT_Q,
635                                                          &tx_pkts[no_of_tx_pkt],
636                                                          IFM_BURST_SIZE - no_of_tx_pkt);
637                 }
638         }
639         if (ifm_debug & IFM_DEBUG_RXTX)
640                 RTE_LOG(INFO, IFM,
641                         "ifm_transmit_bulk_pkts: no_of_tx_pkt %u\n\r",
642                         no_of_tx_pkt);
643         if (ifm_debug & IFM_DEBUG_LOCKS)
644                 RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
645                         __FUNCTION__, __LINE__);
646         if (USE_RTM_LOCKS) {
647                 rtm_unlock();
648         } else {
649                 rte_rwlock_read_unlock(&rwlock);
650         }
651         return no_of_tx_pkt;
652 }
653
654 int ifm_transmit_single_pkt(l2_phy_interface_t *port, struct rte_mbuf *tx_pkts)
655 {
656         uint64_t tx_npkts = 0;
657         if (tx_pkts == NULL || port == NULL) {
658                 RTE_LOG(INFO, IFM,
659                         "ifm_transmit_single_pkt: tx_pkts and port are NULL ");
660                 return IFM_FAILURE;
661         }
662         if (ifm_debug & IFM_DEBUG_RXTX)
663                 RTE_LOG(INFO, IFM,
664                         "ifm_transmit_single_pkt: port->pmdid %u\n\r",
665                         port->pmdid);
666         if (ifm_debug & IFM_DEBUG_LOCKS)
667                 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
668                         __FUNCTION__, __LINE__);
669
670         if (USE_RTM_LOCKS) {
671                 rtm_lock();
672         } else {
673                 rte_rwlock_read_lock(&rwlock);
674         }
675         tx_npkts =
676                         rte_eth_tx_buffer(port->pmdid, IFM_TX_DEFAULT_Q, port->tx_buffer,
677                                                 tx_pkts);
678         if (ifm_debug & IFM_DEBUG_RXTX)
679                 RTE_LOG(INFO, IFM,
680                         "ifm_transmit_single_pkt: port->pmdid %u No of packets buffered %lu\n\r",
681                         port->pmdid, tx_npkts);
682         if (ifm_debug & IFM_DEBUG_LOCKS)
683                 RTE_LOG(INFO, IFM, "%s: Releasing RW lock @ %d\n\r",
684                         __FUNCTION__, __LINE__);
685
686         if (USE_RTM_LOCKS) {
687                 rtm_unlock();
688         } else {
689                 rte_rwlock_read_unlock(&rwlock);
690         }
691         if (ifm_debug & IFM_DEBUG_LOCKS)
692                 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock @ %d\n\r",
693                         __FUNCTION__, __LINE__);
694
695         if (USE_RTM_LOCKS) {
696                 rtm_lock();
697         } else {
698                 rte_rwlock_write_lock(&rwlock);
699         }
700         port->n_txpkts +=
701                         rte_eth_tx_buffer_flush(port->pmdid, IFM_TX_DEFAULT_Q,
702                                                 port->tx_buffer);
703         if (ifm_debug & IFM_DEBUG_LOCKS)
704                 RTE_LOG(INFO, IFM, "%s: Releasing WR lock @ %d\n\r",
705                         __FUNCTION__, __LINE__);
706
707         if (USE_RTM_LOCKS) {
708                 rtm_unlock();
709         } else {
710                 rte_rwlock_write_unlock(&rwlock);
711         }
712         if (ifm_debug & IFM_DEBUG_RXTX)
713                 RTE_LOG(INFO, IFM,
714                         "ifm_transmit_single_pkt: no of pkts flushed %lu\n\r",
715                         port->n_txpkts);
716         return tx_npkts;
717 }
718
719 int16_t ifm_add_ipv4_port(uint8_t port_id, uint32_t ipaddr, uint32_t addrlen)
720 {
721         l2_phy_interface_t *port;
722         ipv4list_t *ipconf;
723         if (ifm_debug & IFM_DEBUG_LOCKS)
724                 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
725                         __LINE__);
726
727         if (USE_RTM_LOCKS) {
728                 rtm_lock();
729         } else {
730                 rte_rwlock_write_lock(&rwlock);
731         }
732         port = ifm.port_list[port_id];
733         if (port == NULL) {
734                 RTE_LOG(ERR, IFM,
735                         "%s: Port %u info not found... configure it first.\n\r",
736                         __FUNCTION__, port_id);
737         }
738         if (port != NULL && port->pmdid == port_id) {
739                 ipconf = (ipv4list_t *) rte_zmalloc(NULL, sizeof(ipv4list_t),
740                                                                 RTE_CACHE_LINE_SIZE);
741                 if (ipconf != NULL) {
742                         ipconf->next = NULL;
743                         //ipconf->ipaddr = rte_bswap32(ipaddr);
744                         ipconf->ipaddr = ipaddr;
745                         ipconf->port = port;
746                         ipconf->addrlen = addrlen;
747                         if (port->ipv4_list == NULL)
748                                 port->flags |= IFM_IPV4_ENABLED;
749                         ipconf->next = (ipv4list_t *) port->ipv4_list;
750                         port->ipv4_list = (ipv4list_t *) ipconf;
751                         if (ifm_debug & IFM_DEBUG_LOCKS)
752                                 RTE_LOG(INFO, IFM,
753                                         "%s: Releasing lock @ %d\n\r",
754                                         __FUNCTION__, __LINE__);
755
756                         if (USE_RTM_LOCKS) {
757                                 rtm_unlock();
758                         } else {
759                                 rte_rwlock_write_unlock(&rwlock);
760                         }
761                         return 0;
762                 }
763         }
764         if (ifm_debug & IFM_DEBUG_LOCKS)
765                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
766                         __LINE__);
767
768         if (USE_RTM_LOCKS) {
769                 rtm_unlock();
770         } else {
771                 rte_rwlock_write_unlock(&rwlock);
772         }
773         return -1;
774 }
775
776 int16_t ifm_remove_ipv4_port(uint8_t port_id, uint32_t ipaddr,
777                                                 uint32_t addrlen)
778 {
779         l2_phy_interface_t *port;
780         ipv4list_t *iplist, *previplist = NULL;
781         if (ifm_debug & IFM_DEBUG_LOCKS)
782                 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
783                         __LINE__);
784
785         if (USE_RTM_LOCKS) {
786                 rtm_lock();
787         } else {
788                 rte_rwlock_write_lock(&rwlock);
789         }
790         port = ifm.port_list[port_id];
791         if (port == NULL) {
792                 RTE_LOG(ERR, IFM,
793                         "%s: Port %u info not found... configure it first.\n\r",
794                         __FUNCTION__, port_id);
795         }
796         if (port != NULL && port->pmdid == port_id) {
797                 if (port->ipv4_list == NULL) {
798                         if (ifm_debug & IFM_DEBUG_LOCKS)
799                                 RTE_LOG(INFO, IFM,
800                                         "%s: Releasing lock @ %d\n\r",
801                                         __FUNCTION__, __LINE__);
802
803                         if (USE_RTM_LOCKS) {
804                                 rtm_unlock();
805                         } else {
806                                 rte_rwlock_write_unlock(&rwlock);
807                         }
808                         return -1;
809                 }
810                 iplist = (ipv4list_t *) port->ipv4_list;
811                 while (iplist != NULL) {
812                         if (addrlen == iplist->addrlen &&
813                                         memcpy(&iplist->ipaddr, &ipaddr, addrlen)) {
814                                 if (iplist == port->ipv4_list) {
815                                         port->ipv4_list = iplist->next;
816                                 } else {
817                                         if (previplist != NULL)
818                                                 previplist->next = iplist->next;
819                                 }
820                                 port->flags &= ~IFM_IPV4_ENABLED;
821                                 rte_free(iplist);
822                                 if (ifm_debug & IFM_DEBUG_LOCKS)
823                                         RTE_LOG(INFO, IFM,
824                                                 "%s: Releasing lock @ %d\n\r",
825                                                 __FUNCTION__, __LINE__);
826
827                                 if (USE_RTM_LOCKS) {
828                                         rtm_unlock();
829                                 } else {
830                                         rte_rwlock_write_unlock(&rwlock);
831                                 }
832                                 return 0;
833                         } else {
834                                 previplist = iplist;
835                                 iplist = iplist->next;
836                         }
837                 }
838         }
839         if (ifm_debug & IFM_DEBUG_LOCKS)
840                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
841                         __LINE__);
842
843         if (USE_RTM_LOCKS) {
844                 rtm_unlock();
845         } else {
846                 rte_rwlock_write_unlock(&rwlock);
847         }
848         return -1;
849 }
850
851 int8_t ifm_add_ipv6_port(uint8_t port_id, uint8_t ip6addr[], uint32_t addrlen)
852 {
853         l2_phy_interface_t *port;
854         ipv6list_t *ip6conf;
855         if (ifm_debug & IFM_DEBUG_LOCKS)
856                 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
857                         __LINE__);
858
859         if (USE_RTM_LOCKS) {
860                 rtm_lock();
861         } else {
862                 rte_rwlock_write_lock(&rwlock);
863         }
864         port = ifm.port_list[port_id];
865         if (port == NULL) {
866                 RTE_LOG(ERR, IFM,
867                         "%s: Port %u info not found... configure it first.\n\r",
868                         __FUNCTION__, port_id);
869         }
870         if (port != NULL && port->pmdid == port_id) {
871                 ip6conf = (ipv6list_t *) rte_zmalloc(NULL, sizeof(ipv6list_t),
872                                                                  RTE_CACHE_LINE_SIZE);
873                 if (ip6conf != NULL) {
874                         ip6conf->next = NULL;
875                         memcpy(ip6conf->ipaddr, ip6addr, IFM_IPV6_ADDR_SIZE);
876                         ip6conf->port = port;
877                         ip6conf->addrlen = addrlen;
878
879                         if (port->ipv6_list == NULL) {
880                                 port->flags |= IFM_IPV6_ENABLED;
881                         }
882                         ip6conf->next = (ipv6list_t *) port->ipv6_list;
883                         port->ipv6_list = (ipv6list_t *) ip6conf;
884                         if (ifm_debug & IFM_DEBUG_LOCKS)
885                                 RTE_LOG(INFO, IFM,
886                                         "%s: Releasing lock @ %d\n\r",
887                                         __FUNCTION__, __LINE__);
888
889                         if (USE_RTM_LOCKS) {
890                                 rtm_unlock();
891                         } else {
892                                 rte_rwlock_write_unlock(&rwlock);
893                         }
894                         return 0;
895                 }
896         }
897         if (ifm_debug & IFM_DEBUG_LOCKS)
898                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
899                         __LINE__);
900
901         if (USE_RTM_LOCKS) {
902                 rtm_unlock();
903         } else {
904                 rte_rwlock_write_unlock(&rwlock);
905         }
906         return -1;
907 }
908
909 int16_t ifm_remove_ipv6_port(uint8_t port_id, uint32_t ip6addr,
910                                                 uint32_t addrlen)
911 {
912         l2_phy_interface_t *port;
913         ipv6list_t *ip6list, *previp6list = NULL;
914
915         if (ifm_debug & IFM_DEBUG_LOCKS)
916                 RTE_LOG(INFO, IFM, "%s: Acquiring lock @ %d\n\r", __FUNCTION__,
917                         __LINE__);
918         if (USE_RTM_LOCKS)
919                 rtm_lock();
920         else
921                 rte_rwlock_write_lock(&rwlock);
922         port = ifm.port_list[port_id];
923         if (port == NULL) {
924                 if (ifm_debug & IFM_DEBUG_LOCKS)
925                         RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
926                                 __FUNCTION__, __LINE__);
927                 if (USE_RTM_LOCKS) {
928                         rtm_unlock();
929                 } else {
930                         rte_rwlock_write_unlock(&rwlock);
931                 }
932                 RTE_LOG(ERR, IFM,
933                         "%s: Port %u info not found... configure it first.\n\r",
934                         __FUNCTION__, port_id);
935         }
936         if (port != NULL && port->pmdid == port_id) {
937                 if (port->ipv6_list == NULL) {
938                         if (ifm_debug & IFM_DEBUG_LOCKS)
939                                 RTE_LOG(INFO, IFM,
940                                         "%s: Releasing lock @ %d\n\r",
941                                         __FUNCTION__, __LINE__);
942
943                         if (USE_RTM_LOCKS) {
944                                 rtm_unlock();
945                         } else {
946                                 rte_rwlock_write_unlock(&rwlock);
947                         }
948                         return -1;
949                 }
950                 ip6list = (ipv6list_t *) port->ipv6_list;
951                 while (ip6list != NULL) {
952                         if (addrlen == ip6list->addrlen &&
953                                         memcpy(&ip6list->ipaddr, &ip6addr, addrlen)) {
954                                 if (ip6list == port->ipv6_list) {
955                                         port->ipv6_list = ip6list->next;
956                                 } else {
957                                         if (previp6list != NULL)
958                                                 previp6list->next =
959                                                                 ip6list->next;
960                                 }
961                                 port->flags &= ~IFM_IPV6_ENABLED;
962                                 rte_free(ip6list);
963                                 if (ifm_debug & IFM_DEBUG_LOCKS)
964                                         RTE_LOG(INFO, IFM,
965                                                 "%s: Releasing lock @ %d\n\r",
966                                                 __FUNCTION__, __LINE__);
967
968                                 if (USE_RTM_LOCKS) {
969                                         rtm_unlock();
970                                 } else {
971                                         rte_rwlock_write_unlock(&rwlock);
972                                 }
973                                 return 0;
974                         } else {
975                                 previp6list = ip6list;
976                                 ip6list = ip6list->next;
977                         }
978                 }
979         }
980         if (ifm_debug & IFM_DEBUG_LOCKS)
981                 RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r", __FUNCTION__,
982                         __LINE__);
983         if (USE_RTM_LOCKS)
984                 rtm_unlock();
985         else
986                 rte_rwlock_write_unlock(&rwlock);
987         return -1;
988 }
989
990 int32_t ifm_chk_port_ipv4_enabled(uint8_t port_id)
991 {
992         l2_phy_interface_t *port;
993
994         if (ifm_debug & IFM_DEBUG_LOCKS)
995                 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
996                         __FUNCTION__, __LINE__);
997         if (USE_RTM_LOCKS)
998                 rtm_lock();
999         else
1000                 rte_rwlock_read_lock(&rwlock);
1001         port = ifm.port_list[port_id];
1002         if (port == NULL) {
1003                 RTE_LOG(ERR, IFM,
1004                         "%s: Port %u info not found... configure it first.\n\r",
1005                         __FUNCTION__, port_id);
1006                 if (ifm_debug & IFM_DEBUG_LOCKS)
1007                         RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
1008                                 __FUNCTION__, __LINE__);
1009                 if (USE_RTM_LOCKS)
1010                         rtm_unlock();
1011                 else
1012                         rte_rwlock_read_unlock(&rwlock);
1013                 return IFM_FAILURE;
1014         }
1015         if ((port->flags & IFM_IPV4_ENABLED) == 0) {
1016                 if (ifm_debug & IFM_DEBUG_LOCKS)
1017                         RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
1018                                 __FUNCTION__, __LINE__);
1019                 if (USE_RTM_LOCKS)
1020                         rtm_unlock();
1021                 else
1022                         rte_rwlock_read_unlock(&rwlock);
1023                 return 0;
1024         } else {
1025                 if (ifm_debug & IFM_DEBUG_LOCKS)
1026                         RTE_LOG(INFO, IFM, "%s: Releasing lock @ %d\n\r",
1027                                 __FUNCTION__, __LINE__);
1028                 if (USE_RTM_LOCKS)
1029                         rtm_unlock();
1030                 else
1031                         rte_rwlock_read_unlock(&rwlock);
1032                 return 1;
1033         }
1034 }
1035
1036 int32_t ifm_chk_port_ipv6_enabled(uint8_t port_id)
1037 {
1038         l2_phy_interface_t *port;
1039
1040         if (ifm_debug & IFM_DEBUG_LOCKS)
1041                 RTE_LOG(INFO, IFM, "%s: Acquiring RD lock @ %d\n\r",
1042                         __FUNCTION__, __LINE__);
1043         if (USE_RTM_LOCKS)
1044                 rtm_lock();
1045         else
1046                 rte_rwlock_read_lock(&rwlock);
1047
1048         port = ifm.port_list[port_id];
1049         if (port == NULL) {
1050                 if (ifm_debug & IFM_DEBUG)
1051                         RTE_LOG(ERR, IFM, "%s: Port %u info not found..."
1052                                 " configure it first.\n\r",
1053                                 __FUNCTION__, port_id);
1054                 if (ifm_debug & IFM_DEBUG_LOCKS)
1055                         RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
1056                                 __FUNCTION__, __LINE__);
1057                 if (USE_RTM_LOCKS)
1058                         rtm_unlock();
1059                 else
1060                         rte_rwlock_read_unlock(&rwlock);
1061                 return IFM_FAILURE;
1062         }
1063         if ((port->flags & IFM_IPV6_ENABLED) == 0) {
1064                 if (ifm_debug & IFM_DEBUG_LOCKS)
1065                         RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
1066                                 __FUNCTION__, __LINE__);
1067                 if (USE_RTM_LOCKS)
1068                         rtm_unlock();
1069                 else
1070                         rte_rwlock_read_unlock(&rwlock);
1071                 return 0;
1072         } else {
1073                 if (ifm_debug & IFM_DEBUG_LOCKS)
1074                         RTE_LOG(INFO, IFM, "%s: Releasing RD lock @ %d\n\r",
1075                                 __FUNCTION__, __LINE__);
1076                 if (USE_RTM_LOCKS)
1077                         rtm_unlock();
1078                 else
1079                         rte_rwlock_read_unlock(&rwlock);
1080                 return 1;
1081         }
1082 }
1083
1084 void ifm_register_for_linkupdate(uint32_t clientid,
1085                                  void (*cb_linkupdate) (uint8_t, unsigned int))
1086 {
1087         ifm.if_client[ifm.nclient].cb_linkupdate = cb_linkupdate;
1088         ifm.if_client[ifm.nclient].clientid = clientid;
1089         ifm.nclient++;
1090 }
1091
1092 int ifm_port_setup(uint8_t port_id, port_config_t *pconfig)
1093 {
1094         int status, sock;
1095         char buf[12];
1096         struct rte_eth_dev_info dev_info;
1097         struct rte_eth_link linkstatus;
1098         l2_phy_interface_t *port = NULL;
1099
1100         if (!ifm.nport_intialized) {
1101                 RTE_LOG(ERR, IFM, "%s: Failed to configure port %u. 0 ports"
1102                         "were intialized during PCI probe...\n\r",
1103                         __FUNCTION__, port_id);
1104                 return IFM_FAILURE;
1105         }
1106         if (ifm_debug & IFM_DEBUG_CONFIG)
1107                 RTE_LOG(INFO, IFM, "%s: Configuring port %u with "
1108                         "nrxq: %u, ntxq: %u\n\r", __FUNCTION__,
1109                         port_id, pconfig->nrx_queue, pconfig->ntx_queue);
1110         if (ifm_debug & IFM_DEBUG_LOCKS)
1111                 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock1 @ %d\n\r",
1112                         __FUNCTION__, __LINE__);
1113         if (USE_RTM_LOCKS)
1114                 rtm_lock();
1115         else
1116                 rte_rwlock_write_lock(&rwlock);
1117
1118         if (ifm.port_list[port_id] == NULL) {
1119                 ifm.port_list[port_id] =
1120                                 (l2_phy_interface_t *) rte_zmalloc(NULL,
1121                                                                          sizeof
1122                                                                          (l2_phy_interface_t),
1123                                                                          RTE_CACHE_LINE_SIZE);
1124                 ifm.port_list[port_id]->pmdid = port_id;
1125         }
1126         if (ifm_debug & IFM_DEBUG_LOCKS)
1127                 RTE_LOG(INFO, IFM, "%s: Releasing WR lock1 @ %d\n\r",
1128                         __FUNCTION__, __LINE__);
1129         if (USE_RTM_LOCKS)
1130                 rtm_unlock();
1131         else
1132                 rte_rwlock_write_unlock(&rwlock);
1133
1134         rte_eth_link_get(port_id, &linkstatus);
1135         if (linkstatus.link_status) {
1136                 if (ifm_debug & IFM_DEBUG_CONFIG) {
1137                         RTE_LOG(INFO, IFM, "%s: %u is up.Stop it before"
1138                                 " reconfiguring.\n\r", __FUNCTION__, port_id);
1139                 }
1140                 rte_eth_dev_stop(port_id);
1141         }
1142         /*Configure an Ethernet device. rets 0 on success queue */
1143         status = rte_eth_dev_configure(port_id, pconfig->nrx_queue,
1144                                                          pconfig->ntx_queue, &pconfig->port_conf);
1145         if (status < 0) {
1146                 ifm_remove_port_details(port_id);
1147                 RTE_LOG(ERR, IFM, "%s: rte_eth_dev_configure is failed"
1148                         "for port %u.\n\r", __FUNCTION__, port_id);
1149                 return IFM_FAILURE;
1150         }
1151         status = rte_eth_dev_callback_register(port_id,
1152                                                                  RTE_ETH_EVENT_INTR_LSC,
1153                                                                  lsi_event_callback, NULL);
1154         if (status < 0) {
1155                 ifm_remove_port_details(port_id);
1156                 RTE_LOG(ERR, IFM, "%s: rte_eth_dev_callback_register()"
1157                         " failed for port %u.\n\r", __FUNCTION__, port_id);
1158                 return IFM_FAILURE;
1159         }
1160         /*promiscuous mode is enabled set it */
1161         if (pconfig->promisc)
1162                 rte_eth_promiscuous_enable(port_id);
1163
1164         sock = rte_eth_dev_socket_id(port_id);
1165         if (sock == -1)
1166                 RTE_LOG(ERR, IFM, "%s: Warning: rte_eth_dev_socket_id,"
1167                         " port_id value is"
1168                         "out of range %u\n\r", __FUNCTION__, port_id);
1169         /*Port initialization */
1170         int ntxqs;
1171         for (ntxqs = 0; ntxqs < pconfig->ntx_queue; ntxqs++) {
1172                 status = rte_eth_tx_queue_setup(port_id, ntxqs,
1173                                                 IFM_TX_DESC_DEFAULT, sock,
1174                                                 &(pconfig->tx_conf));
1175                 if (status < 0) {
1176                         ifm_remove_port_details(port_id);
1177                         RTE_LOG(ERR, IFM, "%s: rte_eth_tx_queue_setup failed"
1178                                 " for port %u\n\r", __FUNCTION__, port_id);
1179                         return IFM_FAILURE;
1180                 }
1181         }
1182         port = ifm_get_port(port_id);
1183         if (port == NULL) {
1184                 RTE_LOG(INFO, IFM, "%s: Port is NULL @ %d\n\r", __FUNCTION__,
1185                         __LINE__);
1186                 return IFM_FAILURE;
1187         }
1188
1189         if (ifm_debug & IFM_DEBUG_LOCKS)
1190                 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock 2 @ %d\n\r",
1191                         __FUNCTION__, __LINE__);
1192         if (USE_RTM_LOCKS)
1193                 rtm_lock();
1194         else
1195                 rte_rwlock_write_lock(&rwlock);
1196
1197         if (port->tx_buf_len == 0) {
1198                 port->tx_buf_len = RTE_ETH_TX_BUFFER_SIZE(IFM_BURST_SIZE);
1199         }
1200         port->tx_buffer = rte_zmalloc_socket("tx_buffer", port->tx_buf_len, 0,
1201                                                          rte_eth_dev_socket_id(port_id));
1202
1203         if (port->tx_buffer == NULL) {
1204                 ifm_remove_port_details(port_id);
1205                 RTE_LOG(ERR, IFM, "%s: Failed to allocate tx buffers for"
1206                         " port %u\n\r", __FUNCTION__, port_id);
1207                 if (ifm_debug & IFM_DEBUG_LOCKS)
1208                         RTE_LOG(INFO, IFM, "%s: Releasing WR lock2 %d\n\r",
1209                                 __FUNCTION__, __LINE__);
1210                 if (USE_RTM_LOCKS)
1211                         rtm_unlock();
1212                 else
1213                         rte_rwlock_write_unlock(&rwlock);
1214                 return IFM_FAILURE;
1215         }
1216         rte_eth_tx_buffer_init(port->tx_buffer, IFM_BURST_SIZE);
1217
1218         sprintf(buf, "MEMPOOL%d", port_id);
1219         port->mempool = rte_mempool_create(buf,
1220                                                  pconfig->mempool.pool_size,
1221                                                  pconfig->mempool.buffer_size,
1222                                                  pconfig->mempool.cache_size,
1223                                                  sizeof(struct
1224                                                         rte_pktmbuf_pool_private),
1225                                                  rte_pktmbuf_pool_init, NULL,
1226                                                  rte_pktmbuf_init, NULL, sock, 0);
1227         if (port->mempool == NULL) {
1228                 ifm_remove_port_details(port_id);
1229                 RTE_LOG(ERR, IFM, "%s: rte_mempool_create is failed for port"
1230                         " %u. Error: %s\n\r",
1231                         __FUNCTION__, port_id, rte_strerror(rte_errno));
1232                 if (ifm_debug & IFM_DEBUG_LOCKS)
1233                         RTE_LOG(INFO, IFM, "%s: Releasing WR lock2 %d\n\r",
1234                                 __FUNCTION__, __LINE__);
1235                 if (USE_RTM_LOCKS)
1236                         rtm_unlock();
1237                 else
1238                         rte_rwlock_write_unlock(&rwlock);
1239                 return IFM_FAILURE;
1240         }
1241         int nrxqs;
1242         for (nrxqs = 0; nrxqs < pconfig->nrx_queue; nrxqs++) {
1243                 status = rte_eth_rx_queue_setup(port_id, nrxqs,
1244                                                 IFM_RX_DESC_DEFAULT, sock,
1245                                                 &(pconfig->rx_conf),
1246                                                 port->mempool);
1247                 if (status < 0) {
1248                         ifm_remove_port_details(port_id);
1249                         RTE_LOG(ERR, IFM,
1250                                 "%s: rte_eth_rx_queue_setup is failed "
1251                                 "for port %u queue %u. Error: %s\n\r",
1252                                 __FUNCTION__, port_id, nrxqs,
1253                                 rte_strerror(rte_errno));
1254                         if (ifm_debug & IFM_DEBUG_LOCKS)
1255                                 RTE_LOG(INFO, IFM,
1256                                         "%s: Releasing WR lock2 %d\n\r",
1257                                         __FUNCTION__, __LINE__);
1258                         if (USE_RTM_LOCKS)
1259                                 rtm_unlock();
1260                         else
1261                                 rte_rwlock_write_unlock(&rwlock);
1262                         return IFM_FAILURE;
1263                 }
1264         }
1265         /*Start link */
1266         if (ifm_debug & IFM_DEBUG_LOCKS)
1267                 RTE_LOG(INFO, IFM, "%s: Releasing WR lock2  @ %d\n\r",
1268                         __FUNCTION__, __LINE__);
1269         if (USE_RTM_LOCKS)
1270                 rtm_unlock();
1271         else
1272                 rte_rwlock_write_unlock(&rwlock);
1273         status = rte_eth_dev_start(port_id);
1274         if (status < 0) {
1275                 ifm_remove_port_details(port_id);
1276                 RTE_LOG(ERR, IFM, "%s: rte_eth_dev_start is failed for"
1277                         " port %u.\n\r", __FUNCTION__, port_id);
1278                 return IFM_FAILURE;
1279         }
1280         rte_delay_ms(5000);
1281         /*Get device info and populate interface structure */
1282         if (ifm_debug & IFM_DEBUG_LOCKS)
1283                 RTE_LOG(INFO, IFM, "%s: Acquiring WR lock3 @ %d\n\r",
1284                         __FUNCTION__, __LINE__);
1285         if (USE_RTM_LOCKS)
1286                 rtm_lock();
1287         else
1288                 rte_rwlock_write_lock(&rwlock);
1289         rte_eth_macaddr_get(port_id, (struct ether_addr *)port->macaddr);
1290         if (pconfig->promisc)
1291                 port->promisc = 1;
1292         rte_eth_link_get(port_id, &linkstatus);
1293         /*Link status */
1294         port->link_duplex = linkstatus.link_duplex;
1295         port->link_autoneg = linkstatus.link_autoneg;
1296         port->link_speed = linkstatus.link_speed;
1297         port->admin_status = pconfig->state;
1298
1299         /*Get dev_info */
1300         memset(&dev_info, 0, sizeof(dev_info));
1301         rte_eth_dev_info_get(port_id, &dev_info);
1302         port->min_rx_bufsize = dev_info.min_rx_bufsize;
1303         port->max_rx_pktlen = dev_info.max_rx_pktlen;
1304         port->max_rx_queues = dev_info.max_rx_queues;
1305         port->max_tx_queues = dev_info.max_tx_queues;
1306         rte_eth_dev_get_mtu(port_id, &(port->mtu));
1307
1308         /*Add rx and tx packet function ptrs */
1309         port->retrieve_bulk_pkts = &ifm_receive_bulk_pkts;
1310         port->transmit_bulk_pkts = &ifm_transmit_bulk_pkts;
1311         port->transmit_single_pkt = &ifm_transmit_single_pkt;
1312         if (ifm_debug & IFM_DEBUG_LOCKS)
1313                 RTE_LOG(INFO, IFM, "%s: Releasing WR3 lock @ %d\n\r",
1314                         __FUNCTION__, __LINE__);
1315         if (USE_RTM_LOCKS)
1316                 rtm_unlock();
1317         else
1318                 rte_rwlock_write_unlock(&rwlock);
1319         RTE_LOG(INFO, IFM, "%s: Port %u is successfully configured.\n\r",
1320                 __FUNCTION__, port_id);
1321         return IFM_SUCCESS;
1322 }
1323
1324 int ifm_configure_ports(port_config_t *pconfig)
1325 {
1326         uint8_t port_id;
1327         int status = 0;
1328         if (!ifm.nport_intialized) {
1329                 RTE_LOG(ERR, IFM, "%s, Configuring ports failed. Zero ports "
1330                         "are intialized during PCI probe", __FUNCTION__);
1331                 return IFM_FAILURE;
1332         }
1333         if (pconfig == NULL) {
1334                 RTE_LOG(ERR, IFM, "%s, Configuring ports failed. "
1335                         "Param pconfig is NULL\n\r", __FUNCTION__);
1336                 return IFM_FAILURE;
1337         }
1338
1339         /*Initialize all ports */
1340         for (port_id = 0; port_id < ifm.nport_intialized; port_id++) {
1341                 if (ifm_debug & IFM_DEBUG_CONFIG)
1342                         RTE_LOG(INFO, IFM, "Call ifm_port_setup %u\n\r",
1343                                 port_id);
1344                 status =
1345                                 ifm_port_setup(pconfig[port_id].port_id, &pconfig[port_id]);
1346                 if (status == IFM_SUCCESS)
1347                         ifm.nport_configured++;
1348         }
1349         if (!ifm.nport_configured) {
1350                 RTE_LOG(ERR, IFM, "%s: Zero ports are configured\n\r",
1351                         __FUNCTION__);
1352                 return IFM_FAILURE;
1353         }
1354         RTE_LOG(INFO, IFM, "%s: Number of ports sucessfully configured:"
1355                 " %d\n\r", __FUNCTION__, ifm.nport_configured);
1356         return IFM_SUCCESS;
1357 }
1358
1359 void print_interface_details(void)
1360 {
1361         l2_phy_interface_t *port;
1362         int i = 0;
1363         struct sockaddr_in ip;
1364         printf("\n\r");
1365
1366         if (ifm_debug & IFM_DEBUG_LOCKS)
1367                 RTE_LOG(INFO, IFM, "%s: Acquiring RW lock @ %d\n\r",
1368                         __FUNCTION__, __LINE__);
1369         if (USE_RTM_LOCKS)
1370                 rtm_lock();
1371         else
1372                 rte_rwlock_read_lock(&rwlock);
1373
1374         for (i = 0; i < RTE_MAX_ETHPORTS && ifm.port_list[i]; i++) {
1375                 port = ifm.port_list[i];
1376                 printf(" %u", port->pmdid);
1377                 if (port->ifname && strlen(port->ifname)) {
1378                         printf(" (%s)\t", port->ifname);
1379                 } else
1380                         printf("\t\t");
1381                 printf("MAC:%02x:%02x:%02x:%02x:%02x:%02x Adminstate:%s"
1382                                          " Operstate:%s \n\r",
1383                                          port->macaddr[0], port->macaddr[1],
1384                                          port->macaddr[2], port->macaddr[3],
1385                                          port->macaddr[4], port->macaddr[5],
1386                                          port->admin_status ? "UP" : "DOWN",
1387                                          port->link_status ? "UP" : "DOWN");
1388                 printf("\t\t");
1389                 printf("Speed: %u, %s-duplex\n\r", port->link_speed,
1390                                          port->link_duplex ? "full" : "half");
1391                 printf("\t\t");
1392
1393                 if (port->ipv4_list != NULL) {
1394                         ip.sin_addr.s_addr =
1395                                         (unsigned long)((ipv4list_t *) (port->ipv4_list))->
1396                                         ipaddr;
1397                         printf("IP: %s/%d", inet_ntoa(ip.sin_addr),
1398                                                  ((ipv4list_t *) (port->ipv4_list))->addrlen);
1399                 } else {
1400                         printf("IP: NA");
1401                 }
1402
1403                 printf("\r\n");
1404                 printf("\t\t");
1405                 if (port->ipv6_list != NULL) {
1406                         uint8_t *addr =
1407                                         ((ipv6list_t *) (port->ipv6_list))->ipaddr;
1408                         printf
1409                                         ("IPv6: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
1410                                          addr[0], addr[1], addr[2], addr[3], addr[4],
1411                                          addr[5], addr[6], addr[7], addr[8], addr[9],
1412                                          addr[10], addr[11], addr[12], addr[13], addr[14],
1413                                          addr[15]);
1414                 } else {
1415                         printf("IPv6: NA");
1416                 }
1417
1418                 if (port->flags & IFM_SLAVE) {
1419                         printf("  IFM_SLAVE ");
1420                         printf(" MasterPort: %u",
1421                                                  port->bond_config->bond_portid);
1422                 }
1423                 if (port->flags & IFM_MASTER) {
1424                         printf("  IFM_MASTER ");
1425                         printf("  Mode: %u", port->bond_config->mode);
1426                         printf("  PrimaryPort: %u", port->bond_config->primary);
1427                         printf("\n\r");
1428                         printf("\t\tSlavePortCount: %u",
1429                                                  port->bond_config->slave_count);
1430                         printf(" SlavePorts:");
1431                         int i;
1432                         for (i = 0; i < port->bond_config->slave_count; i++) {
1433                                 printf(" %u ", port->bond_config->slaves[i]);
1434                         }
1435                         printf(" ActivePortCount: %u",
1436                                                  port->bond_config->active_slave_count);
1437                         printf(" ActivePorts:");
1438                         for (i = 0; i < port->bond_config->active_slave_count;
1439                                          i++) {
1440                                 printf(" %u ",
1441                                                          port->bond_config->active_slaves[i]);
1442                         }
1443                         printf("\n\r");
1444                         printf("\t\t");
1445                         printf("Link_monitor_freq: %u ms ",
1446                                                  port->bond_config->internal_ms);
1447                         printf(" Link_up_prop_delay: %u ms ",
1448                                                  port->bond_config->link_up_delay_ms);
1449                         printf(" Link_down_prop_delay: %u ms ",
1450                                                  port->bond_config->link_down_delay_ms);
1451                         printf("\n\r");
1452                         printf("\t\t");
1453                         printf("Xmit_policy: %u",
1454                                                  port->bond_config->xmit_policy);
1455                 }
1456                 printf("\n\r");
1457                 printf("\t\t");
1458                 printf("n_rxpkts: %" PRIu64 " ,n_txpkts: %" PRIu64 " ,",
1459                                          port->n_rxpkts, port->n_txpkts);
1460                 struct rte_eth_stats eth_stats;
1461                 rte_eth_stats_get(port->pmdid, &eth_stats);
1462                 printf("pkts_in: %" PRIu64 " ,", eth_stats.ipackets);
1463                 printf("pkts_out: %" PRIu64 " ", eth_stats.opackets);
1464                 printf("\n\r");
1465                 printf("\t\t");
1466                 printf("in_errs: %" PRIu64 " ,", eth_stats.ierrors);
1467                 printf("in_missed: %" PRIu64 " ,", eth_stats.imissed);
1468                 printf("out_errs: %" PRIu64 " ,", eth_stats.oerrors);
1469                 printf("mbuf_errs: %" PRIu64 " ", eth_stats.rx_nombuf);
1470                 printf("\n\r");
1471                 printf("\n\r");
1472         }
1473         if (ifm_debug & IFM_DEBUG_LOCKS)
1474                 RTE_LOG(INFO, IFM, "%s: Releasing RW lock @ %d\n\r",
1475                         __FUNCTION__, __LINE__);
1476         if (USE_RTM_LOCKS)
1477                 rtm_unlock();
1478         else
1479                 rte_rwlock_read_unlock(&rwlock);
1480 }