summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2002-03-30 04:50:52 +0000
committermarcel <marcel@FreeBSD.org>2002-03-30 04:50:52 +0000
commitbafbd253600e10b1fa9bb51cd542d73e5d136d5b (patch)
tree86ce61ec53a1965e04b1170f306618b575bc7e80 /sys/boot
parentade94cf6223e6629f571232e9866cc7133931b09 (diff)
downloadFreeBSD-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.
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/efi/libefi/efinet.c70
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;
OpenPOWER on IntegriCloud