|
|
|
@@ -24,6 +24,8 @@
|
|
|
|
|
#include <vsprintf.h>
|
|
|
|
|
#include <net.h>
|
|
|
|
|
|
|
|
|
|
#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;
|
|
|
|
@@ -36,18 +38,28 @@ static int rx_packet_idx;
|
|
|
|
|
static int rx_packet_num;
|
|
|
|
|
static struct efi_net_obj *netobj;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The current network device path. This device path is updated when a new
|
|
|
|
|
* bootfile is downloaded from the network. If then the bootfile is loaded
|
|
|
|
|
* as an efi image, net_dp is passed as the device path of the loaded image.
|
|
|
|
|
*/
|
|
|
|
|
static struct efi_device_path *net_dp;
|
|
|
|
|
struct dp_entry {
|
|
|
|
|
struct efi_device_path *net_dp;
|
|
|
|
|
struct udevice *dev;
|
|
|
|
|
bool is_valid;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The network device path cache. An entry is added when a new bootfile
|
|
|
|
|
* is downloaded from the network. If the bootfile is then loaded as an
|
|
|
|
|
* efi image, the most recent entry corresponding to the device is passed
|
|
|
|
|
* as the device path of the loaded image.
|
|
|
|
|
*/
|
|
|
|
|
static struct dp_entry dp_cache[MAX_NUM_DP_ENTRIES];
|
|
|
|
|
static int next_dp_entry;
|
|
|
|
|
|
|
|
|
|
#if IS_ENABLED(CONFIG_EFI_HTTP_PROTOCOL)
|
|
|
|
|
static struct wget_http_info efi_wget_info = {
|
|
|
|
|
.set_bootdev = false,
|
|
|
|
|
.check_buffer_size = true,
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The notification function of this event is called in every timer cycle
|
|
|
|
@@ -63,6 +75,7 @@ static struct efi_event *wait_for_packet;
|
|
|
|
|
* struct efi_net_obj - EFI object representing a network interface
|
|
|
|
|
*
|
|
|
|
|
* @header: EFI object header
|
|
|
|
|
* @dev: net udevice
|
|
|
|
|
* @net: simple network protocol interface
|
|
|
|
|
* @net_mode: status of the network interface
|
|
|
|
|
* @pxe: PXE base code protocol interface
|
|
|
|
@@ -72,6 +85,7 @@ static struct efi_event *wait_for_packet;
|
|
|
|
|
*/
|
|
|
|
|
struct efi_net_obj {
|
|
|
|
|
struct efi_object header;
|
|
|
|
|
struct udevice *dev;
|
|
|
|
|
struct efi_simple_network net;
|
|
|
|
|
struct efi_simple_network_mode net_mode;
|
|
|
|
|
struct efi_pxe_base_code_protocol pxe;
|
|
|
|
@@ -84,6 +98,21 @@ struct efi_net_obj {
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* efi_netobj_is_active() - checks if a netobj is active in the efi subsystem
|
|
|
|
|
*
|
|
|
|
|
* @netobj: pointer to efi_net_obj
|
|
|
|
|
* Return: true if active
|
|
|
|
|
*/
|
|
|
|
|
static bool efi_netobj_is_active(struct efi_net_obj *netobj)
|
|
|
|
|
{
|
|
|
|
|
if (!netobj || !efi_search_obj(&netobj->header))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* efi_net_start() - start the network interface
|
|
|
|
|
*
|
|
|
|
@@ -99,7 +128,6 @@ static efi_status_t EFIAPI efi_net_start(struct efi_simple_network *this)
|
|
|
|
|
efi_status_t ret = EFI_SUCCESS;
|
|
|
|
|
|
|
|
|
|
EFI_ENTRY("%p", this);
|
|
|
|
|
|
|
|
|
|
/* Check parameters */
|
|
|
|
|
if (!this) {
|
|
|
|
|
ret = EFI_INVALID_PARAMETER;
|
|
|
|
@@ -143,6 +171,8 @@ static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this)
|
|
|
|
|
ret = EFI_NOT_STARTED;
|
|
|
|
|
} else {
|
|
|
|
|
/* Disable hardware and put it into the reset state */
|
|
|
|
|
eth_set_dev(netobj->dev);
|
|
|
|
|
env_set("ethact", eth_get_name());
|
|
|
|
|
eth_halt();
|
|
|
|
|
/* Clear cache of packets */
|
|
|
|
|
rx_packet_num = 0;
|
|
|
|
@@ -189,14 +219,13 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
|
|
|
|
|
|
|
|
|
|
/* Setup packet buffers */
|
|
|
|
|
net_init();
|
|
|
|
|
/* Disable hardware and put it into the reset state */
|
|
|
|
|
eth_halt();
|
|
|
|
|
/* Clear cache of packets */
|
|
|
|
|
rx_packet_num = 0;
|
|
|
|
|
/* Set current device according to environment variables */
|
|
|
|
|
eth_set_current();
|
|
|
|
|
/* Set the net device corresponding to the efi net object */
|
|
|
|
|
eth_set_dev(netobj->dev);
|
|
|
|
|
env_set("ethact", eth_get_name());
|
|
|
|
|
/* Get hardware ready for send and receive operations */
|
|
|
|
|
ret = eth_init();
|
|
|
|
|
ret = eth_start_udev(netobj->dev);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
eth_halt();
|
|
|
|
|
this->mode->state = EFI_NETWORK_STOPPED;
|
|
|
|
@@ -285,6 +314,8 @@ static efi_status_t EFIAPI efi_net_shutdown(struct efi_simple_network *this)
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eth_set_dev(netobj->dev);
|
|
|
|
|
env_set("ethact", eth_get_name());
|
|
|
|
|
eth_halt();
|
|
|
|
|
this->int_status = 0;
|
|
|
|
|
wait_for_packet->is_signaled = false;
|
|
|
|
@@ -576,6 +607,9 @@ static efi_status_t EFIAPI efi_net_transmit
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eth_set_dev(netobj->dev);
|
|
|
|
|
env_set("ethact", eth_get_name());
|
|
|
|
|
|
|
|
|
|
/* Ethernet packets always fit, just bounce */
|
|
|
|
|
memcpy(transmit_buffer, buffer, buffer_size);
|
|
|
|
|
net_send_packet(transmit_buffer, buffer_size);
|
|
|
|
@@ -753,6 +787,8 @@ static void EFIAPI efi_network_timer_notify(struct efi_event *event,
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
if (!rx_packet_num) {
|
|
|
|
|
eth_set_dev(netobj->dev);
|
|
|
|
|
env_set("ethact", eth_get_name());
|
|
|
|
|
push_packet = efi_net_push;
|
|
|
|
|
eth_rx();
|
|
|
|
|
push_packet = NULL;
|
|
|
|
@@ -878,17 +914,106 @@ static efi_status_t EFIAPI efi_pxe_base_code_set_packets(
|
|
|
|
|
return EFI_UNSUPPORTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* efi_netobj_set_dp() - set device path of a netobj
|
|
|
|
|
*
|
|
|
|
|
* @netobj: pointer to efi_net_obj
|
|
|
|
|
* @dp: device path to set, allocated by caller
|
|
|
|
|
* Return: status code
|
|
|
|
|
*/
|
|
|
|
|
efi_status_t efi_netobj_set_dp(struct efi_net_obj *netobj, struct efi_device_path *dp)
|
|
|
|
|
{
|
|
|
|
|
efi_status_t ret;
|
|
|
|
|
struct efi_handler *phandler;
|
|
|
|
|
struct efi_device_path *new_net_dp;
|
|
|
|
|
|
|
|
|
|
if (!efi_netobj_is_active(netobj))
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
|
|
|
|
|
|
// Create a device path for the netobj
|
|
|
|
|
new_net_dp = dp;
|
|
|
|
|
if (!new_net_dp)
|
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
|
|
|
|
|
|
phandler = NULL;
|
|
|
|
|
efi_search_protocol(&netobj->header, &efi_guid_device_path, &phandler);
|
|
|
|
|
|
|
|
|
|
// If the device path protocol is not yet installed, install it
|
|
|
|
|
if (!phandler)
|
|
|
|
|
goto add;
|
|
|
|
|
|
|
|
|
|
// If it is already installed, try to update it
|
|
|
|
|
ret = efi_reinstall_protocol_interface(&netobj->header, &efi_guid_device_path,
|
|
|
|
|
phandler->protocol_interface, new_net_dp);
|
|
|
|
|
if (ret != EFI_SUCCESS)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
|
add:
|
|
|
|
|
ret = efi_add_protocol(&netobj->header, &efi_guid_device_path,
|
|
|
|
|
new_net_dp);
|
|
|
|
|
if (ret != EFI_SUCCESS)
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* efi_netobj_get_dp() - get device path of a netobj
|
|
|
|
|
*
|
|
|
|
|
* @netobj: pointer to efi_net_obj
|
|
|
|
|
* Return: device path, NULL on error
|
|
|
|
|
*/
|
|
|
|
|
static struct efi_device_path *efi_netobj_get_dp(struct efi_net_obj *netobj)
|
|
|
|
|
{
|
|
|
|
|
struct efi_handler *phandler;
|
|
|
|
|
|
|
|
|
|
if (!efi_netobj_is_active(netobj))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
phandler = NULL;
|
|
|
|
|
efi_search_protocol(&netobj->header, &efi_guid_device_path, &phandler);
|
|
|
|
|
|
|
|
|
|
if (phandler && phandler->protocol_interface)
|
|
|
|
|
return efi_dp_dup(phandler->protocol_interface);
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* efi_net_do_start() - start the efi network stack
|
|
|
|
|
*
|
|
|
|
|
* This gets called from do_bootefi_exec() each time a payload gets executed.
|
|
|
|
|
*
|
|
|
|
|
* @dev: net udevice
|
|
|
|
|
* Return: status code
|
|
|
|
|
*/
|
|
|
|
|
efi_status_t efi_net_do_start(void)
|
|
|
|
|
efi_status_t efi_net_do_start(struct udevice *dev)
|
|
|
|
|
{
|
|
|
|
|
efi_status_t r = EFI_SUCCESS;
|
|
|
|
|
struct efi_device_path *net_dp;
|
|
|
|
|
|
|
|
|
|
if (dev != netobj->dev )
|
|
|
|
|
return r;
|
|
|
|
|
|
|
|
|
|
efi_net_dp_from_dev(&net_dp, netobj->dev, true);
|
|
|
|
|
// If no dp cache entry applies and there already
|
|
|
|
|
// is a device path installed, continue
|
|
|
|
|
if (!net_dp) {
|
|
|
|
|
if (efi_netobj_get_dp(netobj))
|
|
|
|
|
goto set_addr;
|
|
|
|
|
else
|
|
|
|
|
net_dp = efi_dp_from_eth(netobj->dev);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!net_dp)
|
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
|
|
|
|
|
|
r = efi_netobj_set_dp(netobj, net_dp);
|
|
|
|
|
if (r != EFI_SUCCESS)
|
|
|
|
|
return r;
|
|
|
|
|
set_addr:
|
|
|
|
|
#ifdef CONFIG_EFI_HTTP_PROTOCOL
|
|
|
|
|
/*
|
|
|
|
|
* No harm on doing the following. If the PXE handle is present, the client could
|
|
|
|
@@ -896,7 +1021,7 @@ efi_status_t efi_net_do_start(void)
|
|
|
|
|
* but the PXE protocol is not yet implmenented, so we add this in the meantime.
|
|
|
|
|
*/
|
|
|
|
|
efi_net_get_addr((struct efi_ipv4_address *)&netobj->pxe_mode.station_ip,
|
|
|
|
|
(struct efi_ipv4_address *)&netobj->pxe_mode.subnet_mask, NULL);
|
|
|
|
|
(struct efi_ipv4_address *)&netobj->pxe_mode.subnet_mask, NULL, dev);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return r;
|
|
|
|
@@ -906,13 +1031,14 @@ efi_status_t efi_net_do_start(void)
|
|
|
|
|
* efi_net_register() - register the simple network protocol
|
|
|
|
|
*
|
|
|
|
|
* This gets called from do_bootefi_exec().
|
|
|
|
|
* @dev: net udevice
|
|
|
|
|
*/
|
|
|
|
|
efi_status_t efi_net_register(void)
|
|
|
|
|
efi_status_t efi_net_register(struct udevice *dev)
|
|
|
|
|
{
|
|
|
|
|
efi_status_t r;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (!eth_get_dev()) {
|
|
|
|
|
if (!dev) {
|
|
|
|
|
/* No network device active, don't expose any */
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
|
}
|
|
|
|
@@ -922,6 +1048,8 @@ efi_status_t efi_net_register(void)
|
|
|
|
|
if (!netobj)
|
|
|
|
|
goto out_of_resources;
|
|
|
|
|
|
|
|
|
|
netobj->dev = dev;
|
|
|
|
|
|
|
|
|
|
/* Allocate an aligned transmit buffer */
|
|
|
|
|
transmit_buffer = calloc(1, PKTSIZE_ALIGN + PKTALIGN);
|
|
|
|
|
if (!transmit_buffer)
|
|
|
|
@@ -938,6 +1066,7 @@ efi_status_t efi_net_register(void)
|
|
|
|
|
if (!receive_buffer[i])
|
|
|
|
|
goto out_of_resources;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
receive_lengths = calloc(ETH_PACKETS_BATCH_RECV,
|
|
|
|
|
sizeof(*receive_lengths));
|
|
|
|
|
if (!receive_lengths)
|
|
|
|
@@ -952,12 +1081,6 @@ efi_status_t efi_net_register(void)
|
|
|
|
|
if (r != EFI_SUCCESS)
|
|
|
|
|
goto failure_to_add_protocol;
|
|
|
|
|
|
|
|
|
|
if (!net_dp)
|
|
|
|
|
efi_net_set_dp("Net", NULL);
|
|
|
|
|
r = efi_add_protocol(&netobj->header, &efi_guid_device_path,
|
|
|
|
|
net_dp);
|
|
|
|
|
if (r != EFI_SUCCESS)
|
|
|
|
|
goto failure_to_add_protocol;
|
|
|
|
|
r = efi_add_protocol(&netobj->header, &efi_pxe_base_code_protocol_guid,
|
|
|
|
|
&netobj->pxe);
|
|
|
|
|
if (r != EFI_SUCCESS)
|
|
|
|
@@ -978,7 +1101,9 @@ efi_status_t efi_net_register(void)
|
|
|
|
|
netobj->net.receive = efi_net_receive;
|
|
|
|
|
netobj->net.mode = &netobj->net_mode;
|
|
|
|
|
netobj->net_mode.state = EFI_NETWORK_STOPPED;
|
|
|
|
|
memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6);
|
|
|
|
|
if (dev_get_plat(dev))
|
|
|
|
|
memcpy(netobj->net_mode.current_address.mac_addr,
|
|
|
|
|
((struct eth_pdata *)dev_get_plat(dev))->enetaddr, 6);
|
|
|
|
|
netobj->net_mode.hwaddr_size = ARP_HLEN;
|
|
|
|
|
netobj->net_mode.media_header_size = ETHER_HDR_SIZE;
|
|
|
|
|
netobj->net_mode.max_packet_size = PKTSIZE;
|
|
|
|
@@ -1012,6 +1137,7 @@ efi_status_t efi_net_register(void)
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
netobj->net.wait_for_packet = wait_for_packet;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Create a timer event.
|
|
|
|
|
*
|
|
|
|
@@ -1045,7 +1171,6 @@ efi_status_t efi_net_register(void)
|
|
|
|
|
if (r != EFI_SUCCESS)
|
|
|
|
|
goto failure_to_add_protocol;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
|
failure_to_add_protocol:
|
|
|
|
|
printf("ERROR: Failure to add protocol\n");
|
|
|
|
@@ -1064,46 +1189,91 @@ out_of_resources:
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* efi_net_set_dp() - set device path of efi net device
|
|
|
|
|
* efi_net_new_dp() - update device path associated to a net udevice
|
|
|
|
|
*
|
|
|
|
|
* This gets called to update the device path when a new boot
|
|
|
|
|
* file is downloaded
|
|
|
|
|
*
|
|
|
|
|
* @dev: dev to set the device path from
|
|
|
|
|
* @server: remote server address
|
|
|
|
|
* @udev: net udevice
|
|
|
|
|
* Return: status code
|
|
|
|
|
*/
|
|
|
|
|
efi_status_t efi_net_set_dp(const char *dev, const char *server)
|
|
|
|
|
efi_status_t efi_net_new_dp(const char *dev, const char *server, struct udevice *udev)
|
|
|
|
|
{
|
|
|
|
|
efi_free_pool(net_dp);
|
|
|
|
|
efi_status_t ret;
|
|
|
|
|
struct efi_device_path *old_net_dp, *new_net_dp;
|
|
|
|
|
struct efi_device_path **dp;
|
|
|
|
|
|
|
|
|
|
net_dp = NULL;
|
|
|
|
|
dp = &dp_cache[next_dp_entry].net_dp;
|
|
|
|
|
|
|
|
|
|
dp_cache[next_dp_entry].dev = udev;
|
|
|
|
|
dp_cache[next_dp_entry].is_valid = true;
|
|
|
|
|
next_dp_entry++;
|
|
|
|
|
next_dp_entry %= MAX_NUM_DP_ENTRIES;
|
|
|
|
|
|
|
|
|
|
old_net_dp = *dp;
|
|
|
|
|
new_net_dp = NULL;
|
|
|
|
|
if (!strcmp(dev, "Net"))
|
|
|
|
|
net_dp = efi_dp_from_eth(eth_get_dev());
|
|
|
|
|
new_net_dp = efi_dp_from_eth(udev);
|
|
|
|
|
else if (!strcmp(dev, "Http"))
|
|
|
|
|
net_dp = efi_dp_from_http(server, eth_get_dev());
|
|
|
|
|
|
|
|
|
|
if (!net_dp)
|
|
|
|
|
new_net_dp = efi_dp_from_http(server, udev);
|
|
|
|
|
if (!new_net_dp)
|
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
|
|
|
|
|
|
*dp = new_net_dp;
|
|
|
|
|
// Free the old cache entry
|
|
|
|
|
efi_free_pool(old_net_dp);
|
|
|
|
|
|
|
|
|
|
if (!netobj || netobj->dev != udev)
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
|
|
|
|
|
|
new_net_dp = efi_dp_dup(*dp);
|
|
|
|
|
if (!new_net_dp)
|
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
|
ret = efi_netobj_set_dp(netobj, new_net_dp);
|
|
|
|
|
if (ret != EFI_SUCCESS)
|
|
|
|
|
efi_free_pool(new_net_dp);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* efi_net_get_dp() - get device path of efi net device
|
|
|
|
|
* efi_net_dp_from_dev() - get device path associated to a net udevice
|
|
|
|
|
*
|
|
|
|
|
* Produce a copy of the current device path
|
|
|
|
|
*
|
|
|
|
|
* @dp: copy of the current device path, or NULL on error
|
|
|
|
|
* @dp: copy of the current device path
|
|
|
|
|
* @udev: net udevice
|
|
|
|
|
* @cache_only: get device path from cache only
|
|
|
|
|
*/
|
|
|
|
|
void efi_net_get_dp(struct efi_device_path **dp)
|
|
|
|
|
void efi_net_dp_from_dev(struct efi_device_path **dp, struct udevice *udev, bool cache_only)
|
|
|
|
|
{
|
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
|
|
if (!dp)
|
|
|
|
|
return;
|
|
|
|
|
if (!net_dp)
|
|
|
|
|
efi_net_set_dp("Net", NULL);
|
|
|
|
|
if (net_dp)
|
|
|
|
|
*dp = efi_dp_dup(net_dp);
|
|
|
|
|
|
|
|
|
|
*dp = NULL;
|
|
|
|
|
|
|
|
|
|
if (cache_only)
|
|
|
|
|
goto cache;
|
|
|
|
|
|
|
|
|
|
if (netobj && netobj->dev == udev) {
|
|
|
|
|
*dp = efi_netobj_get_dp(netobj);
|
|
|
|
|
if (*dp)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
cache:
|
|
|
|
|
// Search in the cache
|
|
|
|
|
i = (next_dp_entry + MAX_NUM_DP_ENTRIES - 1) % MAX_NUM_DP_ENTRIES;
|
|
|
|
|
for (j = 0; dp_cache[i].is_valid && j < MAX_NUM_DP_ENTRIES;
|
|
|
|
|
i = (i + MAX_NUM_DP_ENTRIES - 1) % MAX_NUM_DP_ENTRIES, j++) {
|
|
|
|
|
if (dp_cache[i].dev == udev) {
|
|
|
|
|
*dp = efi_dp_dup(dp_cache[i].net_dp);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@@ -1119,11 +1289,15 @@ void efi_net_get_dp(struct efi_device_path **dp)
|
|
|
|
|
* be filled with the current network mask
|
|
|
|
|
* @gw: pointer to an efi_ipv4_address struct to be
|
|
|
|
|
* filled with the current network gateway
|
|
|
|
|
* @dev: udevice
|
|
|
|
|
*/
|
|
|
|
|
void efi_net_get_addr(struct efi_ipv4_address *ip,
|
|
|
|
|
struct efi_ipv4_address *mask,
|
|
|
|
|
struct efi_ipv4_address *gw)
|
|
|
|
|
struct efi_ipv4_address *gw,
|
|
|
|
|
struct udevice *dev)
|
|
|
|
|
{
|
|
|
|
|
if (!dev)
|
|
|
|
|
dev = eth_get_dev();
|
|
|
|
|
#ifdef CONFIG_NET_LWIP
|
|
|
|
|
char ipstr[] = "ipaddr\0\0";
|
|
|
|
|
char maskstr[] = "netmask\0\0";
|
|
|
|
@@ -1132,7 +1306,7 @@ void efi_net_get_addr(struct efi_ipv4_address *ip,
|
|
|
|
|
struct in_addr tmp;
|
|
|
|
|
char *env;
|
|
|
|
|
|
|
|
|
|
idx = dev_seq(eth_get_dev());
|
|
|
|
|
idx = dev_seq(dev);
|
|
|
|
|
|
|
|
|
|
if (idx < 0 || idx > 99) {
|
|
|
|
|
log_err("unexpected idx %d\n", idx);
|
|
|
|
@@ -1179,11 +1353,15 @@ void efi_net_get_addr(struct efi_ipv4_address *ip,
|
|
|
|
|
* @ip: pointer to new IP address
|
|
|
|
|
* @mask: pointer to new network mask to set
|
|
|
|
|
* @gw: pointer to new network gateway
|
|
|
|
|
* @dev: udevice
|
|
|
|
|
*/
|
|
|
|
|
void efi_net_set_addr(struct efi_ipv4_address *ip,
|
|
|
|
|
struct efi_ipv4_address *mask,
|
|
|
|
|
struct efi_ipv4_address *gw)
|
|
|
|
|
struct efi_ipv4_address *gw,
|
|
|
|
|
struct udevice *dev)
|
|
|
|
|
{
|
|
|
|
|
if (!dev)
|
|
|
|
|
dev = eth_get_dev();
|
|
|
|
|
#ifdef CONFIG_NET_LWIP
|
|
|
|
|
char ipstr[] = "ipaddr\0\0";
|
|
|
|
|
char maskstr[] = "netmask\0\0";
|
|
|
|
@@ -1192,7 +1370,7 @@ void efi_net_set_addr(struct efi_ipv4_address *ip,
|
|
|
|
|
struct in_addr *addr;
|
|
|
|
|
char tmp[46];
|
|
|
|
|
|
|
|
|
|
idx = dev_seq(eth_get_dev());
|
|
|
|
|
idx = dev_seq(dev);
|
|
|
|
|
|
|
|
|
|
if (idx < 0 || idx > 99) {
|
|
|
|
|
log_err("unexpected idx %d\n", idx);
|
|
|
|
@@ -1230,6 +1408,7 @@ void efi_net_set_addr(struct efi_ipv4_address *ip,
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if IS_ENABLED(CONFIG_EFI_HTTP_PROTOCOL)
|
|
|
|
|
/**
|
|
|
|
|
* efi_net_set_buffer() - allocate a buffer of min 64K
|
|
|
|
|
*
|
|
|
|
@@ -1337,6 +1516,8 @@ efi_status_t efi_net_do_request(u8 *url, enum efi_http_method method, void **buf
|
|
|
|
|
ret = efi_net_set_buffer(buffer, last_head ? (size_t)efi_wget_info.hdr_cont_len : 0);
|
|
|
|
|
if (ret != EFI_SUCCESS)
|
|
|
|
|
goto out;
|
|
|
|
|
eth_set_dev(netobj->dev);
|
|
|
|
|
env_set("ethact", eth_get_name());
|
|
|
|
|
wget_ret = wget_request((ulong)*buffer, url, &efi_wget_info);
|
|
|
|
|
if ((ulong)efi_wget_info.hdr_cont_len > efi_wget_info.buffer_size) {
|
|
|
|
|
// Try again with updated buffer size
|
|
|
|
@@ -1344,6 +1525,8 @@ efi_status_t efi_net_do_request(u8 *url, enum efi_http_method method, void **buf
|
|
|
|
|
ret = efi_net_set_buffer(buffer, (size_t)efi_wget_info.hdr_cont_len);
|
|
|
|
|
if (ret != EFI_SUCCESS)
|
|
|
|
|
goto out;
|
|
|
|
|
eth_set_dev(netobj->dev);
|
|
|
|
|
env_set("ethact", eth_get_name());
|
|
|
|
|
if (wget_request((ulong)*buffer, url, &efi_wget_info)) {
|
|
|
|
|
efi_free_pool(*buffer);
|
|
|
|
|
ret = EFI_DEVICE_ERROR;
|
|
|
|
@@ -1363,6 +1546,8 @@ efi_status_t efi_net_do_request(u8 *url, enum efi_http_method method, void **buf
|
|
|
|
|
ret = efi_net_set_buffer(buffer, 0);
|
|
|
|
|
if (ret != EFI_SUCCESS)
|
|
|
|
|
goto out;
|
|
|
|
|
eth_set_dev(netobj->dev);
|
|
|
|
|
env_set("ethact", eth_get_name());
|
|
|
|
|
wget_request((ulong)*buffer, url, &efi_wget_info);
|
|
|
|
|
*file_size = 0;
|
|
|
|
|
*status_code = efi_wget_info.status_code;
|
|
|
|
@@ -1376,3 +1561,4 @@ efi_status_t efi_net_do_request(u8 *url, enum efi_http_method method, void **buf
|
|
|
|
|
out:
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|