[syslinux:lwip] lwip: undiif - initial cut at a UNDI Ethernet-only driver

syslinux-bot for H. Peter Anvin hpa at zytor.com
Fri Apr 22 20:05:31 PDT 2011


Commit-ID:  dcd83b8797252c196e5724508179e9688c7eba20
Gitweb:     http://syslinux.zytor.com/commit/dcd83b8797252c196e5724508179e9688c7eba20
Author:     H. Peter Anvin <hpa at zytor.com>
AuthorDate: Thu, 10 Sep 2009 13:21:53 -0700
Committer:  Eric W. Biederman <ebiederm at xmission.com>
CommitDate: Tue, 12 Apr 2011 14:40:51 -0700

lwip: undiif - initial cut at a UNDI Ethernet-only driver

Initial cut at an UNDI driver -- still needs to be reworked to handle
the receive side.  For now, assume the underlying interface is
Ethernet; supporting generic media types will require changes to the
ARP handling in lwIP.

Signed-off-by: H. Peter Anvin <hpa at zytor.com>


---
 core/lwip/src/netif/{ethernetif.c => undiif.c} |  165 ++++++++++++++----------
 1 files changed, 94 insertions(+), 71 deletions(-)

diff --git a/core/lwip/src/netif/ethernetif.c b/core/lwip/src/netif/undiif.c
similarity index 74%
copy from core/lwip/src/netif/ethernetif.c
copy to core/lwip/src/netif/undiif.c
index a5b7d99..192f396 100644
--- a/core/lwip/src/netif/ethernetif.c
+++ b/core/lwip/src/netif/undiif.c
@@ -6,9 +6,9 @@
 
 /*
  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
- * All rights reserved. 
- * 
- * Redistribution and use in source and binary forms, with or without modification, 
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *
  * 1. Redistributions of source code must retain the above copyright notice,
@@ -17,21 +17,21 @@
  *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
  * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission. 
+ *    derived from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
- * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
- * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
  * OF SUCH DAMAGE.
  *
  * This file is part of the lwIP TCP/IP stack.
- * 
+ *
  * Author: Adam Dunkels <adam at sics.se>
  *
  */
@@ -43,9 +43,9 @@
  * something that better describes your network interface.
  */
 
-#include "lwip/opt.h"
+#include <core.h>
 
-#if 0 /* don't build, this is only a skeleton, see previous comment */
+#include "lwip/opt.h"
 
 #include "lwip/def.h"
 #include "lwip/mem.h"
@@ -56,8 +56,14 @@
 #include "netif/etharp.h"
 #include "netif/ppp_oe.h"
 
+#include <syslinux/pxe_api.h>
+#include <string.h>
+
+int pxe_call(int, void *);
+#define PKTBUF_SIZE	2048
+
 /* Define those to better describe your network interface. */
-#define IFNAME0 'e'
+#define IFNAME0 'u'
 #define IFNAME1 'n'
 
 /**
@@ -66,42 +72,43 @@
  * as it is already kept in the struct netif.
  * But this is only an example, anyway...
  */
-struct ethernetif {
+struct undiif {
   struct eth_addr *ethaddr;
   /* Add whatever per-interface state that is needed here. */
 };
 
 /* Forward declarations. */
-static void  ethernetif_input(struct netif *netif);
+static void  undiif_input(struct netif *netif);
 
 /**
  * In this function, the hardware should be initialized.
- * Called from ethernetif_init().
+ * Called from undiif_init().
  *
  * @param netif the already initialized lwip network interface structure
- *        for this ethernetif
+ *        for this undiif
  */
 static void
 low_level_init(struct netif *netif)
 {
-  struct ethernetif *ethernetif = netif->state;
-  
+  static __lowmem t_PXENV_UNDI_GET_INFORMATION undi_info;
+  /* struct undiif *undiif = netif->state; */
+
+  pxe_call(PXENV_UNDI_GET_INFORMATION, &undi_info);
+
   /* set MAC hardware address length */
-  netif->hwaddr_len = ETHARP_HWADDR_LEN;
+  netif->hwaddr_len = undi_info.HwAddrLen;
 
   /* set MAC hardware address */
-  netif->hwaddr[0] = ;
-  ...
-  netif->hwaddr[5] = ;
+  memcpy(netif->hwaddr, undi_info.CurrentNodeAddress, undi_info.HwAddrLen);
 
   /* maximum transfer unit */
-  netif->mtu = 1500;
-  
+  netif->mtu = undi_info.MaxTranUnit;
+
   /* device capabilities */
   /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
   netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
- 
-  /* Do whatever else is needed to initialize interface. */  
+
+  /* Do whatever else is needed to initialize interface. */
 }
 
 /**
@@ -109,7 +116,7 @@ low_level_init(struct netif *netif)
  * contained in the pbuf that is passed to the function. This pbuf
  * might be chained.
  *
- * @param netif the lwip network interface structure for this ethernetif
+ * @param netif the lwip network interface structure for this undiif
  * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
  * @return ERR_OK if the packet could be sent
  *         an err_t value if the packet couldn't be sent
@@ -120,31 +127,54 @@ low_level_init(struct netif *netif)
  *       dropped because of memory failure (except for the TCP timers).
  */
 
+/*
+ * XXX: This assumes an Ethernet media type.
+ */
 static err_t
 low_level_output(struct netif *netif, struct pbuf *p)
 {
-  struct ethernetif *ethernetif = netif->state;
+  struct pxe_xmit {
+    t_PXENV_UNDI_TRANSMIT xmit;
+    t_PXENV_UNDI_TBD tbd;
+  };
+  static __lowmem struct pxe_xmit pxe;
+  static __lowmem char pkt_buf[PKTBUF_SIZE];
+  char *r;
+  /* struct undiif *undiif = netif->state; */
   struct pbuf *q;
+  static char eth_broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+  (void)netif;
 
-  initiate transfer();
-  
 #if ETH_PAD_SIZE
   pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
 #endif
 
-  for(q = p; q != NULL; q = q->next) {
+  memset(&pxe, 0, sizeof pxe);
+
+  r = pkt_buf;
+  for (q = p; q != NULL; q = q->next) {
     /* Send the data from the pbuf to the interface, one pbuf at a
        time. The size of the data in each pbuf is kept in the ->len
        variable. */
-    send data from(q->payload, q->len);
+    memcpy(r, q->payload, q->len);
+    r += q->len;
   }
 
-  signal that packet should be sent();
+  pxe.xmit.Protocol = 0;	/* XXX: P_UNKNOWN: MAC layer */
+  pxe.xmit.XmitFlag = !memcmp(pkt_buf, eth_broadcast, sizeof eth_broadcast);
+  pxe.xmit.DestAddr = FAR_PTR(pkt_buf);
+  pxe.xmit.TBD = FAR_PTR(&pxe.tbd);
+  pxe.tbd.ImmedLength = r - pkt_buf;
+  pxe.tbd.Xmit = FAR_PTR(pkt_buf);
+  pxe.tbd.DataBlkCount = 0;
+
+  pxe_call(PXENV_UNDI_TRANSMIT, &pxe.xmit);
 
 #if ETH_PAD_SIZE
   pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
 #endif
-  
+
   LINK_STATS_INC(link.xmit);
 
   return ERR_OK;
@@ -154,20 +184,20 @@ low_level_output(struct netif *netif, struct pbuf *p)
  * Should allocate a pbuf and transfer the bytes of the incoming
  * packet from the interface into the pbuf.
  *
- * @param netif the lwip network interface structure for this ethernetif
+ * @param netif the lwip network interface structure for this undiif
  * @return a pbuf filled with the received packet (including MAC header)
  *         NULL on memory error
  */
 static struct pbuf *
 low_level_input(struct netif *netif)
 {
-  struct ethernetif *ethernetif = netif->state;
+  struct undiif *undiif = netif->state;
   struct pbuf *p, *q;
   u16_t len;
 
   /* Obtain the size of the packet and put it into the "len"
      variable. */
-  len = ;
+  len = 0;
 
 #if ETH_PAD_SIZE
   len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
@@ -175,7 +205,7 @@ low_level_input(struct netif *netif)
 
   /* We allocate a pbuf chain of pbufs from the pool. */
   p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
-  
+
   if (p != NULL) {
 
 #if ETH_PAD_SIZE
@@ -187,15 +217,10 @@ low_level_input(struct netif *netif)
     for(q = p; q != NULL; q = q->next) {
       /* Read enough bytes to fill this pbuf in the chain. The
        * available data in the pbuf is given by the q->len
-       * variable.
-       * This does not necessarily have to be a memcpy, you can also preallocate
-       * pbufs for a DMA-enabled MAC and after receiving truncate it to the
-       * actually received size. In this case, ensure the tot_len member of the
-       * pbuf is the sum of the chained pbuf len members.
-       */
-      read data into(q->payload, q->len);
+       * variable. */
+	// read data into(q->payload, q->len);
     }
-    acknowledge that packet has been read();
+    // acknowledge that packet has been read();
 
 #if ETH_PAD_SIZE
     pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
@@ -203,12 +228,12 @@ low_level_input(struct netif *netif)
 
     LINK_STATS_INC(link.recv);
   } else {
-    drop packet();
+      // drop packet();
     LINK_STATS_INC(link.memerr);
     LINK_STATS_INC(link.drop);
   }
 
-  return p;  
+  return p;
 }
 
 /**
@@ -218,16 +243,16 @@ low_level_input(struct netif *netif)
  * interface. Then the type of the received packet is determined and
  * the appropriate input function is called.
  *
- * @param netif the lwip network interface structure for this ethernetif
+ * @param netif the lwip network interface structure for this undiif
  */
 static void
-ethernetif_input(struct netif *netif)
+undiif_input(struct netif *netif)
 {
-  struct ethernetif *ethernetif;
+  struct undiif *undiif;
   struct eth_hdr *ethhdr;
   struct pbuf *p;
 
-  ethernetif = netif->state;
+  undiif = netif->state;
 
   /* move received packet into a new pbuf */
   p = low_level_input(netif);
@@ -247,7 +272,7 @@ ethernetif_input(struct netif *netif)
 #endif /* PPPOE_SUPPORT */
     /* full packet send to tcpip_thread to process */
     if (netif->input(p, netif)!=ERR_OK)
-     { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
+     { LWIP_DEBUGF(NETIF_DEBUG, ("undiif_input: IP input error\n"));
        pbuf_free(p);
        p = NULL;
      }
@@ -267,21 +292,21 @@ ethernetif_input(struct netif *netif)
  *
  * This function should be passed as a parameter to netif_add().
  *
- * @param netif the lwip network interface structure for this ethernetif
+ * @param netif the lwip network interface structure for this undiif
  * @return ERR_OK if the loopif is initialized
  *         ERR_MEM if private data couldn't be allocated
  *         any other err_t on error
  */
 err_t
-ethernetif_init(struct netif *netif)
+undiif_init(struct netif *netif)
 {
-  struct ethernetif *ethernetif;
+  struct undiif *undiif;
 
   LWIP_ASSERT("netif != NULL", (netif != NULL));
-    
-  ethernetif = mem_malloc(sizeof(struct ethernetif));
-  if (ethernetif == NULL) {
-    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
+
+  undiif = mem_malloc(sizeof(struct undiif));
+  if (undiif == NULL) {
+    LWIP_DEBUGF(NETIF_DEBUG, ("undiif_init: out of memory\n"));
     return ERR_MEM;
   }
 
@@ -297,7 +322,7 @@ ethernetif_init(struct netif *netif)
    */
   NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
 
-  netif->state = ethernetif;
+  netif->state = undiif;
   netif->name[0] = IFNAME0;
   netif->name[1] = IFNAME1;
   /* We directly use etharp_output() here to save a function call.
@@ -306,13 +331,11 @@ ethernetif_init(struct netif *netif)
    * is available...) */
   netif->output = etharp_output;
   netif->linkoutput = low_level_output;
-  
-  ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
-  
+
+  undiif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
+
   /* initialize the hardware */
   low_level_init(netif);
 
   return ERR_OK;
 }
-
-#endif /* 0 */



More information about the Syslinux-commits mailing list