core: pxe: additional work on the lwip port
authorH. Peter Anvin <hpa@zytor.com>
Wed, 16 Sep 2009 06:21:24 +0000 (23:21 -0700)
committerEric W. Biederman <ebiederm@xmission.com>
Tue, 12 Apr 2011 21:40:52 +0000 (14:40 -0700)
Additional work on the lwip port.  With this code, we can get pretty
far before having problems.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
core/fs/pxe/isr.c
core/fs/pxe/pxe.c
core/lwip/src/include/lwipopts.h
core/lwip/src/netif/undiif.c

index d645de2..0799061 100644 (file)
@@ -28,7 +28,8 @@ static void pm_return(void)
 
     if (pxe_irq_pending) {
        pxe_irq_pending = 0;
-       sem_up(&pxe_receive_thread_sem);
+       if (pxe_receive_thread_sem.count <= 0)
+         sem_up(&pxe_receive_thread_sem);
     }
 
     __schedule_lock--;
index d655526..b886ed3 100644 (file)
@@ -6,6 +6,9 @@
 #include <minmax.h>
 #include <sys/cpu.h>
 #include "pxe.h"
+#if 1
+#include "lwip/api.h"
+#endif
 
 static uint16_t real_base_mem;    /* Amount of DOS memory after freeing */
 
@@ -1057,7 +1060,16 @@ static void network_init(void)
     if ((DHCPMagic & 1) == 0)
         DHCPMagic = 0;
 
+#if 1
+    extern err_t undi_tcpip_start(struct ip_addr *ipaddr,
+                                 struct ip_addr *netmask,
+                                 struct ip_addr *gw);
+    undi_tcpip_start((struct ip_addr *)&IPInfo.myip,
+                    (struct ip_addr *)&IPInfo.netmask,
+                    (struct ip_addr *)&IPInfo.gateway);
+#else
     udp_init();
+#endif
 }
 
 /*
index 0c67968..53d26e9 100644 (file)
@@ -2,5 +2,6 @@
 #define __LWIPOPTS_H__
 
 #define SYS_LIGHTWEIGHT_PROT   1
+#define LWIP_NETIF_API 1
 
 #endif /* __LWIPOPTS_H__ */
index 9ff004c..4bfd48e 100644 (file)
 #include <lwip/snmp.h>
 #include "netif/etharp.h"
 #include "netif/ppp_oe.h"
+#include "lwip/netifapi.h"
+#include "lwip/tcpip.h"
 
-#include <syslinux/pxe_api.h>
+#include <inttypes.h>
 #include <string.h>
+#include <syslinux/pxe_api.h>
+#include <core.h>
+#include <dprintf.h>
 
 int pxe_call(int, void *);
 #define PKTBUF_SIZE    2048
@@ -66,7 +71,7 @@ int pxe_call(int, void *);
 #define IFNAME0 'u'
 #define IFNAME1 'n'
 
-static struct netif *undi_netif;
+static struct netif undi_netif;
 
 /**
  * In this function, the hardware should be initialized.
@@ -292,7 +297,7 @@ void undiif_input(t_PXENV_UNDI_ISR *isr)
   case ETHTYPE_PPPOE:
 #endif /* PPPOE_SUPPORT */
     /* full packet send to tcpip_thread to process */
-    if (undi_netif->input(p, undi_netif)!=ERR_OK)
+    if (undi_netif.input(p, &undi_netif)!=ERR_OK)
      { LWIP_DEBUGF(NETIF_DEBUG, ("undiif_input: IP input error\n"));
        pbuf_free(p);
        p = NULL;
@@ -318,18 +323,45 @@ void undiif_input(t_PXENV_UNDI_ISR *isr)
  *         ERR_MEM if private data couldn't be allocated
  *         any other err_t on error
  */
-err_t
-undiif_init(struct netif *netif)
+extern uint8_t pxe_irq_vector;
+extern void pxe_isr(void);
+
+/* XXX: move this somewhere sensible */
+static void install_irq_vector(uint8_t irq, void (*isr)(void))
 {
-  LWIP_ASSERT("netif != NULL", (netif != NULL));
+  unsigned int vec;
+
+  if (irq < 8)
+    vec = irq + 0x08;
+  else if (irq < 16)
+    vec = (irq - 8) + 0x70;
+  else
+    return;                    /* ERROR */
+  
+  *(uint32_t *)(vec << 2) = (uint32_t)isr;
+}
 
-  undi_netif = netif;
+static err_t
+undiif_init(struct netif *netif)
+{
+  static __lowmem t_PXENV_UNDI_GET_INFORMATION undi_info;
 
+  LWIP_ASSERT("netif != NULL", (netif != NULL));
 #if LWIP_NETIF_HOSTNAME
   /* Initialize interface hostname */
   netif->hostname = "undi";
 #endif /* LWIP_NETIF_HOSTNAME */
 
+  pxe_call(PXENV_UNDI_GET_INFORMATION, &undi_info);
+
+  dprintf("UNDI: baseio %04x int %d MTU %d type %d\n",
+         undi_info.BaseIo, undi_info.IntNumber, undi_info.MaxTranUnit,
+         undi_info.HwType);
+
+  /* Install the interrupt vector */
+  pxe_irq_vector = undi_info.IntNumber;
+  install_irq_vector(pxe_irq_vector, pxe_isr);
+
   /*
    * Initialize the snmp variables and counters inside the struct netif.
    * The last argument should be replaced with your link speed, in units
@@ -352,3 +384,16 @@ undiif_init(struct netif *netif)
 
   return ERR_OK;
 }
+
+err_t undi_tcpip_start(struct ip_addr *ipaddr,
+                      struct ip_addr *netmask,
+                      struct ip_addr *gw)
+{
+  // Start the TCP/IP thread & init stuff
+  tcpip_init(NULL, NULL);
+
+  // This should be done *after* the threading system and receive thread
+  // have both been started.
+  return netifapi_netif_add(&undi_netif, ipaddr, netmask, gw, NULL,
+                           undiif_init, ethernet_input);
+}