[U-Boot] [PATCH 1/5] efi_loader: interrupts in simple network protocol

Heinrich Schuchardt xypron.glpk at gmx.de
Sun Sep 1 16:06:03 UTC 2019


GetStatus() must clear the interrupt status.
Transmit() should set the TX interrupt.
Receive() should clear the RX interrupt.
Initialize() and Start() should clear the interrupt status.

Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
 include/efi_api.h        |  2 ++
 lib/efi_loader/efi_net.c | 40 +++++++++++++++++++++++++---------------
 2 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/include/efi_api.h b/include/efi_api.h
index 43778197af..7f7b67fa00 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -1281,6 +1281,8 @@ struct efi_simple_network {
 			struct efi_mac_address *dest_addr, u16 *protocol);
 	struct efi_event *wait_for_packet;
 	struct efi_simple_network_mode *mode;
+	/* private fields */
+	u32 int_status;
 };

 #define EFI_PXE_BASE_CODE_PROTOCOL_GUID \
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 825e064f9a..bf6d5ab0b3 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -66,10 +66,13 @@ static efi_status_t EFIAPI efi_net_start(struct efi_simple_network *this)
 		goto out;
 	}

-	if (this->mode->state != EFI_NETWORK_STOPPED)
+	if (this->mode->state != EFI_NETWORK_STOPPED) {
 		ret = EFI_ALREADY_STARTED;
-	else
+	} else {
+		this->int_status = 0;
+		wait_for_packet->is_signaled = false;
 		this->mode->state = EFI_NETWORK_STARTED;
+	}
 out:
 	return EFI_EXIT(ret);
 }
@@ -144,6 +147,8 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
 		r = EFI_DEVICE_ERROR;
 		goto out;
 	} else {
+		this->int_status = 0;
+		wait_for_packet->is_signaled = false;
 		this->mode->state = EFI_NETWORK_INITIALIZED;
 	}
 out:
@@ -192,6 +197,8 @@ static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this)
 	}

 	eth_halt();
+	this->int_status = 0;
+	wait_for_packet->is_signaled = false;
 	this->mode->state = EFI_NETWORK_STOPPED;

 out:
@@ -350,10 +357,8 @@ static efi_status_t EFIAPI efi_net_get_status(struct efi_simple_network *this,
 	}

 	if (int_status) {
-		/* We send packets synchronously, so nothing is outstanding */
-		*int_status = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
-		if (new_rx_packet)
-			*int_status |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
+		*int_status = this->int_status;
+		this->int_status = 0;
 	}
 	if (txbuf)
 		*txbuf = new_tx_packet;
@@ -429,7 +434,7 @@ static efi_status_t EFIAPI efi_net_transmit
 	net_send_packet(transmit_buffer, buffer_size);

 	new_tx_packet = buffer;
-
+	this->int_status |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
 out:
 	return EFI_EXIT(ret);
 }
@@ -487,12 +492,6 @@ static efi_status_t EFIAPI efi_net_receive
 		ret = EFI_NOT_READY;
 		goto out;
 	}
-	/* Check that we at least received an Ethernet header */
-	if (net_rx_packet_len < sizeof(struct ethernet_hdr)) {
-		new_rx_packet = false;
-		ret = EFI_NOT_READY;
-		goto out;
-	}
 	/* Fill export parameters */
 	eth_hdr = (struct ethernet_hdr *)net_rx_packet;
 	protlen = ntohs(eth_hdr->et_protlen);
@@ -517,7 +516,8 @@ static efi_status_t EFIAPI efi_net_receive
 	/* Copy packet */
 	memcpy(buffer, net_rx_packet, net_rx_packet_len);
 	*buffer_size = net_rx_packet_len;
-	new_rx_packet = false;
+	new_rx_packet = 0;
+	this->int_status &= ~EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
 out:
 	return EFI_EXIT(ret);
 }
@@ -548,7 +548,6 @@ void efi_net_set_dhcp_ack(void *pkt, int len)
 static void efi_net_push(void *pkt, int len)
 {
 	new_rx_packet = true;
-	wait_for_packet->is_signaled = true;
 }

 /**
@@ -577,6 +576,17 @@ static void EFIAPI efi_network_timer_notify(struct efi_event *event,
 		push_packet = efi_net_push;
 		eth_rx();
 		push_packet = NULL;
+		if (new_rx_packet) {
+			/* Check that we at least received an Ethernet header */
+			if (net_rx_packet_len >=
+			    sizeof(struct ethernet_hdr)) {
+				this->int_status |=
+					EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
+				wait_for_packet->is_signaled = true;
+			} else {
+				new_rx_packet = 0;
+			}
+		}
 	}
 out:
 	EFI_EXIT(EFI_SUCCESS);
--
2.20.1



More information about the U-Boot mailing list