summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_net.c
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2019-08-31 10:56:30 +0300
committerHeinrich Schuchardt <xypron.glpk@gmx.de>2019-09-06 00:18:51 +0300
commit7f6d874d176e75e817d2c784b752d6f077069b04 (patch)
tree667c4730184e27d5714d98f4f9e3effc734128ae /lib/efi_loader/efi_net.c
parent794219bd1234afcbb156c3674a3864e90047826c (diff)
downloadu-boot-7f6d874d176e75e817d2c784b752d6f077069b04.tar.xz
efi_loader: interrupts in simple network protocol
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@gmx.de>
Diffstat (limited to 'lib/efi_loader/efi_net.c')
-rw-r--r--lib/efi_loader/efi_net.c40
1 files changed, 25 insertions, 15 deletions
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);