summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/charset.c2
-rw-r--r--lib/display_options.c2
-rw-r--r--lib/efi_loader/efi_console.c20
-rw-r--r--lib/efi_loader/efi_net.c92
4 files changed, 81 insertions, 35 deletions
diff --git a/lib/charset.c b/lib/charset.c
index a28034ee1f1..5686d6fb59c 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -104,7 +104,7 @@ static u8 read_console(void *data)
{
int ch;
- ch = getc();
+ ch = getchar();
if (ch < 0)
ch = 0;
return ch;
diff --git a/lib/display_options.c b/lib/display_options.c
index ea9977cc180..b2025eeb5cf 100644
--- a/lib/display_options.c
+++ b/lib/display_options.c
@@ -54,7 +54,7 @@ void print_freq(uint64_t freq, const char *s)
{
unsigned long m = 0;
uint32_t f;
- static const char names[] = {'G', 'M', 'K'};
+ static const char names[] = {'G', 'M', 'k'};
unsigned long d = 1e9;
char c = 0;
unsigned int i;
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index 426de779517..011accab789 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -76,7 +76,7 @@ static int term_get_char(s32 *c)
if (timer_get_us() > timeout)
return 1;
- *c = getc();
+ *c = getchar();
return 0;
}
@@ -269,7 +269,7 @@ static int query_console_serial(int *rows, int *cols)
/* Empty input buffer */
while (tstc())
- getc();
+ getchar();
/*
* Not all terminals understand CSI [18t for querying the console size.
@@ -634,13 +634,13 @@ static int analyze_modifiers(struct efi_key_state *key_state)
{
int c, mod = 0, ret = 0;
- c = getc();
+ c = getchar();
if (c != ';') {
ret = c;
if (c == '~')
goto out;
- c = getc();
+ c = getchar();
}
for (;;) {
switch (c) {
@@ -649,7 +649,7 @@ static int analyze_modifiers(struct efi_key_state *key_state)
mod += c - '0';
/* fall through */
case ';':
- c = getc();
+ c = getchar();
break;
default:
goto out;
@@ -692,25 +692,25 @@ static efi_status_t efi_cin_read_key(struct efi_key_data *key)
* Xterm Control Sequences
* https://www.xfree86.org/4.8.0/ctlseqs.html
*/
- ch = getc();
+ ch = getchar();
switch (ch) {
case cESC: /* ESC */
pressed_key.scan_code = 23;
break;
case 'O': /* F1 - F4, End */
- ch = getc();
+ ch = getchar();
/* consider modifiers */
if (ch == 'F') { /* End */
pressed_key.scan_code = 6;
break;
} else if (ch < 'P') {
set_shift_mask(ch - '0', &key->key_state);
- ch = getc();
+ ch = getchar();
}
pressed_key.scan_code = ch - 'P' + 11;
break;
case '[':
- ch = getc();
+ ch = getchar();
switch (ch) {
case 'A'...'D': /* up, down right, left */
pressed_key.scan_code = ch - 'A' + 1;
@@ -868,7 +868,7 @@ static void efi_cin_check(void)
static void efi_cin_empty_buffer(void)
{
while (tstc())
- getc();
+ getchar();
key_available = false;
}
diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c
index 22f0123eca4..69276b275d9 100644
--- a/lib/efi_loader/efi_net.c
+++ b/lib/efi_loader/efi_net.c
@@ -24,9 +24,12 @@ static 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 bool new_rx_packet;
static void *new_tx_packet;
static void *transmit_buffer;
+static uchar **receive_buffer;
+static size_t *receive_lengths;
+static int rx_packet_idx;
+static int rx_packet_num;
/*
* The notification function of this event is called in every timer cycle
@@ -115,6 +118,8 @@ static efi_status_t EFIAPI efi_net_stop(struct efi_simple_network *this)
} else {
/* Disable hardware and put it into the reset state */
eth_halt();
+ /* Clear cache of packets */
+ rx_packet_num = 0;
this->mode->state = EFI_NETWORK_STOPPED;
}
out:
@@ -160,6 +165,8 @@ static efi_status_t EFIAPI efi_net_initialize(struct efi_simple_network *this,
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();
/* Get hardware ready for send and receive operations */
@@ -602,16 +609,16 @@ static efi_status_t EFIAPI efi_net_receive
break;
}
- if (!new_rx_packet) {
+ if (!rx_packet_num) {
ret = EFI_NOT_READY;
goto out;
}
/* Fill export parameters */
- eth_hdr = (struct ethernet_hdr *)net_rx_packet;
+ eth_hdr = (struct ethernet_hdr *)receive_buffer[rx_packet_idx];
protlen = ntohs(eth_hdr->et_protlen);
if (protlen == 0x8100) {
hdr_size += 4;
- protlen = ntohs(*(u16 *)&net_rx_packet[hdr_size - 2]);
+ protlen = ntohs(*(u16 *)&receive_buffer[rx_packet_idx][hdr_size - 2]);
}
if (header_size)
*header_size = hdr_size;
@@ -621,17 +628,22 @@ static efi_status_t EFIAPI efi_net_receive
memcpy(src_addr, eth_hdr->et_src, ARP_HLEN);
if (protocol)
*protocol = protlen;
- if (*buffer_size < net_rx_packet_len) {
+ if (*buffer_size < receive_lengths[rx_packet_idx]) {
/* Packet doesn't fit, try again with bigger buffer */
- *buffer_size = net_rx_packet_len;
+ *buffer_size = receive_lengths[rx_packet_idx];
ret = EFI_BUFFER_TOO_SMALL;
goto out;
}
/* Copy packet */
- memcpy(buffer, net_rx_packet, net_rx_packet_len);
- *buffer_size = net_rx_packet_len;
- new_rx_packet = 0;
- this->int_status &= ~EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
+ memcpy(buffer, receive_buffer[rx_packet_idx],
+ receive_lengths[rx_packet_idx]);
+ *buffer_size = receive_lengths[rx_packet_idx];
+ rx_packet_idx = (rx_packet_idx + 1) % ETH_PACKETS_BATCH_RECV;
+ rx_packet_num--;
+ if (rx_packet_num)
+ wait_for_packet->is_signaled = true;
+ else
+ this->int_status &= ~EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
out:
return EFI_EXIT(ret);
}
@@ -664,7 +676,26 @@ void efi_net_set_dhcp_ack(void *pkt, int len)
*/
static void efi_net_push(void *pkt, int len)
{
- new_rx_packet = true;
+ int rx_packet_next;
+
+ /* Check that we at least received an Ethernet header */
+ if (len < sizeof(struct ethernet_hdr))
+ return;
+
+ /* Check that the buffer won't overflow */
+ if (len > PKTSIZE_ALIGN)
+ return;
+
+ /* Can't store more than pre-alloced buffer */
+ if (rx_packet_num >= ETH_PACKETS_BATCH_RECV)
+ return;
+
+ rx_packet_next = (rx_packet_idx + rx_packet_num) %
+ ETH_PACKETS_BATCH_RECV;
+ memcpy(receive_buffer[rx_packet_next], pkt, len);
+ receive_lengths[rx_packet_next] = len;
+
+ rx_packet_num++;
}
/**
@@ -689,20 +720,14 @@ static void EFIAPI efi_network_timer_notify(struct efi_event *event,
if (!this || this->mode->state != EFI_NETWORK_INITIALIZED)
goto out;
- if (!new_rx_packet) {
+ if (!rx_packet_num) {
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;
- }
+ if (rx_packet_num) {
+ this->int_status |=
+ EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
+ wait_for_packet->is_signaled = true;
}
}
out:
@@ -830,6 +855,7 @@ efi_status_t efi_net_register(void)
{
struct efi_net_obj *netobj = NULL;
efi_status_t r;
+ int i;
if (!eth_get_dev()) {
/* No network device active, don't expose any */
@@ -847,6 +873,21 @@ efi_status_t efi_net_register(void)
goto out_of_resources;
transmit_buffer = (void *)ALIGN((uintptr_t)transmit_buffer, PKTALIGN);
+ /* Allocate a number of receive buffers */
+ receive_buffer = calloc(ETH_PACKETS_BATCH_RECV,
+ sizeof(*receive_buffer));
+ if (!receive_buffer)
+ goto out_of_resources;
+ for (i = 0; i < ETH_PACKETS_BATCH_RECV; i++) {
+ receive_buffer[i] = malloc(PKTSIZE_ALIGN);
+ if (!receive_buffer[i])
+ goto out_of_resources;
+ }
+ receive_lengths = calloc(ETH_PACKETS_BATCH_RECV,
+ sizeof(*receive_lengths));
+ if (!receive_lengths)
+ goto out_of_resources;
+
/* Hook net up to the device list */
efi_add_handle(&netobj->header);
@@ -941,7 +982,12 @@ failure_to_add_protocol:
return r;
out_of_resources:
free(netobj);
- /* free(transmit_buffer) not needed yet */
+ free(transmit_buffer);
+ if (receive_buffer)
+ for (i = 0; i < ETH_PACKETS_BATCH_RECV; i++)
+ free(receive_buffer[i]);
+ free(receive_buffer);
+ free(receive_lengths);
printf("ERROR: Out of memory\n");
return EFI_OUT_OF_RESOURCES;
}