iPXE
bofm_test.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License as
00006  * published by the Free Software Foundation; either version 2 of the
00007  * License, or any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017  * 02110-1301, USA.
00018  *
00019  * You can also choose to distribute this program under the terms of
00020  * the Unmodified Binary Distribution Licence (as given in the file
00021  * COPYING.UBDL), provided that you have satisfied its requirements.
00022  */
00023 
00024 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00025 
00026 #include <stdint.h>
00027 #include <stdio.h>
00028 #include <string.h>
00029 #include <ipxe/uaccess.h>
00030 #include <ipxe/init.h>
00031 #include <ipxe/pci.h>
00032 #include <ipxe/ethernet.h>
00033 #include <ipxe/bofm.h>
00034 
00035 /** @file
00036  *
00037  * IBM BladeCenter Open Fabric Manager (BOFM) tests
00038  *
00039  */
00040 
00041 /** Harvest test table */
00042 static struct {
00043         struct bofm_global_header header;
00044         struct bofm_section_header en_header;
00045         struct bofm_en en;
00046         struct bofm_section_header done;
00047 } __attribute__ (( packed )) bofmtab_harvest = {
00048         .header = {
00049                 .magic = BOFM_IOAA_MAGIC,
00050                 .action = BOFM_ACTION_HVST,
00051                 .version = 0x01,
00052                 .level = 0x01,
00053                 .length = sizeof ( bofmtab_harvest ),
00054                 .profile = "Harvest test profile",
00055         },
00056         .en_header = {
00057                 .magic = BOFM_EN_MAGIC,
00058                 .length = sizeof ( bofmtab_harvest.en ),
00059         },
00060         .en = {
00061                 .options = ( BOFM_EN_MAP_PFA | BOFM_EN_USAGE_HARVEST |
00062                              BOFM_EN_RQ_HVST_ACTIVE ),
00063                 .mport = 1,
00064         },
00065         .done = {
00066                 .magic = BOFM_DONE_MAGIC,
00067         },
00068 };
00069 
00070 /** Update test table */
00071 static struct {
00072         struct bofm_global_header header;
00073         struct bofm_section_header en_header;
00074         struct bofm_en en;
00075         struct bofm_section_header done;
00076 } __attribute__ (( packed )) bofmtab_update = {
00077         .header = {
00078                 .magic = BOFM_IOAA_MAGIC,
00079                 .action = BOFM_ACTION_UPDT,
00080                 .version = 0x01,
00081                 .level = 0x01,
00082                 .length = sizeof ( bofmtab_update ),
00083                 .profile = "Update test profile",
00084         },
00085         .en_header = {
00086                 .magic = BOFM_EN_MAGIC,
00087                 .length = sizeof ( bofmtab_update.en ),
00088         },
00089         .en = {
00090                 .options = ( BOFM_EN_MAP_PFA | BOFM_EN_EN_A |
00091                              BOFM_EN_USAGE_ENTRY ),
00092                 .mport = 1,
00093                 .mac_a = { 0x02, 0x00, 0x69, 0x50, 0x58, 0x45 },
00094         },
00095         .done = {
00096                 .magic = BOFM_DONE_MAGIC,
00097         },
00098 };
00099 
00100 /**
00101  * Perform BOFM test
00102  *
00103  * @v pci               PCI device
00104  */
00105 void bofm_test ( struct pci_device *pci ) {
00106         int bofmrc;
00107 
00108         printf ( "BOFMTEST using " PCI_FMT "\n", PCI_ARGS ( pci ) );
00109 
00110         /* Perform harvest test */
00111         printf ( "BOFMTEST performing harvest\n" );
00112         bofmtab_harvest.en.busdevfn = pci->busdevfn;
00113         DBG_HDA ( 0, &bofmtab_harvest, sizeof ( bofmtab_harvest ) );
00114         bofmrc = bofm ( virt_to_user ( &bofmtab_harvest ), pci );
00115         printf ( "BOFMTEST harvest result %08x\n", bofmrc );
00116         if ( bofmtab_harvest.en.options & BOFM_EN_HVST ) {
00117                 printf ( "BOFMTEST harvested MAC address %s\n",
00118                          eth_ntoa ( &bofmtab_harvest.en.mac_a ) );
00119         } else {
00120                 printf ( "BOFMTEST failed to harvest a MAC address\n" );
00121         }
00122         DBG_HDA ( 0, &bofmtab_harvest, sizeof ( bofmtab_harvest ) );
00123 
00124         /* Perform update test */
00125         printf ( "BOFMTEST performing update\n" );
00126         bofmtab_update.en.busdevfn = pci->busdevfn;
00127         DBG_HDA ( 0, &bofmtab_update, sizeof ( bofmtab_update ) );
00128         bofmrc = bofm ( virt_to_user ( &bofmtab_update ), pci );
00129         printf ( "BOFMTEST update result %08x\n", bofmrc );
00130         if ( bofmtab_update.en.options & BOFM_EN_CSM_SUCCESS ) {
00131                 printf ( "BOFMTEST updated MAC address to %s\n",
00132                          eth_ntoa ( &bofmtab_update.en.mac_a ) );
00133         } else {
00134                 printf ( "BOFMTEST failed to update MAC address\n" );
00135         }
00136         DBG_HDA ( 0, &bofmtab_update, sizeof ( bofmtab_update ) );
00137 }
00138 
00139 /**
00140  * Perform BOFM test at initialisation time
00141  *
00142  */
00143 static void bofm_test_init ( void ) {
00144         struct pci_device pci;
00145         int busdevfn = -1;
00146         int rc;
00147 
00148         /* Uncomment the following line and specify the correct PCI
00149          * bus:dev.fn address in order to perform a BOFM test at
00150          * initialisation time.
00151          */
00152         // busdevfn = PCI_BUSDEVFN ( <bus>, <dev>, <fn> );
00153 
00154         /* Skip test if no PCI bus:dev.fn is defined */
00155         if ( busdevfn < 0 )
00156                 return;
00157 
00158         /* Initialise PCI device */
00159         memset ( &pci, 0, sizeof ( pci ) );
00160         pci_init ( &pci, busdevfn );
00161         if ( ( rc = pci_read_config ( &pci ) ) != 0 ) {
00162                 printf ( "BOFMTEST could not create " PCI_FMT " device: %s\n",
00163                          PCI_ARGS ( &pci ), strerror ( rc ) );
00164                 return;
00165         }
00166 
00167         /* Perform test */
00168         bofm_test ( &pci );
00169 }
00170 
00171 /** BOFM test initialisation function */
00172 struct init_fn bofm_test_init_fn __init_fn ( INIT_NORMAL ) = {
00173         .initialise = bofm_test_init,
00174 };