diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index ec71b447..749c5ff5 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -267,18 +267,19 @@ static void rtl8139if_handler(struct state* s) } } -/* - * Can be called in a polling manner, or only after the RTL8139 has raised - * an interrupt request. - */ -err_t rtl8139if_poll(struct netif* netif) +err_t rtl8139if_wait(struct netif* netif, uint32_t poll) { rtl1839if_t* rtl8139if = netif->state; struct eth_hdr *ethhdr; struct pbuf *p = NULL; err_t err = ERR_OK; - - mailbox_ptr_fetch(&(rtl8139if->mbox), (void**) &p); + + if (poll) { + if (mailbox_ptr_tryfetch(&(rtl8139if->mbox), (void**) &p)) + return err; + } else { + mailbox_ptr_fetch(&(rtl8139if->mbox), (void**) &p); + } /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; diff --git a/drivers/net/rtl8139.h b/drivers/net/rtl8139.h index f8e4ef7e..c1d4325e 100644 --- a/drivers/net/rtl8139.h +++ b/drivers/net/rtl8139.h @@ -229,7 +229,17 @@ typedef struct rtl1839if { mailbox_ptr_t mbox; } rtl1839if_t; -err_t rtl8139if_poll(struct netif* netif); +/* + * Wait for incoming messages. + * + * poll = 0 : wait blocks until a message is received + * poll != 0: non-blocking wait + */ +err_t rtl8139if_wait(struct netif* netif, uint32_t poll); + +/* + * Initialize the network driver for the RealTek RTL8139 family + */ err_t rtl8139if_init(struct netif* netif); #endif diff --git a/kernel/Makefile b/kernel/Makefile index 70009bff..5bee79f0 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -1,4 +1,4 @@ -C_source = main.c tasks.c processor.c syscall.c tests.c echo.c ping.c +C_source = main.c tasks.c processor.c syscall.c tests.c echo.c ping.c net.c OBJS += $(patsubst %.c, %.o, $(filter %.c, $(C_source))) diff --git a/kernel/main.c b/kernel/main.c index e9367aeb..0ccd4824 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -29,22 +29,9 @@ #include #include #include -#ifdef CONFIG_PCI -#include -#endif -#ifdef CONFIG_LWIP -#include -#include -#include -#include -#include -#include -#include -#include -#endif -#include extern int test_init(void); +extern int network_init(void); /* * Note that linker symbols are not variables, they have no memory allocated for @@ -89,73 +76,11 @@ static void list_root(void) { list_fs(fs_root, 1); } -#if defined(CONFIG_LWIP) && defined(CONFIG_PCI) -void echo_init(void); -void ping_init(void); - -int STDCALL rtl8139if_task(void* arg) -{ - struct netif netif; - struct ip_addr ipaddr; - struct ip_addr netmask; - struct ip_addr gw; - uint32_t mscnt = 0; - - kputs("Network task is started\n"); - - /* Set network address variables */ - //IP4_ADDR(&gw, 192,168,1,254); - //IP4_ADDR(&ipaddr, 192,168,1,100); - //IP4_ADDR(&netmask, 255,255,255,0); - /* 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); - - /* Clear the IP address, Subnet Mask, and Gateway */ - ipaddr.addr = 0; - netmask.addr = 0; - gw.addr = 0; - - /* Bring up the network interface */ - if (!netif_add(&netif, &ipaddr, &netmask, &gw, NULL, rtl8139if_init, ethernet_input)) { - kputs("Unable to add network interface\n"); - return -ENXIO; - } - - netif_set_default(&netif); - - if (netif_is_up(&netif)) { - kputs("Network interface is not up\n"); - return -EIO; - } - - kprintf("Starting DHCPCD...\n"); - dhcp_start(&netif); - - // start echo server - echo_init(); - ping_init(); - - while(1) { - rtl8139if_poll(&netif); - } - - dhcp_release(&netif); - dhcp_stop(&netif); - - return 0; -} -#endif - int main(void) { -#if defined(CONFIG_LWIP) && defined(CONFIG_PCI) - tid_t rtl8139_id; -#endif - kprintf("This is MetalSVM %s Build %u, %u, %u\n", METALSVM_VERSION, &__BUILD_VERSION, &__BUILD_DATE, &__BUILD_TIME); + lowlevel_init(); system_init(); irq_init(); timer_init(); @@ -172,9 +97,7 @@ int main(void) kprintf("Kernel starts at %p and ends at %p\n", &kernel_start, &kernel_end); system_calibration(); -#ifdef CONFIG_LWIP - lwip_init(); -#endif + network_init(); kprintf("Processor frequency: %u MHz\n", get_cpu_frequency()); kprintf("Total memory: %u MBytes\n", atomic_int32_read(&total_pages)/((1024*1024)/PAGE_SIZE)); @@ -185,10 +108,6 @@ int main(void) list_root(); //test_init(); -#if defined(CONFIG_LWIP) && defined(CONFIG_PCI) - create_kernel_task(&rtl8139_id, rtl8139if_task, NULL); -#endif - per_core(current_task)->status = TASK_IDLE; reschedule(); diff --git a/kernel/net.c b/kernel/net.c new file mode 100644 index 00000000..66966bd1 --- /dev/null +++ b/kernel/net.c @@ -0,0 +1,125 @@ +/* + * 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 +#ifdef CONFIG_LWIP +#include +#include +#include +#include +#include +#include +#include +#include +#endif +#include + +void echo_init(void); +void ping_init(void); + +static volatile int done = 0; + +#if defined(CONFIG_LWIP) && defined(CONFIG_PCI) +static tid_t netid; + +int STDCALL network_task(void* arg) +{ + struct netif netif; + struct ip_addr ipaddr; + struct ip_addr netmask; + struct ip_addr gw; + + kputs("Network task is started\n"); + + /* Set network address variables */ + //IP4_ADDR(&gw, 192,168,1,254); + //IP4_ADDR(&ipaddr, 192,168,1,100); + //IP4_ADDR(&netmask, 255,255,255,0); + /* 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); + + /* Clear the IP address, Subnet Mask, and Gateway */ + ipaddr.addr = 0; + netmask.addr = 0; + gw.addr = 0; + + /* Bring up the network interface */ + if (!netif_add(&netif, &ipaddr, &netmask, &gw, NULL, rtl8139if_init, ethernet_input)) { + kputs("Unable to add network interface\n"); + return -ENXIO; + } + + netif_set_default(&netif); + + if (netif_is_up(&netif)) { + kputs("Network interface is not up\n"); + return -EIO; + } + + kprintf("Starting DHCPCD...\n"); + dhcp_start(&netif); + + /* wait for ip address */ + while(!netif.ip_addr.addr) { + rtl8139if_wait(&netif, 1); + udelay(500000); + } + + // start echo and ping server + echo_init(); + ping_init(); + + while(!done) { + rtl8139if_wait(&netif, 0); + } + + dhcp_release(&netif); + dhcp_stop(&netif); + + return 0; +} +#endif + +int network_shotdown(void) +{ + done = 1; + + return 0; +} + +int network_init(void) +{ +#if defined(CONFIG_LWIP) + lwip_init(); +#endif + +#if defined(CONFIG_LWIP) && defined(CONFIG_PCI) + return create_kernel_task(&netid, network_task, NULL); +#else + return 0; +#endif +}