]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[hermon] Add BOFM support
authorMichael Brown <mcb30@ipxe.org>
Thu, 10 Feb 2011 16:40:56 +0000 (16:40 +0000)
committerMichael Brown <mcb30@ipxe.org>
Thu, 3 Mar 2011 02:40:12 +0000 (02:40 +0000)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/infiniband/MT25408_PRM.h
src/drivers/infiniband/hermon.c
src/drivers/infiniband/hermon.h

index fac39c822f663f1c39da8193eb15291c154bb1ad..cc248daf9ee4670673f4be6d5257dc4beba1cd6b 100644 (file)
@@ -1335,7 +1335,11 @@ struct hermonprm_virtual_physical_mapping_st {   /* Little Endian */
 /* MOD_STAT_CFG            #### michal - gdror fix */
 
 struct hermonprm_mod_stat_cfg_st {     /* Little Endian */
-    pseudo_bit_t       reserved0[0x00010];
+    pseudo_bit_t       log_pg_sz[0x00008];
+    pseudo_bit_t       log_pg_sz_m[0x00001];
+    pseudo_bit_t       reserved0[0x00005];
+    pseudo_bit_t       dife[0x00001];
+    pseudo_bit_t       dife_m[0x00001];
     pseudo_bit_t       rx_options[0x00004];   /* number of RX options to sweep when doing SerDes parameters AutoNegotiation. */
     pseudo_bit_t       reserved1[0x00003];
     pseudo_bit_t       rx_options_m[0x00001]; /* Modify rx_options */
@@ -1343,46 +1347,129 @@ struct hermonprm_mod_stat_cfg_st {     /* Little Endian */
     pseudo_bit_t       reserved2[0x00003];
     pseudo_bit_t       tx_options_m[0x00001]; /* Modify tx_options */
 /* -------------- */
-    pseudo_bit_t       reserved3[0x00020];
+    pseudo_bit_t       reserved3[0x00010];
+    pseudo_bit_t       qdr_rx_options[0x00004];
+    pseudo_bit_t       reserved4[0x00003];
+    pseudo_bit_t       qdr_rx_options_m[0x00001];
+    pseudo_bit_t       qdr_tx_options[0x00004];
+    pseudo_bit_t       reserved5[0x00003];
+    pseudo_bit_t       qdr_tx_options_m[0x00001];
 /* -------------- */
-    pseudo_bit_t       pre_amp[0x00004];      /* Pre Amplitude */
-    pseudo_bit_t       pre_emp_pre_amp[0x00004];
-    pseudo_bit_t       pre_emp_out[0x00004];  /* Pre Emphasis Out */
-    pseudo_bit_t       voltage[0x00004];
-    pseudo_bit_t       equ[0x00004];          /* Equalization */
-    pseudo_bit_t       reserved4[0x0000b];
-    pseudo_bit_t       serdes_m[0x00001];     /* Modify serdes parameters */
+    pseudo_bit_t       reserved6[0x00020];
 /* -------------- */
     pseudo_bit_t       lid[0x00010];          /* default LID */
     pseudo_bit_t       lid_m[0x00001];        /* Modify default LID */
-    pseudo_bit_t       reserved5[0x00003];
+    pseudo_bit_t       reserved7[0x00003];
     pseudo_bit_t       port_en[0x00001];      /* enable port (E_Key) */
     pseudo_bit_t       port_en_m[0x00001];    /* Modify  port_en */
-    pseudo_bit_t       reserved6[0x0000a];
+    pseudo_bit_t       reserved8[0x00002];
+    pseudo_bit_t       port_pause_mode[0x00002];
+    pseudo_bit_t       reserved9[0x00001];
+    pseudo_bit_t       port_pause_mode_m[0x00001];
+    pseudo_bit_t       reserved10[0x00004];
 /* -------------- */
-    pseudo_bit_t       reserved7[0x0001f];
+    pseudo_bit_t       reserved11[0x0001f];
     pseudo_bit_t       guid_hi_m[0x00001];    /* Modify guid_hi */
 /* -------------- */
     pseudo_bit_t       guid_hi[0x00020];
 /* -------------- */
-    pseudo_bit_t       reserved8[0x0001f];
+    pseudo_bit_t       reserved12[0x0001f];
     pseudo_bit_t       guid_lo_m[0x00001];    /* Modify guid_lo */
 /* -------------- */
     pseudo_bit_t       guid_lo[0x00020];
 /* -------------- */
-    pseudo_bit_t       reserved9[0x0001f];
+    pseudo_bit_t       reserved13[0x0001f];
     pseudo_bit_t       nodeguid_hi_m[0x00001];
 /* -------------- */
     pseudo_bit_t       nodeguid_hi[0x00020];
 /* -------------- */
-    pseudo_bit_t       reserved10[0x0001f];
+    pseudo_bit_t       reserved14[0x0001f];
     pseudo_bit_t       nodeguid_lo_m[0x00001];
 /* -------------- */
     pseudo_bit_t       nodeguid_lo[0x00020];
 /* -------------- */
-    pseudo_bit_t       reserved11[0x00680];
+    pseudo_bit_t       ob_preemp_pre[0x00005];
+    pseudo_bit_t       reserved15[0x00003];
+    pseudo_bit_t       ob_preemp_post[0x00005];
+    pseudo_bit_t       reserved16[0x00003];
+    pseudo_bit_t       ob_preemp_main[0x00005];
+    pseudo_bit_t       reserved17[0x00003];
+    pseudo_bit_t       ob_preemp[0x00005];
+    pseudo_bit_t       reserved18[0x00002];
+    pseudo_bit_t       serdes_m[0x00001];
 /* -------------- */
-}; 
+    pseudo_bit_t       inbuf_ind_en[0x00003];
+    pseudo_bit_t       reserved19[0x00001];
+    pseudo_bit_t       sd_main[0x00004];
+    pseudo_bit_t       reserved20[0x00004];
+    pseudo_bit_t       sd_equal[0x00004];
+    pseudo_bit_t       reserved21[0x00004];
+    pseudo_bit_t       sd_mux_main[0x00002];
+    pseudo_bit_t       reserved22[0x00002];
+    pseudo_bit_t       mux_eq[0x00002];
+    pseudo_bit_t       reserved23[0x00002];
+    pseudo_bit_t       sigdet_th[0x00003];
+    pseudo_bit_t       reserved24[0x00001];
+/* -------------- */
+    pseudo_bit_t       reserved25[0x00040];
+/* -------------- */
+    pseudo_bit_t       port_protocol[0x00008];
+    pseudo_bit_t       port_dual[0x00001];
+    pseudo_bit_t       reserved26[0x00006];
+    pseudo_bit_t       port_protocol_m[0x00001];
+    pseudo_bit_t       num_port[0x00008];
+    pseudo_bit_t       reserved27[0x00008];
+/* -------------- */
+    pseudo_bit_t       port_protocol_vpi[0x00008];
+    pseudo_bit_t       reserved28[0x00018];
+/* -------------- */
+    pseudo_bit_t       reserved29[0x00180];
+/* -------------- */
+    pseudo_bit_t       fw_rev_major[0x00010];
+    pseudo_bit_t       reserved30[0x0000f];
+    pseudo_bit_t       fw_rev_support[0x00001];
+/* -------------- */
+    pseudo_bit_t       fw_rev_minor[0x00010];
+    pseudo_bit_t       fw_rev_subminor[0x00010];
+/* -------------- */
+    pseudo_bit_t       cmd_interface_rev[0x00010];
+    pseudo_bit_t       reserved31[0x00010];
+/* -------------- */
+    pseudo_bit_t       reserved32[0x00060];
+/* -------------- */
+    pseudo_bit_t       mac_high[0x00010];
+    pseudo_bit_t       reserved33[0x0000f];
+    pseudo_bit_t       mac_m[0x00001];
+/* -------------- */
+    pseudo_bit_t       mac_low[0x00020];
+/* -------------- */
+    pseudo_bit_t       reserved34[0x00010];
+    pseudo_bit_t       num_veps[0x00008];
+    pseudo_bit_t       num_vep_groups[0x00008];
+/* -------------- */
+    pseudo_bit_t       reserved35[0x00020];
+/* -------------- */
+    pseudo_bit_t       reserved36[0x00018];
+    pseudo_bit_t       outer_vlan_en[0x00001];
+    pseudo_bit_t       reserved37[0x00002];
+    pseudo_bit_t       outer_vlan_en_m[0x00001];
+    pseudo_bit_t       port_net_boot[0x00001];
+    pseudo_bit_t       reserved38[0x00002];
+    pseudo_bit_t       port_net_boot_m[0x00001];
+/* -------------- */
+    pseudo_bit_t       reserved39[0x00060];
+/* -------------- */
+    pseudo_bit_t       port_eth_mode_capability[0x0001f];
+    pseudo_bit_t       reserved40[0x00001];
+/* -------------- */
+    pseudo_bit_t       port_eth_mode_enabled[0x0001f];
+    pseudo_bit_t       port_eth_mod_m[0x00001];
+/* -------------- */
+    pseudo_bit_t       port_eth_mode_current[0x0001f];
+    pseudo_bit_t       reserved41[0x00001];
+/* -------------- */
+    pseudo_bit_t       reserved42[0x00220];
+};
 
 /* SRQ Context */
 
index 011892f2aff6470657e913f55a4321240d454e0e..043f2a686e06dc88accc85e0121913fea73ef55b 100644 (file)
@@ -40,6 +40,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/ethernet.h>
 #include <ipxe/fcoe.h>
 #include <ipxe/vlan.h>
+#include <ipxe/bofm.h>
 #include "hermon.h"
 
 /**
@@ -496,6 +497,17 @@ hermon_cmd_mgid_hash ( struct hermon *hermon, const union ib_gid *gid,
                            0, gid, 0, hash );
 }
 
+static inline int
+hermon_cmd_mod_stat_cfg ( struct hermon *hermon, unsigned int mode,
+                         unsigned int input_mod,
+                         struct hermonprm_scalar_parameter *portion ) {
+       return hermon_cmd ( hermon,
+                           HERMON_HCR_INOUT_CMD ( HERMON_HCR_MOD_STAT_CFG,
+                                                  0, sizeof ( *portion ),
+                                                  0, sizeof ( *portion ) ),
+                           mode, portion, input_mod, portion );
+}
+
 static inline int
 hermon_cmd_query_port ( struct hermon *hermon, unsigned int port,
                        struct hermonprm_query_port_cap *query_port ) {
@@ -682,6 +694,59 @@ static void hermon_free_mtt ( struct hermon *hermon,
                              mtt->num_pages );
 }
 
+/***************************************************************************
+ *
+ * Static configuration operations
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Calculate offset within static configuration
+ *
+ * @v field            Field
+ * @ret offset         Offset
+ */
+#define HERMON_MOD_STAT_CFG_OFFSET( field )                                 \
+       ( ( MLX_BIT_OFFSET ( struct hermonprm_mod_stat_cfg_st, field ) / 8 ) \
+         & ~( sizeof ( struct hermonprm_scalar_parameter ) - 1 ) )
+
+/**
+ * Query or modify static configuration
+ *
+ * @v hermon           Hermon device
+ * @v port             Port
+ * @v mode             Command mode
+ * @v offset           Offset within static configuration
+ * @v stat_cfg         Static configuration
+ * @ret rc             Return status code
+ */
+static int hermon_mod_stat_cfg ( struct hermon *hermon, unsigned int port,
+                                unsigned int mode, unsigned int offset,
+                                struct hermonprm_mod_stat_cfg *stat_cfg ) {
+       struct hermonprm_scalar_parameter *portion =
+               ( ( void * ) &stat_cfg->u.bytes[offset] );
+       struct hermonprm_mod_stat_cfg_input_mod mod;
+       int rc;
+
+       /* Sanity check */
+       assert ( ( offset % sizeof ( *portion ) ) == 0 );
+
+       /* Construct input modifier */
+       memset ( &mod, 0, sizeof ( mod ) );
+       MLX_FILL_2 ( &mod, 0,
+                    portnum, port,
+                    offset, offset );
+
+       /* Issue command */
+       if ( ( rc = hermon_cmd_mod_stat_cfg ( hermon, mode,
+                                             be32_to_cpu ( mod.u.dwords[0] ),
+                                             portion ) ) != 0 )
+               return rc;
+
+       return 0;
+}
+
 /***************************************************************************
  *
  * MAD operations
@@ -3230,6 +3295,103 @@ static void hermon_free_icm ( struct hermon *hermon ) {
        hermon->icm = UNULL;
 }
 
+/***************************************************************************
+ *
+ * BOFM interface
+ *
+ ***************************************************************************
+ */
+
+/**
+ * Harvest 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 hermon_bofm_harvest ( struct bofm_device *bofm, unsigned int mport,
+                                uint8_t *mac ) {
+       struct hermon *hermon = container_of ( bofm, struct hermon, bofm );
+       struct hermonprm_mod_stat_cfg stat_cfg;
+       union {
+               uint8_t bytes[8];
+               uint32_t dwords[2];
+       } buf;
+       int rc;
+
+       /* Query static configuration */
+       if ( ( rc = hermon_mod_stat_cfg ( hermon, mport,
+                                         HERMON_MOD_STAT_CFG_QUERY,
+                                         HERMON_MOD_STAT_CFG_OFFSET ( mac_m ),
+                                         &stat_cfg ) ) != 0 ) {
+               DBGC ( hermon, "Hermon %p port %d could not query "
+                      "configuration: %s\n", hermon, mport, strerror ( rc ) );
+               return rc;
+       }
+
+       /* Retrieve MAC address */
+       buf.dwords[0] = htonl ( MLX_GET ( &stat_cfg, mac_high ) );
+       buf.dwords[1] = htonl ( MLX_GET ( &stat_cfg, mac_low ) );
+       memcpy ( mac, &buf.bytes[ sizeof ( buf.bytes ) - ETH_ALEN ],
+                ETH_ALEN );
+
+       DBGC ( hermon, "Hermon %p port %d harvested MAC address %s\n",
+              hermon, 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 hermon_bofm_update ( struct bofm_device *bofm, unsigned int mport,
+                               const uint8_t *mac ) {
+       struct hermon *hermon = container_of ( bofm, struct hermon, bofm );
+       struct hermonprm_mod_stat_cfg stat_cfg;
+       union {
+               uint8_t bytes[8];
+               uint32_t dwords[2];
+       } buf;
+       int rc;
+
+       /* Prepare MAC address */
+       memset ( &buf, 0, sizeof ( buf ) );
+       memcpy ( &buf.bytes[ sizeof ( buf.bytes ) - ETH_ALEN ], mac,
+                ETH_ALEN );
+
+       /* Modify static configuration */
+       memset ( &stat_cfg, 0, sizeof ( stat_cfg ) );
+       MLX_FILL_2 ( &stat_cfg, 36,
+                    mac_m, 1,
+                    mac_high, ntohl ( buf.dwords[0] ) );
+       MLX_FILL_1 ( &stat_cfg, 37, mac_low, ntohl ( buf.dwords[1] ) );
+       if ( ( rc = hermon_mod_stat_cfg ( hermon, mport,
+                                         HERMON_MOD_STAT_CFG_SET,
+                                         HERMON_MOD_STAT_CFG_OFFSET ( mac_m ),
+                                         &stat_cfg ) ) != 0 ) {
+               DBGC ( hermon, "Hermon %p port %d could not modify "
+                      "configuration: %s\n", hermon, mport, strerror ( rc ) );
+               return rc;
+       }
+
+       DBGC ( hermon, "Hermon %p port %d updated MAC address to %s\n",
+              hermon, mport, eth_ntoa ( mac ) );
+
+       return 0;
+}
+
+/** Hermon BOFM operations */
+static struct bofm_operations hermon_bofm_operations = {
+       .harvest = hermon_bofm_harvest,
+       .update = hermon_bofm_update,
+};
+
 /***************************************************************************
  *
  * PCI interface
@@ -3325,6 +3487,72 @@ static void hermon_reset ( struct hermon *hermon,
        pci_restore ( pci, &backup, backup_exclude );
 }
 
+/**
+ * Allocate Hermon device
+ *
+ * @v pci              PCI device
+ * @v id               PCI ID
+ * @ret rc             Return status code
+ */
+static struct hermon * hermon_alloc ( void ) {
+       struct hermon *hermon;
+
+       /* Allocate Hermon device */
+       hermon = zalloc ( sizeof ( *hermon ) );
+       if ( ! hermon )
+               goto err_hermon;
+
+       /* Allocate space for mailboxes */
+       hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
+                                         HERMON_MBOX_ALIGN );
+       if ( ! hermon->mailbox_in )
+               goto err_mailbox_in;
+       hermon->mailbox_out = malloc_dma ( HERMON_MBOX_SIZE,
+                                          HERMON_MBOX_ALIGN );
+       if ( ! hermon->mailbox_out )
+               goto err_mailbox_out;
+
+       return hermon;
+
+       free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
+ err_mailbox_out:
+       free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
+ err_mailbox_in:
+       free ( hermon );
+ err_hermon:
+       return NULL;
+}
+
+/**
+ * Free Hermon device
+ *
+ * @v hermon           Hermon device
+ */
+static void hermon_free ( struct hermon *hermon ) {
+
+       free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
+       free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
+       free ( hermon );
+}
+
+/**
+ * Initialise Hermon PCI parameters
+ *
+ * @v hermon           Hermon device
+ * @v pci              PCI device
+ */
+static void hermon_pci_init ( struct hermon *hermon, struct pci_device *pci ) {
+
+       /* Fix up PCI device */
+       adjust_pci_device ( pci );
+
+       /* Get PCI BARs */
+       hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR),
+                                  HERMON_PCI_CONFIG_BAR_SIZE );
+       hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
+                               HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
+}
+
 /**
  * Probe PCI device
  *
@@ -3342,39 +3570,19 @@ static int hermon_probe ( struct pci_device *pci ) {
        int rc;
 
        /* Allocate Hermon device */
-       hermon = zalloc ( sizeof ( *hermon ) );
+       hermon = hermon_alloc();
        if ( ! hermon ) {
                rc = -ENOMEM;
-               goto err_alloc_hermon;
+               goto err_alloc;
        }
        pci_set_drvdata ( pci, hermon );
 
-       /* Fix up PCI device */
-       adjust_pci_device ( pci );
-
-       /* Get PCI BARs */
-       hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR),
-                                  HERMON_PCI_CONFIG_BAR_SIZE );
-       hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ),
-                               HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE );
+       /* Initialise PCI parameters */
+       hermon_pci_init ( hermon, pci );
 
        /* Reset device */
        hermon_reset ( hermon, pci );
 
-       /* Allocate space for mailboxes */
-       hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE,
-                                         HERMON_MBOX_ALIGN );
-       if ( ! hermon->mailbox_in ) {
-               rc = -ENOMEM;
-               goto err_mailbox_in;
-       }
-       hermon->mailbox_out = malloc_dma ( HERMON_MBOX_SIZE,
-                                          HERMON_MBOX_ALIGN );
-       if ( ! hermon->mailbox_out ) {
-               rc = -ENOMEM;
-               goto err_mailbox_out;
-       }
-
        /* Start firmware */
        if ( ( rc = hermon_start_firmware ( hermon ) ) != 0 )
                goto err_start_firmware;
@@ -3483,12 +3691,8 @@ static int hermon_probe ( struct pci_device *pci ) {
  err_get_cap:
        hermon_stop_firmware ( hermon );
  err_start_firmware:
-       free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
- err_mailbox_out:
-       free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
- err_mailbox_in:
-       free ( hermon );
- err_alloc_hermon:
+       hermon_free ( hermon );
+ err_alloc:
        return rc;
 }
 
@@ -3511,15 +3715,65 @@ static void hermon_remove ( struct pci_device *pci ) {
        hermon_free_icm ( hermon );
        hermon_stop_firmware ( hermon );
        hermon_stop_firmware ( hermon );
-       free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE );
-       free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE );
        for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- ) {
                netdev_nullify ( hermon->port[i].netdev );
                netdev_put ( hermon->port[i].netdev );
        }
        for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- )
                ibdev_put ( hermon->port[i].ibdev );
-       free ( hermon );
+       hermon_free ( hermon );
+}
+
+/**
+ * Probe PCI device for BOFM
+ *
+ * @v pci              PCI device
+ * @v id               PCI ID
+ * @ret rc             Return status code
+ */
+static int hermon_bofm_probe ( struct pci_device *pci ) {
+       struct hermon *hermon;
+       int rc;
+
+       /* Allocate Hermon device */
+       hermon = hermon_alloc();
+       if ( ! hermon ) {
+               rc = -ENOMEM;
+               goto err_alloc;
+       }
+       pci_set_drvdata ( pci, hermon );
+
+       /* Initialise PCI parameters */
+       hermon_pci_init ( hermon, pci );
+
+       /* Initialise BOFM device */
+       bofm_init ( &hermon->bofm, pci, &hermon_bofm_operations );
+
+       /* Register BOFM device */
+       if ( ( rc = bofm_register ( &hermon->bofm ) ) != 0 ) {
+               DBGC ( hermon, "Hermon %p could not register BOFM device: "
+                      "%s\n", hermon, strerror ( rc ) );
+               goto err_bofm_register;
+       }
+
+       return 0;
+
+ err_bofm_register:
+       hermon_free ( hermon );
+ err_alloc:
+       return rc;
+}
+
+/**
+ * Remove PCI device for BOFM
+ *
+ * @v pci              PCI device
+ */
+static void hermon_bofm_remove ( struct pci_device *pci ) {
+       struct hermon *hermon = pci_get_drvdata ( pci );
+
+       bofm_unregister ( &hermon->bofm );
+       hermon_free ( hermon );
 }
 
 static struct pci_device_id hermon_nics[] = {
@@ -3543,3 +3797,10 @@ struct pci_driver hermon_driver __pci_driver = {
        .probe = hermon_probe,
        .remove = hermon_remove,
 };
+
+struct pci_driver hermon_bofm_driver __bofm_driver = {
+       .ids = hermon_nics,
+       .id_count = ( sizeof ( hermon_nics ) / sizeof ( hermon_nics[0] ) ),
+       .probe = hermon_bofm_probe,
+       .remove = hermon_bofm_remove,
+};
index ca343f7aaf96d1fdf508c70e71855d541f9cb5ac..1c862303529cc2f0d23c1a48764acd393184702a 100644 (file)
@@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <stdint.h>
 #include <ipxe/uaccess.h>
 #include <ipxe/ib_packet.h>
+#include <ipxe/bofm.h>
 #include "mlx_bitops.h"
 #include "MT25408_PRM.h"
 
@@ -131,6 +132,9 @@ FILE_LICENCE ( GPL2_OR_LATER );
 
 #define HERMON_RETRY_MAX               0x07
 
+#define HERMON_MOD_STAT_CFG_SET                0x01
+#define HERMON_MOD_STAT_CFG_QUERY      0x03
+
 /*
  * Datatypes that seem to be missing from the autogenerated documentation
  *
@@ -417,13 +421,14 @@ struct hermonprm_set_port_vlan_st {
 /* -------------- */
 } __attribute__ (( packed ));
 
-struct hermonprm_mod_stat_cfg_pf_net_boot_st {
-       pseudo_bit_t reserved1[0x0001c];
-       pseudo_bit_t pf_net_boot[0x00001];
-       pseudo_bit_t reserved2[0x00002];
-       pseudo_bit_t pf_net_boot_m[0x00001];
-/* -------------- */
-       pseudo_bit_t reserved0[0x00020];
+struct hermonprm_mod_stat_cfg_input_mod_st {
+       pseudo_bit_t offset[0x00008];
+       pseudo_bit_t portnum[0x00008];
+       pseudo_bit_t xnum[0x00004];
+       pseudo_bit_t linkspeed[0x00003];
+       pseudo_bit_t autoneg[0x00001];
+       pseudo_bit_t reserved[0x00004];
+       pseudo_bit_t setup_mode[0x00004];
 } __attribute__ (( packed ));
 
 /*
@@ -444,7 +449,8 @@ struct MLX_DECLARE_STRUCT ( hermonprm_init_hca );
 struct MLX_DECLARE_STRUCT ( hermonprm_mad_ifc );
 struct MLX_DECLARE_STRUCT ( hermonprm_mcg_entry );
 struct MLX_DECLARE_STRUCT ( hermonprm_mgm_hash );
-struct MLX_DECLARE_STRUCT ( hermonprm_mod_stat_cfg_pf_net_boot );
+struct MLX_DECLARE_STRUCT ( hermonprm_mod_stat_cfg );
+struct MLX_DECLARE_STRUCT ( hermonprm_mod_stat_cfg_input_mod );
 struct MLX_DECLARE_STRUCT ( hermonprm_mpt );
 struct MLX_DECLARE_STRUCT ( hermonprm_mtt );
 struct MLX_DECLARE_STRUCT ( hermonprm_port_state_change_event );
@@ -866,6 +872,9 @@ struct hermon {
 
        /** Ports */
        struct hermon_port port[HERMON_MAX_PORTS];
+
+       /** BOFM device */
+       struct bofm_device bofm;
 };
 
 /** Global protection domain */