Commit a0549ef6073e346eb0cbbae1395d4db446b7b05e
Committed by
Alexander Graf
1 parent
61da678c39
Exists in
smarc_8mq_lf_v2020.04
and in
17 other branches
efi_loader: use events for efi_net_receive
A timer event is defined. The timer handler cares for receiving new packets. efi_timer_check is called both in efi_net_transmit and efi_net_receive to enable events during network communication. Calling efi_timer_check in efi_net_get_status is implemented in a separate patch. [agraf] This patch is needed to make efi_net_get_status() actually report incoming packets. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> [agraf: fix spelling in comment] Reviewed-by: Simon Glass <sjg@chromium.org> Signed-off-by: Alexander Graf <agraf@suse.de>
Showing 1 changed file with 50 additions and 3 deletions Side-by-side Diff
lib/efi_loader/efi_net.c
... | ... | @@ -19,6 +19,11 @@ |
19 | 19 | static struct efi_pxe_packet *dhcp_ack; |
20 | 20 | static bool new_rx_packet; |
21 | 21 | static void *new_tx_packet; |
22 | +/* | |
23 | + * The notification function of this event is called in every timer cycle | |
24 | + * to check if a new network packet has been received. | |
25 | + */ | |
26 | +static struct efi_event *network_timer_event; | |
22 | 27 | |
23 | 28 | struct efi_net_obj { |
24 | 29 | /* Generic EFI object parent class data */ |
... | ... | @@ -143,6 +148,8 @@ |
143 | 148 | EFI_ENTRY("%p, %lx, %lx, %p, %p, %p, %p", this, header_size, |
144 | 149 | buffer_size, buffer, src_addr, dest_addr, protocol); |
145 | 150 | |
151 | + efi_timer_check(); | |
152 | + | |
146 | 153 | if (header_size) { |
147 | 154 | /* We would need to create the header if header_size != 0 */ |
148 | 155 | return EFI_EXIT(EFI_INVALID_PARAMETER); |
... | ... | @@ -174,9 +181,7 @@ |
174 | 181 | EFI_ENTRY("%p, %p, %p, %p, %p, %p, %p", this, header_size, |
175 | 182 | buffer_size, buffer, src_addr, dest_addr, protocol); |
176 | 183 | |
177 | - push_packet = efi_net_push; | |
178 | - eth_rx(); | |
179 | - push_packet = NULL; | |
184 | + efi_timer_check(); | |
180 | 185 | |
181 | 186 | if (!new_rx_packet) |
182 | 187 | return EFI_EXIT(EFI_NOT_READY); |
183 | 188 | |
... | ... | @@ -204,10 +209,32 @@ |
204 | 209 | memcpy(dhcp_ack, pkt, min(len, maxsize)); |
205 | 210 | } |
206 | 211 | |
212 | +/* | |
213 | + * Check if a new network packet has been received. | |
214 | + * | |
215 | + * This notification function is called in every timer cycle. | |
216 | + * | |
217 | + * @event the event for which this notification function is registered | |
218 | + * @context event context - not used in this function | |
219 | + */ | |
220 | +static void EFIAPI efi_network_timer_notify(struct efi_event *event, | |
221 | + void *context) | |
222 | +{ | |
223 | + EFI_ENTRY("%p, %p", event, context); | |
224 | + | |
225 | + if (!new_rx_packet) { | |
226 | + push_packet = efi_net_push; | |
227 | + eth_rx(); | |
228 | + push_packet = NULL; | |
229 | + } | |
230 | + EFI_EXIT(EFI_SUCCESS); | |
231 | +} | |
232 | + | |
207 | 233 | /* This gets called from do_bootefi_exec(). */ |
208 | 234 | int efi_net_register(void) |
209 | 235 | { |
210 | 236 | struct efi_net_obj *netobj; |
237 | + efi_status_t r; | |
211 | 238 | |
212 | 239 | if (!eth_get_dev()) { |
213 | 240 | /* No eth device active, don't expose any */ |
... | ... | @@ -252,6 +279,26 @@ |
252 | 279 | |
253 | 280 | /* Hook net up to the device list */ |
254 | 281 | list_add_tail(&netobj->parent.link, &efi_obj_list); |
282 | + | |
283 | + /* | |
284 | + * Create a timer event. | |
285 | + * | |
286 | + * The notification function is used to check if a new network packet | |
287 | + * has been received. | |
288 | + */ | |
289 | + r = efi_create_event(EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, | |
290 | + efi_network_timer_notify, NULL, | |
291 | + &network_timer_event); | |
292 | + if (r != EFI_SUCCESS) { | |
293 | + printf("ERROR: Failed to register network event\n"); | |
294 | + return r; | |
295 | + } | |
296 | + /* Network is time critical, create event in every timer cyle */ | |
297 | + r = efi_set_timer(network_timer_event, EFI_TIMER_PERIODIC, 0); | |
298 | + if (r != EFI_SUCCESS) { | |
299 | + printf("ERROR: Failed to set network timer\n"); | |
300 | + return r; | |
301 | + } | |
255 | 302 | |
256 | 303 | return 0; |
257 | 304 | } |