[PATCH 05/16] efi_net: efi_loader: Add efi_netobj_alloc to allocate an efi_net_obj
Heinrich Schuchardt
xypron.glpk at gmx.de
Tue Apr 15 10:18:54 CEST 2025
On 11.03.25 17:47, Adriano Cordova wrote:
> Rework the logic to allocate an efi_net_obj and its members. An
> efi_net_obj now gets allocated only in efi_netobj_alloc.
>
> Signed-off-by: Adriano Cordova <adriano.cordova at canonical.com>
> ---
> lib/efi_loader/efi_net.c | 131 ++++++++++++++++++++++++---------------
> 1 file changed, 80 insertions(+), 51 deletions(-)
>
> diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
> index a40d319a27f..a14ecf3d182 100644
> --- a/lib/efi_loader/efi_net.c
> +++ b/lib/efi_loader/efi_net.c
> @@ -1152,19 +1152,10 @@ static int efi_netobj_init(struct efi_net_obj *netobj)
> size_t *receive_lengths = NULL;
> int i, j;
>
> - if (!netobj || efi_netobj_is_active(netobj))
> + if (!netobj || !netobj->net || efi_netobj_is_active(netobj))
> return 0;
>
> dev = netobj->dev;
> - if (!dev) {
> - /* No network device active, don't expose any */
> - return 0;
> - }
> -
> - if (!netobj->net)
> - netobj->net = calloc(1, sizeof(*netobj->net));
> - if (!netobj->net)
> - goto out_of_resources;
>
> if (!netobj->net_mode)
> netobj->net_mode = calloc(1, sizeof(*netobj->net_mode));
> @@ -1344,6 +1335,84 @@ efi_status_t efi_net_init(void)
> return EFI_SUCCESS;
> }
>
> +/**
> + * efi_netobj_alloc() - allocate an efi_net_obj from either a simple
> + * network protocol interface or a net udevice
> + *
> + * @handle: EFI handle
> + * @net: pointer to simple network protocol
> + * @dev: pointer to net udevice
> + * Return: pointer to EFI net object, NULL on error
> + */
> +struct efi_net_obj *efi_netobj_alloc(efi_handle_t handle,
> + struct efi_simple_network *net,
> + struct udevice *dev)
> +{
> + int i;
> + struct efi_net_obj *netobj;
> +
> + // Find a slot for this efi_net_obj
> +
> + // Try to recycle
> + for (i = 0; i < MAX_EFI_NET_OBJS; i++) {
We should avoid artificial limitations like MAX_EFI_NET_OBJS.
Objects that exist once per handle should be linked to the handle by
installing a protocol interface.
> + if (net_objs[i] && !net_objs[i]->net && !net_objs[i]->dev && !net_objs[i]->handle)
> + break;
> + }
> + if (i == MAX_EFI_NET_OBJS) {
> + for (i = 0; i < MAX_EFI_NET_OBJS; i++) {
> + if (!net_objs[i])
> + break;
> + }
> + }
> + if (i == MAX_EFI_NET_OBJS)
> + return NULL;
> +
> + if (!net_objs[i]) {
> + netobj = calloc(1, sizeof(*netobj));
> + net_objs[i] = netobj;
> + } else {
> + netobj = net_objs[i];
> + }
> + if (!netobj)
> + return NULL;
> +
> + if (netobj->net) {
> + if (netobj->net->mode)
> + free(netobj->net->mode);
> + free(netobj->net);
> + }
> +
> + if (handle) {
> + netobj->handle = handle;
> + }
> + else {
> + netobj->handle = calloc(1, sizeof(*netobj->handle));
All handles in U-Boot have to be in a linked list, see
LIST_HEAD(efi_obj_list) in lib/efi_loader/efi_boottime.c.
The only way to create an EFI handle is by installing a protocol
interface calling InstallMultipleProtocolInterfaces(*handle) or
InstallProtocolInterface(*handle) with handle = NULL.
> + if (!netobj->handle) {
> + free(netobj);
> + return NULL;
> + }
> + }
> +
> + if (net) {
> + netobj->net = net;
> + netobj->net_mode = net->mode;
> + } else {
> + netobj->net = calloc(1, sizeof(*netobj->net));
> + if (!netobj->net) {
> + free(netobj->handle);
EFI handles can only be deleted by uninstalling all protocol interfaces.
> + free(netobj);
> + return NULL;
> + }
> + }
> +
> + netobj->dev = dev;
> + netobj->efi_seq_num = i;
> +
> + printf("\nefi_net: allocated EFI net device %d\n", netobj->efi_seq_num);
This printf could be useful for debugging but it is disrupting the
output of network devices and nothing that an end user would be
interested in.
efi_net: allocated EFI net device 0
eth0: eth at 10002000
efi_net: allocated EFI net device 1
, eth5: eth at 10003000
efi_net: allocated EFI net device 2
, eth3: sbe5
efi_net: allocated EFI net device 3
, eth6: eth at 10004000
efi_net: allocated EFI net device 4
, eth8: phy-test-eth
efi_net: allocated EFI net device 5
, eth4: dsa-test-eth
efi_net: allocated EFI net device 6
, eth2: lan0
efi_net: allocated EFI net device 7
, eth7: lan1
How about:
log_debug("efinet %d\n", netobj->efi_seq_num);
Best regards
Heinrich
> +
> + return netobj;
> +}
> +
> /**
> * efi_net_register() - register a net device
> *
> @@ -1356,9 +1425,7 @@ efi_status_t efi_net_init(void)
> int efi_net_register(void *ctx, struct event *event)
> {
> struct udevice *dev;
> - int seq_num;
> enum uclass_id id;
> - struct efi_net_obj *netobj;
> int i;
>
> dev = event->data.dm.dev;
> @@ -1378,48 +1445,10 @@ int efi_net_register(void *ctx, struct event *event)
> }
> }
>
> - // Find a slot for this efi_net_obj
> - seq_num = -1;
> - // Try to recycle
> - for (i = 0; i < MAX_EFI_NET_OBJS; i++) {
> - if (net_objs[i] && !net_objs[i]->dev) {
> - seq_num = i;
> - break;
> - }
> - }
> - if (seq_num < 0) {
> - for (i = 0; i < MAX_EFI_NET_OBJS; i++) {
> - if (!net_objs[i]) {
> - seq_num = i;
> - break;
> - }
> - }
> - }
> - if (seq_num < 0)
> + if (!efi_netobj_alloc(NULL, NULL, dev))
> return -1;
>
> - if (!net_objs[seq_num]) {
> - netobj = calloc(1, sizeof(*netobj));
> - net_objs[seq_num] = netobj;
> - } else {
> - netobj = net_objs[seq_num];
> - }
> - if (!netobj)
> - goto out_of_resources;
> -
> - netobj->handle = calloc(1, sizeof(*netobj->handle));
> - if (!netobj->handle) {
> - free(netobj);
> - goto out_of_resources;
> - }
> -
> - netobj->dev = dev;
> - netobj->efi_seq_num = seq_num;
> - printf("efi_net registered device number %d\n", netobj->efi_seq_num);
> return 0;
> -out_of_resources:
> - printf("ERROR: Out of memory\n");
> - return -1;
> }
>
> /**
More information about the U-Boot
mailing list