Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/alpha/alpha If we're netbooting on a system with, f...



details:   https://anonhg.NetBSD.org/src/rev/c768eabe99e4
branches:  trunk
changeset: 984462:c768eabe99e4
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Fri Jul 09 01:29:20 2021 +0000

description:
If we're netbooting on a system with, for example, an ISA DE204 Ethernet
interface, we don't have sufficient information to find the device using
the bus/slot scheme that we do with a PCI network interface.  However, in
these cases, some versions of the SRM console supply the MAC address of
the interface in the booted_dev environment variable, like so:

        BOOTP 1 1 0 0 0 5 0 08-00-2B-xx-xx-xx 1

So, if we weren't able to find the booted device by the usual means,
check for this and, if we find a MAC address, try to find the network
interface by the MAC address.

diffstat:

 sys/arch/alpha/alpha/autoconf.c |  118 ++++++++++++++++++++++++++++++++++++---
 1 files changed, 107 insertions(+), 11 deletions(-)

diffs (173 lines):

diff -r 9a871205022e -r c768eabe99e4 sys/arch/alpha/alpha/autoconf.c
--- a/sys/arch/alpha/alpha/autoconf.c   Thu Jul 08 20:11:15 2021 +0000
+++ b/sys/arch/alpha/alpha/autoconf.c   Fri Jul 09 01:29:20 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.57 2021/05/22 15:05:36 thorpej Exp $ */
+/* $NetBSD: autoconf.c,v 1.58 2021/07/09 01:29:20 thorpej Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -42,7 +42,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.57 2021/05/22 15:05:36 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.58 2021/07/09 01:29:20 thorpej Exp $");
 
 #include "pci.h"
 
@@ -57,6 +57,9 @@
 
 #include <dev/pci/pcivar.h>
 
+#include <net/if.h>
+#include <net/if_ether.h>
+
 #include <machine/autoconf.h>
 #include <machine/alpha.h>
 #include <machine/cpu.h>
@@ -66,8 +69,7 @@
 
 struct bootdev_data    *bootdev_data;
 
-void   parse_prom_bootdev(void);
-static inline int atoi(const char *);
+static void    parse_prom_bootdev(void);
 
 /*
  * cpu_configure:
@@ -138,6 +140,86 @@
        booted_device = device_find_by_xname(cp);
 }
 
+static bool
+parse_dec_macaddr(const char *str, uint8_t enaddr[ETHER_ADDR_LEN])
+{
+       char *cp;
+       long long l;
+       int i;
+
+       /*
+        * DEC Ethernet address strings are formatted like so:
+        *
+        *      XX-XX-XX-XX-XX-XX
+        */
+
+       for (i = 0; i < ETHER_ADDR_LEN; i++) {
+               l = strtoll(str, &cp, 16);
+               if (l < 0 || l > 0xff) {
+                       /* Not a valid MAC address. */
+                       return false;
+               }
+               if (*cp == '-') {
+                       /* Octet separator. */
+                       enaddr[i] = (uint8_t)l;
+                       str = cp + 1;
+                       continue;
+               }
+               if (*cp == ' ' || *cp == '\0') {
+                       /* End of the string. */
+                       enaddr[i] = (uint8_t)l;
+                       return i == ETHER_ADDR_LEN - 1;
+               }
+               /* Bogus character. */
+               break;
+       }
+
+       /* Encountered bogus character or didn't reach end of string. */
+       return false;
+}
+
+static void
+netboot_find_rootdev_planb(void)
+{
+       struct psref psref;
+       uint8_t enaddr[ETHER_ADDR_LEN];
+       char ifname[IFNAMSIZ];
+       int i;
+
+       if (strncasecmp(bootinfo.booted_dev, "BOOTP ", 6) != 0 &&
+           strncasecmp(bootinfo.booted_dev, "MOP ", 4) != 0) {
+               /* We weren't netbooted. */
+               return;
+       }
+
+       for (i = 2; bootinfo.booted_dev[i] != '\0'; i++) {
+               if (bootinfo.booted_dev[i] == '-') {
+                       if (parse_dec_macaddr(&bootinfo.booted_dev[i - 2],
+                                             enaddr)) {
+                               /* Found it! */
+                               break;
+                       }
+               }
+       }
+       if (bootinfo.booted_dev[i] == '\0') {
+               /* No MAC address in string. */
+               return;
+       }
+
+       /* Now try to look up the interface by the link address. */
+       struct ifnet *ifp = if_get_bylla(enaddr, ETHER_ADDR_LEN, &psref);
+       if (ifp == NULL) {
+               /* No interface attached with that MAC address. */
+               return;
+       }
+
+       strlcpy(ifname, if_name(ifp), sizeof(ifname));
+       if_put(ifp, &psref);
+
+       /* Ok! Now look up the device_t by name! */
+       booted_device = device_find_by_xname(ifname);
+}
+
 void
 cpu_rootconf(void)
 {
@@ -147,13 +229,33 @@
        }
 
        if (booted_device == NULL) {
+               /*
+                * It's possible that we netbooted from an Ethernet
+                * interface that can't be matched via the usual
+                * logic in device_register() (a DE204 in an ISA slot,
+                * for example).  In these cases, the console may have
+                * provided us with a MAC address that we can use to
+                * try and find the interface, * e.g.:
+                *
+                *      BOOTP 1 1 0 0 0 5 0 08-00-2B-xx-xx-xx 1
+                */
+               netboot_find_rootdev_planb();
+       }
+
+       if (booted_device == NULL) {
                printf("WARNING: can't figure what device matches \"%s\"\n",
                    bootinfo.booted_dev);
        }
        rootconf();
 }
 
-void
+static inline int
+atoi(const char *s)
+{
+       return (int)strtoll(s, NULL, 10);
+}
+
+static void
 parse_prom_bootdev(void)
 {
        static char hacked_boot_dev[128];
@@ -213,12 +315,6 @@
        bootdev_data = &bd;
 }
 
-static inline int
-atoi(const char *s)
-{
-       return (int)strtoll(s, NULL, 10);
-}
-
 void
 device_register(device_t dev, void *aux)
 {



Home | Main Index | Thread Index | Old Index