Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / 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/efi/efi.h>
32 #include <ipxe/efi/efi_driver.h>
33 #include <ipxe/efi/efi_strings.h>
34 #include <ipxe/efi/efi_utils.h>
35 #include <ipxe/efi/efi_snp.h>
36 #include <usr/autoboot.h>
37
38 /** List of SNP devices */
39 static LIST_HEAD ( efi_snp_devices );
40
41 /** Network devices are currently claimed for use by iPXE */
42 static int efi_snp_claimed;
43
44 /**
45  * Set EFI SNP mode state
46  *
47  * @v snp               SNP interface
48  */
49 static void efi_snp_set_state ( struct efi_snp_device *snpdev ) {
50         struct net_device *netdev = snpdev->netdev;
51         EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
52
53         /* Calculate state */
54         if ( ! snpdev->started ) {
55                 /* Start() method not called; report as Stopped */
56                 mode->State = EfiSimpleNetworkStopped;
57         } else if ( ! netdev_is_open ( netdev ) ) {
58                 /* Network device not opened; report as Started */
59                 mode->State = EfiSimpleNetworkStarted;
60         } else if ( efi_snp_claimed ) {
61                 /* Network device opened but claimed for use by iPXE; report
62                  * as Started to inhibit receive polling.
63                  */
64                 mode->State = EfiSimpleNetworkStarted;
65         } else {
66                 /* Network device opened and available for use via SNP; report
67                  * as Initialized.
68                  */
69                 mode->State = EfiSimpleNetworkInitialized;
70         }
71 }
72
73 /**
74  * Set EFI SNP mode based on iPXE net device parameters
75  *
76  * @v snp               SNP interface
77  */
78 static void efi_snp_set_mode ( struct efi_snp_device *snpdev ) {
79         struct net_device *netdev = snpdev->netdev;
80         EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
81         struct ll_protocol *ll_protocol = netdev->ll_protocol;
82         unsigned int ll_addr_len = ll_protocol->ll_addr_len;
83
84         mode->HwAddressSize = ll_addr_len;
85         mode->MediaHeaderSize = ll_protocol->ll_header_len;
86         mode->MaxPacketSize = netdev->max_pkt_len;
87         mode->ReceiveFilterMask = ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
88                                     EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
89                                     EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST );
90         assert ( ll_addr_len <= sizeof ( mode->CurrentAddress ) );
91         memcpy ( &mode->CurrentAddress, netdev->ll_addr, ll_addr_len );
92         memcpy ( &mode->BroadcastAddress, netdev->ll_broadcast, ll_addr_len );
93         ll_protocol->init_addr ( netdev->hw_addr, &mode->PermanentAddress );
94         mode->IfType = ntohs ( ll_protocol->ll_proto );
95         mode->MacAddressChangeable = TRUE;
96         mode->MediaPresentSupported = TRUE;
97         mode->MediaPresent = ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
98 }
99
100 /**
101  * Poll net device and count received packets
102  *
103  * @v snpdev            SNP device
104  */
105 static void efi_snp_poll ( struct efi_snp_device *snpdev ) {
106         struct io_buffer *iobuf;
107         unsigned int before = 0;
108         unsigned int after = 0;
109         unsigned int arrived;
110
111         /* We have to report packet arrivals, and this is the easiest
112          * way to fake it.
113          */
114         list_for_each_entry ( iobuf, &snpdev->netdev->rx_queue, list )
115                 before++;
116         netdev_poll ( snpdev->netdev );
117         list_for_each_entry ( iobuf, &snpdev->netdev->rx_queue, list )
118                 after++;
119         arrived = ( after - before );
120
121         snpdev->rx_count_interrupts += arrived;
122         snpdev->rx_count_events += arrived;
123 }
124
125 /**
126  * Change SNP state from "stopped" to "started"
127  *
128  * @v snp               SNP interface
129  * @ret efirc           EFI status code
130  */
131 static EFI_STATUS EFIAPI
132 efi_snp_start ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
133         struct efi_snp_device *snpdev =
134                 container_of ( snp, struct efi_snp_device, snp );
135
136         DBGC2 ( snpdev, "SNPDEV %p START\n", snpdev );
137
138         /* Fail if net device is currently claimed for use by iPXE */
139         if ( efi_snp_claimed )
140                 return EFI_NOT_READY;
141
142         snpdev->started = 1;
143         efi_snp_set_state ( snpdev );
144         return 0;
145 }
146
147 /**
148  * Change SNP state from "started" to "stopped"
149  *
150  * @v snp               SNP interface
151  * @ret efirc           EFI status code
152  */
153 static EFI_STATUS EFIAPI
154 efi_snp_stop ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
155         struct efi_snp_device *snpdev =
156                 container_of ( snp, struct efi_snp_device, snp );
157
158         DBGC2 ( snpdev, "SNPDEV %p STOP\n", snpdev );
159
160         /* Fail if net device is currently claimed for use by iPXE */
161         if ( efi_snp_claimed )
162                 return EFI_NOT_READY;
163
164         snpdev->started = 0;
165         efi_snp_set_state ( snpdev );
166         return 0;
167 }
168
169 /**
170  * Open the network device
171  *
172  * @v snp               SNP interface
173  * @v extra_rx_bufsize  Extra RX buffer size, in bytes
174  * @v extra_tx_bufsize  Extra TX buffer size, in bytes
175  * @ret efirc           EFI status code
176  */
177 static EFI_STATUS EFIAPI
178 efi_snp_initialize ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
179                      UINTN extra_rx_bufsize, UINTN extra_tx_bufsize ) {
180         struct efi_snp_device *snpdev =
181                 container_of ( snp, struct efi_snp_device, snp );
182         int rc;
183
184         DBGC2 ( snpdev, "SNPDEV %p INITIALIZE (%ld extra RX, %ld extra TX)\n",
185                 snpdev, ( ( unsigned long ) extra_rx_bufsize ),
186                 ( ( unsigned long ) extra_tx_bufsize ) );
187
188         /* Fail if net device is currently claimed for use by iPXE */
189         if ( efi_snp_claimed )
190                 return EFI_NOT_READY;
191
192         if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
193                 DBGC ( snpdev, "SNPDEV %p could not open %s: %s\n",
194                        snpdev, snpdev->netdev->name, strerror ( rc ) );
195                 return EFIRC ( rc );
196         }
197         efi_snp_set_state ( snpdev );
198
199         return 0;
200 }
201
202 /**
203  * Reset the network device
204  *
205  * @v snp               SNP interface
206  * @v ext_verify        Extended verification required
207  * @ret efirc           EFI status code
208  */
209 static EFI_STATUS EFIAPI
210 efi_snp_reset ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ext_verify ) {
211         struct efi_snp_device *snpdev =
212                 container_of ( snp, struct efi_snp_device, snp );
213         int rc;
214
215         DBGC2 ( snpdev, "SNPDEV %p RESET (%s extended verification)\n",
216                 snpdev, ( ext_verify ? "with" : "without" ) );
217
218         /* Fail if net device is currently claimed for use by iPXE */
219         if ( efi_snp_claimed )
220                 return EFI_NOT_READY;
221
222         netdev_close ( snpdev->netdev );
223         efi_snp_set_state ( snpdev );
224
225         if ( ( rc = netdev_open ( snpdev->netdev ) ) != 0 ) {
226                 DBGC ( snpdev, "SNPDEV %p could not reopen %s: %s\n",
227                        snpdev, snpdev->netdev->name, strerror ( rc ) );
228                 return EFIRC ( rc );
229         }
230         efi_snp_set_state ( snpdev );
231
232         return 0;
233 }
234
235 /**
236  * Shut down the network device
237  *
238  * @v snp               SNP interface
239  * @ret efirc           EFI status code
240  */
241 static EFI_STATUS EFIAPI
242 efi_snp_shutdown ( EFI_SIMPLE_NETWORK_PROTOCOL *snp ) {
243         struct efi_snp_device *snpdev =
244                 container_of ( snp, struct efi_snp_device, snp );
245
246         DBGC2 ( snpdev, "SNPDEV %p SHUTDOWN\n", snpdev );
247
248         /* Fail if net device is currently claimed for use by iPXE */
249         if ( efi_snp_claimed )
250                 return EFI_NOT_READY;
251
252         netdev_close ( snpdev->netdev );
253         efi_snp_set_state ( snpdev );
254
255         return 0;
256 }
257
258 /**
259  * Manage receive filters
260  *
261  * @v snp               SNP interface
262  * @v enable            Receive filters to enable
263  * @v disable           Receive filters to disable
264  * @v mcast_reset       Reset multicast filters
265  * @v mcast_count       Number of multicast filters
266  * @v mcast             Multicast filters
267  * @ret efirc           EFI status code
268  */
269 static EFI_STATUS EFIAPI
270 efi_snp_receive_filters ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, UINT32 enable,
271                           UINT32 disable, BOOLEAN mcast_reset,
272                           UINTN mcast_count, EFI_MAC_ADDRESS *mcast ) {
273         struct efi_snp_device *snpdev =
274                 container_of ( snp, struct efi_snp_device, snp );
275         unsigned int i;
276
277         DBGC2 ( snpdev, "SNPDEV %p RECEIVE_FILTERS %08x&~%08x%s %ld mcast\n",
278                 snpdev, enable, disable, ( mcast_reset ? " reset" : "" ),
279                 ( ( unsigned long ) mcast_count ) );
280         for ( i = 0 ; i < mcast_count ; i++ ) {
281                 DBGC2_HDA ( snpdev, i, &mcast[i],
282                             snpdev->netdev->ll_protocol->ll_addr_len );
283         }
284
285         /* Fail if net device is currently claimed for use by iPXE */
286         if ( efi_snp_claimed )
287                 return EFI_NOT_READY;
288
289         /* Lie through our teeth, otherwise MNP refuses to accept us */
290         return 0;
291 }
292
293 /**
294  * Set station address
295  *
296  * @v snp               SNP interface
297  * @v reset             Reset to permanent address
298  * @v new               New station address
299  * @ret efirc           EFI status code
300  */
301 static EFI_STATUS EFIAPI
302 efi_snp_station_address ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
303                           EFI_MAC_ADDRESS *new ) {
304         struct efi_snp_device *snpdev =
305                 container_of ( snp, struct efi_snp_device, snp );
306         struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
307
308         DBGC2 ( snpdev, "SNPDEV %p STATION_ADDRESS %s\n", snpdev,
309                 ( reset ? "reset" : ll_protocol->ntoa ( new ) ) );
310
311         /* Fail if net device is currently claimed for use by iPXE */
312         if ( efi_snp_claimed )
313                 return EFI_NOT_READY;
314
315         /* Set the MAC address */
316         if ( reset )
317                 new = &snpdev->mode.PermanentAddress;
318         memcpy ( snpdev->netdev->ll_addr, new, ll_protocol->ll_addr_len );
319
320         /* MAC address changes take effect only on netdev_open() */
321         if ( netdev_is_open ( snpdev->netdev ) ) {
322                 DBGC ( snpdev, "SNPDEV %p MAC address changed while net "
323                        "device open\n", snpdev );
324         }
325
326         return 0;
327 }
328
329 /**
330  * Get (or reset) statistics
331  *
332  * @v snp               SNP interface
333  * @v reset             Reset statistics
334  * @v stats_len         Size of statistics table
335  * @v stats             Statistics table
336  * @ret efirc           EFI status code
337  */
338 static EFI_STATUS EFIAPI
339 efi_snp_statistics ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN reset,
340                      UINTN *stats_len, EFI_NETWORK_STATISTICS *stats ) {
341         struct efi_snp_device *snpdev =
342                 container_of ( snp, struct efi_snp_device, snp );
343         EFI_NETWORK_STATISTICS stats_buf;
344
345         DBGC2 ( snpdev, "SNPDEV %p STATISTICS%s", snpdev,
346                 ( reset ? " reset" : "" ) );
347
348         /* Fail if net device is currently claimed for use by iPXE */
349         if ( efi_snp_claimed )
350                 return EFI_NOT_READY;
351
352         /* Gather statistics */
353         memset ( &stats_buf, 0, sizeof ( stats_buf ) );
354         stats_buf.TxGoodFrames = snpdev->netdev->tx_stats.good;
355         stats_buf.TxDroppedFrames = snpdev->netdev->tx_stats.bad;
356         stats_buf.TxTotalFrames = ( snpdev->netdev->tx_stats.good +
357                                     snpdev->netdev->tx_stats.bad );
358         stats_buf.RxGoodFrames = snpdev->netdev->rx_stats.good;
359         stats_buf.RxDroppedFrames = snpdev->netdev->rx_stats.bad;
360         stats_buf.RxTotalFrames = ( snpdev->netdev->rx_stats.good +
361                                     snpdev->netdev->rx_stats.bad );
362         if ( *stats_len > sizeof ( stats_buf ) )
363                 *stats_len = sizeof ( stats_buf );
364         if ( stats )
365                 memcpy ( stats, &stats_buf, *stats_len );
366
367         /* Reset statistics if requested to do so */
368         if ( reset ) {
369                 memset ( &snpdev->netdev->tx_stats, 0,
370                          sizeof ( snpdev->netdev->tx_stats ) );
371                 memset ( &snpdev->netdev->rx_stats, 0,
372                          sizeof ( snpdev->netdev->rx_stats ) );
373         }
374
375         return 0;
376 }
377
378 /**
379  * Convert multicast IP address to MAC address
380  *
381  * @v snp               SNP interface
382  * @v ipv6              Address is IPv6
383  * @v ip                IP address
384  * @v mac               MAC address
385  * @ret efirc           EFI status code
386  */
387 static EFI_STATUS EFIAPI
388 efi_snp_mcast_ip_to_mac ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN ipv6,
389                           EFI_IP_ADDRESS *ip, EFI_MAC_ADDRESS *mac ) {
390         struct efi_snp_device *snpdev =
391                 container_of ( snp, struct efi_snp_device, snp );
392         struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
393         const char *ip_str;
394         int rc;
395
396         ip_str = ( ipv6 ? "(IPv6)" /* FIXME when we have inet6_ntoa() */ :
397                    inet_ntoa ( *( ( struct in_addr * ) ip ) ) );
398         DBGC2 ( snpdev, "SNPDEV %p MCAST_IP_TO_MAC %s\n", snpdev, ip_str );
399
400         /* Fail if net device is currently claimed for use by iPXE */
401         if ( efi_snp_claimed )
402                 return EFI_NOT_READY;
403
404         /* Try to hash the address */
405         if ( ( rc = ll_protocol->mc_hash ( ( ipv6 ? AF_INET6 : AF_INET ),
406                                            ip, mac ) ) != 0 ) {
407                 DBGC ( snpdev, "SNPDEV %p could not hash %s: %s\n",
408                        snpdev, ip_str, strerror ( rc ) );
409                 return EFIRC ( rc );
410         }
411
412         return 0;
413 }
414
415 /**
416  * Read or write non-volatile storage
417  *
418  * @v snp               SNP interface
419  * @v read              Operation is a read
420  * @v offset            Starting offset within NVRAM
421  * @v len               Length of data buffer
422  * @v data              Data buffer
423  * @ret efirc           EFI status code
424  */
425 static EFI_STATUS EFIAPI
426 efi_snp_nvdata ( EFI_SIMPLE_NETWORK_PROTOCOL *snp, BOOLEAN read,
427                  UINTN offset, UINTN len, VOID *data ) {
428         struct efi_snp_device *snpdev =
429                 container_of ( snp, struct efi_snp_device, snp );
430
431         DBGC2 ( snpdev, "SNPDEV %p NVDATA %s %lx+%lx\n", snpdev,
432                 ( read ? "read" : "write" ), ( ( unsigned long ) offset ),
433                 ( ( unsigned long ) len ) );
434         if ( ! read )
435                 DBGC2_HDA ( snpdev, offset, data, len );
436
437         /* Fail if net device is currently claimed for use by iPXE */
438         if ( efi_snp_claimed )
439                 return EFI_NOT_READY;
440
441         return EFI_UNSUPPORTED;
442 }
443
444 /**
445  * Read interrupt status and TX recycled buffer status
446  *
447  * @v snp               SNP interface
448  * @v interrupts        Interrupt status, or NULL
449  * @v txbufs            Recycled transmit buffer address, or NULL
450  * @ret efirc           EFI status code
451  */
452 static EFI_STATUS EFIAPI
453 efi_snp_get_status ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
454                      UINT32 *interrupts, VOID **txbufs ) {
455         struct efi_snp_device *snpdev =
456                 container_of ( snp, struct efi_snp_device, snp );
457
458         DBGC2 ( snpdev, "SNPDEV %p GET_STATUS", snpdev );
459
460         /* Fail if net device is currently claimed for use by iPXE */
461         if ( efi_snp_claimed )
462                 return EFI_NOT_READY;
463
464         /* Poll the network device */
465         efi_snp_poll ( snpdev );
466
467         /* Interrupt status.  In practice, this seems to be used only
468          * to detect TX completions.
469          */
470         if ( interrupts ) {
471                 *interrupts = 0;
472                 /* Report TX completions once queue is empty; this
473                  * avoids having to add hooks in the net device layer.
474                  */
475                 if ( snpdev->tx_count_interrupts &&
476                      list_empty ( &snpdev->netdev->tx_queue ) ) {
477                         *interrupts |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
478                         snpdev->tx_count_interrupts--;
479                 }
480                 /* Report RX */
481                 if ( snpdev->rx_count_interrupts ) {
482                         *interrupts |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
483                         snpdev->rx_count_interrupts--;
484                 }
485                 DBGC2 ( snpdev, " INTS:%02x", *interrupts );
486         }
487
488         /* TX completions.  It would be possible to design a more
489          * idiotic scheme for this, but it would be a challenge.
490          * According to the UEFI header file, txbufs will be filled in
491          * with a list of "recycled transmit buffers" (i.e. completed
492          * TX buffers).  Observant readers may care to note that
493          * *txbufs is a void pointer.  Precisely how a list of
494          * completed transmit buffers is meant to be represented as an
495          * array of voids is left as an exercise for the reader.
496          *
497          * The only users of this interface (MnpDxe/MnpIo.c and
498          * PxeBcDxe/Bc.c within the EFI dev kit) both just poll until
499          * seeing a non-NULL result return in txbufs.  This is valid
500          * provided that they do not ever attempt to transmit more
501          * than one packet concurrently (and that TX never times out).
502          */
503         if ( txbufs ) {
504                 if ( snpdev->tx_count_txbufs &&
505                      list_empty ( &snpdev->netdev->tx_queue ) ) {
506                         *txbufs = "Which idiot designed this API?";
507                         snpdev->tx_count_txbufs--;
508                 } else {
509                         *txbufs = NULL;
510                 }
511                 DBGC2 ( snpdev, " TX:%s", ( *txbufs ? "some" : "none" ) );
512         }
513
514         DBGC2 ( snpdev, "\n" );
515         return 0;
516 }
517
518 /**
519  * Start packet transmission
520  *
521  * @v snp               SNP interface
522  * @v ll_header_len     Link-layer header length, if to be filled in
523  * @v len               Length of data buffer
524  * @v data              Data buffer
525  * @v ll_src            Link-layer source address, if specified
526  * @v ll_dest           Link-layer destination address, if specified
527  * @v net_proto         Network-layer protocol (in host order)
528  * @ret efirc           EFI status code
529  */
530 static EFI_STATUS EFIAPI
531 efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
532                    UINTN ll_header_len, UINTN len, VOID *data,
533                    EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
534                    UINT16 *net_proto ) {
535         struct efi_snp_device *snpdev =
536                 container_of ( snp, struct efi_snp_device, snp );
537         struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
538         struct io_buffer *iobuf;
539         size_t payload_len;
540         int rc;
541
542         DBGC2 ( snpdev, "SNPDEV %p TRANSMIT %p+%lx", snpdev, data,
543                 ( ( unsigned long ) len ) );
544         if ( ll_header_len ) {
545                 if ( ll_src ) {
546                         DBGC2 ( snpdev, " src %s",
547                                 ll_protocol->ntoa ( ll_src ) );
548                 }
549                 if ( ll_dest ) {
550                         DBGC2 ( snpdev, " dest %s",
551                                 ll_protocol->ntoa ( ll_dest ) );
552                 }
553                 if ( net_proto ) {
554                         DBGC2 ( snpdev, " proto %04x", *net_proto );
555                 }
556         }
557         DBGC2 ( snpdev, "\n" );
558
559         /* Fail if net device is currently claimed for use by iPXE */
560         if ( efi_snp_claimed )
561                 return EFI_NOT_READY;
562
563         /* Sanity checks */
564         if ( ll_header_len ) {
565                 if ( ll_header_len != ll_protocol->ll_header_len ) {
566                         DBGC ( snpdev, "SNPDEV %p TX invalid header length "
567                                "%ld\n", snpdev,
568                                ( ( unsigned long ) ll_header_len ) );
569                         rc = -EINVAL;
570                         goto err_sanity;
571                 }
572                 if ( len < ll_header_len ) {
573                         DBGC ( snpdev, "SNPDEV %p invalid packet length %ld\n",
574                                snpdev, ( ( unsigned long ) len ) );
575                         rc = -EINVAL;
576                         goto err_sanity;
577                 }
578                 if ( ! ll_dest ) {
579                         DBGC ( snpdev, "SNPDEV %p TX missing destination "
580                                "address\n", snpdev );
581                         rc = -EINVAL;
582                         goto err_sanity;
583                 }
584                 if ( ! net_proto ) {
585                         DBGC ( snpdev, "SNPDEV %p TX missing network "
586                                "protocol\n", snpdev );
587                         rc = -EINVAL;
588                         goto err_sanity;
589                 }
590                 if ( ! ll_src )
591                         ll_src = &snpdev->mode.CurrentAddress;
592         }
593
594         /* Allocate buffer */
595         payload_len = ( len - ll_protocol->ll_header_len );
596         iobuf = alloc_iob ( MAX_LL_HEADER_LEN + ( ( payload_len > IOB_ZLEN ) ?
597                                                   payload_len : IOB_ZLEN ) );
598         if ( ! iobuf ) {
599                 DBGC ( snpdev, "SNPDEV %p TX could not allocate %ld-byte "
600                        "buffer\n", snpdev, ( ( unsigned long ) len ) );
601                 rc = -ENOMEM;
602                 goto err_alloc_iob;
603         }
604         iob_reserve ( iobuf, ( MAX_LL_HEADER_LEN -
605                                ll_protocol->ll_header_len ) );
606         memcpy ( iob_put ( iobuf, len ), data, len );
607
608         /* Create link-layer header, if specified */
609         if ( ll_header_len ) {
610                 iob_pull ( iobuf, ll_protocol->ll_header_len );
611                 if ( ( rc = ll_protocol->push ( snpdev->netdev,
612                                                 iobuf, ll_dest, ll_src,
613                                                 htons ( *net_proto ) )) != 0 ){
614                         DBGC ( snpdev, "SNPDEV %p TX could not construct "
615                                "header: %s\n", snpdev, strerror ( rc ) );
616                         goto err_ll_push;
617                 }
618         }
619
620         /* Transmit packet */
621         if ( ( rc = netdev_tx ( snpdev->netdev, iob_disown ( iobuf ) ) ) != 0){
622                 DBGC ( snpdev, "SNPDEV %p TX could not transmit: %s\n",
623                        snpdev, strerror ( rc ) );
624                 goto err_tx;
625         }
626
627         /* Record transmission as outstanding */
628         snpdev->tx_count_interrupts++;
629         snpdev->tx_count_txbufs++;
630
631         return 0;
632
633  err_tx:
634  err_ll_push:
635         free_iob ( iobuf );
636  err_alloc_iob:
637  err_sanity:
638         return EFIRC ( rc );
639 }
640
641 /**
642  * Receive packet
643  *
644  * @v snp               SNP interface
645  * @v ll_header_len     Link-layer header length, if to be filled in
646  * @v len               Length of data buffer
647  * @v data              Data buffer
648  * @v ll_src            Link-layer source address, if specified
649  * @v ll_dest           Link-layer destination address, if specified
650  * @v net_proto         Network-layer protocol (in host order)
651  * @ret efirc           EFI status code
652  */
653 static EFI_STATUS EFIAPI
654 efi_snp_receive ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
655                   UINTN *ll_header_len, UINTN *len, VOID *data,
656                   EFI_MAC_ADDRESS *ll_src, EFI_MAC_ADDRESS *ll_dest,
657                   UINT16 *net_proto ) {
658         struct efi_snp_device *snpdev =
659                 container_of ( snp, struct efi_snp_device, snp );
660         struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
661         struct io_buffer *iobuf;
662         const void *iob_ll_dest;
663         const void *iob_ll_src;
664         uint16_t iob_net_proto;
665         unsigned int iob_flags;
666         int rc;
667
668         DBGC2 ( snpdev, "SNPDEV %p RECEIVE %p(+%lx)", snpdev, data,
669                 ( ( unsigned long ) *len ) );
670
671         /* Fail if net device is currently claimed for use by iPXE */
672         if ( efi_snp_claimed )
673                 return EFI_NOT_READY;
674
675         /* Poll the network device */
676         efi_snp_poll ( snpdev );
677
678         /* Dequeue a packet, if one is available */
679         iobuf = netdev_rx_dequeue ( snpdev->netdev );
680         if ( ! iobuf ) {
681                 DBGC2 ( snpdev, "\n" );
682                 rc = -EAGAIN;
683                 goto out_no_packet;
684         }
685         DBGC2 ( snpdev, "+%zx\n", iob_len ( iobuf ) );
686
687         /* Return packet to caller */
688         memcpy ( data, iobuf->data, iob_len ( iobuf ) );
689         *len = iob_len ( iobuf );
690
691         /* Attempt to decode link-layer header */
692         if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
693                                         &iob_ll_src, &iob_net_proto,
694                                         &iob_flags ) ) != 0 ) {
695                 DBGC ( snpdev, "SNPDEV %p could not parse header: %s\n",
696                        snpdev, strerror ( rc ) );
697                 goto out_bad_ll_header;
698         }
699
700         /* Return link-layer header parameters to caller, if required */
701         if ( ll_header_len )
702                 *ll_header_len = ll_protocol->ll_header_len;
703         if ( ll_src )
704                 memcpy ( ll_src, iob_ll_src, ll_protocol->ll_addr_len );
705         if ( ll_dest )
706                 memcpy ( ll_dest, iob_ll_dest, ll_protocol->ll_addr_len );
707         if ( net_proto )
708                 *net_proto = ntohs ( iob_net_proto );
709
710         rc = 0;
711
712  out_bad_ll_header:
713         free_iob ( iobuf );
714  out_no_packet:
715         return EFIRC ( rc );
716 }
717
718 /**
719  * Poll event
720  *
721  * @v event             Event
722  * @v context           Event context
723  */
724 static VOID EFIAPI efi_snp_wait_for_packet ( EFI_EVENT event,
725                                              VOID *context ) {
726         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
727         struct efi_snp_device *snpdev = context;
728
729         DBGCP ( snpdev, "SNPDEV %p WAIT_FOR_PACKET\n", snpdev );
730
731         /* Do nothing unless the net device is open */
732         if ( ! netdev_is_open ( snpdev->netdev ) )
733                 return;
734
735         /* Do nothing if net device is currently claimed for use by iPXE */
736         if ( efi_snp_claimed )
737                 return;
738
739         /* Poll the network device */
740         efi_snp_poll ( snpdev );
741
742         /* Fire event if packets have been received */
743         if ( snpdev->rx_count_events != 0 ) {
744                 DBGC2 ( snpdev, "SNPDEV %p firing WaitForPacket event\n",
745                         snpdev );
746                 bs->SignalEvent ( event );
747                 snpdev->rx_count_events--;
748         }
749 }
750
751 /** SNP interface */
752 static EFI_SIMPLE_NETWORK_PROTOCOL efi_snp_device_snp = {
753         .Revision       = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION,
754         .Start          = efi_snp_start,
755         .Stop           = efi_snp_stop,
756         .Initialize     = efi_snp_initialize,
757         .Reset          = efi_snp_reset,
758         .Shutdown       = efi_snp_shutdown,
759         .ReceiveFilters = efi_snp_receive_filters,
760         .StationAddress = efi_snp_station_address,
761         .Statistics     = efi_snp_statistics,
762         .MCastIpToMac   = efi_snp_mcast_ip_to_mac,
763         .NvData         = efi_snp_nvdata,
764         .GetStatus      = efi_snp_get_status,
765         .Transmit       = efi_snp_transmit,
766         .Receive        = efi_snp_receive,
767 };
768
769 /******************************************************************************
770  *
771  * Component name protocol
772  *
773  ******************************************************************************
774  */
775
776 /**
777  * Look up driver name
778  *
779  * @v name2             Component name protocol
780  * @v language          Language to use
781  * @v driver_name       Driver name to fill in
782  * @ret efirc           EFI status code
783  */
784 static EFI_STATUS EFIAPI
785 efi_snp_get_driver_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
786                           CHAR8 *language __unused, CHAR16 **driver_name ) {
787         struct efi_snp_device *snpdev =
788                 container_of ( name2, struct efi_snp_device, name2 );
789
790         *driver_name = snpdev->driver_name;
791         return 0;
792 }
793
794 /**
795  * Look up controller name
796  *
797  * @v name2                     Component name protocol
798  * @v device            Device
799  * @v child             Child device, or NULL
800  * @v language          Language to use
801  * @v driver_name       Device name to fill in
802  * @ret efirc           EFI status code
803  */
804 static EFI_STATUS EFIAPI
805 efi_snp_get_controller_name ( EFI_COMPONENT_NAME2_PROTOCOL *name2,
806                               EFI_HANDLE device __unused,
807                               EFI_HANDLE child __unused,
808                               CHAR8 *language __unused,
809                               CHAR16 **controller_name ) {
810         struct efi_snp_device *snpdev =
811                 container_of ( name2, struct efi_snp_device, name2 );
812
813         *controller_name = snpdev->controller_name;
814         return 0;
815 }
816
817 /******************************************************************************
818  *
819  * Load file protocol
820  *
821  ******************************************************************************
822  */
823
824 /**
825  * Load file
826  *
827  * @v loadfile          Load file protocol
828  * @v path              File path
829  * @v booting           Loading as part of a boot attempt
830  * @ret efirc           EFI status code
831  */
832 static EFI_STATUS EFIAPI
833 efi_snp_load_file ( EFI_LOAD_FILE_PROTOCOL *load_file,
834                     EFI_DEVICE_PATH_PROTOCOL *path __unused,
835                     BOOLEAN booting, UINTN *len __unused,
836                     VOID *data __unused ) {
837         struct efi_snp_device *snpdev =
838                 container_of ( load_file, struct efi_snp_device, load_file );
839         struct net_device *netdev = snpdev->netdev;
840
841         /* Fail unless this is a boot attempt */
842         if ( ! booting ) {
843                 DBGC ( snpdev, "SNPDEV %p cannot load non-boot file\n",
844                        snpdev );
845                 return EFI_UNSUPPORTED;
846         }
847
848         /* Claim network devices for use by iPXE */
849         efi_snp_claim();
850
851         /* Boot from network device */
852         ipxe ( netdev );
853
854         /* Release network devices for use via SNP */
855         efi_snp_release();
856
857         /* Assume boot process was aborted */
858         return EFI_ABORTED;
859 }
860
861 /** Load file protocol */
862 static EFI_LOAD_FILE_PROTOCOL efi_snp_load_file_protocol = {
863         .LoadFile       = efi_snp_load_file,
864 };
865
866 /******************************************************************************
867  *
868  * iPXE network driver
869  *
870  ******************************************************************************
871  */
872
873 /**
874  * Locate SNP device corresponding to network device
875  *
876  * @v netdev            Network device
877  * @ret snp             SNP device, or NULL if not found
878  */
879 static struct efi_snp_device * efi_snp_demux ( struct net_device *netdev ) {
880         struct efi_snp_device *snpdev;
881
882         list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
883                 if ( snpdev->netdev == netdev )
884                         return snpdev;
885         }
886         return NULL;
887 }
888
889 /**
890  * Create SNP device
891  *
892  * @v netdev            Network device
893  * @ret rc              Return status code
894  */
895 static int efi_snp_probe ( struct net_device *netdev ) {
896         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
897         struct efi_device *efidev;
898         struct efi_snp_device *snpdev;
899         union {
900                 EFI_DEVICE_PATH_PROTOCOL *path;
901                 void *interface;
902         } path;
903         EFI_DEVICE_PATH_PROTOCOL *path_end;
904         MAC_ADDR_DEVICE_PATH *macpath;
905         size_t path_prefix_len = 0;
906         EFI_STATUS efirc;
907         int rc;
908
909         /* Find parent EFI device */
910         efidev = efidev_parent ( netdev->dev );
911         if ( ! efidev ) {
912                 DBG ( "SNP skipping non-EFI device %s\n", netdev->name );
913                 rc = 0;
914                 goto err_no_efidev;
915         }
916
917         /* Allocate the SNP device */
918         snpdev = zalloc ( sizeof ( *snpdev ) );
919         if ( ! snpdev ) {
920                 rc = -ENOMEM;
921                 goto err_alloc_snp;
922         }
923         snpdev->netdev = netdev_get ( netdev );
924         snpdev->efidev = efidev;
925
926         /* Sanity check */
927         if ( netdev->ll_protocol->ll_addr_len > sizeof ( EFI_MAC_ADDRESS ) ) {
928                 DBGC ( snpdev, "SNPDEV %p cannot support link-layer address "
929                        "length %d for %s\n", snpdev,
930                        netdev->ll_protocol->ll_addr_len, netdev->name );
931                 rc = -ENOTSUP;
932                 goto err_ll_addr_len;
933         }
934
935         /* Populate the SNP structure */
936         memcpy ( &snpdev->snp, &efi_snp_device_snp, sizeof ( snpdev->snp ) );
937         snpdev->snp.Mode = &snpdev->mode;
938         if ( ( efirc = bs->CreateEvent ( EVT_NOTIFY_WAIT, TPL_NOTIFY,
939                                          efi_snp_wait_for_packet, snpdev,
940                                          &snpdev->snp.WaitForPacket ) ) != 0 ){
941                 rc = -EEFI ( efirc );
942                 DBGC ( snpdev, "SNPDEV %p could not create event: %s\n",
943                        snpdev, strerror ( rc ) );
944                 goto err_create_event;
945         }
946
947         /* Populate the SNP mode structure */
948         snpdev->mode.State = EfiSimpleNetworkStopped;
949         efi_snp_set_mode ( snpdev );
950
951         /* Populate the NII structure */
952         snpdev->nii.Revision =
953                 EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION;
954         strncpy ( snpdev->nii.StringId, "iPXE",
955                   sizeof ( snpdev->nii.StringId ) );
956
957         /* Populate the component name structure */
958         efi_snprintf ( snpdev->driver_name,
959                        ( sizeof ( snpdev->driver_name ) /
960                          sizeof ( snpdev->driver_name[0] ) ),
961                        "%s %s", product_short_name, netdev->dev->driver_name );
962         efi_snprintf ( snpdev->controller_name,
963                        ( sizeof ( snpdev->controller_name ) /
964                          sizeof ( snpdev->controller_name[0] ) ),
965                        "%s %s (%s, %s)", product_short_name,
966                        netdev->dev->driver_name, netdev->dev->name,
967                        netdev_addr ( netdev ) );
968         snpdev->name2.GetDriverName = efi_snp_get_driver_name;
969         snpdev->name2.GetControllerName = efi_snp_get_controller_name;
970         snpdev->name2.SupportedLanguages = "en";
971
972         /* Populate the load file protocol structure */
973         memcpy ( &snpdev->load_file, &efi_snp_load_file_protocol,
974                  sizeof ( snpdev->load_file ) );
975
976         /* Populate the device name */
977         efi_snprintf ( snpdev->name, ( sizeof ( snpdev->name ) /
978                                        sizeof ( snpdev->name[0] ) ),
979                        "%s", netdev->name );
980
981         /* Get the parent device path */
982         if ( ( efirc = bs->OpenProtocol ( efidev->device,
983                                           &efi_device_path_protocol_guid,
984                                           &path.interface, efi_image_handle,
985                                           efidev->device,
986                                           EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
987                 rc = -EEFI ( efirc );
988                 DBGC ( snpdev, "SNPDEV %p cannot get %p %s device path: %s\n",
989                        snpdev, efidev->device,
990                        efi_handle_name ( efidev->device ), strerror ( rc ) );
991                 goto err_open_device_path;
992         }
993
994         /* Allocate the new device path */
995         path_end = efi_devpath_end ( path.path );
996         path_prefix_len = ( ( ( void * ) path_end ) - ( ( void * ) path.path ));
997         snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
998                                 sizeof ( *path_end ) );
999         if ( ! snpdev->path ) {
1000                 rc = -ENOMEM;
1001                 goto err_alloc_device_path;
1002         }
1003
1004         /* Populate the device path */
1005         memcpy ( snpdev->path, path.path, path_prefix_len );
1006         macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
1007         path_end = ( ( void * ) ( macpath + 1 ) );
1008         memset ( macpath, 0, sizeof ( *macpath ) );
1009         macpath->Header.Type = MESSAGING_DEVICE_PATH;
1010         macpath->Header.SubType = MSG_MAC_ADDR_DP;
1011         macpath->Header.Length[0] = sizeof ( *macpath );
1012         memcpy ( &macpath->MacAddress, netdev->ll_addr,
1013                  sizeof ( macpath->MacAddress ) );
1014         macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
1015         memset ( path_end, 0, sizeof ( *path_end ) );
1016         path_end->Type = END_DEVICE_PATH_TYPE;
1017         path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
1018         path_end->Length[0] = sizeof ( *path_end );
1019
1020         /* Install the SNP */
1021         if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
1022                         &snpdev->handle,
1023                         &efi_simple_network_protocol_guid, &snpdev->snp,
1024                         &efi_device_path_protocol_guid, snpdev->path,
1025                         &efi_nii_protocol_guid, &snpdev->nii,
1026                         &efi_nii31_protocol_guid, &snpdev->nii,
1027                         &efi_component_name2_protocol_guid, &snpdev->name2,
1028                         &efi_load_file_protocol_guid, &snpdev->load_file,
1029                         NULL ) ) != 0 ) {
1030                 rc = -EEFI ( efirc );
1031                 DBGC ( snpdev, "SNPDEV %p could not install protocols: "
1032                        "%s\n", snpdev, strerror ( rc ) );
1033                 goto err_install_protocol_interface;
1034         }
1035
1036         /* Add as child of EFI parent device */
1037         if ( ( rc = efi_child_add ( efidev->device, snpdev->handle ) ) != 0 ) {
1038                 DBGC ( snpdev, "SNPDEV %p could not become child of %p %s: "
1039                        "%s\n", snpdev, efidev->device,
1040                        efi_handle_name ( efidev->device ), strerror ( rc ) );
1041                 goto err_efi_child_add;
1042         }
1043
1044         /* Install HII */
1045         if ( ( rc = efi_snp_hii_install ( snpdev ) ) != 0 ) {
1046                 DBGC ( snpdev, "SNPDEV %p could not install HII: %s\n",
1047                        snpdev, strerror ( rc ) );
1048                 /* HII fails on several platforms.  It's
1049                  * non-essential, so treat this as a non-fatal
1050                  * error.
1051                  */
1052         }
1053
1054         /* Add to list of SNP devices */
1055         list_add ( &snpdev->list, &efi_snp_devices );
1056
1057         /* Close device path */
1058         bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
1059                             efi_image_handle, efidev->device );
1060
1061         DBGC ( snpdev, "SNPDEV %p installed for %s as device %p %s\n",
1062                snpdev, netdev->name, snpdev->handle,
1063                efi_handle_name ( snpdev->handle ) );
1064         return 0;
1065
1066         if ( snpdev->package_list )
1067                 efi_snp_hii_uninstall ( snpdev );
1068         efi_child_del ( efidev->device, snpdev->handle );
1069  err_efi_child_add:
1070         bs->UninstallMultipleProtocolInterfaces (
1071                         snpdev->handle,
1072                         &efi_simple_network_protocol_guid, &snpdev->snp,
1073                         &efi_device_path_protocol_guid, snpdev->path,
1074                         &efi_nii_protocol_guid, &snpdev->nii,
1075                         &efi_nii31_protocol_guid, &snpdev->nii,
1076                         &efi_component_name2_protocol_guid, &snpdev->name2,
1077                         &efi_load_file_protocol_guid, &snpdev->load_file,
1078                         NULL );
1079  err_install_protocol_interface:
1080         free ( snpdev->path );
1081  err_alloc_device_path:
1082         bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
1083                             efi_image_handle, efidev->device );
1084  err_open_device_path:
1085         bs->CloseEvent ( snpdev->snp.WaitForPacket );
1086  err_create_event:
1087  err_ll_addr_len:
1088         netdev_put ( netdev );
1089         free ( snpdev );
1090  err_alloc_snp:
1091  err_no_efidev:
1092         return rc;
1093 }
1094
1095 /**
1096  * Handle SNP device or link state change
1097  *
1098  * @v netdev            Network device
1099  */
1100 static void efi_snp_notify ( struct net_device *netdev ) {
1101         struct efi_snp_device *snpdev;
1102
1103         /* Locate SNP device */
1104         snpdev = efi_snp_demux ( netdev );
1105         if ( ! snpdev ) {
1106                 DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
1107                 return;
1108         }
1109
1110         /* Update link state */
1111         snpdev->mode.MediaPresent =
1112                 ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
1113         DBGC ( snpdev, "SNPDEV %p link is %s\n", snpdev,
1114                ( snpdev->mode.MediaPresent ? "up" : "down" ) );
1115
1116         /* Update mode state */
1117         efi_snp_set_state ( snpdev );
1118 }
1119
1120 /**
1121  * Destroy SNP device
1122  *
1123  * @v netdev            Network device
1124  */
1125 static void efi_snp_remove ( struct net_device *netdev ) {
1126         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
1127         struct efi_snp_device *snpdev;
1128
1129         /* Locate SNP device */
1130         snpdev = efi_snp_demux ( netdev );
1131         if ( ! snpdev ) {
1132                 DBG ( "SNP skipping non-SNP device %s\n", netdev->name );
1133                 return;
1134         }
1135
1136         /* Uninstall the SNP */
1137         if ( snpdev->package_list )
1138                 efi_snp_hii_uninstall ( snpdev );
1139         efi_child_del ( snpdev->efidev->device, snpdev->handle );
1140         list_del ( &snpdev->list );
1141         bs->UninstallMultipleProtocolInterfaces (
1142                         snpdev->handle,
1143                         &efi_simple_network_protocol_guid, &snpdev->snp,
1144                         &efi_device_path_protocol_guid, snpdev->path,
1145                         &efi_nii_protocol_guid, &snpdev->nii,
1146                         &efi_nii31_protocol_guid, &snpdev->nii,
1147                         &efi_component_name2_protocol_guid, &snpdev->name2,
1148                         &efi_load_file_protocol_guid, &snpdev->load_file,
1149                         NULL );
1150         free ( snpdev->path );
1151         bs->CloseEvent ( snpdev->snp.WaitForPacket );
1152         netdev_put ( snpdev->netdev );
1153         free ( snpdev );
1154 }
1155
1156 /** SNP driver */
1157 struct net_driver efi_snp_driver __net_driver = {
1158         .name = "SNP",
1159         .probe = efi_snp_probe,
1160         .notify = efi_snp_notify,
1161         .remove = efi_snp_remove,
1162 };
1163
1164 /**
1165  * Find SNP device by EFI device handle
1166  *
1167  * @v handle            EFI device handle
1168  * @ret snpdev          SNP device, or NULL
1169  */
1170 struct efi_snp_device * find_snpdev ( EFI_HANDLE handle ) {
1171         struct efi_snp_device *snpdev;
1172
1173         list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
1174                 if ( snpdev->handle == handle )
1175                         return snpdev;
1176         }
1177         return NULL;
1178 }
1179
1180 /**
1181  * Get most recently opened SNP device
1182  *
1183  * @ret snpdev          Most recently opened SNP device, or NULL
1184  */
1185 struct efi_snp_device * last_opened_snpdev ( void ) {
1186         struct net_device *netdev;
1187
1188         netdev = last_opened_netdev();
1189         if ( ! netdev )
1190                 return NULL;
1191
1192         return efi_snp_demux ( netdev );
1193 }
1194
1195 /**
1196  * Set SNP claimed/released state
1197  *
1198  * @v claimed           Network devices are claimed for use by iPXE
1199  */
1200 void efi_snp_set_claimed ( int claimed ) {
1201         struct efi_snp_device *snpdev;
1202
1203         /* Claim SNP devices */
1204         efi_snp_claimed = claimed;
1205
1206         /* Update SNP mode state for each interface */
1207         list_for_each_entry ( snpdev, &efi_snp_devices, list )
1208                 efi_snp_set_state ( snpdev );
1209 }