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