[efi] Run at TPL_CALLBACK to protect against UEFI timers
[ipxe.git] / src / interface / efi / efi_snp.c
1 /*
2 * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <assert.h>
26 #include <byteswap.h>
27 #include <ipxe/netdevice.h>
28 #include <ipxe/vlan.h>
29 #include <ipxe/iobuf.h>
30 #include <ipxe/in.h>
31 #include <ipxe/version.h>
32 #include <ipxe/console.h>
33 #include <ipxe/efi/efi.h>
34 #include <ipxe/efi/efi_driver.h>
35 #include <ipxe/efi/efi_strings.h>
36 #include <ipxe/efi/efi_utils.h>
37 #include <ipxe/efi/efi_watchdog.h>
38 #include <ipxe/efi/efi_snp.h>
39 #include <usr/autoboot.h>
40 #include <config/general.h>
41
42 /** List of SNP devices */
43 static LIST_HEAD ( efi_snp_devices );
44
45 /** Network devices are currently claimed for use by iPXE */
46 static int efi_snp_claimed;
47
48 /** TPL prior to network devices being claimed */
49 static EFI_TPL efi_snp_old_tpl;
50
51 /* Downgrade user experience if configured to do so
52 *
53 * The default UEFI user experience for network boot is somewhat
54 * excremental: only TFTP is available as a download protocol, and if
55 * anything goes wrong the user will be shown just a dot on an
56 * otherwise blank screen. (Some programmer was clearly determined to
57 * win a bet that they could outshine Apple at producing uninformative
58 * error messages.)
59 *
60 * For comparison, the default iPXE user experience provides the
61 * option to use protocols designed more recently than 1980 (such as
62 * HTTP and iSCSI), and if anything goes wrong the the user will be
63 * shown one of over 1200 different error messages, complete with a
64 * link to a wiki page describing that specific error.
65 *
66 * We default to upgrading the user experience to match that available
67 * in a "legacy" BIOS environment, by installing our own instance of
68 * EFI_LOAD_FILE_PROTOCOL.
69 *
70 * Note that unfortunately we can't sensibly provide the choice of
71 * both options to the user in the same build, because the UEFI boot
72 * menu ignores the multitude of ways in which a network device handle
73 * can be described and opaquely labels both menu entries as just "EFI
74 * Network".
75 */
76 #ifdef EFI_DOWNGRADE_UX
77 static EFI_GUID dummy_load_file_protocol_guid = {
78 0x6f6c7323, 0x2077, 0x7523,
79 { 0x6e, 0x68, 0x65, 0x6c, 0x70, 0x66, 0x75, 0x6c }
80 };
81 #define efi_load_file_protocol_guid dummy_load_file_protocol_guid
82 #endif
83
84 /**
85 * Set EFI SNP mode state
86 *
87 * @v snp SNP interface
88 */
89 static void efi_snp_set_state ( struct efi_snp_device *snpdev ) {
90 struct net_device *netdev = snpdev->netdev;
91 EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
92
93 /* Calculate state */
94 if ( ! snpdev->started ) {
95 /* Start() method not called; report as Stopped */
96 mode->State = EfiSimpleNetworkStopped;
97 } else if ( ! netdev_is_open ( netdev ) ) {
98 /* Network device not opened; report as Started */
99 mode->State = EfiSimpleNetworkStarted;
100 } else if ( efi_snp_claimed ) {
101 /* Network device opened but claimed for use by iPXE; report
102 * as Started to inhibit receive polling.
103 */
104 mode->State = EfiSimpleNetworkStarted;
105 } else {
106 /* Network device opened and available for use via SNP; report
107 * as Initialized.
108 */
109 mode->State = EfiSimpleNetworkInitialized;
110 }
111 }
112
113 /**
114 * Set EFI SNP mode based on iPXE net device parameters
115 *
116 * @v snp SNP interface
117 */
118 static void efi_snp_set_mode ( struct efi_snp_device *snpdev ) {
119 struct net_device *netdev = snpdev->netdev;
120 EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
121 struct ll_protocol *ll_protocol = netdev->ll_protocol;
122 unsigned int ll_addr_len = ll_protocol->ll_addr_len;
123
124 mode->HwAddressSize = ll_addr_len;
125 mode->MediaHeaderSize = ll_protocol->ll_header_len;
126 mode->MaxPacketSize = netdev->max_pkt_len;
127 mode->ReceiveFilterMask = ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
128 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
129 EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST );
130 assert ( ll_addr_len <= sizeof ( mode->CurrentAddress ) );
131 memcpy ( &mode->CurrentAddress, netdev->ll_addr, ll_addr_len );
132 memcpy ( &mode->BroadcastAddress, netdev->ll_broadcast, ll_addr_len );
133 ll_protocol->init_addr ( netdev->hw_addr, &mode->PermanentAddress );
134 mode->IfType = ntohs ( ll_protocol->ll_proto );
135 mode->MacAddressChangeable = TRUE;
136 mode->MediaPresentSupported = TRUE;
137 mode->MediaPresent = ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
138 }
139
140 /**
141 * Flush transmit ring and receive queue
142 *
143 * @v snpdev SNP device
144 */
145 static void efi_snp_flush ( struct efi_snp_device *snpdev ) {
146 struct io_buffer *iobuf;
147 struct io_buffer *tmp;
148
149 /* Reset transmit completion ring */
150 snpdev->tx_prod = 0;
151 snpdev->tx_cons = 0;
152
153 /* Discard any queued receive buffers */
154 list_for_each_entry_safe ( iobuf, tmp, &snpdev->rx, list ) {
155 list_del ( &iobuf->list );
156 free_iob ( iobuf );
157 }
158 }
159
160 /**
161 * Poll net device and count received packets
162 *
163 * @v snpdev SNP device
164 */
165 static void efi_snp_poll ( struct efi_snp_device *snpdev ) {
166 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
167 struct io_buffer *iobuf;
168
169 /* Poll network device */
170 netdev_poll ( snpdev->netdev );
171
172 /* Retrieve any received packets */
173 while ( ( iobuf = netdev_rx_dequeue ( snpdev->netdev ) ) ) {
174 list_add_tail ( &iobuf->list, &snpdev->rx );
175 snpdev->interrupts |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
176 bs->SignalEvent ( &snpdev->snp.WaitForPacket );
177 }
178 }
179
180 /**
181 * Change SNP state from "stopped" to "started"
182 *
183 * @v snp SNP interface
184 * @ret efirc EFI status code
185 */
186 static EFI_STATUS EFIAPI
187 efi_snp_start ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
188 struct efi_snp_device *snpdev =
189 container_of ( snp, struct efi_snp_device, snp );
190
191 DBGC ( snpdev, "SNPDEV %p START\n", snpdev );
192
193 /* Fail if net device is currently claimed for use by iPXE */
194 if ( efi_snp_claimed )
195 return EFI_NOT_READY;
196
197 snpdev->started = 1;
198 efi_snp_set_state ( snpdev );
199 return 0;
200 }
201
202 /**
203 * Change SNP state from "started" to "stopped"
204 *
205 * @v snp SNP interface
206 * @ret efirc EFI status code
207 */
208 static EFI_STATUS EFIAPI
209 efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
210 struct efi_snp_device *snpdev =
211 container_of ( snp, struct efi_snp_device, snp );
212
213 DBGC ( snpdev, "SNPDEV %p STOP\n", snpdev );
214
215 /* Fail if net device is currently claimed for use by iPXE */
216 if ( efi_snp_claimed )
217 return EFI_NOT_READY;
218
219 snpdev->started = 0;
220 efi_snp_set_state ( snpdev );
221
222 return 0;
223 }
224
225 /**
226 * Open the network device
227 *
228 * @v snp SNP interface
229 * @v extra_rx_bufsize Extra RX buffer size, in bytes
230 * @v extra_tx_bufsize Extra TX buffer size, in bytes
231 * @ret efirc EFI status code
232 */
233 static EFI_STATUS EFIAPI
234 efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
235 UINTN extra_rx_bufsize, UINTN extra_tx_bufsize ) {
236 struct efi_snp_device *snpdev =
237 container_of ( snp, struct efi_snp_device, snp );
238 int rc;
239
240 DBGC ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
241 snpdev, ( ( unsigned long ) extra_rx_bufsize ),
242 ( ( unsigned long ) extra_tx_bufsize ) );
243
244 /* Fail if net device is currently claimed for use by iPXE */
245 if ( efi_snp_claimed )
246 return EFI_NOT_READY;
247
248 if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
249 DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
250 snpdev, snpdev->netdev->name, strerror ( rc ) );
251 return EFIRC ( rc );
252 }
253 efi_snp_set_state ( snpdev );
254
255 return 0;
256 }
257
258 /**
259 * Reset the network device
260 *
261 * @v snp SNP interface
262 * @v ext_verify Extended verification required
263 * @ret efirc EFI status code
264 */
265 static EFI_STATUS EFIAPI
266 efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
267 struct efi_snp_device *snpdev =
268 container_of ( snp, struct efi_snp_device, snp );
269 int rc;
270
271 DBGC ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
272 snpdev, ( ext_verify ? "with" : "without" ) );
273
274 /* Fail if net device is currently claimed for use by iPXE */
275 if ( efi_snp_claimed )
276 return EFI_NOT_READY;
277
278 netdev_close ( snpdev->netdev );
279 efi_snp_set_state ( snpdev );
280 efi_snp_flush ( snpdev );
281
282 if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
283 DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
284 snpdev, snpdev->netdev->name, strerror ( rc ) );
285 return EFIRC ( rc );
286 }
287 efi_snp_set_state ( snpdev );
288
289 return 0;
290 }
291
292 /**
293 * Shut down the network device
294 *
295 * @v snp SNP interface
296 * @ret efirc EFI status code
297 */
298 static EFI_STATUS EFIAPI
299 efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
300 struct efi_snp_device *snpdev =
301 container_of ( snp, struct efi_snp_device, snp );
302
303 DBGC ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
304
305 /* Fail if net device is currently claimed for use by iPXE */
306 if ( efi_snp_claimed )
307 return EFI_NOT_READY;
308
309 netdev_close ( snpdev->netdev );
310 efi_snp_set_state ( snpdev );
311 efi_snp_flush ( snpdev );
312
313 return 0;
314 }
315
316 /**
317 * Manage receive filters
318 *
319 * @v snp SNP interface
320 * @v enable Receive filters to enable
321 * @v disable Receive filters to disable
322 * @v mcast_reset Reset multicast filters
323 * @v mcast_count Number of multicast filters
324 * @v mcast Multicast filters
325 * @ret efirc EFI status code
326 */
327 static EFI_STATUS EFIAPI
328 efi_snp_receive_filters ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 enable,
329 UINT32 disable, BOOLEAN mcast_reset,
330 UINTN mcast_count, EFI_MAC_ADDRESS *mcast ) {
331 struct efi_snp_device *snpdev =
332 container_of ( snp, struct efi_snp_device, snp );
333 unsigned int i;
334
335 DBGC ( snpdev, "SNPDEV %p RECEIVE_FILTERS %08x&~%08x%s %ld mcast\n",
336 snpdev, enable, disable, ( mcast_reset ? " reset" : "" ),
337 ( ( unsigned long ) mcast_count ) );
338 for ( i = 0 ; i < mcast_count ; i++ ) {
339 DBGC2_HDA ( snpdev, i, &mcast[i],
340 snpdev->netdev->ll_protocol->ll_addr_len );
341 }
342
343 /* Lie through our teeth, otherwise MNP refuses to accept us.
344 *
345 * Return success even if the SNP device is currently claimed
346 * for use by iPXE, since otherwise Windows Deployment
347 * Services refuses to attempt to receive further packets via
348 * our EFI PXE Base Code protocol.
349 */
350 return 0;
351 }
352
353 /**
354 * Set station address
355 *
356 * @v snp SNP interface
357 * @v reset Reset to permanent address
358 * @v new New station address
359 * @ret efirc EFI status code
360 */
361 static EFI_STATUS EFIAPI
362 efi_snp_station_address ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
363 EFI_MAC_ADDRESS *new ) {
364 struct efi_snp_device *snpdev =
365 container_of ( snp, struct efi_snp_device, snp );
366 struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
367
368 DBGC ( snpdev, "SNPDEV %p STATION_ADDRESS %s\n", snpdev,
369 ( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
370
371 /* Fail if net device is currently claimed for use by iPXE */
372 if ( efi_snp_claimed )
373 return EFI_NOT_READY;
374
375 /* Set the MAC address */
376 if ( reset )
377 new = &snpdev->mode.PermanentAddress;
378 memcpy ( snpdev->netdev->ll_addr, new, ll_protocol->ll_addr_len );
379
380 /* MAC address changes take effect only on netdev_open() */
381 if ( netdev_is_open ( snpdev->netdev ) ) {
382 DBGC ( snpdev, "SNPDEV %p MAC address changed while net "
383 "device open\n", snpdev );
384 }
385
386 return 0;
387 }
388
389 /**
390 * Get (or reset) statistics
391 *
392 * @v snp SNP interface
393 * @v reset Reset statistics
394 * @v stats_len Size of statistics table
395 * @v stats Statistics table
396 * @ret efirc EFI status code
397 */
398 static EFI_STATUS EFIAPI
399 efi_snp_statistics ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
400 UINTN *stats_len, EFI_NETWORK_STATISTICS *stats ) {
401 struct efi_snp_device *snpdev =
402 container_of ( snp, struct efi_snp_device, snp );
403 EFI_NETWORK_STATISTICS stats_buf;
404
405 DBGC ( snpdev, "SNPDEV %p STATISTICS%s", snpdev,
406 ( reset ? " reset" : "" ) );
407
408 /* Fail if net device is currently claimed for use by iPXE */
409 if ( efi_snp_claimed )
410 return EFI_NOT_READY;
411
412 /* Gather statistics */
413 memset ( &stats_buf, 0, sizeof ( stats_buf ) );
414 stats_buf.TxGoodFrames = snpdev->netdev->tx_stats.good;
415 stats_buf.TxDroppedFrames = snpdev->netdev->tx_stats.bad;
416 stats_buf.TxTotalFrames = ( snpdev->netdev->tx_stats.good +
417 snpdev->netdev->tx_stats.bad );
418 stats_buf.RxGoodFrames = snpdev->netdev->rx_stats.good;
419 stats_buf.RxDroppedFrames = snpdev->netdev->rx_stats.bad;
420 stats_buf.RxTotalFrames = ( snpdev->netdev->rx_stats.good +
421 snpdev->netdev->rx_stats.bad );
422 if ( *stats_len > sizeof ( stats_buf ) )
423 *stats_len = sizeof ( stats_buf );
424 if ( stats )
425 memcpy ( stats, &stats_buf, *stats_len );
426
427 /* Reset statistics if requested to do so */
428 if ( reset ) {
429 memset ( &snpdev->netdev->tx_stats, 0,
430 sizeof ( snpdev->netdev->tx_stats ) );
431 memset ( &snpdev->netdev->rx_stats, 0,
432 sizeof ( snpdev->netdev->rx_stats ) );
433 }
434
435 return 0;
436 }
437
438 /**
439 * Convert multicast IP address to MAC address
440 *
441 * @v snp SNP interface
442 * @v ipv6 Address is IPv6
443 * @v ip IP address
444 * @v mac MAC address
445 * @ret efirc EFI status code
446 */
447 static EFI_STATUS EFIAPI
448 efi_snp_mcast_ip_to_mac ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ipv6,
449 EFI_IP_ADDRESS *ip, EFI_MAC_ADDRESS *mac ) {
450 struct efi_snp_device *snpdev =
451 container_of ( snp, struct efi_snp_device, snp );
452 struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
453 const char *ip_str;
454 int rc;
455
456 ip_str = ( ipv6 ? "(IPv6)" /* FIXME when we have inet6_ntoa() */ :
457 inet_ntoa ( *( ( struct in_addr * ) ip ) ) );
458 DBGC ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
459
460 /* Fail if net device is currently claimed for use by iPXE */
461 if ( efi_snp_claimed )
462 return EFI_NOT_READY;
463
464 /* Try to hash the address */
465 if ( ( rc = ll_protocol->mc_hash ( ( ipv6 ? AF_INET6 : AF_INET ),
466 ip, mac ) ) != 0 ) {
467 DBGC ( snpdev, "SNPDEV %p could not hash %s: %s\n",
468 snpdev, ip_str, strerror ( rc ) );
469 return EFIRC ( rc );
470 }
471
472 return 0;
473 }
474
475 /**
476 * Read or write non-volatile storage
477 *
478 * @v snp SNP interface
479 * @v read Operation is a read
480 * @v offset Starting offset within NVRAM
481 * @v len Length of data buffer
482 * @v data Data buffer
483 * @ret efirc EFI status code
484 */
485 static EFI_STATUS EFIAPI
486 efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read,
487 UINTN offset, UINTN len, VOID *data ) {
488 struct efi_snp_device *snpdev =
489 container_of ( snp, struct efi_snp_device, snp );
490
491 DBGC ( snpdev, "SNPDEV %p NVDATA %s %lx+%lx\n", snpdev,
492 ( read ? "read" : "write" ), ( ( unsigned long ) offset ),
493 ( ( unsigned long ) len ) );
494 if ( ! read )
495 DBGC2_HDA ( snpdev, offset, data, len );
496
497 /* Fail if net device is currently claimed for use by iPXE */
498 if ( efi_snp_claimed )
499 return EFI_NOT_READY;
500
501 return EFI_UNSUPPORTED;
502 }
503
504 /**
505 * Read interrupt status and TX recycled buffer status
506 *
507 * @v snp SNP interface
508 * @v interrupts Interrupt status, or NULL
509 * @v txbuf Recycled transmit buffer address, or NULL
510 * @ret efirc EFI status code
511 */
512 static EFI_STATUS EFIAPI
513 efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
514 UINT32 *interrupts, VOID **txbuf ) {
515 struct efi_snp_device *snpdev =
516 container_of ( snp, struct efi_snp_device, snp );
517
518 DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
519
520 /* Fail if net device is currently claimed for use by iPXE */
521 if ( efi_snp_claimed ) {
522 DBGC2 ( snpdev, "\n" );
523 return EFI_NOT_READY;
524 }
525
526 /* Poll the network device */
527 efi_snp_poll ( snpdev );
528
529 /* Interrupt status. In practice, this seems to be used only
530 * to detect TX completions.
531 */
532 if ( interrupts ) {
533 *interrupts = snpdev->interrupts;
534 DBGC2 ( snpdev, " INTS:%02x", *interrupts );
535 snpdev->interrupts = 0;
536 }
537
538 /* TX completions */
539 if ( txbuf ) {
540 if ( snpdev->tx_prod != snpdev->tx_cons ) {
541 *txbuf = snpdev->tx[snpdev->tx_cons++ % EFI_SNP_NUM_TX];
542 } else {
543 *txbuf = NULL;
544 }
545 DBGC2 ( snpdev, " TX:%p", *txbuf );
546 }
547
548 DBGC2 ( snpdev, "\n" );
549 return 0;
550 }
551
552 /**
553 * Start packet transmission
554 *
555 * @v snp SNP interface
556 * @v ll_header_len Link-layer header length, if to be filled in
557 * @v len Length of data buffer
558 * @v data Data buffer
559 * @v ll_src Link-layer source address, if specified
560 * @v ll_dest Link-layer destination address, if specified
561 * @v net_proto Network-layer protocol (in host order)
562 * @ret efirc EFI status code
563 */
564 static EFI_STATUS EFIAPI
565 efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
566 UINTN ll_header_len, UINTN len, VOID *data,
567 EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
568 UINT16 *net_proto ) {
569 struct efi_snp_device *snpdev =
570 container_of ( snp, struct efi_snp_device, snp );
571 struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
572 struct io_buffer *iobuf;
573 size_t payload_len;
574 unsigned int tx_fill;
575 int rc;
576
577 DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
578 ( ( unsigned long ) len ) );
579 if ( ll_header_len ) {
580 if ( ll_src ) {
581 DBGC2 ( snpdev, " src %s",
582 ll_protocol->ntoa ( ll_src ) );
583 }
584 if ( ll_dest ) {
585 DBGC2 ( snpdev, " dest %s",
586 ll_protocol->ntoa ( ll_dest ) );
587 }
588 if ( net_proto ) {
589 DBGC2 ( snpdev, " proto %04x", *net_proto );
590 }
591 }
592 DBGC2 ( snpdev, "\n" );
593
594 /* Fail if net device is currently claimed for use by iPXE */
595 if ( efi_snp_claimed )
596 return EFI_NOT_READY;
597
598 /* Sanity checks */
599 if ( ll_header_len ) {
600 if ( ll_header_len != ll_protocol->ll_header_len ) {
601 DBGC ( snpdev, "SNPDEV %p TX invalid header length "
602 "%ld\n", snpdev,
603 ( ( unsigned long ) ll_header_len ) );
604 rc = -EINVAL;
605 goto err_sanity;
606 }
607 if ( len < ll_header_len ) {
608 DBGC ( snpdev, "SNPDEV %p invalid packet length %ld\n",
609 snpdev, ( ( unsigned long ) len ) );
610 rc = -EINVAL;
611 goto err_sanity;
612 }
613 if ( ! ll_dest ) {
614 DBGC ( snpdev, "SNPDEV %p TX missing destination "
615 "address\n", snpdev );
616 rc = -EINVAL;
617 goto err_sanity;
618 }
619 if ( ! net_proto ) {
620 DBGC ( snpdev, "SNPDEV %p TX missing network "
621 "protocol\n", snpdev );
622 rc = -EINVAL;
623 goto err_sanity;
624 }
625 if ( ! ll_src )
626 ll_src = &snpdev->mode.CurrentAddress;
627 }
628
629 /* Allocate buffer */
630 payload_len = ( len - ll_protocol->ll_header_len );
631 iobuf = alloc_iob ( MAX_LL_HEADER_LEN + ( ( payload_len > IOB_ZLEN ) ?
632 payload_len : IOB_ZLEN ) );
633 if ( ! iobuf ) {
634 DBGC ( snpdev, "SNPDEV %p TX could not allocate %ld-byte "
635 "buffer\n", snpdev, ( ( unsigned long ) len ) );
636 rc = -ENOMEM;
637 goto err_alloc_iob;
638 }
639 iob_reserve ( iobuf, ( MAX_LL_HEADER_LEN -
640 ll_protocol->ll_header_len ) );
641 memcpy ( iob_put ( iobuf, len ), data, len );
642
643 /* Create link-layer header, if specified */
644 if ( ll_header_len ) {
645 iob_pull ( iobuf, ll_protocol->ll_header_len );
646 if ( ( rc = ll_protocol->push ( snpdev->netdev,
647 iobuf, ll_dest, ll_src,
648 htons ( *net_proto ) )) != 0 ){
649 DBGC ( snpdev, "SNPDEV %p TX could not construct "
650 "header: %s\n", snpdev, strerror ( rc ) );
651 goto err_ll_push;
652 }
653 }
654
655 /* Transmit packet */
656 if ( ( rc = netdev_tx ( snpdev->netdev, iob_disown ( iobuf ) ) ) != 0){
657 DBGC ( snpdev, "SNPDEV %p TX could not transmit: %s\n",
658 snpdev, strerror ( rc ) );
659 goto err_tx;
660 }
661
662 /* Record in transmit completion ring. If we run out of
663 * space, report the failure even though we have already
664 * transmitted the packet.
665 *
666 * This allows us to report completions only for packets for
667 * which we had reported successfully initiating transmission,
668 * while continuing to support clients that never poll for
669 * transmit completions.
670 */
671 tx_fill = ( snpdev->tx_prod - snpdev->tx_cons );
672 if ( tx_fill >= EFI_SNP_NUM_TX ) {
673 DBGC ( snpdev, "SNPDEV %p TX completion ring full\n", snpdev );
674 rc = -ENOBUFS;
675 goto err_ring_full;
676 }
677 snpdev->tx[ snpdev->tx_prod++ % EFI_SNP_NUM_TX ] = data;
678 snpdev->interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
679
680 return 0;
681
682 err_ring_full:
683 err_tx:
684 err_ll_push:
685 free_iob ( iobuf );
686 err_alloc_iob:
687 err_sanity:
688 return EFIRC ( rc );
689 }
690
691 /**
692 * Receive packet
693 *
694 * @v snp SNP interface
695 * @v ll_header_len Link-layer header length, if to be filled in
696 * @v len Length of data buffer
697 * @v data Data buffer
698 * @v ll_src Link-layer source address, if specified
699 * @v ll_dest Link-layer destination address, if specified
700 * @v net_proto Network-layer protocol (in host order)
701 * @ret efirc EFI status code
702 */
703 static EFI_STATUS EFIAPI
704 efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
705 UINTN *ll_header_len, UINTN *len, VOID *data,
706 EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
707 UINT16 *net_proto ) {
708 struct efi_snp_device *snpdev =
709 container_of ( snp, struct efi_snp_device, snp );
710 struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
711 struct io_buffer *iobuf;
712 const void *iob_ll_dest;
713 const void *iob_ll_src;
714 uint16_t iob_net_proto;
715 unsigned int iob_flags;
716 size_t copy_len;
717 int rc;
718
719 DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
720 ( ( unsigned long ) *len ) );
721
722 /* Fail if net device is currently claimed for use by iPXE */
723 if ( efi_snp_claimed )
724 return EFI_NOT_READY;
725
726 /* Poll the network device */
727 efi_snp_poll ( snpdev );
728
729 /* Check for an available packet */
730 iobuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
731 if ( ! iobuf ) {
732 DBGC2 ( snpdev, "\n" );
733 rc = -EAGAIN;
734 goto out_no_packet;
735 }
736 DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) );
737
738 /* Dequeue packet */
739 list_del ( &iobuf->list );
740
741 /* Return packet to caller, truncating to buffer length */
742 copy_len = iob_len ( iobuf );
743 if ( copy_len > *len )
744 copy_len = *len;
745 memcpy ( data, iobuf->data, copy_len );
746 *len = iob_len ( iobuf );
747
748 /* Attempt to decode link-layer header */
749 if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
750 &iob_ll_src, &iob_net_proto,
751 &iob_flags ) ) != 0 ) {
752 DBGC ( snpdev, "SNPDEV %p could not parse header: %s\n",
753 snpdev, strerror ( rc ) );
754 goto out_bad_ll_header;
755 }
756
757 /* Return link-layer header parameters to caller, if required */
758 if ( ll_header_len )
759 *ll_header_len = ll_protocol->ll_header_len;
760 if ( ll_src )
761 memcpy ( ll_src, iob_ll_src, ll_protocol->ll_addr_len );
762 if ( ll_dest )
763 memcpy ( ll_dest, iob_ll_dest, ll_protocol->ll_addr_len );
764 if ( net_proto )
765 *net_proto = ntohs ( iob_net_proto );
766
767 /* Check buffer length */
768 rc = ( ( copy_len == *len ) ? 0 : -ERANGE );
769
770 out_bad_ll_header:
771 free_iob ( iobuf );
772 out_no_packet:
773 return EFIRC ( rc );
774 }
775
776 /**
777 * Poll event
778 *
779 * @v event Event
780 * @v context Event context
781 */
782 static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event __unused,
783 VOID *context ) {
784 struct efi_snp_device *snpdev = context;
785
786 DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
787
788 /* Do nothing unless the net device is open */
789 if ( ! netdev_is_open ( snpdev->netdev ) )
790 return;
791
792 /* Do nothing if net device is currently claimed for use by iPXE */
793 if ( efi_snp_claimed )
794 return;
795
796 /* Poll the network device */
797 efi_snp_poll ( snpdev );
798 }
799
800 /** SNP interface */
801 static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp = {
802 .Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION,
803 .Start = efi_snp_start,
804 .Stop = efi_snp_stop,
805 .Initialize = efi_snp_initialize,
806 .Reset = efi_snp_reset,
807 .Shutdown = efi_snp_shutdown,
808 .ReceiveFilters = efi_snp_receive_filters,
809 .StationAddress = efi_snp_station_address,
810 .Statistics = efi_snp_statistics,
811 .MCastIpToMac = efi_snp_mcast_ip_to_mac,
812 .NvData = efi_snp_nvdata,
813 .GetStatus = efi_snp_get_status,
814 .Transmit = efi_snp_transmit,
815 .Receive = efi_snp_receive,
816 };
817
818 /******************************************************************************
819 *
820 * UNDI protocol
821 *
822 ******************************************************************************
823 */
824
825 /** Union type for command parameter blocks */
826 typedef union {
827 PXE_CPB_STATION_ADDRESS station_address;
828 PXE_CPB_FILL_HEADER fill_header;
829 PXE_CPB_FILL_HEADER_FRAGMENTED fill_header_fragmented;
830 PXE_CPB_TRANSMIT transmit;
831 PXE_CPB_RECEIVE receive;
832 } PXE_CPB_ANY;
833
834 /** Union type for data blocks */
835 typedef union {
836 PXE_DB_GET_INIT_INFO get_init_info;
837 PXE_DB_STATION_ADDRESS station_address;
838 PXE_DB_GET_STATUS get_status;
839 PXE_DB_RECEIVE receive;
840 } PXE_DB_ANY;
841
842 /**
843 * Calculate UNDI byte checksum
844 *
845 * @v data Data
846 * @v len Length of data
847 * @ret sum Checksum
848 */
849 static uint8_t efi_undi_checksum ( void *data, size_t len ) {
850 uint8_t *bytes = data;
851 uint8_t sum = 0;
852
853 while ( len-- )
854 sum += *bytes++;
855 return sum;
856 }
857
858 /**
859 * Get UNDI SNP device interface number
860 *
861 * @v snpdev SNP device
862 * @ret ifnum UNDI interface number
863 */
864 static unsigned int efi_undi_ifnum ( struct efi_snp_device *snpdev ) {
865
866 /* iPXE network device indexes are one-based (leaving zero
867 * meaning "unspecified"). UNDI interface numbers are
868 * zero-based.
869 */
870 return ( snpdev->netdev->index - 1 );
871 }
872
873 /**
874 * Identify UNDI SNP device
875 *
876 * @v ifnum Interface number
877 * @ret snpdev SNP device, or NULL if not found
878 */
879 static struct efi_snp_device * efi_undi_snpdev ( unsigned int ifnum ) {
880 struct efi_snp_device *snpdev;
881
882 list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
883 if ( efi_undi_ifnum ( snpdev ) == ifnum )
884 return snpdev;
885 }
886 return NULL;
887 }
888
889 /**
890 * Convert EFI status code to UNDI status code
891 *
892 * @v efirc EFI status code
893 * @ret statcode UNDI status code
894 */
895 static PXE_STATCODE efi_undi_statcode ( EFI_STATUS efirc ) {
896
897 switch ( efirc ) {
898 case EFI_INVALID_PARAMETER: return PXE_STATCODE_INVALID_PARAMETER;
899 case EFI_UNSUPPORTED: return PXE_STATCODE_UNSUPPORTED;
900 case EFI_OUT_OF_RESOURCES: return PXE_STATCODE_BUFFER_FULL;
901 case EFI_PROTOCOL_ERROR: return PXE_STATCODE_DEVICE_FAILURE;
902 case EFI_NOT_READY: return PXE_STATCODE_NO_DATA;
903 default:
904 return PXE_STATCODE_INVALID_CDB;
905 }
906 }
907
908 /**
909 * Get state
910 *
911 * @v snpdev SNP device
912 * @v cdb Command description block
913 * @ret efirc EFI status code
914 */
915 static EFI_STATUS efi_undi_get_state ( struct efi_snp_device *snpdev,
916 PXE_CDB *cdb ) {
917 EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
918
919 DBGC ( snpdev, "UNDI %p GET STATE\n", snpdev );
920
921 /* Return current state */
922 if ( mode->State == EfiSimpleNetworkInitialized ) {
923 cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_INITIALIZED;
924 } else if ( mode->State == EfiSimpleNetworkStarted ) {
925 cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_STARTED;
926 } else {
927 cdb->StatFlags |= PXE_STATFLAGS_GET_STATE_STOPPED;
928 }
929
930 return 0;
931 }
932
933 /**
934 * Start
935 *
936 * @v snpdev SNP device
937 * @ret efirc EFI status code
938 */
939 static EFI_STATUS efi_undi_start ( struct efi_snp_device *snpdev ) {
940 EFI_STATUS efirc;
941
942 DBGC ( snpdev, "UNDI %p START\n", snpdev );
943
944 /* Start SNP device */
945 if ( ( efirc = efi_snp_start ( &snpdev->snp ) ) != 0 )
946 return efirc;
947
948 return 0;
949 }
950
951 /**
952 * Stop
953 *
954 * @v snpdev SNP device
955 * @ret efirc EFI status code
956 */
957 static EFI_STATUS efi_undi_stop ( struct efi_snp_device *snpdev ) {
958 EFI_STATUS efirc;
959
960 DBGC ( snpdev, "UNDI %p STOP\n", snpdev );
961
962 /* Stop SNP device */
963 if ( ( efirc = efi_snp_stop ( &snpdev->snp ) ) != 0 )
964 return efirc;
965
966 return 0;
967 }
968
969 /**
970 * Get initialisation information
971 *
972 * @v snpdev SNP device
973 * @v cdb Command description block
974 * @v db Data block
975 * @ret efirc EFI status code
976 */
977 static EFI_STATUS efi_undi_get_init_info ( struct efi_snp_device *snpdev,
978 PXE_CDB *cdb,
979 PXE_DB_GET_INIT_INFO *db ) {
980 struct net_device *netdev = snpdev->netdev;
981 struct ll_protocol *ll_protocol = netdev->ll_protocol;
982
983 DBGC ( snpdev, "UNDI %p GET INIT INFO\n", snpdev );
984
985 /* Populate structure */
986 memset ( db, 0, sizeof ( *db ) );
987 db->FrameDataLen = ( netdev->max_pkt_len - ll_protocol->ll_header_len );
988 db->MediaHeaderLen = ll_protocol->ll_header_len;
989 db->HWaddrLen = ll_protocol->ll_addr_len;
990 db->IFtype = ntohs ( ll_protocol->ll_proto );
991 cdb->StatFlags |= ( PXE_STATFLAGS_CABLE_DETECT_SUPPORTED |
992 PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED );
993
994 return 0;
995 }
996
997 /**
998 * Initialise
999 *
1000 * @v snpdev SNP device
1001 * @v cdb Command description block
1002 * @v efirc EFI status code
1003 */
1004 static EFI_STATUS efi_undi_initialize ( struct efi_snp_device *snpdev,
1005 PXE_CDB *cdb ) {
1006 struct net_device *netdev = snpdev->netdev;
1007 EFI_STATUS efirc;
1008
1009 DBGC ( snpdev, "UNDI %p INITIALIZE\n", snpdev );
1010
1011 /* Reset SNP device */
1012 if ( ( efirc = efi_snp_initialize ( &snpdev->snp, 0, 0 ) ) != 0 )
1013 return efirc;
1014
1015 /* Report link state */
1016 if ( ! netdev_link_ok ( netdev ) )
1017 cdb->StatFlags |= PXE_STATFLAGS_INITIALIZED_NO_MEDIA;
1018
1019 return 0;
1020 }
1021
1022 /**
1023 * Reset
1024 *
1025 * @v snpdev SNP device
1026 * @v efirc EFI status code
1027 */
1028 static EFI_STATUS efi_undi_reset ( struct efi_snp_device *snpdev ) {
1029 EFI_STATUS efirc;
1030
1031 DBGC ( snpdev, "UNDI %p RESET\n", snpdev );
1032
1033 /* Reset SNP device */
1034 if ( ( efirc = efi_snp_reset ( &snpdev->snp, 0 ) ) != 0 )
1035 return efirc;
1036
1037 return 0;
1038 }
1039
1040 /**
1041 * Shutdown
1042 *
1043 * @v snpdev SNP device
1044 * @v efirc EFI status code
1045 */
1046 static EFI_STATUS efi_undi_shutdown ( struct efi_snp_device *snpdev ) {
1047 EFI_STATUS efirc;
1048
1049 DBGC ( snpdev, "UNDI %p SHUTDOWN\n", snpdev );
1050
1051 /* Reset SNP device */
1052 if ( ( efirc = efi_snp_shutdown ( &snpdev->snp ) ) != 0 )
1053 return efirc;
1054
1055 return 0;
1056 }
1057
1058 /**
1059 * Get/set receive filters
1060 *
1061 * @v snpdev SNP device
1062 * @v cdb Command description block
1063 * @v efirc EFI status code
1064 */
1065 static EFI_STATUS efi_undi_receive_filters ( struct efi_snp_device *snpdev,
1066 PXE_CDB *cdb ) {
1067
1068 DBGC ( snpdev, "UNDI %p RECEIVE FILTERS\n", snpdev );
1069
1070 /* Mark everything as supported */
1071 cdb->StatFlags |= ( PXE_STATFLAGS_RECEIVE_FILTER_UNICAST |
1072 PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST |
1073 PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS |
1074 PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST );
1075
1076 return 0;
1077 }
1078
1079 /**
1080 * Get/set station address
1081 *
1082 * @v snpdev SNP device
1083 * @v cdb Command description block
1084 * @v cpb Command parameter block
1085 * @v efirc EFI status code
1086 */
1087 static EFI_STATUS efi_undi_station_address ( struct efi_snp_device *snpdev,
1088 PXE_CDB *cdb,
1089 PXE_CPB_STATION_ADDRESS *cpb,
1090 PXE_DB_STATION_ADDRESS *db ) {
1091 struct net_device *netdev = snpdev->netdev;
1092 struct ll_protocol *ll_protocol = netdev->ll_protocol;
1093 void *mac;
1094 int reset;
1095 EFI_STATUS efirc;
1096
1097 DBGC ( snpdev, "UNDI %p STATION ADDRESS\n", snpdev );
1098
1099 /* Update address if applicable */
1100 reset = ( cdb->OpFlags & PXE_OPFLAGS_STATION_ADDRESS_RESET );
1101 mac = ( cpb ? &cpb->StationAddr : NULL );
1102 if ( ( reset || mac ) &&
1103 ( ( efirc = efi_snp_station_address ( &snpdev->snp, reset,
1104 mac ) ) != 0 ) )
1105 return efirc;
1106
1107 /* Fill in current addresses, if applicable */
1108 if ( db ) {
1109 memset ( db, 0, sizeof ( *db ) );
1110 memcpy ( &db->StationAddr, netdev->ll_addr,
1111 ll_protocol->ll_addr_len );
1112 memcpy ( &db->BroadcastAddr, netdev->ll_broadcast,
1113 ll_protocol->ll_addr_len );
1114 memcpy ( &db->PermanentAddr, netdev->hw_addr,
1115 ll_protocol->hw_addr_len );
1116 }
1117
1118 return 0;
1119 }
1120
1121 /**
1122 * Get interrupt status
1123 *
1124 * @v snpdev SNP device
1125 * @v cdb Command description block
1126 * @v db Data block
1127 * @v efirc EFI status code
1128 */
1129 static EFI_STATUS efi_undi_get_status ( struct efi_snp_device *snpdev,
1130 PXE_CDB *cdb, PXE_DB_GET_STATUS *db ) {
1131 UINT32 interrupts;
1132 VOID *txbuf;
1133 struct io_buffer *rxbuf;
1134 EFI_STATUS efirc;
1135
1136 DBGC2 ( snpdev, "UNDI %p GET STATUS\n", snpdev );
1137
1138 /* Get status */
1139 if ( ( efirc = efi_snp_get_status ( &snpdev->snp, &interrupts,
1140 &txbuf ) ) != 0 )
1141 return efirc;
1142
1143 /* Report status */
1144 memset ( db, 0, sizeof ( *db ) );
1145 if ( interrupts & EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT )
1146 cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_RECEIVE;
1147 if ( interrupts & EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT )
1148 cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_TRANSMIT;
1149 if ( txbuf ) {
1150 db->TxBuffer[0] = ( ( intptr_t ) txbuf );
1151 } else {
1152 cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN;
1153 /* The specification states clearly that UNDI drivers
1154 * should set TXBUF_QUEUE_EMPTY if all completed
1155 * buffer addresses are written into the returned data
1156 * block. However, SnpDxe chooses to interpret
1157 * TXBUF_QUEUE_EMPTY as a synonym for
1158 * NO_TXBUFS_WRITTEN, thereby rendering it entirely
1159 * pointless. Work around this UEFI stupidity, as per
1160 * usual.
1161 */
1162 if ( snpdev->tx_prod == snpdev->tx_cons )
1163 cdb->StatFlags |=
1164 PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY;
1165 }
1166 rxbuf = list_first_entry ( &snpdev->rx, struct io_buffer, list );
1167 if ( rxbuf )
1168 db->RxFrameLen = iob_len ( rxbuf );
1169 if ( ! netdev_link_ok ( snpdev->netdev ) )
1170 cdb->StatFlags |= PXE_STATFLAGS_GET_STATUS_NO_MEDIA;
1171
1172 return 0;
1173 }
1174
1175 /**
1176 * Fill header
1177 *
1178 * @v snpdev SNP device
1179 * @v cdb Command description block
1180 * @v cpb Command parameter block
1181 * @v efirc EFI status code
1182 */
1183 static EFI_STATUS efi_undi_fill_header ( struct efi_snp_device *snpdev,
1184 PXE_CDB *cdb, PXE_CPB_ANY *cpb ) {
1185 struct net_device *netdev = snpdev->netdev;
1186 struct ll_protocol *ll_protocol = netdev->ll_protocol;
1187 PXE_CPB_FILL_HEADER *whole = &cpb->fill_header;
1188 PXE_CPB_FILL_HEADER_FRAGMENTED *fragged = &cpb->fill_header_fragmented;
1189 VOID *data;
1190 void *dest;
1191 void *src;
1192 uint16_t proto;
1193 struct io_buffer iobuf;
1194 int rc;
1195
1196 /* SnpDxe will (pointlessly) use PXE_CPB_FILL_HEADER_FRAGMENTED
1197 * even though we choose to explicitly not claim support for
1198 * fragments via PXE_ROMID_IMP_FRAG_SUPPORTED.
1199 */
1200 if ( cdb->OpFlags & PXE_OPFLAGS_FILL_HEADER_FRAGMENTED ) {
1201 data = ( ( void * ) ( intptr_t ) fragged->FragDesc[0].FragAddr);
1202 dest = &fragged->DestAddr;
1203 src = &fragged->SrcAddr;
1204 proto = fragged->Protocol;
1205 } else {
1206 data = ( ( void * ) ( intptr_t ) whole->MediaHeader );
1207 dest = &whole->DestAddr;
1208 src = &whole->SrcAddr;
1209 proto = whole->Protocol;
1210 }
1211
1212 /* Construct link-layer header */
1213 iob_populate ( &iobuf, data, 0, ll_protocol->ll_header_len );
1214 iob_reserve ( &iobuf, ll_protocol->ll_header_len );
1215 if ( ( rc = ll_protocol->push ( netdev, &iobuf, dest, src,
1216 proto ) ) != 0 )
1217 return EFIRC ( rc );
1218
1219 return 0;
1220 }
1221
1222 /**
1223 * Transmit
1224 *
1225 * @v snpdev SNP device
1226 * @v cpb Command parameter block
1227 * @v efirc EFI status code
1228 */
1229 static EFI_STATUS efi_undi_transmit ( struct efi_snp_device *snpdev,
1230 PXE_CPB_TRANSMIT *cpb ) {
1231 VOID *data = ( ( void * ) ( intptr_t ) cpb->FrameAddr );
1232 EFI_STATUS efirc;
1233
1234 DBGC2 ( snpdev, "UNDI %p TRANSMIT\n", snpdev );
1235
1236 /* Transmit packet */
1237 if ( ( efirc = efi_snp_transmit ( &snpdev->snp, 0, cpb->DataLen,
1238 data, NULL, NULL, NULL ) ) != 0 )
1239 return efirc;
1240
1241 return 0;
1242 }
1243
1244 /**
1245 * Receive
1246 *
1247 * @v snpdev SNP device
1248 * @v cpb Command parameter block
1249 * @v efirc EFI status code
1250 */
1251 static EFI_STATUS efi_undi_receive ( struct efi_snp_device *snpdev,
1252 PXE_CPB_RECEIVE *cpb,
1253 PXE_DB_RECEIVE *db ) {
1254 struct net_device *netdev = snpdev->netdev;
1255 struct ll_protocol *ll_protocol = netdev->ll_protocol;
1256 VOID *data = ( ( void * ) ( intptr_t ) cpb->BufferAddr );
1257 UINTN hdr_len;
1258 UINTN len = cpb->BufferLen;
1259 EFI_MAC_ADDRESS src;
1260 EFI_MAC_ADDRESS dest;
1261 UINT16 proto;
1262 EFI_STATUS efirc;
1263
1264 DBGC2 ( snpdev, "UNDI %p RECEIVE\n", snpdev );
1265
1266 /* Receive packet */
1267 if ( ( efirc = efi_snp_receive ( &snpdev->snp, &hdr_len, &len, data,
1268 &src, &dest, &proto ) ) != 0 )
1269 return efirc;
1270
1271 /* Describe frame */
1272 memset ( db, 0, sizeof ( *db ) );
1273 memcpy ( &db->SrcAddr, &src, ll_protocol->ll_addr_len );
1274 memcpy ( &db->DestAddr, &dest, ll_protocol->ll_addr_len );
1275 db->FrameLen = len;
1276 db->Protocol = proto;
1277 db->MediaHeaderLen = ll_protocol->ll_header_len;
1278 db->Type = PXE_FRAME_TYPE_PROMISCUOUS;
1279
1280 return 0;
1281 }
1282
1283 /** UNDI entry point */
1284 static EFIAPI VOID efi_undi_issue ( UINT64 cdb_phys ) {
1285 PXE_CDB *cdb = ( ( void * ) ( intptr_t ) cdb_phys );
1286 PXE_CPB_ANY *cpb = ( ( void * ) ( intptr_t ) cdb->CPBaddr );
1287 PXE_DB_ANY *db = ( ( void * ) ( intptr_t ) cdb->DBaddr );
1288 struct efi_snp_device *snpdev;
1289 EFI_STATUS efirc;
1290
1291 /* Identify device */
1292 snpdev = efi_undi_snpdev ( cdb->IFnum );
1293 if ( ! snpdev ) {
1294 DBGC ( cdb, "UNDI invalid interface number %d\n", cdb->IFnum );
1295 cdb->StatCode = PXE_STATCODE_INVALID_CDB;
1296 cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
1297 return;
1298 }
1299
1300 /* Fail if net device is currently claimed for use by iPXE */
1301 if ( efi_snp_claimed ) {
1302 cdb->StatCode = PXE_STATCODE_BUSY;
1303 cdb->StatFlags = PXE_STATFLAGS_COMMAND_FAILED;
1304 return;
1305 }
1306
1307 /* Handle opcode */
1308 cdb->StatCode = PXE_STATCODE_SUCCESS;
1309 cdb->StatFlags = PXE_STATFLAGS_COMMAND_COMPLETE;
1310 switch ( cdb->OpCode ) {
1311
1312 case PXE_OPCODE_GET_STATE:
1313 efirc = efi_undi_get_state ( snpdev, cdb );
1314 break;
1315
1316 case PXE_OPCODE_START:
1317 efirc = efi_undi_start ( snpdev );
1318 break;
1319
1320 case PXE_OPCODE_STOP:
1321 efirc = efi_undi_stop ( snpdev );
1322 break;
1323
1324 case PXE_OPCODE_GET_INIT_INFO:
1325 efirc = efi_undi_get_init_info ( snpdev, cdb,
1326 &db->get_init_info );
1327 break;
1328
1329 case PXE_OPCODE_INITIALIZE:
1330 efirc = efi_undi_initialize ( snpdev, cdb );
1331 break;
1332
1333 case PXE_OPCODE_RESET:
1334 efirc = efi_undi_reset ( snpdev );
1335 break;
1336
1337 case PXE_OPCODE_SHUTDOWN:
1338 efirc = efi_undi_shutdown ( snpdev );
1339 break;
1340
1341 case PXE_OPCODE_RECEIVE_FILTERS:
1342 efirc = efi_undi_receive_filters ( snpdev, cdb );
1343 break;
1344
1345 case PXE_OPCODE_STATION_ADDRESS:
1346 efirc = efi_undi_station_address ( snpdev, cdb,
1347 &cpb->station_address,
1348 &db->station_address );
1349 break;
1350
1351 case PXE_OPCODE_GET_STATUS:
1352 efirc = efi_undi_get_status ( snpdev, cdb, &db->get_status );
1353 break;
1354
1355 case PXE_OPCODE_FILL_HEADER:
1356 efirc = efi_undi_fill_header ( snpdev, cdb, cpb );
1357 break;
1358
1359 case PXE_OPCODE_TRANSMIT:
1360 efirc = efi_undi_transmit ( snpdev, &cpb->transmit );
1361 break;
1362
1363 case PXE_OPCODE_RECEIVE:
1364 efirc = efi_undi_receive ( snpdev, &cpb->receive,
1365 &db->receive );
1366 break;
1367
1368 default:
1369 DBGC ( snpdev, "UNDI %p unsupported opcode %#04x\n",
1370 snpdev, cdb->OpCode );
1371 efirc = EFI_UNSUPPORTED;
1372 break;
1373 }
1374
1375 /* Convert EFI status code to UNDI status code */
1376 if ( efirc != 0 ) {
1377 cdb->StatFlags &= ~PXE_STATFLAGS_STATUS_MASK;
1378 cdb->StatFlags |= PXE_STATFLAGS_COMMAND_FAILED;
1379 cdb->StatCode = efi_undi_statcode ( efirc );
1380 }
1381 }
1382
1383 /** UNDI interface
1384 *
1385 * Must be aligned on a 16-byte boundary, for no particularly good
1386 * reason.
1387 */
1388 static PXE_SW_UNDI efi_snp_undi __attribute__ (( aligned ( 16 ) )) = {
1389 .Signature = PXE_ROMID_SIGNATURE,
1390 .Len = sizeof ( efi_snp_undi ),
1391 .Rev = PXE_ROMID_REV,
1392 .MajorVer = PXE_ROMID_MAJORVER,
1393 .MinorVer = PXE_ROMID_MINORVER,
1394 .Implementation = ( PXE_ROMID_IMP_SW_VIRT_ADDR |
1395 PXE_ROMID_IMP_STATION_ADDR_SETTABLE |
1396 PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED |
1397 PXE_ROMID_IMP_PROMISCUOUS_RX_SUPPORTED |
1398 PXE_ROMID_IMP_BROADCAST_RX_SUPPORTED |
1399 PXE_ROMID_IMP_TX_COMPLETE_INT_SUPPORTED |
1400 PXE_ROMID_IMP_PACKET_RX_INT_SUPPORTED ),
1401 /* SnpDxe checks that BusCnt is non-zero. It makes no further
1402 * use of BusCnt, and never looks as BusType[]. As with much
1403 * of the EDK2 code, this check seems to serve no purpose
1404 * whatsoever but must nonetheless be humoured.
1405 */
1406 .BusCnt = 1,
1407 .BusType[0] = PXE_BUSTYPE ( 'i', 'P', 'X', 'E' ),
1408 };
1409
1410 /** Network Identification Interface (NII) */
1411 static EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL efi_snp_device_nii = {
1412 .Revision = EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION,
1413 .StringId = "UNDI",
1414 .Type = EfiNetworkInterfaceUndi,
1415 .MajorVer = 3,
1416 .MinorVer = 1,
1417 .Ipv6Supported = TRUE, /* This is a raw packet interface, FFS! */
1418 };
1419
1420 /******************************************************************************
1421 *
1422 * Component name protocol
1423 *
1424 ******************************************************************************
1425 */
1426
1427 /**
1428 * Look up driver name
1429 *
1430 * @v name2 Component name protocol
1431 * @v language Language to use
1432 * @v driver_name Driver name to fill in
1433 * @ret efirc EFI status code
1434 */
1435 static EFI_STATUS EFIAPI
1436 efi_snp_get_driver_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
1437 CHAR8 *language __unused, CHAR16 **driver_name ) {
1438 struct efi_snp_device *snpdev =
1439 container_of ( name2, struct efi_snp_device, name2 );
1440
1441 *driver_name = snpdev->driver_name;
1442 return 0;
1443 }
1444
1445 /**
1446 * Look up controller name
1447 *
1448 * @v name2 Component name protocol
1449 * @v device Device
1450 * @v child Child device, or NULL
1451 * @v language Language to use
1452 * @v driver_name Device name to fill in
1453 * @ret efirc EFI status code
1454 */
1455 static EFI_STATUS EFIAPI
1456 efi_snp_get_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
1457 EFI_HANDLE device __unused,
1458 EFI_HANDLE child __unused,
1459 CHAR8 *language __unused,
1460 CHAR16 **controller_name ) {
1461 struct efi_snp_device *snpdev =
1462 container_of ( name2, struct efi_snp_device, name2 );
1463
1464 *controller_name = snpdev->controller_name;
1465 return 0;
1466 }
1467
1468 /******************************************************************************
1469 *
1470 * Load file protocol
1471 *
1472 ******************************************************************************
1473 */
1474
1475 /**
1476 * Load file
1477 *
1478 * @v loadfile Load file protocol
1479 * @v path File path
1480 * @v booting Loading as part of a boot attempt
1481 * @ret efirc EFI status code
1482 */
1483 static EFI_STATUS EFIAPI
1484 efi_snp_load_file ( EFI_LOAD_FILE_PROTOCOL *load_file,
1485 EFI_DEVICE_PATH_PROTOCOL *path __unused,
1486 BOOLEAN booting, UINTN *len __unused,
1487 VOID *data __unused ) {
1488 struct efi_snp_device *snpdev =
1489 container_of ( load_file, struct efi_snp_device, load_file );
1490 struct net_device *netdev = snpdev->netdev;
1491 int rc;
1492
1493 /* Fail unless this is a boot attempt */
1494 if ( ! booting ) {
1495 DBGC ( snpdev, "SNPDEV %p cannot load non-boot file\n",
1496 snpdev );
1497 return EFI_UNSUPPORTED;
1498 }
1499
1500 /* Claim network devices for use by iPXE */
1501 efi_snp_claim();
1502
1503 /* Start watchdog holdoff timer */
1504 efi_watchdog_start();
1505
1506 /* Boot from network device */
1507 if ( ( rc = ipxe ( netdev ) ) != 0 )
1508 goto err_ipxe;
1509
1510 /* Reset console */
1511 console_reset();
1512
1513 err_ipxe:
1514 efi_watchdog_stop();
1515 efi_snp_release();
1516 return EFIRC ( rc );
1517 }
1518
1519 /** Load file protocol */
1520 static EFI_LOAD_FILE_PROTOCOL efi_snp_load_file_protocol = {
1521 .LoadFile = efi_snp_load_file,
1522 };
1523
1524 /******************************************************************************
1525 *
1526 * iPXE network driver
1527 *
1528 ******************************************************************************
1529 */
1530
1531 /**
1532 * Locate SNP device corresponding to network device
1533 *
1534 * @v netdev Network device
1535 * @ret snp SNP device, or NULL if not found
1536 */
1537 static struct efi_snp_device * efi_snp_demux ( struct net_device *netdev ) {
1538 struct efi_snp_device *snpdev;
1539
1540 list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
1541 if ( snpdev->netdev == netdev )
1542 return snpdev;
1543 }
1544 return NULL;
1545 }
1546
1547 /**
1548 * Create SNP device
1549 *
1550 * @v netdev Network device
1551 * @ret rc Return status code
1552 */
1553 static int efi_snp_probe ( struct net_device *netdev ) {
1554 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1555 struct efi_device *efidev;
1556 struct efi_snp_device *snpdev;
1557 EFI_DEVICE_PATH_PROTOCOL *path_end;
1558 MAC_ADDR_DEVICE_PATH *macpath;
1559 VLAN_DEVICE_PATH *vlanpath;
1560 size_t path_prefix_len = 0;
1561 unsigned int ifcnt;
1562 unsigned int tag;
1563 void *interface;
1564 EFI_STATUS efirc;
1565 int rc;
1566
1567 /* Find parent EFI device */
1568 efidev = efidev_parent ( netdev->dev );
1569 if ( ! efidev ) {
1570 DBG ( "SNP skipping non-EFI device %s\n", netdev->name );
1571 rc = 0;
1572 goto err_no_efidev;
1573 }
1574
1575 /* Allocate the SNP device */
1576 snpdev = zalloc ( sizeof ( *snpdev ) );
1577 if ( ! snpdev ) {
1578 rc = -ENOMEM;
1579 goto err_alloc_snp;
1580 }
1581 snpdev->netdev = netdev_get ( netdev );
1582 snpdev->efidev = efidev;
1583 INIT_LIST_HEAD ( &snpdev->rx );
1584
1585 /* Sanity check */
1586 if ( netdev->ll_protocol->ll_addr_len > sizeof ( EFI_MAC_ADDRESS ) ) {
1587 DBGC ( snpdev, "SNPDEV %p cannot support link-layer address "
1588 "length %d for %s\n", snpdev,
1589 netdev->ll_protocol->ll_addr_len, netdev->name );
1590 rc = -ENOTSUP;
1591 goto err_ll_addr_len;
1592 }
1593
1594 /* Populate the SNP structure */
1595 memcpy ( &snpdev->snp, &efi_snp_device_snp, sizeof ( snpdev->snp ) );
1596 snpdev->snp.Mode = &snpdev->mode;
1597 if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY,
1598 efi_snp_wait_for_packet, snpdev,
1599 &snpdev->snp.WaitForPacket ) ) != 0 ){
1600 rc = -EEFI ( efirc );
1601 DBGC ( snpdev, "SNPDEV %p could not create event: %s\n",
1602 snpdev, strerror ( rc ) );
1603 goto err_create_event;
1604 }
1605
1606 /* Populate the SNP mode structure */
1607 snpdev->mode.State = EfiSimpleNetworkStopped;
1608 efi_snp_set_mode ( snpdev );
1609
1610 /* Populate the NII structure */
1611 memcpy ( &snpdev->nii, &efi_snp_device_nii, sizeof ( snpdev->nii ) );
1612 snpdev->nii.Id = ( ( intptr_t ) &efi_snp_undi );
1613 snpdev->nii.IfNum = efi_undi_ifnum ( snpdev );
1614 efi_snp_undi.EntryPoint = ( ( intptr_t ) efi_undi_issue );
1615 ifcnt = ( ( efi_snp_undi.IFcntExt << 8 ) | efi_snp_undi.IFcnt );
1616 if ( ifcnt < snpdev->nii.IfNum )
1617 ifcnt = snpdev->nii.IfNum;
1618 efi_snp_undi.IFcnt = ( ifcnt & 0xff );
1619 efi_snp_undi.IFcntExt = ( ifcnt >> 8 );
1620 efi_snp_undi.Fudge -= efi_undi_checksum ( &efi_snp_undi,
1621 sizeof ( efi_snp_undi ) );
1622
1623 /* Populate the component name structure */
1624 efi_snprintf ( snpdev->driver_name,
1625 ( sizeof ( snpdev->driver_name ) /
1626 sizeof ( snpdev->driver_name[0] ) ),
1627 "%s %s", product_short_name, netdev->dev->driver_name );
1628 efi_snprintf ( snpdev->controller_name,
1629 ( sizeof ( snpdev->controller_name ) /
1630 sizeof ( snpdev->controller_name[0] ) ),
1631 "%s %s (%s, %s)", product_short_name,
1632 netdev->dev->driver_name, netdev->dev->name,
1633 netdev_addr ( netdev ) );
1634 snpdev->name2.GetDriverName = efi_snp_get_driver_name;
1635 snpdev->name2.GetControllerName = efi_snp_get_controller_name;
1636 snpdev->name2.SupportedLanguages = "en";
1637
1638 /* Populate the load file protocol structure */
1639 memcpy ( &snpdev->load_file, &efi_snp_load_file_protocol,
1640 sizeof ( snpdev->load_file ) );
1641
1642 /* Populate the device name */
1643 efi_snprintf ( snpdev->name, ( sizeof ( snpdev->name ) /
1644 sizeof ( snpdev->name[0] ) ),
1645 "%s", netdev->name );
1646
1647 /* Allocate the new device path */
1648 path_prefix_len = efi_devpath_len ( efidev->path );
1649 snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
1650 sizeof ( *vlanpath ) + sizeof ( *path_end ) );
1651 if ( ! snpdev->path ) {
1652 rc = -ENOMEM;
1653 goto err_alloc_device_path;
1654 }
1655
1656 /* Populate the device path */
1657 memcpy ( snpdev->path, efidev->path, path_prefix_len );
1658 macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
1659 memset ( macpath, 0, sizeof ( *macpath ) );
1660 macpath->Header.Type = MESSAGING_DEVICE_PATH;
1661 macpath->Header.SubType = MSG_MAC_ADDR_DP;
1662 macpath->Header.Length[0] = sizeof ( *macpath );
1663 memcpy ( &macpath->MacAddress, netdev->ll_addr,
1664 netdev->ll_protocol->ll_addr_len );
1665 macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
1666 if ( ( tag = vlan_tag ( netdev ) ) ) {
1667 vlanpath = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
1668 memset ( vlanpath, 0, sizeof ( *vlanpath ) );
1669 vlanpath->Header.Type = MESSAGING_DEVICE_PATH;
1670 vlanpath->Header.SubType = MSG_VLAN_DP;
1671 vlanpath->Header.Length[0] = sizeof ( *vlanpath );
1672 vlanpath->VlanId = tag;
1673 path_end = ( ( ( void * ) vlanpath ) + sizeof ( *vlanpath ) );
1674 } else {
1675 path_end = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
1676 }
1677 memset ( path_end, 0, sizeof ( *path_end ) );
1678 path_end->Type = END_DEVICE_PATH_TYPE;
1679 path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
1680 path_end->Length[0] = sizeof ( *path_end );
1681
1682 /* Install the SNP */
1683 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1684 &snpdev->handle,
1685 &efi_simple_network_protocol_guid, &snpdev->snp,
1686 &efi_device_path_protocol_guid, snpdev->path,
1687 &efi_nii_protocol_guid, &snpdev->nii,
1688 &efi_nii31_protocol_guid, &snpdev->nii,
1689 &efi_component_name2_protocol_guid, &snpdev->name2,
1690 &efi_load_file_protocol_guid, &snpdev->load_file,
1691 NULL ) ) != 0 ) {
1692 rc = -EEFI ( efirc );
1693 DBGC ( snpdev, "SNPDEV %p could not install protocols: %s\n",
1694 snpdev, strerror ( rc ) );
1695 goto err_install_protocol_interface;
1696 }
1697
1698 /* SnpDxe will repeatedly start up and shut down our NII/UNDI
1699 * interface (in order to obtain the MAC address) before
1700 * discovering that it cannot install another SNP on the same
1701 * handle. This causes the underlying network device to be
1702 * unexpectedly closed.
1703 *
1704 * Prevent this by opening our own NII (and NII31) protocol
1705 * instances to prevent SnpDxe from attempting to bind to
1706 * them.
1707 */
1708 if ( ( efirc = bs->OpenProtocol ( snpdev->handle,
1709 &efi_nii_protocol_guid, &interface,
1710 efi_image_handle, snpdev->handle,
1711 ( EFI_OPEN_PROTOCOL_BY_DRIVER |
1712 EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
1713 rc = -EEFI ( efirc );
1714 DBGC ( snpdev, "SNPDEV %p could not open NII protocol: %s\n",
1715 snpdev, strerror ( rc ) );
1716 goto err_open_nii;
1717 }
1718 if ( ( efirc = bs->OpenProtocol ( snpdev->handle,
1719 &efi_nii31_protocol_guid, &interface,
1720 efi_image_handle, snpdev->handle,
1721 ( EFI_OPEN_PROTOCOL_BY_DRIVER |
1722 EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
1723 rc = -EEFI ( efirc );
1724 DBGC ( snpdev, "SNPDEV %p could not open NII31 protocol: %s\n",
1725 snpdev, strerror ( rc ) );
1726 goto err_open_nii31;
1727 }
1728
1729 /* Add as child of EFI parent device */
1730 if ( ( rc = efi_child_add ( efidev->device, snpdev->handle ) ) != 0 ) {
1731 DBGC ( snpdev, "SNPDEV %p could not become child of %s: %s\n",
1732 snpdev, efi_handle_name ( efidev->device ),
1733 strerror ( rc ) );
1734 goto err_efi_child_add;
1735 }
1736
1737 /* Install HII */
1738 if ( ( rc = efi_snp_hii_install ( snpdev ) ) != 0 ) {
1739 DBGC ( snpdev, "SNPDEV %p could not install HII: %s\n",
1740 snpdev, strerror ( rc ) );
1741 /* HII fails on several platforms. It's
1742 * non-essential, so treat this as a non-fatal
1743 * error.
1744 */
1745 }
1746
1747 /* Add to list of SNP devices */
1748 list_add ( &snpdev->list, &efi_snp_devices );
1749
1750 /* Close device path */
1751 bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
1752 efi_image_handle, efidev->device );
1753
1754 DBGC ( snpdev, "SNPDEV %p installed for %s as device %s\n",
1755 snpdev, netdev->name, efi_handle_name ( snpdev->handle ) );
1756 return 0;
1757
1758 list_del ( &snpdev->list );
1759 if ( snpdev->package_list )
1760 efi_snp_hii_uninstall ( snpdev );
1761 efi_child_del ( efidev->device, snpdev->handle );
1762 err_efi_child_add:
1763 bs->CloseProtocol ( snpdev->handle, &efi_nii_protocol_guid,
1764 efi_image_handle, snpdev->handle );
1765 err_open_nii:
1766 bs->CloseProtocol ( snpdev->handle, &efi_nii31_protocol_guid,
1767 efi_image_handle, snpdev->handle );
1768 err_open_nii31:
1769 bs->UninstallMultipleProtocolInterfaces (
1770 snpdev->handle,
1771 &efi_simple_network_protocol_guid, &snpdev->snp,
1772 &efi_device_path_protocol_guid, snpdev->path,
1773 &efi_nii_protocol_guid, &snpdev->nii,
1774 &efi_nii31_protocol_guid, &snpdev->nii,
1775 &efi_component_name2_protocol_guid, &snpdev->name2,
1776 &efi_load_file_protocol_guid, &snpdev->load_file,
1777 NULL );
1778 err_install_protocol_interface:
1779 free ( snpdev->path );
1780 err_alloc_device_path:
1781 bs->CloseEvent ( snpdev->snp.WaitForPacket );
1782 err_create_event:
1783 err_ll_addr_len:
1784 netdev_put ( netdev );
1785 free ( snpdev );
1786 err_alloc_snp:
1787 err_no_efidev:
1788 return rc;
1789 }
1790
1791 /**
1792 * Handle SNP device or link state change
1793 *
1794 * @v netdev Network device
1795 */
1796 static void efi_snp_notify ( struct net_device *netdev ) {
1797 struct efi_snp_device *snpdev;
1798
1799 /* Locate SNP device */
1800 snpdev = efi_snp_demux ( netdev );
1801 if ( ! snpdev ) {
1802 DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
1803 return;
1804 }
1805
1806 /* Update link state */
1807 snpdev->mode.MediaPresent =
1808 ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
1809 DBGC ( snpdev, "SNPDEV %p link is %s\n", snpdev,
1810 ( snpdev->mode.MediaPresent ? "up" : "down" ) );
1811
1812 /* Update mode state */
1813 efi_snp_set_state ( snpdev );
1814 }
1815
1816 /**
1817 * Destroy SNP device
1818 *
1819 * @v netdev Network device
1820 */
1821 static void efi_snp_remove ( struct net_device *netdev ) {
1822 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1823 struct efi_snp_device *snpdev;
1824
1825 /* Locate SNP device */
1826 snpdev = efi_snp_demux ( netdev );
1827 if ( ! snpdev ) {
1828 DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
1829 return;
1830 }
1831
1832 /* Uninstall the SNP */
1833 list_del ( &snpdev->list );
1834 if ( snpdev->package_list )
1835 efi_snp_hii_uninstall ( snpdev );
1836 efi_child_del ( snpdev->efidev->device, snpdev->handle );
1837 bs->CloseProtocol ( snpdev->handle, &efi_nii_protocol_guid,
1838 efi_image_handle, snpdev->handle );
1839 bs->CloseProtocol ( snpdev->handle, &efi_nii31_protocol_guid,
1840 efi_image_handle, snpdev->handle );
1841 bs->UninstallMultipleProtocolInterfaces (
1842 snpdev->handle,
1843 &efi_simple_network_protocol_guid, &snpdev->snp,
1844 &efi_device_path_protocol_guid, snpdev->path,
1845 &efi_nii_protocol_guid, &snpdev->nii,
1846 &efi_nii31_protocol_guid, &snpdev->nii,
1847 &efi_component_name2_protocol_guid, &snpdev->name2,
1848 &efi_load_file_protocol_guid, &snpdev->load_file,
1849 NULL );
1850 free ( snpdev->path );
1851 bs->CloseEvent ( snpdev->snp.WaitForPacket );
1852 netdev_put ( snpdev->netdev );
1853 free ( snpdev );
1854 }
1855
1856 /** SNP driver */
1857 struct net_driver efi_snp_driver __net_driver = {
1858 .name = "SNP",
1859 .probe = efi_snp_probe,
1860 .notify = efi_snp_notify,
1861 .remove = efi_snp_remove,
1862 };
1863
1864 /**
1865 * Find SNP device by EFI device handle
1866 *
1867 * @v handle EFI device handle
1868 * @ret snpdev SNP device, or NULL
1869 */
1870 struct efi_snp_device * find_snpdev ( EFI_HANDLE handle ) {
1871 struct efi_snp_device *snpdev;
1872
1873 list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
1874 if ( snpdev->handle == handle )
1875 return snpdev;
1876 }
1877 return NULL;
1878 }
1879
1880 /**
1881 * Get most recently opened SNP device
1882 *
1883 * @ret snpdev Most recently opened SNP device, or NULL
1884 */
1885 struct efi_snp_device * last_opened_snpdev ( void ) {
1886 struct net_device *netdev;
1887
1888 netdev = last_opened_netdev();
1889 if ( ! netdev )
1890 return NULL;
1891
1892 return efi_snp_demux ( netdev );
1893 }
1894
1895 /**
1896 * Add to SNP claimed/released count
1897 *
1898 * @v delta Claim count change
1899 */
1900 void efi_snp_add_claim ( int delta ) {
1901 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1902 struct efi_snp_device *snpdev;
1903
1904 /* Raise TPL if we are about to claim devices */
1905 if ( ! efi_snp_claimed )
1906 efi_snp_old_tpl = bs->RaiseTPL ( TPL_CALLBACK );
1907
1908 /* Claim SNP devices */
1909 efi_snp_claimed += delta;
1910 assert ( efi_snp_claimed >= 0 );
1911
1912 /* Update SNP mode state for each interface */
1913 list_for_each_entry ( snpdev, &efi_snp_devices, list )
1914 efi_snp_set_state ( snpdev );
1915
1916 /* Restore TPL if we have released devices */
1917 if ( ! efi_snp_claimed )
1918 bs->RestoreTPL ( efi_snp_old_tpl );
1919 }