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 ); }