changeset 849:23fd347aba65

support multiple net drivers in RedBoot
author msalter
date Thu, 20 Mar 2003 15:44:39 +0000
parents ddac09c38f55
children c3c6ed4ef316
files packages/io/eth/current/ChangeLog packages/io/eth/current/cdl/eth_drivers.cdl packages/net/common/current/ChangeLog packages/net/common/current/cdl/net.cdl packages/redboot/current/ChangeLog packages/redboot/current/cdl/redboot.cdl packages/redboot/current/include/flash_config.h packages/redboot/current/include/net/net.h packages/redboot/current/src/flash.c packages/redboot/current/src/net/net_io.c
diffstat 10 files changed, 157 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/packages/io/eth/current/ChangeLog
+++ b/packages/io/eth/current/ChangeLog
@@ -1,3 +1,7 @@
+2003-03-20  Mark Salter  <msalter@redhat.com>
+
+	* cdl/eth_drivers.cdl (CYGHWR_NET_DRIVERS): Moved here from net/common.
+
 2003-03-14  Nick Garnett  <nickg@calivar.com>
 
 	* src/net/eth_drv.c: Added calls to cyg_net_show_mbufs() whenever
--- a/packages/io/eth/current/cdl/eth_drivers.cdl
+++ b/packages/io/eth/current/cdl/eth_drivers.cdl
@@ -58,6 +58,10 @@ cdl_package CYGPKG_IO_ETH_DRIVERS {
 
     implements    CYGPKG_NET_DRIVER_FRAMEWORK
 
+    cdl_interface CYGHWR_NET_DRIVERS {
+        display "Network drivers"
+    }
+
     cdl_interface     CYGINT_IO_ETH_MULTICAST {
         display   "Driver supports multicast addressing"
         description "
--- a/packages/net/common/current/ChangeLog
+++ b/packages/net/common/current/ChangeLog
@@ -1,3 +1,7 @@
+2003-03-20  Mark Salter  <msalter@redhat.com>
+
+	* cdl/net.cdl (CYGHWR_NET_DRIVERS): Removed to io/eth.
+
 2003-03-18 Barton Meeks  <bartonm2002@yahoo.com>
 
         * src/tftp_client.c: Reduce size of initial request packet
--- a/packages/net/common/current/cdl/net.cdl
+++ b/packages/net/common/current/cdl/net.cdl
@@ -401,10 +401,6 @@ cdl_package CYGPKG_NET {
 
 # Description and control over different interfaces
 
-    cdl_interface CYGHWR_NET_DRIVERS {
-        display "Network drivers"
-    }
-
     cdl_interface CYGHWR_NET_DRIVER_ETH0 {
         display "Does the hardware provide an 'eth0' device?"
         requires { CYGHWR_NET_DRIVER_ETH0 <= 1 }
--- a/packages/redboot/current/ChangeLog
+++ b/packages/redboot/current/ChangeLog
@@ -1,3 +1,11 @@
+2003-03-20  Mark Salter  <msalter@redhat.com>
+
+	* include/flash_config.h (CONFIG_NETPORT): New config option.
+	* src/flash.c: Support CONFIG_NETPORT.
+	* cdl/redboot.cdl: New option to select default ethernet device.
+	* 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@ecoscentric.com>
 
 	* doc/redboot_installing.sgml: Update Atmel AT91EB40 RedBoot
--- a/packages/redboot/current/cdl/redboot.cdl
+++ b/packages/redboot/current/cdl/redboot.cdl
@@ -351,6 +351,17 @@ cdl_package CYGPKG_REDBOOT {
                 }
     
             }
+
+	    cdl_option CYGNUM_REDBOOT_DEFAULT_NETWORK_DEVICE {
+                display         "Default network device driver"
+                flavor          data
+                active_if       { !CYGSEM_REDBOOT_FLASH_CONFIG && CYGHWR_NET_DRIVERS > 1 }
+	        legal_values    0 to CYGHWR_NET_DRIVERS-1
+                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 {
--- a/packages/redboot/current/include/flash_config.h
+++ b/packages/redboot/current/include/flash_config.h
@@ -8,7 +8,7 @@
 //####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
@@ -67,6 +67,7 @@
 #ifdef CYGPKG_REDBOOT_NETWORKING
 #define CONFIG_IP      5
 #define CONFIG_ESA     6
+#define CONFIG_NETPORT 7
 #endif
 
 struct config_option {
--- a/packages/redboot/current/include/net/net.h
+++ b/packages/redboot/current/include/net/net.h
@@ -8,7 +8,7 @@
 //####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
@@ -617,6 +617,10 @@ extern void net_io_test(bool is_idle);
 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
--- a/packages/redboot/current/src/flash.c
+++ b/packages/redboot/current/src/flash.c
@@ -8,7 +8,7 @@
 //####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
@@ -1403,6 +1403,11 @@ get_config(unsigned char *dp, char *titl
             if (esa_ptr < (sizeof(enet_addr_t)-1)) lp += diag_sprintf(lp, ":");
         }
         break;
+#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
+    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);
@@ -1502,6 +1507,19 @@ get_config(unsigned char *dp, char *titl
         }
         return CONFIG_CHANGED;
         break;
+#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
+    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
@@ -1550,6 +1568,10 @@ config_length(int type)
         // 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;
+#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
+    case CONFIG_NETPORT:
+        return MAX_STRING_LENGTH;
+#endif
 #endif
     case CONFIG_STRING:
         return MAX_STRING_LENGTH;
@@ -1962,6 +1984,21 @@ flash_config_insert_value(unsigned char 
     case CONFIG_ESA:
         memcpy(dp, (void *)&opt->dflt, sizeof(enet_addr_t));
         break;
+#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
+    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));
--- a/packages/redboot/current/src/net/net_io.c
+++ b/packages/redboot/current/src/net/net_io.c
@@ -8,7 +8,7 @@
 //####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
@@ -76,6 +76,14 @@ RedBoot_config_option("Network debug at 
                       CONFIG_BOOL,
                       false
     );
+#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
+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
@@ -609,10 +617,47 @@ 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;
+#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
+    char *default_devname;
+    int default_index;
+#endif
 
     // Set defaults as appropriate
 #ifdef CYGSEM_REDBOOT_DEFAULT_NO_BOOTP
@@ -628,6 +673,9 @@ net_init(void)
     gdb_port = CYGNUM_REDBOOT_NETWORKING_TCP_PORT;
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
     // Fetch values from saved config data, if available
+#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
+    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);
@@ -652,15 +700,40 @@ net_init(void)
     // 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
+
+#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
+    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++) {
+#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
+		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
+		}
+	    }
+	}
+#if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
     }
+#endif
     if (!__local_enet_sc) {
         diag_printf("No network interfaces found\n");
         return;