From 7608f7cb80f2d84637c6aaa02da80dee5ab025bc Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sat, 30 Mar 2002 04:50:52 +0000 Subject: Fix the initialization of the protocol: o Query the state field of the protocol mode to determine whether we need to start and/or initialize the protocol. When we're loaded across the network, the protocol has already been started and is already initialized. When no networking has happened yet, we have to start and initialize the protocol ourselves. o After initialization, we have to set the receive filters. Not doing this results in a deaf interface. We set the unicast and broadcast filters. Multicast may not be supported. This specific change fixes the problem we had that we could not netboot if the loader was started from the EFI shell. o To help future debugging, add a function that dumps the current mode of the interface. It's conditional on EFINET_DEBUG. o To help in runtime problems, emit a diagnostic message when we could not initialize the protocol properly. --- sys/boot/efi/libefi/efinet.c | 70 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) (limited to 'sys/boot/efi') diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c index 0b27fc764666..10b172181681 100644 --- a/sys/boot/efi/libefi/efinet.c +++ b/sys/boot/efi/libefi/efinet.c @@ -39,6 +39,40 @@ extern struct netif_driver efi_net; +#ifdef EFINET_DEBUG +static void +dump_mode(EFI_SIMPLE_NETWORK_MODE *mode) +{ + int i; + + printf("State = %x\n", mode->State); + printf("HwAddressSize = %u\n", mode->HwAddressSize); + printf("MediaHeaderSize = %u\n", mode->MediaHeaderSize); + printf("MaxPacketSize = %u\n", mode->MaxPacketSize); + printf("NvRamSize = %u\n", mode->NvRamSize); + printf("NvRamAccessSize = %u\n", mode->NvRamAccessSize); + printf("ReceiveFilterMask = %x\n", mode->ReceiveFilterMask); + printf("ReceiveFilterSetting = %u\n", mode->ReceiveFilterSetting); + printf("MaxMCastFilterCount = %u\n", mode->MaxMCastFilterCount); + printf("MCastFilterCount = %u\n", mode->MCastFilterCount); + printf("MCastFilter = {"); + for (i = 0; i < mode->MCastFilterCount; i++) + printf(" %s", ether_sprintf(mode->MCastFilter[i].Addr)); + printf(" }\n"); + printf("CurrentAddress = %s\n", + ether_sprintf(mode->CurrentAddress.Addr)); + printf("BroadcastAddress = %s\n", + ether_sprintf(mode->BroadcastAddress.Addr)); + printf("PermanentAddress = %s\n", + ether_sprintf(mode->PermanentAddress.Addr)); + printf("IfType = %u\n", mode->IfType); + printf("MacAddressChangeable = %d\n", mode->MacAddressChangeable); + printf("MultipleTxSupported = %d\n", mode->MultipleTxSupported); + printf("MediaPresentSupported = %d\n", mode->MediaPresentSupported); + printf("MediaPresent = %d\n", mode->MediaPresent); +} +#endif + int efinet_match(struct netif *nif, void *machdep_hint) { @@ -107,12 +141,44 @@ efinet_init(struct iodesc *desc, void *machdep_hint) { struct netif *nif = desc->io_netif; EFI_SIMPLE_NETWORK *net; + EFI_STATUS status; net = nif->nif_driver->netif_ifs[nif->nif_unit].dif_private; nif->nif_devdata = net; - net->Start(net); - net->Initialize(net, 0, 0); + if (net->Mode->State == EfiSimpleNetworkStopped) { + status = net->Start(net); + if (status != EFI_SUCCESS) { + printf("net%d: cannot start interface (status=%d)\n", + nif->nif_unit, status); + return; + } + } + + if (net->Mode->State != EfiSimpleNetworkInitialized) { + status = net->Initialize(net, 0, 0); + if (status != EFI_SUCCESS) { + printf("net%d: cannot init. interface (status=%d)\n", + nif->nif_unit, status); + return; + } + } + + if (net->Mode->ReceiveFilterSetting == 0) { + UINT32 mask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST | + EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST; + + status = net->ReceiveFilters(net, mask, 0, FALSE, 0, 0); + if (status != EFI_SUCCESS) { + printf("net%d: cannot set rx. filters (status=%d)\n", + nif->nif_unit, status); + return; + } + } + +#ifdef EFINET_DEBUG + dump_mode(net->Mode); +#endif bcopy(net->Mode->CurrentAddress.Addr, desc->myea, 6); desc->xid = 1; -- cgit v1.3