Source-Changes-HG archive

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

[src/trunk]: src/sys/stand/efiboot Add support for netbooting with non-PCI ne...



details:   https://anonhg.NetBSD.org/src/rev/579fb1a90732
branches:  trunk
changeset: 449992:579fb1a90732
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Mar 31 22:24:41 2019 +0000

description:
Add support for netbooting with non-PCI network devices.

diffstat:

 sys/stand/efiboot/efinet.c |  136 +++++++++++++++++++-------------------------
 1 files changed, 60 insertions(+), 76 deletions(-)

diffs (220 lines):

diff -r d1f88700da28 -r 579fb1a90732 sys/stand/efiboot/efinet.c
--- a/sys/stand/efiboot/efinet.c        Sun Mar 31 20:08:45 2019 +0000
+++ b/sys/stand/efiboot/efinet.c        Sun Mar 31 22:24:41 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: efinet.c,v 1.5 2019/03/05 08:25:03 msaitoh Exp $       */
+/*     $NetBSD: efinet.c,v 1.6 2019/03/31 22:24:41 jmcneill Exp $      */
 
 /*-
  * Copyright (c) 2001 Doug Rabson
@@ -117,6 +117,33 @@
 }
 #endif
 
+static const EFI_MAC_ADDRESS *
+efinet_hwaddr(const EFI_SIMPLE_NETWORK_MODE *mode)
+{
+       int valid, n;
+
+       for (valid = 0, n = 0; n < mode->HwAddressSize; n++)
+               if (mode->CurrentAddress.Addr[n] != 0x00) {
+                       valid = true;
+                       break;
+               }
+       if (!valid)
+               goto use_permanent;
+
+       for (valid = 0, n = 0; n < mode->HwAddressSize; n++)
+               if (mode->CurrentAddress.Addr[n] != 0xff) {
+                       valid = true;
+                       break;
+               }
+       if (!valid)
+               goto use_permanent;
+
+       return &mode->CurrentAddress;
+
+use_permanent:
+       return &mode->PermanentAddress;
+}
+
 static int
 efinet_match(struct netif *nif, void *machdep_hint)
 {
@@ -143,12 +170,16 @@
        EFI_SIMPLE_NETWORK *net;
        EFI_STATUS status;
        void *buf;
+       char *ptr;
 
        if (eni == NULL)
                return -1;
        net = eni->net;
 
-       status = uefi_call_wrapper(net->Transmit, 7, net, 0, (UINTN)len, pkt, NULL,
+       ptr = eni->pktbuf;
+
+       memcpy(ptr, pkt, len);
+       status = uefi_call_wrapper(net->Transmit, 7, net, 0, (UINTN)len, ptr, NULL,
            NULL, NULL);
        if (EFI_ERROR(status))
                return -1;
@@ -202,6 +233,7 @@
                if (!EFI_ERROR(status)) {
                        rsz = uimin(rsz, len);
                        memcpy(pkt, ptr, rsz);
+
                        ret = (int)rsz;
                        break;
                }
@@ -252,7 +284,7 @@
 
        status = uefi_call_wrapper(net->ReceiveFilters, 6, net, mask, 0, FALSE,
            0, NULL);
-       if (EFI_ERROR(status) && status != EFI_INVALID_PARAMETER) {
+       if (EFI_ERROR(status) && status != EFI_INVALID_PARAMETER && status != EFI_UNSUPPORTED) {
                printf("net%d: cannot set rx. filters (status=%" PRIxMAX ")\n",
                    nif->nif_unit, (uintmax_t)status);
                return;
@@ -272,7 +304,7 @@
        dump_mode(net->Mode);
 #endif
 
-       memcpy(desc->myea, net->Mode->PermanentAddress.Addr, 6);
+       memcpy(desc->myea, efinet_hwaddr(net->Mode)->Addr, 6);
        desc->xid = 1;
 }
 
@@ -289,44 +321,13 @@
        uefi_call_wrapper(net->Shutdown, 1, net);
 }
 
-static bool
-efi_net_pci_probe(struct efinetinfo *eni, EFI_DEVICE_PATH *dp, EFI_DEVICE_PATH *pdp)
-{
-#if notyet
-       PCI_DEVICE_PATH *pci = (PCI_DEVICE_PATH *)dp;
-#endif
-       int bus = -1;
-
-       if (pdp != NULL &&
-           DevicePathType(pdp) == ACPI_DEVICE_PATH &&
-           (DevicePathSubType(pdp) == ACPI_DP ||
-            DevicePathSubType(pdp) == EXPANDED_ACPI_DP)) {
-               ACPI_HID_DEVICE_PATH *acpi = (ACPI_HID_DEVICE_PATH *)pdp;
-               /* PCI root bus */
-               if (acpi->HID == EISA_PNP_ID(0x0A08) ||
-                   acpi->HID == EISA_PNP_ID(0x0A03)) {
-                       bus = acpi->UID;
-               }
-       }
-       if (bus < 0)
-               return false;
-
-#if notyet
-       eni->bus.type = BI_BUS_PCI;
-       eni->bus.tag = (bus & 0xff) << 8;
-       eni->bus.tag |= (pci->Device & 0x1f) << 3;
-       eni->bus.tag |= pci->Function & 0x7;
-#endif
-       return true;
-}
-
 void
 efi_net_probe(void)
 {
        struct efinetinfo *enis;
        struct netif_dif *dif;
        struct netif_stats *stats;
-       EFI_DEVICE_PATH *dp0, *dp, *pdp;
+       EFI_DEVICE_PATH *dp0, *dp;
        EFI_SIMPLE_NETWORK *net;
        EFI_HANDLE *handles;
        EFI_STATUS status;
@@ -375,45 +376,33 @@
                        printf("Unable to open network interface %" PRIuMAX
                            " for exclusive access: %" PRIxMAX "\n",
                            (uintmax_t)i, (uintmax_t)status);
+                       continue;
                }
 
-               found = false;
-               for (pdp = NULL, dp = dp0;
-                   !IsDevicePathEnd(dp);
-                   pdp = dp, dp = NextDevicePathNode(dp)) {
-                       if (DevicePathType(dp) == HARDWARE_DEVICE_PATH) {
-                               if (DevicePathSubType(dp) == HW_PCI_DP)
-                                       found = efi_net_pci_probe(&enis[nifs],
-                                           dp, pdp);
-                               break;
+               enis[nifs].net = net;
+               enis[nifs].bootdev = efi_pxe_match_booted_interface(
+                   efinet_hwaddr(net->Mode), net->Mode->HwAddressSize);
+               enis[nifs].pktbufsz = net->Mode->MaxPacketSize +
+                   ETHER_EXT_LEN;
+               enis[nifs].pktbuf = alloc(enis[nifs].pktbufsz);
+               if (enis[nifs].pktbuf == NULL) {
+                       while (i-- > 0) {
+                               dealloc(enis[i].pktbuf, enis[i].pktbufsz);
+                               if (i == 0)
+                                       break;
                        }
+                       dealloc(enis, nhandles * sizeof(*enis));
+                       FreePool(handles);
+                       return;
                }
-               if (found) {
-                       enis[nifs].net = net;
-                       enis[nifs].bootdev = efi_pxe_match_booted_interface(
-                           &net->Mode->PermanentAddress, net->Mode->HwAddressSize);
-                       enis[nifs].pktbufsz = net->Mode->MaxPacketSize +
-                           ETHER_EXT_LEN;
-                       enis[nifs].pktbuf = alloc(enis[nifs].pktbufsz);
-                       if (enis[nifs].pktbuf == NULL) {
-                               while (i-- > 0) {
-                                       dealloc(enis[i].pktbuf, enis[i].pktbufsz);
-                                       if (i == 0)
-                                               break;
-                               }
-                               dealloc(enis, nhandles * sizeof(*enis));
-                               FreePool(handles);
-                               return;
-                       }
 
-                       if (depth > 0 && efi_device_path_ncmp(efi_bootdp, dp0, depth) == 0) {
-                               char devname[9];
-                               snprintf(devname, sizeof(devname), "net%u", nifs);
-                               set_default_device(devname);
-                       }
+               if (depth > 0 && efi_device_path_ncmp(efi_bootdp, dp0, depth) == 0) {
+                       char devname[9];
+                       snprintf(devname, sizeof(devname), "net%u", nifs);
+                       set_default_device(devname);
+               }
 
-                       nifs++;
-               }
+               nifs++;
        }
 
        FreePool(handles);
@@ -463,17 +452,12 @@
 
                printf("net%d", dif->dif_unit);
                if (net->Mode != NULL) {
+                       const EFI_MAC_ADDRESS *mac = efinet_hwaddr(net->Mode);
                        for (UINT32 x = 0; x < net->Mode->HwAddressSize; x++) {
                                printf("%c%02x", x == 0 ? ' ' : ':',
-                                   net->Mode->PermanentAddress.Addr[x]);
+                                   mac->Addr[x]);
                        }
                }
-#if notyet
-               if (eni->bus.type == BI_BUS_PCI) {
-                       printf(" pci%d,%d,%d", (eni->bus.tag >> 8) & 0xff,
-                           (eni->bus.tag >> 3) & 0x1f, eni->bus.tag & 0x7);
-               }
-#endif
                if (eni->bootdev)
                        printf(" pxeboot");
                printf("\n");



Home | Main Index | Thread Index | Old Index