/* * Copyright 2010 Stefan Lankes, Chair for Operating Systems, * RWTH Aachen University * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This file is part of MetalSVM. */ #include #include #include #include #include #include #include #include #ifdef CONFIG_LWIP #include #include #include #include #include #include #include #include #include #include #endif #include #include #include #ifdef CONFIG_ROCKCREEK #include #include #endif void echo_init(void); void ping_init(void); /* * Note that linker symbols are not variables, they have no memory allocated for * maintaining a value, rather their address is their value. */ extern const void bss_start; extern const void bss_end; int lowlevel_init(void) { // initialize .bss section memset((void*)&bss_start, 0x00, ((size_t) &bss_end - (size_t) &bss_start)); koutput_init(); //kprintf("Now, the BSS section (0x%x - 0x%x) is initialized.\n", (size_t) &bss_start, (size_t) &bss_end); return 0; } #if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK)) static struct netif* default_netif = NULL; static volatile uint32_t lwip_initialized = 0; static void tcp_init_ok(void* e) { kputs("TCP/IP init COMPLETE!!\n"); lwip_initialized = 1; } #endif int network_init(void) { #if defined(CONFIG_LWIP) && (defined(CONFIG_PCI) || defined(CONFIG_ROCKCREEK)) struct ip_addr ipaddr; struct ip_addr netmask; struct ip_addr gw; kputs("Initialize network...\n"); // Initialize lwIP modules tcpip_init(tcp_init_ok, NULL); while(!lwip_initialized) { reschedule(); } // Set up the lwIP network interface // Allocate and configure netif default_netif = (struct netif *) mem_malloc(sizeof(struct netif)); if(default_netif == NULL) { kprintf("ERROR: Out of memory for default netif\n"); return -ENOMEM; } memset(default_netif, 0x00, sizeof(struct netif)); #ifdef CONFIG_ROCKCREEK /* Set network address variables */ IP4_ADDR(&gw, 192,168,4,254); IP4_ADDR(&ipaddr, 192,168,4,RCCE_ue()+1); IP4_ADDR(&netmask, 255,255,255,0); /* Bring up the network interface */ if (!netif_add(default_netif, &ipaddr, &netmask, &gw, NULL, rckemacif_init, tcpip_input)) { #else /* Clear network address because we use DHCP to get an ip address */ IP4_ADDR(&gw, 0,0,0,0); IP4_ADDR(&ipaddr, 0,0,0,0); IP4_ADDR(&netmask, 0,0,0,0); /* Bring up the network interface */ if (!netif_add(default_netif, &ipaddr, &netmask, &gw, NULL, rtl8139if_init, tcpip_input)) { #endif kputs("Unable to add network interface\n"); return -ENODEV; } netif_set_default(default_netif); netif_set_up(default_netif); /* test if interface is really up */ if (!netif_is_up(default_netif)) { kputs("network interface is not up\n"); return -ENODEV; } #ifndef CONFIG_ROCKCREEK kprintf("Starting DHCPCD...\n"); dhcp_start(default_netif); int mscnt = 0; /* wait for ip address */ while(!default_netif->ip_addr.addr) { sys_msleep(DHCP_FINE_TIMER_MSECS); dhcp_fine_tmr(); mscnt += DHCP_FINE_TIMER_MSECS; if (mscnt >= DHCP_COARSE_TIMER_SECS*1000) { dhcp_coarse_tmr(); mscnt = 0; } } #else mmnif_open(); #endif // start echo and ping server echo_init(); ping_init(); #endif return 0; } int network_shutdown(void) { #if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK) mmnif_close(); #elif defined(CONFIG_LWIP) && defined(CONFIG_PCI) dhcp_release(default_netif); dhcp_stop(default_netif); #endif mem_free(default_netif); default_netif = NULL; return 0; }