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