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