Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / net / efi / snpnet.c
1 /*
2  * Copyright (C) 2014 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 <stdio.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <ipxe/iobuf.h>
27 #include <ipxe/netdevice.h>
28 #include <ipxe/ethernet.h>
29 #include <ipxe/vsprintf.h>
30 #include <ipxe/efi/efi.h>
31 #include <ipxe/efi/Protocol/SimpleNetwork.h>
32 #include <ipxe/efi/efi_driver.h>
33 #include <ipxe/efi/efi_utils.h>
34 #include "snpnet.h"
35
36 /** @file
37  *
38  * SNP NIC driver
39  *
40  */
41
42 /** An SNP NIC */
43 struct snp_nic {
44         /** EFI device */
45         struct efi_device *efidev;
46         /** Simple network protocol */
47         EFI_SIMPLE_NETWORK_PROTOCOL *snp;
48         /** Generic device */
49         struct device dev;
50
51         /** Maximum packet size
52          *
53          * This is calculated as the sum of MediaHeaderSize and
54          * MaxPacketSize, and may therefore be an overestimate.
55          */
56         size_t mtu;
57
58         /** Current transmit buffer */
59         struct io_buffer *txbuf;
60         /** Current receive buffer */
61         struct io_buffer *rxbuf;
62 };
63
64 /** Maximum number of received packets per poll */
65 #define SNP_RX_QUOTA 4
66
67 /**
68  * Format SNP MAC address (for debugging)
69  *
70  * @v mac               MAC address
71  * @v len               Length of MAC address
72  * @ret text            MAC address as text
73  */
74 static const char * snpnet_mac_text ( EFI_MAC_ADDRESS *mac, size_t len ) {
75         static char buf[ sizeof ( *mac ) * 3 /* "xx:" or "xx\0" */ ];
76         size_t used = 0;
77         unsigned int i;
78
79         for ( i = 0 ; i < len ; i++ ) {
80                 used += ssnprintf ( &buf[used], ( sizeof ( buf ) - used ),
81                                     "%s%02x", ( used ? ":" : "" ),
82                                     mac->Addr[i] );
83         }
84         return buf;
85 }
86
87 /**
88  * Dump SNP mode information (for debugging)
89  *
90  * @v netdev            Network device
91  */
92 static void snpnet_dump_mode ( struct net_device *netdev ) {
93         struct snp_nic *snp = netdev_priv ( netdev );
94         EFI_SIMPLE_NETWORK_MODE *mode = snp->snp->Mode;
95         size_t mac_len = mode->HwAddressSize;
96         unsigned int i;
97
98         /* Do nothing unless debugging is enabled */
99         if ( ! DBG_EXTRA )
100                 return;
101
102         DBGC2 ( snp, "SNP %s st %d type %d hdr %d pkt %d rxflt %#x/%#x%s "
103                 "nvram %d acc %d mcast %d/%d\n", netdev->name, mode->State,
104                 mode->IfType, mode->MediaHeaderSize, mode->MaxPacketSize,
105                 mode->ReceiveFilterSetting, mode->ReceiveFilterMask,
106                 ( mode->MultipleTxSupported ? " multitx" : "" ),
107                 mode->NvRamSize, mode->NvRamAccessSize,
108                 mode->MCastFilterCount, mode->MaxMCastFilterCount );
109         DBGC2 ( snp, "SNP %s hw %s", netdev->name,
110                 snpnet_mac_text ( &mode->PermanentAddress, mac_len ) );
111         DBGC2 ( snp, " addr %s%s",
112                 snpnet_mac_text ( &mode->CurrentAddress, mac_len ),
113                 ( mode->MacAddressChangeable ? "" : "(f)" ) );
114         DBGC2 ( snp, " bcast %s\n",
115                 snpnet_mac_text ( &mode->BroadcastAddress, mac_len ) );
116         for ( i = 0 ; i < mode->MCastFilterCount ; i++ ) {
117                 DBGC2 ( snp, "SNP %s mcast %s\n", netdev->name,
118                         snpnet_mac_text ( &mode->MCastFilter[i], mac_len ) );
119         }
120         DBGC2 ( snp, "SNP %s media %s\n", netdev->name,
121                 ( mode->MediaPresentSupported ?
122                   ( mode->MediaPresent ? "present" : "not present" ) :
123                   "presence not supported" ) );
124 }
125
126 /**
127  * Check link state
128  *
129  * @v netdev            Network device
130  */
131 static void snpnet_check_link ( struct net_device *netdev ) {
132         struct snp_nic *snp = netdev_priv ( netdev );
133         EFI_SIMPLE_NETWORK_MODE *mode = snp->snp->Mode;
134
135         /* Do nothing unless media presence detection is supported */
136         if ( ! mode->MediaPresentSupported )
137                 return;
138
139         /* Report any link status change */
140         if ( mode->MediaPresent && ( ! netdev_link_ok ( netdev ) ) ) {
141                 netdev_link_up ( netdev );
142         } else if ( ( ! mode->MediaPresent ) && netdev_link_ok ( netdev ) ) {
143                 netdev_link_down ( netdev );
144         }
145 }
146
147 /**
148  * Transmit packet
149  *
150  * @v netdev            Network device
151  * @v iobuf             I/O buffer
152  * @ret rc              Return status code
153  */
154 static int snpnet_transmit ( struct net_device *netdev,
155                              struct io_buffer *iobuf ) {
156         struct snp_nic *snp = netdev_priv ( netdev );
157         EFI_STATUS efirc;
158         int rc;
159
160         /* Defer the packet if there is already a transmission in progress */
161         if ( snp->txbuf ) {
162                 netdev_tx_defer ( netdev, iobuf );
163                 return 0;
164         }
165
166         /* Transmit packet */
167         if ( ( efirc = snp->snp->Transmit ( snp->snp, 0, iob_len ( iobuf ),
168                                             iobuf->data, NULL, NULL,
169                                             NULL ) ) != 0 ) {
170                 rc = -EEFI ( efirc );
171                 DBGC ( snp, "SNP %s could not transmit: %s\n",
172                        netdev->name, strerror ( rc ) );
173                 return rc;
174         }
175         snp->txbuf = iobuf;
176
177         return 0;
178 }
179
180 /**
181  * Poll for completed packets
182  *
183  * @v netdev            Network device
184  */
185 static void snpnet_poll_tx ( struct net_device *netdev ) {
186         struct snp_nic *snp = netdev->priv;
187         struct io_buffer *iobuf;
188         UINT32 irq;
189         VOID *txbuf;
190         EFI_STATUS efirc;
191         int rc;
192
193         /* Get status */
194         if ( ( efirc = snp->snp->GetStatus ( snp->snp, &irq, &txbuf ) ) != 0 ) {
195                 rc = -EEFI ( efirc );
196                 DBGC ( snp, "SNP %s could not get status: %s\n",
197                        netdev->name, strerror ( rc ) );
198                 netdev_rx_err ( netdev, NULL, rc );
199                 return;
200         }
201
202         /* Do nothing unless we have a completion */
203         if ( ! txbuf )
204                 return;
205
206         /* Sanity check */
207         if ( ! snp->txbuf ) {
208                 DBGC ( snp, "SNP %s reported spurious TX completion\n",
209                        netdev->name );
210                 netdev_tx_err ( netdev, NULL, -EPIPE );
211                 return;
212         }
213
214         /* Complete transmission */
215         iobuf = snp->txbuf;
216         snp->txbuf = NULL;
217         netdev_tx_complete ( netdev, iobuf );
218 }
219
220 /**
221  * Poll for received packets
222  *
223  * @v netdev            Network device
224  */
225 static void snpnet_poll_rx ( struct net_device *netdev ) {
226         struct snp_nic *snp = netdev->priv;
227         UINTN len;
228         unsigned int quota;
229         EFI_STATUS efirc;
230         int rc;
231
232         /* Retrieve up to SNP_RX_QUOTA packets */
233         for ( quota = SNP_RX_QUOTA ; quota ; quota-- ) {
234
235                 /* Allocate buffer, if required */
236                 if ( ! snp->rxbuf ) {
237                         snp->rxbuf = alloc_iob ( snp->mtu );
238                         if ( ! snp->rxbuf ) {
239                                 /* Leave for next poll */
240                                 break;
241                         }
242                 }
243
244                 /* Receive packet */
245                 len = iob_tailroom ( snp->rxbuf );
246                 if ( ( efirc = snp->snp->Receive ( snp->snp, NULL, &len,
247                                                    snp->rxbuf->data, NULL,
248                                                    NULL, NULL ) ) != 0 ) {
249
250                         /* EFI_NOT_READY is just the usual "no packet"
251                          * status indication; ignore it.
252                          */
253                         if ( efirc == EFI_NOT_READY )
254                                 break;
255
256                         /* Anything else is an error */
257                         rc = -EEFI ( efirc );
258                         DBGC ( snp, "SNP %s could not receive: %s\n",
259                                netdev->name, strerror ( rc ) );
260                         netdev_rx_err ( netdev, NULL, rc );
261                         break;
262                 }
263
264                 /* Hand off to network stack */
265                 iob_put ( snp->rxbuf, len );
266                 netdev_rx ( netdev, snp->rxbuf );
267                 snp->rxbuf = NULL;
268         }
269 }
270
271 /**
272  * Poll for completed packets
273  *
274  * @v netdev            Network device
275  */
276 static void snpnet_poll ( struct net_device *netdev ) {
277
278         /* Process any TX completions */
279         snpnet_poll_tx ( netdev );
280
281         /* Process any RX completions */
282         snpnet_poll_rx ( netdev );
283
284         /* Check for link state changes */
285         snpnet_check_link ( netdev );
286 }
287
288 /**
289  * Set receive filters
290  *
291  * @v netdev            Network device
292  * @ret rc              Return status code
293  */
294 static int snpnet_rx_filters ( struct net_device *netdev ) {
295         struct snp_nic *snp = netdev->priv;
296         UINT32 filters[] = {
297                 snp->snp->Mode->ReceiveFilterMask,
298                 ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
299                   EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
300                   EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST ),
301                 ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
302                   EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST ),
303                 ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST ),
304         };
305         unsigned int i;
306         EFI_STATUS efirc;
307         int rc;
308
309         /* Try possible receive filters in turn */
310         for ( i = 0; i < ( sizeof ( filters ) / sizeof ( filters[0] ) ); i++ ) {
311                 efirc = snp->snp->ReceiveFilters ( snp->snp, filters[i],
312                                                    0, TRUE, 0, NULL );
313                 if ( efirc == 0 )
314                         return 0;
315                 rc = -EEFI ( efirc );
316                 DBGC ( snp, "SNP %s could not set receive filters %#02x (have "
317                        "%#02x): %s\n", netdev->name, filters[i],
318                        snp->snp->Mode->ReceiveFilterSetting, strerror ( rc ) );
319         }
320
321         return rc;
322 }
323
324 /**
325  * Open network device
326  *
327  * @v netdev            Network device
328  * @ret rc              Return status code
329  */
330 static int snpnet_open ( struct net_device *netdev ) {
331         struct snp_nic *snp = netdev->priv;
332         EFI_MAC_ADDRESS *mac = ( ( void * ) netdev->ll_addr );
333         EFI_STATUS efirc;
334         int rc;
335
336         /* Try setting MAC address (before initialising) */
337         if ( ( efirc = snp->snp->StationAddress ( snp->snp, FALSE, mac ) ) !=0){
338                 rc = -EEFI ( efirc );
339                 DBGC ( snp, "SNP %s could not set station address before "
340                        "initialising: %s\n", netdev->name, strerror ( rc ) );
341                 /* Ignore error */
342         }
343
344         /* Initialise NIC */
345         if ( ( efirc = snp->snp->Initialize ( snp->snp, 0, 0 ) ) != 0 ) {
346                 rc = -EEFI ( efirc );
347                 snpnet_dump_mode ( netdev );
348                 DBGC ( snp, "SNP %s could not initialise: %s\n",
349                        netdev->name, strerror ( rc ) );
350                 return rc;
351         }
352
353         /* Try setting MAC address (after initialising) */
354         if ( ( efirc = snp->snp->StationAddress ( snp->snp, FALSE, mac ) ) !=0){
355                 rc = -EEFI ( efirc );
356                 DBGC ( snp, "SNP %s could not set station address after "
357                        "initialising: %s\n", netdev->name, strerror ( rc ) );
358                 /* Ignore error */
359         }
360
361         /* Set receive filters */
362         if ( ( rc = snpnet_rx_filters ( netdev ) ) != 0 ) {
363                 /* Ignore error */
364         }
365
366         /* Dump mode information (for debugging) */
367         snpnet_dump_mode ( netdev );
368
369         return 0;
370 }
371
372 /**
373  * Close network device
374  *
375  * @v netdev            Network device
376  */
377 static void snpnet_close ( struct net_device *netdev ) {
378         struct snp_nic *snp = netdev->priv;
379         EFI_STATUS efirc;
380         int rc;
381
382         /* Shut down NIC */
383         if ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) {
384                 rc = -EEFI ( efirc );
385                 DBGC ( snp, "SNP %s could not shut down: %s\n",
386                        netdev->name, strerror ( rc ) );
387                 /* Nothing we can do about this */
388         }
389
390         /* Discard transmit buffer, if applicable */
391         if ( snp->txbuf ) {
392                 netdev_tx_complete_err ( netdev, snp->txbuf, -ECANCELED );
393                 snp->txbuf = NULL;
394         }
395
396         /* Discard receive buffer, if applicable */
397         if ( snp->rxbuf ) {
398                 free_iob ( snp->rxbuf );
399                 snp->rxbuf = NULL;
400         }
401 }
402
403 /** SNP network device operations */
404 static struct net_device_operations snpnet_operations = {
405         .open = snpnet_open,
406         .close = snpnet_close,
407         .transmit = snpnet_transmit,
408         .poll = snpnet_poll,
409 };
410
411 /**
412  * Attach driver to device
413  *
414  * @v efidev            EFI device
415  * @ret rc              Return status code
416  */
417 int snpnet_start ( struct efi_device *efidev ) {
418         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
419         EFI_HANDLE device = efidev->device;
420         EFI_SIMPLE_NETWORK_MODE *mode;
421         struct net_device *netdev;
422         struct snp_nic *snp;
423         void *interface;
424         EFI_STATUS efirc;
425         int rc;
426
427         /* Open SNP protocol */
428         if ( ( efirc = bs->OpenProtocol ( device,
429                                           &efi_simple_network_protocol_guid,
430                                           &interface, efi_image_handle, device,
431                                           ( EFI_OPEN_PROTOCOL_BY_DRIVER |
432                                             EFI_OPEN_PROTOCOL_EXCLUSIVE )))!=0){
433                 rc = -EEFI ( efirc );
434                 DBGC ( device, "SNP %p %s cannot open SNP protocol: %s\n",
435                        device, efi_handle_name ( device ), strerror ( rc ) );
436                 DBGC_EFI_OPENERS ( device, device,
437                                    &efi_simple_network_protocol_guid );
438                 goto err_open_protocol;
439         }
440
441         /* Allocate and initialise structure */
442         netdev = alloc_etherdev ( sizeof ( *snp ) );
443         if ( ! netdev ) {
444                 rc = -ENOMEM;
445                 goto err_alloc;
446         }
447         netdev_init ( netdev, &snpnet_operations );
448         snp = netdev->priv;
449         snp->efidev = efidev;
450         snp->snp = interface;
451         mode = snp->snp->Mode;
452         efidev_set_drvdata ( efidev, netdev );
453
454         /* Populate underlying device information */
455         efi_device_info ( device, "SNP", &snp->dev );
456         snp->dev.driver_name = "SNP";
457         snp->dev.parent = &efidev->dev;
458         list_add ( &snp->dev.siblings, &efidev->dev.children );
459         INIT_LIST_HEAD ( &snp->dev.children );
460         netdev->dev = &snp->dev;
461
462         /* Bring to the Started state */
463         if ( ( mode->State == EfiSimpleNetworkStopped ) &&
464              ( ( efirc = snp->snp->Start ( snp->snp ) ) != 0 ) ) {
465                 rc = -EEFI ( efirc );
466                 DBGC ( device, "SNP %p %s could not start: %s\n", device,
467                        efi_handle_name ( device ), strerror ( rc ) );
468                 goto err_start;
469         }
470         if ( ( mode->State == EfiSimpleNetworkInitialized ) &&
471              ( ( efirc = snp->snp->Shutdown ( snp->snp ) ) != 0 ) ) {
472                 rc = -EEFI ( efirc );
473                 DBGC ( device, "SNP %p %s could not shut down: %s\n", device,
474                        efi_handle_name ( device ), strerror ( rc ) );
475                 goto err_shutdown;
476         }
477
478         /* Populate network device parameters */
479         if ( mode->HwAddressSize != netdev->ll_protocol->hw_addr_len ) {
480                 DBGC ( device, "SNP %p %s has invalid hardware address "
481                        "length %d\n", device, efi_handle_name ( device ),
482                        mode->HwAddressSize );
483                 rc = -ENOTSUP;
484                 goto err_hw_addr_len;
485         }
486         memcpy ( netdev->hw_addr, &mode->PermanentAddress,
487                  netdev->ll_protocol->hw_addr_len );
488         if ( mode->HwAddressSize != netdev->ll_protocol->ll_addr_len ) {
489                 DBGC ( device, "SNP %p %s has invalid link-layer address "
490                        "length %d\n", device, efi_handle_name ( device ),
491                        mode->HwAddressSize );
492                 rc = -ENOTSUP;
493                 goto err_ll_addr_len;
494         }
495         memcpy ( netdev->ll_addr, &mode->CurrentAddress,
496                  netdev->ll_protocol->ll_addr_len );
497         snp->mtu = ( snp->snp->Mode->MaxPacketSize +
498                      snp->snp->Mode->MediaHeaderSize );
499
500         /* Register network device */
501         if ( ( rc = register_netdev ( netdev ) ) != 0 )
502                 goto err_register_netdev;
503         DBGC ( device, "SNP %p %s registered as %s\n",
504                device, efi_handle_name ( device ), netdev->name );
505
506         /* Set initial link state */
507         if ( snp->snp->Mode->MediaPresentSupported ) {
508                 snpnet_check_link ( netdev );
509         } else {
510                 netdev_link_up ( netdev );
511         }
512
513         return 0;
514
515         unregister_netdev ( netdev );
516  err_register_netdev:
517  err_ll_addr_len:
518  err_hw_addr_len:
519  err_shutdown:
520  err_start:
521         list_del ( &snp->dev.siblings );
522         netdev_nullify ( netdev );
523         netdev_put ( netdev );
524  err_alloc:
525         bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
526                             efi_image_handle, device );
527  err_open_protocol:
528         return rc;
529 }
530
531 /**
532  * Detach driver from device
533  *
534  * @v efidev            EFI device
535   */
536 void snpnet_stop ( struct efi_device *efidev ) {
537         EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
538         struct net_device *netdev = efidev_get_drvdata ( efidev );
539         struct snp_nic *snp = netdev->priv;
540         EFI_HANDLE device = efidev->device;
541         EFI_STATUS efirc;
542         int rc;
543
544         /* Unregister network device */
545         unregister_netdev ( netdev );
546
547         /* Stop SNP protocol */
548         if ( ( efirc = snp->snp->Stop ( snp->snp ) ) != 0 ) {
549                 rc = -EEFI ( efirc );
550                 DBGC ( device, "SNP %p %s could not stop: %s\n", device,
551                        efi_handle_name ( device ), strerror ( rc ) );
552                 /* Nothing we can do about this */
553         }
554
555         /* Free network device */
556         list_del ( &snp->dev.siblings );
557         netdev_nullify ( netdev );
558         netdev_put ( netdev );
559
560         /* Close SNP protocol */
561         bs->CloseProtocol ( device, &efi_simple_network_protocol_guid,
562                             efi_image_handle, device );
563 }