From: Michael Brown Date: Tue, 29 Apr 2025 12:39:12 +0000 (+0100) Subject: [bofm] Allow BOFM tests to be run without a BOFM-capable device driver X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=08007238456b7349a16c67b2cc76a10368734fea;p=thirdparty%2Fipxe.git [bofm] Allow BOFM tests to be run without a BOFM-capable device driver The BOFM tests are not part of the standard unit test suite, since they are designed to allow for exercising real BOFM driver code outside of the context of a real IBM blade server. Allow for the BOFM tests to be run without a real BOFM driver, by providing a dummy driver for the specified PCI test device. Signed-off-by: Michael Brown --- diff --git a/src/include/ipxe/bofm.h b/src/include/ipxe/bofm.h index bc994ea8b..816effd4d 100644 --- a/src/include/ipxe/bofm.h +++ b/src/include/ipxe/bofm.h @@ -328,6 +328,9 @@ struct bofm_operations { #define __bofm_driver #endif +/** Declare a BOFM test driver */ +#define __bofm_test_driver __table_entry ( BOFM_DRIVERS, 02 ) + /** * Initialise BOFM device * diff --git a/src/tests/bofm_test.c b/src/tests/bofm_test.c index dbef1eb90..6d472bc7e 100644 --- a/src/tests/bofm_test.c +++ b/src/tests/bofm_test.c @@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include #include #include #include @@ -135,6 +136,109 @@ void bofm_test ( struct pci_device *pci ) { DBG_HDA ( 0, &bofmtab_update, sizeof ( bofmtab_update ) ); } +/** + * Harvest dummy Ethernet MAC + * + * @v bofm BOFM device + * @v mport Multi-port index + * @v mac MAC to fill in + * @ret rc Return status code + */ +static int bofm_dummy_harvest ( struct bofm_device *bofm, unsigned int mport, + uint8_t *mac ) { + struct { + uint16_t vendor; + uint16_t device; + uint16_t mport; + } __attribute__ (( packed )) dummy_mac; + + /* Construct dummy MAC address */ + dummy_mac.vendor = cpu_to_be16 ( bofm->pci->vendor ); + dummy_mac.device = cpu_to_be16 ( bofm->pci->device ); + dummy_mac.mport = cpu_to_be16 ( mport ); + memcpy ( mac, &dummy_mac, sizeof ( dummy_mac ) ); + printf ( "BOFMTEST mport %d constructed dummy MAC %s\n", + mport, eth_ntoa ( mac ) ); + + return 0; +} + +/** + * Update Ethernet MAC for BOFM + * + * @v bofm BOFM device + * @v mport Multi-port index + * @v mac MAC to fill in + * @ret rc Return status code + */ +static int bofm_dummy_update ( struct bofm_device *bofm __unused, + unsigned int mport, const uint8_t *mac ) { + + printf ( "BOFMTEST mport %d asked to update MAC to %s\n", + mport, eth_ntoa ( mac ) ); + return 0; +} + +/** Dummy BOFM operations */ +static struct bofm_operations bofm_dummy_operations = { + .harvest = bofm_dummy_harvest, + .update = bofm_dummy_update, +}; + +/** Dummy BOFM device */ +static struct bofm_device bofm_dummy; + +/** + * Probe dummy BOFM device + * + * @v pci PCI device + * @v id PCI ID + * @ret rc Return status code + */ +static int bofm_dummy_probe ( struct pci_device *pci ) { + int rc; + + /* Ignore probe for any other devices */ + if ( pci->busdevfn != bofm_dummy.pci->busdevfn ) + return 0; + + /* Register BOFM device */ + if ( ( rc = bofm_register ( &bofm_dummy ) ) != 0 ) + return rc; + + printf ( "BOFMTEST using dummy BOFM driver\n" ); + return 0; +} + +/** + * Remove dummy BOFM device + * + * @v pci PCI device + */ +static void bofm_dummy_remove ( struct pci_device *pci ) { + + /* Ignore removal for any other devices */ + if ( pci->busdevfn != bofm_dummy.pci->busdevfn ) + return; + + /* Unregister BOFM device */ + bofm_unregister ( &bofm_dummy ); +} + +/** Dummy BOFM driver PCI IDs */ +static struct pci_device_id bofm_dummy_ids[1] = { + { .name = "dummy" }, +}; + +/** Dummy BOFM driver */ +struct pci_driver bofm_dummy_driver __bofm_test_driver = { + .ids = bofm_dummy_ids, + .id_count = ( sizeof ( bofm_dummy_ids ) / + sizeof ( bofm_dummy_ids[0] ) ), + .probe = bofm_dummy_probe, + .remove = bofm_dummy_remove, +}; + /** * Perform BOFM test at initialisation time * @@ -148,7 +252,7 @@ static void bofm_test_init ( void ) { * bus:dev.fn address in order to perform a BOFM test at * initialisation time. */ - // busdevfn = PCI_BUSDEVFN ( , , ); + // busdevfn = PCI_BUSDEVFN ( , , , ); /* Skip test if no PCI bus:dev.fn is defined */ if ( busdevfn < 0 ) @@ -163,6 +267,11 @@ static void bofm_test_init ( void ) { return; } + /* Initialise dummy BOFM device */ + bofm_init ( &bofm_dummy, &pci, &bofm_dummy_operations ); + bofm_dummy_ids[0].vendor = pci.vendor; + bofm_dummy_ids[0].device = pci.device; + /* Perform test */ bofm_test ( &pci ); }