iPXE
Data Structures | Defines | Functions
bofm.h File Reference

IBM BladeCenter Open Fabric Manager (BOFM) More...

#include <stdint.h>
#include <ipxe/list.h>
#include <ipxe/pci.h>
#include <config/sideband.h>

Go to the source code of this file.

Data Structures

struct  bofm_global_header
 BOFM table header. More...
struct  bofm_section_header
 BOFM section header. More...
struct  bofm_en
 BOFM Ethernet parameter entry. More...
struct  bofm_device
 A BOFM device. More...
struct  bofm_operations
 BOFM device operations. More...

Defines

#define IBMs_SIGNATURE   ( ( 'I' << 24 ) + ( 'B' << 16 ) + ( 'M' << 8 ) + ' ' )
 'IBM ' signature
#define sIBM_SIGNATURE   ( ( ' ' << 24 ) + ( 'I' << 16 ) + ( 'B' << 8 ) + 'M' )
 ' IBM' signature
#define BOFM_SUCCESS   0x00
 Successful.
#define BOFM_ERR_INVALID_ACTION   0x01
 Invalid action string.
#define BOFM_ERR_UNSUPPORTED   0x02
 Unsupported parameter structure version.
#define BOFM_ERR_DEVICE_ERROR   0x03
 Device error prohibited MAC/WWN update.
#define BOFM_PCI_RESET   0x80
 PCI reset required (may be combined with another return code)
#define BOFM_SKIP_INIT   0x80000000UL
 Skip option ROM initialisation.
#define BOFM_IOAA_MAGIC   ( 'I' + ( 'O' << 8 ) + ( 'A' << 16 ) + ( 'A' << 24 ) )
 BOFM table header signature.
#define BOFM_ACTION_UPDT   ( 'U' + ( 'P' << 8 ) + ( 'D' << 16 ) + ( 'T' << 24 ) )
 Update MAC/WWN.
#define BOFM_ACTION_DFLT   ( 'D' + ( 'F' << 8 ) + ( 'L' << 16 ) + ( 'T' << 24 ) )
 Restore MAC/WWN to factory default.
#define BOFM_ACTION_HVST   ( 'H' + ( 'V' << 8 ) + ( 'S' << 16 ) + ( 'T' << 24 ) )
 Harvest MAC/WWN.
#define BOFM_ACTION_PARM   ( 'P' + ( 'A' << 8 ) + ( 'R' << 16 ) + ( 'M' << 24 ) )
 Update MAC/WWN and initialise device.
#define BOFM_ACTION_NONE   ( 'N' + ( 'O' << 8 ) + ( 'N' << 16 ) + ( 'E' << 24 ) )
 Just initialise the device.
#define BOFM_EN_MAGIC   ( ' ' + ( ' ' << 8 ) + ( 'E' << 16 ) + ( 'N' << 24 ) )
 EN start marker.
#define BOFM_DONE_MAGIC   ( 'D' + ( 'O' << 8 ) + ( 'N' << 16 ) + ( 'E' << 24 ) )
 End marker.
#define BOFM_EN_MAP_MASK   0x0001
 Port mapping mask.
#define BOFM_EN_MAP_PFA   0x0000
 Port mapping is by PCI bus:dev.fn.
#define BOFM_EN_MAP_SLOT_PORT   0x0001
 Port mapping is by slot/port.
#define BOFM_EN_EN_B   0x0002
 MAC address B is present.
#define BOFM_EN_VLAN_B   0x0004
 VLAN tag for MAC address B is present.
#define BOFM_EN_EN_A   0x0008
 MAC address A is present.
#define BOFM_EN_VLAN_A   0x0010
 VLAN tag for MAC address A is present.
#define BOFM_EN_CSM_MASK   0x00c0
 Entry consumption indicator mask.
#define BOFM_EN_CSM_UNUSED   0x0000
 Entry has not been used.
#define BOFM_EN_CSM_SUCCESS   0x0040
 Entry has been used successfully.
#define BOFM_EN_CSM_FAILED   0x0080
 Entry has been used but failed.
#define BOFM_EN_CHG_MASK   0x0100
 Consumed entry change mask.
#define BOFM_EN_CHG_UNCHANGED   0x0000
 Consumed entry is same as previous active entry.
#define BOFM_EN_CHG_CHANGED   0x0100
 Consumed entry is different than previous active entry.
#define BOFM_EN_USAGE_HARVEST   0x1000
 Ignore values - it's harvest time.
#define BOFM_EN_USAGE_ENTRY   0x0800
 Use entry values for assignment.
#define BOFM_EN_USAGE_DEFAULT   0x0400
 Use factory default values.
#define BOFM_EN_HVST   0x2000
 Harvest complete.
#define BOFM_EN_RQ_HVST_MASK   0xc000
 Harvest request mask.
#define BOFM_EN_RQ_HVST_NONE   0x0000
 Do not harvest.
#define BOFM_EN_RQ_HVST_DEFAULT   0x4000
 Harvest factory default values.
#define BOFM_EN_RQ_HVST_ACTIVE   0xc000
 Harvest active values.
#define BOFM_MAGIC_FMT   "'%c%c%c%c'"
 BOFM magic value debug message format.
#define BOFM_MAGIC_ARGS(magic)
 BOFM magic value debug message arguments.
#define BOFM_DRIVERS   __table ( struct pci_driver, "bofm_drivers" )
 BOFM driver table.
#define __bofm_driver
 Declare a BOFM driver.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static void bofm_init (struct bofm_device *bofm, struct pci_device *pci, struct bofm_operations *op)
 Initialise BOFM device.
int bofm_register (struct bofm_device *bofm)
 Register BOFM device.
void bofm_unregister (struct bofm_device *bofm)
 Unregister BOFM device.
int bofm_find_driver (struct pci_device *pci)
 Find BOFM driver for PCI device.
int bofm (userptr_t bofmtab, struct pci_device *pci)
 Process BOFM table.
void bofm_test (struct pci_device *pci)
 Perform BOFM test.

Detailed Description

IBM BladeCenter Open Fabric Manager (BOFM)

Definition in file bofm.h.


Define Documentation

#define IBMs_SIGNATURE   ( ( 'I' << 24 ) + ( 'B' << 16 ) + ( 'M' << 8 ) + ' ' )

'IBM ' signature

Present in edi when the BIOS initialisation entry point is called, with the BOFM table pointer in esi.

Defined in section 4.1.2 of the POST/BIOS BOFM I/O Address Re-Assignment Architecture document.

Definition at line 26 of file bofm.h.

#define sIBM_SIGNATURE   ( ( ' ' << 24 ) + ( 'I' << 16 ) + ( 'B' << 8 ) + 'M' )

' IBM' signature

Returned in edi from the BIOS initialisation entry point, with the return code in dl.

Defined in section 4.1.2 of the POST/BIOS BOFM I/O Address Re-Assignment Architecture document.

Definition at line 36 of file bofm.h.

#define BOFM_SKIP_INIT   0x80000000UL

Skip option ROM initialisation.

A BOFM BIOS may call the initialisation entry point multiple times; only the last call should result in actual initialisation.

This flag is internal to iPXE.

Definition at line 70 of file bofm.h.

Referenced by bofm().

#define BOFM_IOAA_MAGIC   ( 'I' + ( 'O' << 8 ) + ( 'A' << 16 ) + ( 'A' << 24 ) )

BOFM table header signature.

Defined in section 4.1.2 of the POST/BIOS BOFM I/O Address Re-Assignment Architecture document.

Definition at line 103 of file bofm.h.

Referenced by bofm().

#define BOFM_MAGIC_FMT   "'%c%c%c%c'"

BOFM magic value debug message format.

Definition at line 278 of file bofm.h.

Referenced by bofm().

#define BOFM_MAGIC_ARGS (   magic)
Value:
( ( (magic) >> 0 ) & 0xff ), ( ( (magic) >> 8 ) & 0xff ),       \
        ( ( (magic) >> 16 ) & 0xff ), ( ( (magic) >> 24 ) & 0xff )

BOFM magic value debug message arguments.

Definition at line 281 of file bofm.h.

Referenced by bofm().

#define BOFM_DRIVERS   __table ( struct pci_driver, "bofm_drivers" )

BOFM driver table.

Definition at line 318 of file bofm.h.

Referenced by bofm_find_driver().

#define __bofm_driver

Declare a BOFM driver.

In the common case of non-BOFM-enabled builds, allow any BOFM code to be garbage-collected at link time to save space.

Definition at line 328 of file bofm.h.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static void bofm_init ( struct bofm_device bofm,
struct pci_device pci,
struct bofm_operations op 
) [inline, static]

Initialise BOFM device.

Parameters:
bofmBOFM device
pciPCI device
opBOFM device operations

Definition at line 339 of file bofm.h.

References op, and bofm_device::pci.

Referenced by hermon_bofm_probe().

                                         {
        bofm->pci = pci;
        bofm->op = op;
}
int bofm_register ( struct bofm_device bofm)

Register BOFM device.

Parameters:
bofmBOFM device
Return values:
rcReturn status code

Definition at line 49 of file bofm.c.

References DBG, pci_device::id, bofm_device::list, list_add, pci_device_id::name, bofm_device::pci, PCI_ARGS, and PCI_FMT.

Referenced by hermon_bofm_probe().

                                               {

        list_add ( &bofm->list, &bofmdevs );
        DBG ( "BOFM: " PCI_FMT " registered using driver \"%s\"\n",
              PCI_ARGS ( bofm->pci ), bofm->pci->id->name );
        return 0;
}
void bofm_unregister ( struct bofm_device bofm)

Unregister BOFM device.

Parameters:
bofmBOFM device

Definition at line 62 of file bofm.c.

References DBG, bofm_device::list, list_del, bofm_device::pci, PCI_ARGS, and PCI_FMT.

Referenced by hermon_bofm_remove().

                                                  {

        list_del ( &bofm->list );
        DBG ( "BOFM: " PCI_FMT " unregistered\n", PCI_ARGS ( bofm->pci ) );
}
int bofm_find_driver ( struct pci_device pci)

Find BOFM driver for PCI device.

Parameters:
pciPCI device
Return values:
rcReturn status code

Definition at line 90 of file bofm.c.

References BOFM_DRIVERS, pci_device_id::device, pci_device::device, driver, ENOENT, for_each_table_entry, id, pci_driver::id_count, pci_driver::ids, pci_set_driver(), pci_device_id::vendor, and pci_device::vendor.

Referenced by bofm(), and efi_bofm_supported().

                                                {
        struct pci_driver *driver;
        struct pci_device_id *id;
        unsigned int i;

        for_each_table_entry ( driver, BOFM_DRIVERS ) {
                for ( i = 0 ; i < driver->id_count ; i++ ) {
                        id = &driver->ids[i];
                        if ( ( id->vendor == pci->vendor ) &&
                             ( id->device == pci->device ) ) {
                                pci_set_driver ( pci, driver, id );
                                return 0;
                        }
                }
        }
        return -ENOENT;
}
int bofm ( userptr_t  bofmtab,
struct pci_device pci 
)

Process BOFM table.

Parameters:
bofmtabBOFM table
pciPCI device
Return values:
bofmrcBOFM return status

Definition at line 238 of file bofm.c.

References bofm_global_header::action, bofm(), BOFM_ACTION_DFLT, BOFM_ACTION_HVST, BOFM_ACTION_NONE, BOFM_ACTION_PARM, BOFM_ACTION_UPDT, BOFM_EN_CSM_FAILED, BOFM_EN_CSM_SUCCESS, BOFM_EN_MAGIC, BOFM_EN_MAP_MASK, BOFM_EN_MAP_PFA, BOFM_ERR_DEVICE_ERROR, BOFM_ERR_INVALID_ACTION, bofm_find_busdevfn(), bofm_find_driver(), BOFM_IOAA_MAGIC, bofm_locate_section(), BOFM_MAGIC_ARGS, BOFM_MAGIC_FMT, bofm_probe(), bofm_remove(), BOFM_SKIP_INIT, BOFM_SUCCESS, bofm_en::busdevfn, copy_from_user(), copy_to_user(), DBG, DBG2, DBG2_HDA, en, bofm_global_header::length, bofm_section_header::length, bofm_global_header::magic, bofm_en::mport, bofm_en::options, PCI_ARGS, PCI_BUS, PCI_FMT, PCI_FUNC, PCI_SLOT, bofm_en::port, bofm_global_header::profile, rc, and bofm_en::slot.

Referenced by bofm(), bofm_find_busdevfn(), bofm_test(), and efi_bofm_start().

                                                       {
        struct bofm_global_header bofmhdr;
        struct bofm_section_header bofmsec;
        struct bofm_en en;
        struct bofm_device *bofm;
        size_t en_region_offset;
        size_t en_offset;
        int skip;
        int rc;
        int bofmrc;

        /* Read BOFM structure */
        copy_from_user ( &bofmhdr, bofmtab, 0, sizeof ( bofmhdr ) );
        if ( bofmhdr.magic != BOFM_IOAA_MAGIC ) {
                DBG ( "BOFM: invalid table signature " BOFM_MAGIC_FMT "\n",
                      BOFM_MAGIC_ARGS ( bofmhdr.magic ) );
                bofmrc = BOFM_ERR_INVALID_ACTION;
                goto err_bad_signature;
        }
        DBG ( "BOFM: " BOFM_MAGIC_FMT " (profile \"%s\")\n",
              BOFM_MAGIC_ARGS ( bofmhdr.action ), bofmhdr.profile );

        /* Determine whether or not we should skip normal POST
         * initialisation.
         */
        switch ( bofmhdr.action ) {
        case BOFM_ACTION_UPDT:
        case BOFM_ACTION_DFLT:
        case BOFM_ACTION_HVST:
                skip = BOFM_SKIP_INIT;
                break;
        case BOFM_ACTION_PARM:
        case BOFM_ACTION_NONE:
                skip = 0;
                break;
        default:
                DBG ( "BOFM: invalid action " BOFM_MAGIC_FMT "\n",
                      BOFM_MAGIC_ARGS ( bofmhdr.action ) );
                bofmrc = BOFM_ERR_INVALID_ACTION;
                goto err_bad_action;
        }

        /* Find BOFM driver */
        if ( ( rc = bofm_find_driver ( pci ) ) != 0 ) {
                DBG ( "BOFM: " PCI_FMT " has no driver\n", PCI_ARGS ( pci ) );
                bofmrc = BOFM_ERR_DEVICE_ERROR;
                goto err_find_driver;
        }

        /* Probe driver for PCI device */
        if ( ( rc = bofm_probe ( pci ) ) != 0 ) {
                bofmrc = BOFM_ERR_DEVICE_ERROR;
                goto err_probe;
        }

        /* Locate EN section, if present */
        en_region_offset = bofm_locate_section ( bofmtab, bofmhdr.length,
                                                 BOFM_EN_MAGIC, &bofmsec );
        if ( ! en_region_offset ) {
                DBG ( "BOFM: No EN section found\n" );
                bofmrc = ( BOFM_SUCCESS | skip );
                goto err_no_en_section;
        }

        /* Iterate through EN entries */
        for ( en_offset = ( en_region_offset + sizeof ( bofmsec ) ) ;
              en_offset < ( en_region_offset + sizeof ( bofmsec ) +
                            bofmsec.length ) ; en_offset += sizeof ( en ) ) {
                copy_from_user ( &en, bofmtab, en_offset, sizeof ( en ) );
                DBG2 ( "BOFM: EN entry found:\n" );
                DBG2_HDA ( en_offset, &en, sizeof ( en ) );
                if ( ( en.options & BOFM_EN_MAP_MASK ) != BOFM_EN_MAP_PFA ) {
                        DBG ( "BOFM: slot %d port %d has no PCI mapping\n",
                              en.slot, ( en.port + 1 ) );
                        continue;
                }
                DBG ( "BOFM: slot %d port %d%s is " PCI_FMT " mport %d\n",
                      en.slot, ( en.port + 1 ),
                      ( ( en.slot || en.port ) ? "" : "(?)" ), 0,
                      PCI_BUS ( en.busdevfn ), PCI_SLOT ( en.busdevfn ),
                      PCI_FUNC ( en.busdevfn ), en.mport );
                bofm = bofm_find_busdevfn ( en.busdevfn );
                if ( ! bofm ) {
                        DBG ( "BOFM: " PCI_FMT " mport %d ignored\n", 0,
                              PCI_BUS ( en.busdevfn ), PCI_SLOT ( en.busdevfn ),
                              PCI_FUNC ( en.busdevfn ), en.mport );
                        continue;
                }
                if ( ( rc = bofm_en ( bofm, &en ) ) == 0 ) {
                        en.options |= BOFM_EN_CSM_SUCCESS;
                } else {
                        en.options |= BOFM_EN_CSM_FAILED;
                }
                DBG2 ( "BOFM: EN entry after processing:\n" );
                DBG2_HDA ( en_offset, &en, sizeof ( en ) );
                copy_to_user ( bofmtab, en_offset, &en, sizeof ( en ) );
        }

        bofmrc = ( BOFM_SUCCESS | skip );

 err_no_en_section:
        bofm_remove ( pci );
 err_probe:
 err_find_driver:
 err_bad_action:
 err_bad_signature:
        return bofmrc;
}
void bofm_test ( struct pci_device pci)

Perform BOFM test.

Parameters:
pciPCI device

Definition at line 105 of file bofm_test.c.

References bofm(), BOFM_EN_CSM_SUCCESS, BOFM_EN_HVST, pci_device::busdevfn, DBG_HDA, eth_ntoa(), PCI_ARGS, PCI_FMT, printf(), and virt_to_user().

Referenced by bofm_test_init().

                                          {
        int bofmrc;

        printf ( "BOFMTEST using " PCI_FMT "\n", PCI_ARGS ( pci ) );

        /* Perform harvest test */
        printf ( "BOFMTEST performing harvest\n" );
        bofmtab_harvest.en.busdevfn = pci->busdevfn;
        DBG_HDA ( 0, &bofmtab_harvest, sizeof ( bofmtab_harvest ) );
        bofmrc = bofm ( virt_to_user ( &bofmtab_harvest ), pci );
        printf ( "BOFMTEST harvest result %08x\n", bofmrc );
        if ( bofmtab_harvest.en.options & BOFM_EN_HVST ) {
                printf ( "BOFMTEST harvested MAC address %s\n",
                         eth_ntoa ( &bofmtab_harvest.en.mac_a ) );
        } else {
                printf ( "BOFMTEST failed to harvest a MAC address\n" );
        }
        DBG_HDA ( 0, &bofmtab_harvest, sizeof ( bofmtab_harvest ) );

        /* Perform update test */
        printf ( "BOFMTEST performing update\n" );
        bofmtab_update.en.busdevfn = pci->busdevfn;
        DBG_HDA ( 0, &bofmtab_update, sizeof ( bofmtab_update ) );
        bofmrc = bofm ( virt_to_user ( &bofmtab_update ), pci );
        printf ( "BOFMTEST update result %08x\n", bofmrc );
        if ( bofmtab_update.en.options & BOFM_EN_CSM_SUCCESS ) {
                printf ( "BOFMTEST updated MAC address to %s\n",
                         eth_ntoa ( &bofmtab_update.en.mac_a ) );
        } else {
                printf ( "BOFMTEST failed to update MAC address\n" );
        }
        DBG_HDA ( 0, &bofmtab_update, sizeof ( bofmtab_update ) );
}