[PATCH 7/8] efi_loader: efi_net: Add dhcp cache
Adriano Cordova
adrianox at gmail.com
Thu Feb 6 18:40:17 CET 2025
Add a dhcp cache to store the DHCP ACKs received by the U-Boot network
stack.
Signed-off-by: Adriano Cordova <adriano.cordova at canonical.com>
---
lib/efi_loader/efi_net.c | 55 +++++++++++++++++++++++++++++++---------
1 file changed, 43 insertions(+), 12 deletions(-)
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index f65287ad6ab..2fac39ae513 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -24,12 +24,12 @@
#include <vsprintf.h>
#include <net.h>
+#define MAX_NUM_DHCP_ENTRIES 10
#define MAX_NUM_DP_ENTRIES 10
const efi_guid_t efi_net_guid = EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
static const efi_guid_t efi_pxe_base_code_protocol_guid =
EFI_PXE_BASE_CODE_PROTOCOL_GUID;
-static struct efi_pxe_packet *dhcp_ack;
static void *new_tx_packet;
static void *transmit_buffer;
static uchar **receive_buffer;
@@ -61,6 +61,15 @@ static struct wget_http_info efi_wget_info = {
};
#endif
+struct dhcp_entry {
+ struct efi_pxe_packet *dhcp_ack;
+ struct udevice *dev;
+ bool is_valid;
+};
+
+static struct dhcp_entry dhcp_cache[MAX_NUM_DHCP_ENTRIES];
+static int next_dhcp_entry;
+
/*
* The notification function of this event is called in every timer cycle
* to check if a new network packet has been received.
@@ -317,6 +326,7 @@ static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this)
eth_set_dev(netobj->dev);
env_set("ethact", eth_get_name());
eth_halt();
+
this->int_status = 0;
wait_for_packet->is_signaled = false;
this->mode->state = EFI_NETWORK_STARTED;
@@ -718,18 +728,28 @@ out:
*/
void efi_net_set_dhcp_ack(void *pkt, int len)
{
- int maxsize = sizeof(*dhcp_ack);
+ struct efi_pxe_packet **dhcp_ack;
+ struct udevice *dev;
+
+ dhcp_ack = &dhcp_cache[next_dhcp_entry].dhcp_ack;
+
+ /* For now this function gets called only by the current device */
+ dev = eth_get_dev();
- if (!dhcp_ack) {
- dhcp_ack = malloc(maxsize);
- if (!dhcp_ack)
+ int maxsize = sizeof(**dhcp_ack);
+
+ if (!*dhcp_ack) {
+ *dhcp_ack = malloc(maxsize);
+ if (!*dhcp_ack)
return;
}
- memset(dhcp_ack, 0, maxsize);
- memcpy(dhcp_ack, pkt, min(len, maxsize));
+ memset(*dhcp_ack, 0, maxsize);
+ memcpy(*dhcp_ack, pkt, min(len, maxsize));
- if (netobj)
- netobj->pxe_mode.dhcp_ack = *dhcp_ack;
+ dhcp_cache[next_dhcp_entry].is_valid = true;
+ dhcp_cache[next_dhcp_entry].dev = dev;
+ next_dhcp_entry++;
+ next_dhcp_entry %= MAX_NUM_DHCP_ENTRIES;
}
/**
@@ -1036,7 +1056,7 @@ set_addr:
efi_status_t efi_net_register(struct udevice *dev)
{
efi_status_t r;
- int i;
+ int i, j;
if (!dev) {
/* No network device active, don't expose any */
@@ -1123,8 +1143,19 @@ efi_status_t efi_net_register(struct udevice *dev)
netobj->pxe.set_station_ip = efi_pxe_base_code_set_station_ip;
netobj->pxe.set_packets = efi_pxe_base_code_set_packets;
netobj->pxe.mode = &netobj->pxe_mode;
- if (dhcp_ack)
- netobj->pxe_mode.dhcp_ack = *dhcp_ack;
+
+ /*
+ * Scan dhcp entries for one corresponding
+ * to this udevice, from newest to oldest
+ */
+ i = (next_dhcp_entry + MAX_NUM_DHCP_ENTRIES - 1) % MAX_NUM_DHCP_ENTRIES;
+ for (j = 0; dhcp_cache[i].is_valid && j < MAX_NUM_DHCP_ENTRIES;
+ i = (i + MAX_NUM_DHCP_ENTRIES - 1) % MAX_NUM_DHCP_ENTRIES, j++) {
+ if (dev == dhcp_cache[i].dev) {
+ netobj->pxe_mode.dhcp_ack = *dhcp_cache[i].dhcp_ack;
+ break;
+ }
+ }
/*
* Create WaitForPacket event.
--
2.45.2
More information about the U-Boot
mailing list