This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

multiple eth devices for RedBoot


Here's a patch I've been playing around with which adds multiple
ethernet device support to RedBoot. RedBoot doesn't support all
of the devices simultaneouly, but it does allow for boot time
selection among available devices. With flash, you can select
the preferred net device through fconfig. Without flash, the
preferred device is selected with CDL. If the preferred device
is not found (or otherwise fails to initialize), the rest of
the devices are tried in order until one is successfully
initialized. The first one successfully initialized becomes the
RedBoot net device.

What do other folks think about this? I really wish there was a
way to eliminate CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS. I
couldn't think of a better build-time way to determine that there
are multiple devices configured into the system.

--Mark


Index: redboot/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/ChangeLog,v
retrieving revision 1.97
diff -u -p -5 -r1.97 ChangeLog
--- redboot/current/ChangeLog	19 Mar 2003 16:22:11 -0000	1.97
+++ redboot/current/ChangeLog	19 Mar 2003 19:57:08 -0000
@@ -1,5 +1,13 @@
+2003-03-19  Mark Salter  <msalter at redhat dot com>
+
+	* include/flash_config.h (CONFIG_NETPORT): New config option.
+	* src/flash.c: Support CONFIG_NETPORT.
+	* cdl/redboot.cdl: New options to support multiple ethernet devices.
+	* src/net/net_io.c: Support multiple ethernet devices.
+	* include/net/net.h: Add externs for net_devname and net_devindex.
+	
 2002-03-19  John Dallaway  <jld at ecoscentric dot com>
 
 	* doc/redboot_installing.sgml: Update Atmel AT91EB40 RedBoot
 	installation instructions.
 
Index: redboot/current/cdl/redboot.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/cdl/redboot.cdl,v
retrieving revision 1.45
diff -u -p -5 -r1.45 redboot.cdl
--- redboot/current/cdl/redboot.cdl	24 Feb 2003 14:32:21 -0000	1.45
+++ redboot/current/cdl/redboot.cdl	19 Mar 2003 19:57:10 -0000
@@ -349,10 +349,30 @@ cdl_package CYGPKG_REDBOOT {
                       This option sets the timeout used when looking up an
                       address via the DNS. Default is 10 seconds."
                 }
     
             }
+
+            cdl_component CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS {
+                display          "More than one network devices supported"
+                flavor           bool
+                default_value    0
+                description      "
+                  Enabling this option will allow the RedBoot networking
+                stack to select among more than one network driver. By default,
+                the first device to initialize successfully is used."
+    
+                cdl_option CYGNUM_REDBOOT_DEFAULT_NETWORK_DEVICE {
+                    display         "Default network device driver"
+                    flavor          data
+                    active_if       !CYGSEM_REDBOOT_FLASH_CONFIG
+                    default_value   0
+                    description     "
+                        This is the index of the first network device driver that
+                        RedBoot will try to initialize."
+                }
+            }
         }
     
         cdl_option CYGPKG_REDBOOT_ANY_CONSOLE {
             display       "Allow RedBoot to use any I/O channel for its console."
             flavor        bool
Index: redboot/current/include/flash_config.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/include/flash_config.h,v
retrieving revision 1.8
diff -u -p -5 -r1.8 flash_config.h
--- redboot/current/include/flash_config.h	23 May 2002 23:08:27 -0000	1.8
+++ redboot/current/include/flash_config.h	19 Mar 2003 19:57:10 -0000
@@ -6,11 +6,11 @@
 //
 //==========================================================================
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
 // Software Foundation; either version 2 or (at your option) any later version.
 //
@@ -65,10 +65,11 @@
 #define CONFIG_STRING  3
 #define CONFIG_SCRIPT  4
 #ifdef CYGPKG_REDBOOT_NETWORKING
 #define CONFIG_IP      5
 #define CONFIG_ESA     6
+#define CONFIG_NETPORT 7
 #endif
 
 struct config_option {
     char *key;
     char *title;
Index: redboot/current/include/net/net.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/include/net/net.h,v
retrieving revision 1.15
diff -u -p -5 -r1.15 net.h
--- redboot/current/include/net/net.h	16 Jul 2002 16:25:42 -0000	1.15
+++ redboot/current/include/net/net.h	19 Mar 2003 19:57:12 -0000
@@ -6,11 +6,11 @@
 //
 //==========================================================================
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
 // Copyright (C) 2002 Gary Thomas
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
 // Software Foundation; either version 2 or (at your option) any later version.
@@ -614,10 +614,14 @@ extern void net_init(void);
 extern void net_io_test(bool is_idle);
 
 // Conversion between IP addresses and printable strings
 extern bool  inet_aton(const char *, in_addr_t *);
 extern char *inet_ntoa(in_addr_t *);
+
+// Network device table access
+extern const char *net_devname(unsigned index);
+extern int net_devindex(char *name);
 
 // FIXME
 /* #define NET_SUPPORT_RARP  1 */
 #define NET_SUPPORT_ICMP 1
 #define NET_SUPPORT_UDP  1
Index: redboot/current/src/flash.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/src/flash.c,v
retrieving revision 1.43
diff -u -p -5 -r1.43 flash.c
--- redboot/current/src/flash.c	3 Mar 2003 17:10:14 -0000	1.43
+++ redboot/current/src/flash.c	19 Mar 2003 19:57:16 -0000
@@ -6,11 +6,11 @@
 //
 //==========================================================================
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
 // Software Foundation; either version 2 or (at your option) any later version.
 //
@@ -1401,10 +1401,15 @@ get_config(unsigned char *dp, char *titl
         for (esa_ptr = 0;  esa_ptr < sizeof(enet_addr_t);  esa_ptr++) {
             lp += diag_sprintf(lp, "0x%02X", ((unsigned char *)val_ptr)[esa_ptr]);
             if (esa_ptr < (sizeof(enet_addr_t)-1)) lp += diag_sprintf(lp, ":");
         }
         break;
+#ifdef CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS
+    case CONFIG_NETPORT:
+        lp += diag_sprintf(lp, "%s", (unsigned char *)val_ptr);
+        break;
+#endif
 #endif
     case CONFIG_STRING:
         lp += diag_sprintf(lp, "%s", (unsigned char *)val_ptr);
         break;
     case CONFIG_SCRIPT:
@@ -1500,10 +1505,23 @@ get_config(unsigned char *dp, char *titl
             }
             ((unsigned char *)val_ptr)[esa_ptr] = esa_byte;
         }
         return CONFIG_CHANGED;
         break;
+#ifdef CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS
+    case CONFIG_NETPORT:
+	if (strlen(line) >= MAX_STRING_LENGTH || net_devindex(line) < 0) {
+	    int index;
+	    const char *name;
+	    diag_printf("Sorry, Port name must be one of:\n");
+	    for (index = 0; name = net_devname(index); index++)
+		diag_printf("    %s\n", name);
+            return CONFIG_BAD;
+	}
+        strcpy((unsigned char *)val_ptr, line);
+	break;
+#endif
 #endif
     case CONFIG_SCRIPT:
         // Assume it always changes
         sp = (unsigned char *)val_ptr;
         diag_printf("Enter script, terminate with empty line\n");
@@ -1548,10 +1566,14 @@ config_length(int type)
         return sizeof(in_addr_t);
     case CONFIG_ESA:
         // Would like this to be sizeof(enet_addr_t), but that causes much
         // pain since it fouls the alignment of data which follows.
         return 8;
+#ifdef CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS
+    case CONFIG_NETPORT:
+        return MAX_STRING_LENGTH;
+#endif
 #endif
     case CONFIG_STRING:
         return MAX_STRING_LENGTH;
     case CONFIG_SCRIPT:
         return MAX_SCRIPT_LENGTH;
@@ -1960,10 +1982,25 @@ flash_config_insert_value(unsigned char 
         memcpy(dp, (void *)&opt->dflt, sizeof(in_addr_t));
         break;
     case CONFIG_ESA:
         memcpy(dp, (void *)&opt->dflt, sizeof(enet_addr_t));
         break;
+#ifdef CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS
+    case CONFIG_NETPORT:
+	// validate dflt and if not acceptable use first port
+        {
+	    int index;
+	    const char *name;
+	    for (index = 0; (name = net_devname(index)) != NULL; index++)
+		if (!strcmp((char *)opt->dflt, name))
+		    break;
+	    if (name == NULL)
+		name = net_devname(0);
+	    memcpy(dp, name, strlen(name) + 1);
+        }
+        break;
+#endif
 #endif
     case CONFIG_STRING:
         memcpy(dp, (void *)opt->dflt, config_length(CONFIG_STRING));
         break;
     case CONFIG_SCRIPT:
Index: redboot/current/src/net/net_io.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/redboot/current/src/net/net_io.c,v
retrieving revision 1.31
diff -u -p -5 -r1.31 net_io.c
--- redboot/current/src/net/net_io.c	11 Sep 2002 12:14:52 -0000	1.31
+++ redboot/current/src/net/net_io.c	19 Mar 2003 19:57:16 -0000
@@ -6,11 +6,11 @@
 //
 //==========================================================================
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
-// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
 // Copyright (C) 2002 Gary Thomas
 //
 // eCos is free software; you can redistribute it and/or modify it under
 // the terms of the GNU General Public License as published by the Free
 // Software Foundation; either version 2 or (at your option) any later version.
@@ -74,10 +74,18 @@ RedBoot_config_option("Network debug at 
                       net_debug, 
                       ALWAYS_ENABLED, true,
                       CONFIG_BOOL,
                       false
     );
+#ifdef CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS
+RedBoot_config_option("Default network device", 
+                      net_device, 
+                      ALWAYS_ENABLED, true,
+                      CONFIG_NETPORT,
+                      ""
+    );
+#endif
 // Note: the following options are related.  If 'bootp' is false, then
 // the other values are used in the configuration.  Because of the way
 // that configuration tables are generated, they should have names which
 // are related.  The configuration options will show up lexicographically
 // ordered, thus the peculiar naming.  In this case, the 'use' option is
@@ -607,14 +615,51 @@ flash_get_IP(char *id, ip_addr_t *val)
         }        
     }
 }
 #endif
 
+static cyg_netdevtab_entry_t *
+net_devtab_entry(unsigned index)
+{
+    cyg_netdevtab_entry_t *t = &__NETDEVTAB__[index];
+
+    if (t < &__NETDEVTAB__[0] || t >= &__NETDEVTAB_END__)
+	return NULL;
+
+    return t;
+}
+
+const char *
+net_devname(unsigned index)
+{
+    cyg_netdevtab_entry_t *t = net_devtab_entry(index);
+    if (t)
+	return t->name;
+    return NULL;
+}
+
+int
+net_devindex(char *name)
+{
+    const char *devname;
+    int index;
+
+    for (index = 0; (devname = net_devname(index)) != NULL; index++)
+	if (!strcmp(name, devname))
+	    return index;
+    return -1;
+}
+
 void
 net_init(void)
 {
     cyg_netdevtab_entry_t *t;
+    unsigned index;
+#ifdef CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS
+    char *default_devname;
+    int default_index;
+#endif
 
     // Set defaults as appropriate
 #ifdef CYGSEM_REDBOOT_DEFAULT_NO_BOOTP
     use_bootp = false;
 #else
@@ -626,10 +671,13 @@ net_init(void)
     net_debug = false;
 #endif
     gdb_port = CYGNUM_REDBOOT_NETWORKING_TCP_PORT;
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
     // Fetch values from saved config data, if available
+#ifdef CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS
+    flash_get_config("net_device", &default_devname, CONFIG_NETPORT);
+#endif
     flash_get_config("net_debug", &net_debug, CONFIG_BOOL);
     flash_get_config("gdb_port", &gdb_port, CONFIG_INT);
     flash_get_config("bootp", &use_bootp, CONFIG_BOOL);
     if (!use_bootp)
     {
@@ -650,19 +698,44 @@ net_init(void)
 # endif
     have_net = false;
     // Make sure the recv buffers are set up
     eth_drv_buffers_init();
     __pktbuf_init();
-    // Initialize all network devices
-    for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
-        if (t->init(t)) {
+
+    // Initialize network device.
+    // Try default device first, then others
+#ifdef CYGNUM_REDBOOT_DEFAULT_NETWORK_DEVICE
+    default_devname = net_devname(CYGNUM_REDBOOT_DEFAULT_NETWORK_DEVICE);
+#endif
+
+#ifdef CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS
+    default_index = net_devindex(default_devname);
+    if (default_index < 0)
+	default_index = 0;
+    if ((t = net_devtab_entry(default_index)) != NULL) {
+	if (t->init(t))
             t->status = CYG_NETDEVTAB_STATUS_AVAIL;
-        } else {
-            // What to do if device init fails?
-            t->status = 0;  // Device not [currently] available
-        }
+	else
+#endif
+	{
+	    for (index = 0; t = net_devtab_entry(index); index++) {
+#ifdef CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS
+		if (index == default_index)
+		    continue;
+#endif
+		if (t->init(t)) {
+		    t->status = CYG_NETDEVTAB_STATUS_AVAIL;
+		    break; // stop after first good device found
+		} else {
+		    // What to do if device init fails?
+		    t->status = 0;  // Device not [currently] available
+		}
+	    }
+	}
+#ifdef CYGSEM_REDBOOT_NETWORKING_HAS_MULTIPLE_DEVS
     }
+#endif
     if (!__local_enet_sc) {
         diag_printf("No network interfaces found\n");
         return;
     }    
     // Initialize the network [if present]

-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]