diff options
author | marcel <marcel@FreeBSD.org> | 2002-03-30 04:50:52 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2002-03-30 04:50:52 +0000 |
commit | bafbd253600e10b1fa9bb51cd542d73e5d136d5b (patch) | |
tree | 86ce61ec53a1965e04b1170f306618b575bc7e80 | |
parent | ade94cf6223e6629f571232e9866cc7133931b09 (diff) | |
download | FreeBSD-src-bafbd253600e10b1fa9bb51cd542d73e5d136d5b.zip FreeBSD-src-bafbd253600e10b1fa9bb51cd542d73e5d136d5b.tar.gz |
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.
-rw-r--r-- | sys/boot/efi/libefi/efinet.c | 70 |
1 files changed, 68 insertions, 2 deletions
diff --git a/sys/boot/efi/libefi/efinet.c b/sys/boot/efi/libefi/efinet.c index 0b27fc7..10b1721 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; |