1/** 2 * @file 3 * Modules initialization 4 * 5 */ 6 7/* 8 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without modification, 12 * are permitted provided that the following conditions are met: 13 * 14 * 1. Redistributions of source code must retain the above copyright notice, 15 * this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright notice, 17 * this list of conditions and the following disclaimer in the documentation 18 * and/or other materials provided with the distribution. 19 * 3. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31 * OF SUCH DAMAGE. 32 * 33 * This file is part of the lwIP TCP/IP stack. 34 * 35 * Author: Adam Dunkels <adam@sics.se> 36 * 37 */ 38 39#include "lwip/opt.h" 40 41#include "lwip/init.h" 42#include "lwip/stats.h" 43#include "lwip/sys.h" 44#include "lwip/mem.h" 45#include "lwip/memp.h" 46#include "lwip/pbuf.h" 47#include "lwip/netif.h" 48#include "lwip/sockets.h" 49#include "lwip/ip.h" 50#include "lwip/raw.h" 51#include "lwip/udp.h" 52#include "lwip/tcp.h" 53#include "lwip/snmp_msg.h" 54#include "lwip/autoip.h" 55#include "lwip/igmp.h" 56#include "lwip/dns.h" 57#include "netif/bfeth.h" 58#include "netif/etharp.h" 59 60#include <idc_barrelfish.h> 61#include <mem_barrelfish.h> 62 63#include <barrelfish/barrelfish.h> 64#include <barrelfish/deferred.h> 65#include <barrelfish/net_constants.h> 66#include <netbench/netbench.h> 67 68 69/* FIXME: Move this to config */ 70#define MYDEBUGLWIP 1 71 72#ifdef MYDEBUGLWIP 73#define DEBUGPRINTPS(arg...) printf(arg) 74#else 75#define DEBUGPRINTPS(arg...) ((void)0) 76#endif // MYDEBUGLWIP 77 78 79 80 81 82 83 84/* Compile-time sanity checks for configuration errors. 85 * These can be done independently of LWIP_DEBUG, without penalty. 86 */ 87#ifndef BYTE_ORDER 88#error "BYTE_ORDER is not defined, you have to define it in your cc.h" 89#endif 90#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV) 91#error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h" 92#endif 93#if (!LWIP_ARP && ARP_QUEUEING) 94#error "If you want to use ARP Queueing, you have to define LWIP_ARP=1 in your lwipopts.h" 95#endif 96#if (!LWIP_UDP && LWIP_UDPLITE) 97#error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h" 98#endif 99#if (!LWIP_UDP && LWIP_SNMP) 100#error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h" 101#endif 102#if (!LWIP_UDP && LWIP_DHCP) 103#error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h" 104#endif 105#if (!LWIP_UDP && LWIP_IGMP) 106#error "If you want to use IGMP, you have to define LWIP_UDP=1 in your lwipopts.h" 107#endif 108#if (!LWIP_UDP && LWIP_DNS) 109#error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h" 110#endif 111#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) 112#error "If you want to use ARP, ARP_TABLE_SIZE must fit in an s8_t, so, you have to reduce it in your lwipopts.h" 113#endif 114#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0)) 115#error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h" 116#endif 117#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0)) 118#error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h" 119#endif 120#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0)) 121#error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h" 122#endif 123#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0)) 124#error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h" 125#endif 126#if (LWIP_TCP && (TCP_WND > 0xffff)) 127#error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h" 128#endif 129#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff)) 130#error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h" 131#endif 132#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12))) 133#error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h" 134#endif 135#if (LWIP_TCP && TCP_LISTEN_BACKLOG && (TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff)) 136#error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t" 137#endif 138#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) 139#error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" 140#endif 141#if (PPP_SUPPORT && (NO_SYS==1)) 142#error "If you want to use PPP, you have to define NO_SYS=0 in your lwipopts.h" 143#endif 144#if (LWIP_NETIF_API && (NO_SYS==1)) 145#error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h" 146#endif 147#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1)) 148#error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h" 149#endif 150#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) 151#error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" 152#endif 153#if (!LWIP_NETCONN && LWIP_SOCKET) 154#error "If you want to use Socket API, you have to define LWIP_NETCONN=1 in your lwipopts.h" 155#endif 156#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP) 157#error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h" 158#endif 159#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK) 160#error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h" 161#endif 162#if (!LWIP_ARP && LWIP_AUTOIP) 163#error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h" 164#endif 165#if (LWIP_SNMP && (SNMP_CONCURRENT_REQUESTS<=0)) 166#error "If you want to use SNMP, you have to define SNMP_CONCURRENT_REQUESTS>=1 in your lwipopts.h" 167#endif 168#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0)) 169#error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h" 170#endif 171#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API))) 172#error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h" 173#endif 174/* There must be sufficient timeouts, taking into account requirements of the subsystems. */ 175#if ((NO_SYS==0) && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT))) 176#error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts" 177#endif 178#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS)) 179#error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!" 180#endif 181#if (MEM_LIBC_MALLOC && MEM_USE_POOLS) 182#error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h" 183#endif 184#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS) 185#error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h" 186#endif 187 188#if (PBUF_POOL_BUFSIZE <= MEM_ALIGNMENT) 189#error "PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf" 190#endif 191 192#if (TCP_QUEUE_OOSEQ && !LWIP_TCP) 193#error "TCP_QUEUE_OOSEQ requires LWIP_TCP" 194#endif 195#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT))) 196#error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST" 197#endif 198 199 200/* Compile-time checks for deprecated options. 201 */ 202#ifdef MEMP_NUM_TCPIP_MSG 203#error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h." 204#endif 205#ifdef MEMP_NUM_API_MSG 206#error "MEMP_NUM_API_MSG option is deprecated. Remove it from your lwipopts.h." 207#endif 208#ifdef TCP_REXMIT_DEBUG 209#error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h." 210#endif 211#ifdef RAW_STATS 212#error "RAW_STATS option is deprecated. Remove it from your lwipopts.h." 213#endif 214#ifdef ETHARP_QUEUE_FIRST 215#error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h." 216#endif 217#ifdef ETHARP_ALWAYS_INSERT 218#error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h." 219#endif 220#if SO_REUSE 221/* I removed the lot since this was an ugly hack. It broke the raw-API. 222 It also came with many ugly goto's, Christiaan Simons. */ 223#error "SO_REUSE currently unavailable, this was a hack" 224#endif 225 226#ifdef LWIP_DEBUG 227static void lwip_sanity_check(void) 228{ 229 /* Warnings */ 230#if LWIP_NETCONN 231 if (MEMP_NUM_NETCONN > 232 (MEMP_NUM_TCP_PCB + MEMP_NUM_TCP_PCB_LISTEN + MEMP_NUM_UDP_PCB + 233 MEMP_NUM_RAW_PCB)) 234 LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN\n")); 235#endif /* LWIP_NETCONN */ 236#if LWIP_TCP 237 if (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) 238 LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN\n")); 239 if (TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS))) 240 LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work\n")); 241 if (TCP_SNDLOWAT > TCP_SND_BUF) 242 LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than or equal to TCP_SND_BUF.\n")); 243 if (TCP_WND > (PBUF_POOL_SIZE * PBUF_POOL_BUFSIZE)) 244 LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE*PBUF_POOL_BUFSIZE\n")); 245 246 if (TCP_WND < TCP_MSS) 247 LWIP_PLATFORM_DIAG(("lwip_sanity_check: WARNING: TCP_WND is smaller than MSS\n")); 248#endif /* LWIP_TCP */ 249} 250#else /* LWIP_DEBUG */ 251#define lwip_sanity_check() 252#endif /* LWIP_DEBUG */ 253 254static int is_ctl = 0; 255struct netbench_details *nb = NULL; 256 257static struct netif netif; 258 259bool is_this_special_app(void) 260{ 261 return (is_ctl > 0); 262} // end function: is_this_special_app 263 264static void remaining_lwip_initialization(char *card_name, uint64_t queueid) 265{ 266 nb = netbench_alloc("app", RECORDED_EVENTS_COUNT); 267 //asq: connect to the NIC driver, before doing anything else 268 idc_connect_to_driver(card_name, queueid); 269 DEBUGPRINTPS("Connected to driver [%s]\n", card_name); 270 stats_init(); 271 sys_init(); 272 DEBUGPRINTPS("remaining_lwip_init: allocating pbuf memory\n"); 273#ifdef CONFIG_QEMU_NETWORK 274 printf("#### Networking with small amount of memory #####\n"); 275#endif // CONFIG_QEMU_NETWORK 276 printf("#### [%u:%"PRIuDOMAINID":%s] [%s] [%d] MEM_SIZE[%d], " 277 "PBUF_POOL_SIZE[%d], MEMP_MAX[%d], RECEIVE_BUFFERS[%d] qid[%"PRIu64"]####\n", 278 disp_get_core_id(), disp_get_domain_id(), disp_name(), 279 MEM_CONF_LOC, is_ctl, MEM_SIZE, PBUF_POOL_SIZE, MEMP_MAX, 280 RECEIVE_BUFFERS, queueid); 281 282 memp_init(); // 0'st buffer 283 284 DEBUGPRINTPS("remaining_lwip_init: allocating memory for sending\n"); 285 mem_init(); // 1'th buffer 286 DEBUGPRINTPS("remaining_lwip_init: done with memroy allocation\n"); 287 288 DEBUGPRINTPS("LWIP: lwip_starting\n"); 289 netif_init(); 290#if LWIP_SOCKET 291 lwip_socket_init(); 292#endif /* LWIP_SOCKET */ 293 ip_init(); 294 DEBUGPRINTPS("r_lwip_init: done ip_init\n"); 295#if LWIP_ARP 296 etharp_init(); 297#endif /* LWIP_ARP */ 298#if LWIP_RAW 299 raw_init(); 300#endif /* LWIP_RAW */ 301#if LWIP_UDP 302 udp_init(); 303 DEBUGPRINTPS("r_lwip_init: done udp_init\n"); 304#endif /* LWIP_UDP */ 305#if LWIP_TCP 306 tcp_init(); 307 DEBUGPRINTPS("r_lwip_init: done tcp_init\n"); 308#endif /* LWIP_TCP */ 309#if LWIP_SNMP 310 snmp_init(); 311 DEBUGPRINTPS("r_lwip_init: done snmp_init\n"); 312#endif /* LWIP_SNMP */ 313#if LWIP_AUTOIP 314 autoip_init(); 315 DEBUGPRINTPS("r_lwip_init: done autoip_init\n"); 316#endif /* LWIP_AUTOIP */ 317#if LWIP_IGMP 318 igmp_init(); 319 DEBUGPRINTPS("r_lwip_init: done igmp_init\n"); 320#endif /* LWIP_IGMP */ 321 DEBUGPRINTPS("r_lwip_init: done2 igmp_init\n"); 322#if LWIP_DNS 323 DEBUGPRINTPS("r_lwip_init: starting DNS_init\n"); 324 dns_init(); 325 DEBUGPRINTPS("r_lwip_init: done DNS_init\n"); 326#endif /* LWIP_DNS */ 327 DEBUGPRINTPS("LWIP: lwip_started\n"); 328} 329 330extern struct waitset *lwip_waitset; // idc_barrelfish.c 331extern struct thread_mutex *lwip_mutex; // idc_barrelfish.c 332 333/** 334 * To be called by the app which wants to perform DHCP on it's own 335 * In current implementation, it is netd. 336 * Perform Sanity check of user-configurable values, and initialize all modules. 337 */ 338struct netif *owner_lwip_init(char *card_name, uint64_t queueid) 339{ 340 DEBUGPRINTPS("owner_lwip_init: Inside lwip_init\n"); 341 is_ctl = 1; 342 lwip_init(card_name, queueid); 343 DEBUGPRINTPS("LWIP: owner_lwip_init: done with connection setup\n"); 344 return &netif; 345} 346 347static void call_tcp_tmr(void) 348{ 349 lwip_mutex_lock(); 350 tcp_tmr(); 351 lwip_mutex_unlock(); 352} 353 354/** 355 * Perform Sanity check of user-configurable values, and initialize all modules. 356 * 357 * \param card_name Name of service implementing ethernet driver 358 * \param queueid Queueid which is allocated to this application 359 * \param opt_waitset Optional pointer to waitset to be used by LWIP 360 * \param opt_mutex Optional pointer to mutex to protect multi-threaded domains 361 * 362 * \returns True iff init completes 363 */ 364bool lwip_init_ex(const char *card_name, uint64_t queueid, 365 struct waitset *opt_waitset, struct thread_mutex *opt_mutex) 366{ 367 printf("lwip_init_ex: starting......................\n"); 368 DEBUGPRINTPS("LWIP_other: Inside lwip_init\n"); 369 static bool run_once; 370 371 if (run_once) { 372 return false; 373 } 374 run_once = true; 375 376 if (opt_waitset == NULL) { 377 printf("#### %s Going ahead with default wait-set\n", disp_name()); 378 lwip_waitset = get_default_waitset(); 379 } else { 380 printf("#### %s Going ahead with non-default wait-set\n", disp_name()); 381// lwip_waitset = get_default_waitset(); 382 lwip_waitset = opt_waitset; 383 } 384 385 if (opt_mutex != NULL) { 386 lwip_mutex = opt_mutex; 387 } 388 389 /* Sanity check user-configurable values */ 390 lwip_sanity_check(); 391 DEBUGPRINTPS("LWIP: lwip_init: done with sanity check\n"); 392 printf("LWIP: done with sanity check\n"); 393 /* Modules initialization */ 394 char port_manager_name[MAX_NET_SERVICE_NAME_LEN]; 395 396 snprintf(port_manager_name, sizeof(port_manager_name), "%s%s", 397 card_name, NET_PORTS_MNG_SUFFIX); 398 399 // Connecting to the port_manager_service 400 idc_connect_port_manager_service(port_manager_name); 401 402 403 if (is_ctl != 1) { 404 // connecting to ARP lookup service 405 // Doing this before everything else so that we know all needed 406 // services are up and running. 407 char ARP_service_name[MAX_NET_SERVICE_NAME_LEN]; 408 snprintf(ARP_service_name, sizeof(ARP_service_name), "%s%s", 409 card_name, NET_ARP_LOOKUP_SUFFIX); 410 idc_connect_ARP_lookup_service(ARP_service_name); 411 } 412 413 DEBUGPRINTPS("LWIP: lwip_init: done with connection setup\n"); 414 printf("LWIP: done with connection setup\n"); 415 remaining_lwip_initialization((char *) card_name, queueid); 416 417 if (is_ctl != 1) { 418 DEBUGPRINTPS("getting IP from ARP service\n"); 419 printf("LWIP: getting IP from ARP service\n"); 420 idc_get_ip_from_ARP_lookup(); 421 } 422 423 // Register timers... (TCP only) 424 // FIXME: These timers should be added only when first TCP connection 425 // is requested and not when networking is started!!!! 426 static struct periodic_event tcp_timer; 427 errval_t err = periodic_event_create(&tcp_timer, lwip_waitset, 428 TCP_TMR_INTERVAL * 1000, 429 MKCLOSURE((void (*)(void *)) 430 call_tcp_tmr, NULL)); 431 assert(err_is_ok(err)); 432 433 // FIXME: I am not sure if this should be in the codepath for both 434 // is_ctl and non-is_ctl. Specially becasuse non is_ctl is anyways 435 // adding one interface with idc_get_ip* call. 436 437 // Bring interface up 438 struct ip_addr ipaddr, netmask, gw; 439 440 ip_addr_set(&ipaddr, IP_ADDR_ANY); 441 ip_addr_set(&netmask, IP_ADDR_ANY); 442 ip_addr_set(&gw, IP_ADDR_ANY); 443 struct netif *n = netif_add(&netif, &ipaddr, &netmask, &gw, 444 NULL, bfeth_init, ethernet_input); 445 446 assert(n != NULL); 447 extern bool lwip_init_done; 448 lwip_init_done = true; 449 450 printf("lwip_init_ex: done......................\n"); 451 return true; 452} 453 454 455/** 456 * Figure out the best NIC card to connect and initialize library network stack. 457 */ 458bool lwip_init_auto_ex(struct waitset * opt_waitset, 459 struct thread_mutex * opt_mutex) 460{ 461 char *card_name = NULL; 462 uint64_t default_queueid = 0; 463 /* Figure out the best NIC card that can be used */ 464 /* FIXME: hardcoding the NIC card right now, will do smarter detection 465 in future. */ 466 467#ifdef CONFIG_QEMU_NETWORK 468 card_name = "rtl8029"; 469#else 470 // FIXME: also check for e10k 471 // FIXME: get this from kaluga 472 card_name = "e1000"; 473 //card_name = "e10k"; 474 //card_name = "vmkitmon_eth"; 475#endif // CONFIG_QEMU_NETWORK 476 477 return lwip_init_ex(card_name, default_queueid, opt_waitset, opt_mutex); 478} // end function: lwip_init_auto_ex 479 480 481/** 482 * 483 */ 484bool lwip_init_auto(void) 485{ 486 return lwip_init_auto_ex(NULL, NULL); 487} 488 489/** 490 * Perform Sanity check of user-configurable values, and initialize all modules. 491 */ 492bool lwip_init(const char *card_name, uint64_t queueid) 493{ 494 if (card_name == NULL) { 495 return lwip_init_auto_ex(NULL, NULL); 496 } else { 497 return lwip_init_ex(card_name, queueid, NULL, NULL); 498 } 499} 500 501 502void lwip_debug_show_spp_status(int connection) 503{ 504 debug_show_spp_status(connection); 505} 506 507uint64_t wrapper_perform_lwip_work(void) 508{ 509 return perform_lwip_work(); 510} 511 512void lwip_benchmark_control(int direction, uint8_t state, uint64_t trigger, 513 uint64_t cl) 514{ 515// printf("calling lwip_benchmark_control\n"); 516 //idc_benchmark_control(direction, state, trigger, cl); 517} // end function: lwip_benchmark_control 518 519uint8_t lwip_driver_benchmark_state(int direction, uint64_t *delta, 520 uint64_t *cl) 521{ 522 return get_driver_benchmark_state(direction, delta, cl); 523} 524 525#define FREE_SLOT_THRESHOLD 100 526int is_lwip_loaded(void) 527{ 528 // Check for availability of free pbufs 529 if (free_pbuf_pool_count() == 0) { 530 return 1; 531 } 532 533 int slots = lwip_check_sp_capacity(TRANSMIT_CONNECTION); 534 if (slots < FREE_SLOT_THRESHOLD) { 535 return 2; 536 } 537 538 // for receivign connection, one should check if queue is free 539 slots = lwip_check_sp_capacity(RECEIVE_CONNECTION); 540 if (slots < FREE_SLOT_THRESHOLD) { 541// printf("slots left are %d\n", slots); 542 return 5; 543 } 544 545 // Check load on RX connection 546 slots = idc_check_capacity(RECEIVE_CONNECTION); 547 548 if (slots < FREE_SLOT_THRESHOLD) { 549 return 3; 550 } 551 // Check load on TX connection 552 slots = idc_check_capacity(TRANSMIT_CONNECTION); 553 if (slots < FREE_SLOT_THRESHOLD) { 554 return 4; 555 } 556 // Check for load the driver itself 557 uint64_t tx_slots_left = idc_check_driver_load(); 558 559 // Everything is great! 560 return 0; 561} // end function: is_lwip_loaded? 562 563 564 565uint64_t lwip_packet_drop_count(void) 566{ 567 return idc_get_packet_drop_count(); 568} // end function: lwip_packet_drop_count 569 570 571// ****************************************************************** 572// Functions to assist in benchmarking the network path 573 574 575// Records the time (ts) spent in the event (event_type) 576// Simplified version of netbench_record_event_simple by giving default 577// nbp pointer 578void lwip_record_event_simple(uint8_t event_type, uint64_t ts) 579{ 580 netbench_record_event_simple(nb, event_type, ts); 581} // end function: lwip_record_event_simple 582 583void lwip_print_interesting_stats(void) 584{ 585 586 netbench_print_event_stat(nb, RPC_CALL_T, "U: RPC_CALL_T", 1); 587 netbench_print_event_stat(nb, NFS_READCB_T, "U: NFS_READCB_T", 1); 588 netbench_print_event_stat(nb, NFS_READ_T, "U: NFS_READ_T", 1); 589 netbench_print_event_stat(nb, NFS_READ_1_T, "U: NFS_READ_1_T", 1); 590 netbench_print_event_stat(nb, NFS_READ_w_T, "U: NFS_READ_w_T", 1); 591 /* 592 netbench_print_event_stat(nb, RPC_RECV_T, "U: RPC_RECV_T", 1); 593 netbench_print_event_stat(nb, RPC_CALLBACK_T, "U: RPC_CALLBACK_T", 1); 594 netbench_print_event_stat(nb, RPC_RECV_OUT_T, "U: RPC_RECV_OUT_T", 1); 595 */ 596 597/* 598 netbench_print_event_stat(nb, RE_ALL, "U: RX ALL", 1); 599 netbench_print_event_stat(nb, RX_ALL_PROCESS , "U: RX ALL process", 1); 600 netbench_print_event_stat(nb, RE_PBUF_REPLACE, "U: RX Replace pbuf", 1); 601 netbench_print_event_stat(nb, TX_A_SP_RN_CS, "U: Notification pending", 1); 602*/ 603 604/* 605 netbench_print_event_stat(nb, RE_PBUF_REPLACE_1, "U: RX Replace pbuf_1", 1); 606 netbench_print_event_stat(nb, RE_PBUF_REPLACE_2, "U: RX Replace pbuf_2", 1); 607 netbench_print_event_stat(nb, RE_PBUF_REPLACE_3, "U: RX Replace pbuf_3", 1); 608 netbench_print_event_stat(nb, RE_PBUF_QUEUE, "U: RX RPL PbufQ", 1); 609 netbench_print_event_stat(nb, RE_PKT_RCV_CS, "U: RX PKT RCV CS", 1); 610*/ 611 612/* 613 netbench_print_event_stat(nb, TX_SP, "U: TX send-pt", 1); 614 netbench_print_event_stat(nb, TX_SP1, "U: TX send-pt no-noti", 1); 615 netbench_print_event_stat(nb, TX_SPP_FULL, "U: TX D SPP FUL", 0); 616 netbench_print_event_stat(nb, TX_SN_WAIT, "U: TX SN WAIT", 1); 617 netbench_print_event_stat(nb, TX_SN_SEND, "U: TX SN SEND", 1); 618 netbench_print_event_stat(nb, TX_A_SP_RN_CS, "U: TX SP RN CS", 1); 619 netbench_print_event_stat(nb, TX_A_SP_RN_T, "U: TX SP RN T", 1); 620 netbench_print_event_stat(nb, TX_SND_PKT_S, "U: TX SND PKT SLOT", 0); 621 netbench_print_event_stat(nb, TX_SND_PKT_C, "U: TX SND PKTS", 0); 622*/ 623 624} 625 626 627// checks and tells if given hardware feature is enabled or not. 628// NOTE: This code is kept in this file because the information about the 629// card name is available here. But we should move into separate file 630// in future. 631bool is_hw_feature_enabled(int hw_feature) 632{ 633 // FIXME: based on the cardname and configuration, hardware feature's 634 // activeness should be decided 635 return false; 636} // end function: is_hw_feature_enabled 637