summaryrefslogtreecommitdiffstats
path: root/src/drivers/infiniband
diff options
context:
space:
mode:
authorRaed Salem2016-12-08 10:01:51 +0100
committerMichael Brown2016-12-08 10:35:52 +0100
commit26050fd4c87c50503d5bd573b2ec91703676e211 (patch)
tree51dac8a878d188803b1d76d7a0f150656f466ed3 /src/drivers/infiniband
parent[efi] Work around temporal anomaly encountered during ExitBootServices() (diff)
downloadipxe-26050fd4c87c50503d5bd573b2ec91703676e211.tar.gz
ipxe-26050fd4c87c50503d5bd573b2ec91703676e211.tar.xz
ipxe-26050fd4c87c50503d5bd573b2ec91703676e211.zip
[golan] Update Connect-IB, ConnectX-4 and ConnectX-4 Lx (Infiniband) support
Updates: - Nodnic: Support for arm cq doorbell via the UAR BAR - Ensure hardware is quiescent when no interface is open - WinPE WA - Support for clear interrupt via BAR - Nodnic: Support for send TX doorbells via the UAR BAR - Added ConnectX-5EX device - Added ConnectX-5 device Signed-off-by: Raed Salem <raeds@mellanox.com> Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/infiniband')
-rw-r--r--src/drivers/infiniband/flexboot_nodnic.c166
-rw-r--r--src/drivers/infiniband/flexboot_nodnic.h28
-rwxr-xr-xsrc/drivers/infiniband/golan.c206
-rwxr-xr-xsrc/drivers/infiniband/golan.h8
-rw-r--r--src/drivers/infiniband/mlx_nodnic/include/mlx_nodnic_data_structures.h32
-rw-r--r--src/drivers/infiniband/mlx_nodnic/include/mlx_port.h13
-rw-r--r--src/drivers/infiniband/mlx_nodnic/src/mlx_device.c34
-rw-r--r--src/drivers/infiniband/mlx_nodnic/src/mlx_port.c354
-rw-r--r--src/drivers/infiniband/mlx_utils/include/private/mlx_pci_priv.h5
-rw-r--r--src/drivers/infiniband/mlx_utils/include/public/mlx_logging.h1
-rw-r--r--src/drivers/infiniband/mlx_utils/include/public/mlx_pci.h5
-rw-r--r--src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h5
-rw-r--r--src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.c7
-rw-r--r--src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h16
-rw-r--r--src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.c30
-rw-r--r--src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h6
-rw-r--r--src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h94
-rw-r--r--src/drivers/infiniband/mlx_utils/src/public/mlx_icmd.c2
-rw-r--r--src/drivers/infiniband/mlx_utils/src/public/mlx_pci.c16
-rw-r--r--src/drivers/infiniband/mlx_utils/src/public/mlx_utils.c5
-rw-r--r--src/drivers/infiniband/mlx_utils_flexboot/include/mlx_logging_priv.h5
-rw-r--r--src/drivers/infiniband/mlx_utils_flexboot/include/mlx_types_priv.h2
-rw-r--r--src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c13
23 files changed, 901 insertions, 152 deletions
diff --git a/src/drivers/infiniband/flexboot_nodnic.c b/src/drivers/infiniband/flexboot_nodnic.c
index dea19ca6..1ee10f54 100644
--- a/src/drivers/infiniband/flexboot_nodnic.c
+++ b/src/drivers/infiniband/flexboot_nodnic.c
@@ -22,7 +22,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
-#include <byteswap.h>
#include <ipxe/pci.h>
#include <ipxe/malloc.h>
#include <ipxe/umalloc.h>
@@ -31,10 +30,6 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/vlan.h>
#include <ipxe/io.h>
#include "flexboot_nodnic.h"
-#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
-#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h"
-#include "mlx_utils/include/public/mlx_pci_gw.h"
-#include "mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.h"
#include "mlx_utils/include/public/mlx_types.h"
#include "mlx_utils/include/public/mlx_utils.h"
#include "mlx_utils/include/public/mlx_bail.h"
@@ -43,6 +38,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include "mlx_utils/include/public/mlx_pci.h"
#include "mlx_nodnic/include/mlx_device.h"
#include "mlx_nodnic/include/mlx_port.h"
+#include <byteswap.h>
+#include <usr/ifmgmt.h>
+#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
+#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h"
+#include "mlx_utils/include/public/mlx_pci_gw.h"
+#include "mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.h"
/***************************************************************************
*
@@ -52,10 +53,27 @@ FILE_LICENCE ( GPL2_OR_LATER );
*/
static int flexboot_nodnic_arm_cq ( struct flexboot_nodnic_port *port ) {
#ifndef DEVICE_CX3
- mlx_uint32 val = ( port->eth_cq->next_idx & 0xffff );
- if ( nodnic_port_set ( & port->port_priv, nodnic_port_option_arm_cq, val ) ) {
- MLX_DEBUG_ERROR( port->port_priv.device, "Failed to arm the CQ\n" );
- return MLX_FAILED;
+ mlx_uint32 val32 = 0;
+ union arm_cq_uar cq_uar;
+
+#define ARM_CQ_UAR_CQ_CI_MASK 0xffffff
+#define ARM_CQ_UAR_CMDSN_MASK 3
+#define ARM_CQ_UAR_CMDSN_OFFSET 28
+#define ARM_CQ_UAR_CQ_CI_OFFSET 0x20
+ if ( port->port_priv.device->device_cap.support_bar_cq_ctrl ) {
+ cq_uar.dword[0] = cpu_to_be32((port->eth_cq->next_idx & ARM_CQ_UAR_CQ_CI_MASK) |
+ ((port->cmdsn++ & ARM_CQ_UAR_CMDSN_MASK) << ARM_CQ_UAR_CMDSN_OFFSET));
+ cq_uar.dword[1] = cpu_to_be32(port->eth_cq->cqn);
+ wmb();
+ writeq(cq_uar.qword, port->port_priv.device->uar.virt + ARM_CQ_UAR_CQ_CI_OFFSET);
+ port->port_priv.arm_cq_doorbell_record->dword[0] = cq_uar.dword[1];
+ port->port_priv.arm_cq_doorbell_record->dword[1] = cq_uar.dword[0];
+ } else {
+ val32 = ( port->eth_cq->next_idx & 0xffffff );
+ if ( nodnic_port_set ( & port->port_priv, nodnic_port_option_arm_cq, val32 ) ) {
+ MLX_DEBUG_ERROR( port->port_priv.device, "Failed to arm the CQ\n" );
+ return MLX_FAILED;
+ }
}
#else
mlx_utils *utils = port->port_priv.device->utils;
@@ -77,7 +95,7 @@ static int flexboot_nodnic_arm_cq ( struct flexboot_nodnic_port *port ) {
data = ( ( ( port->eth_cq->next_idx & 0xffff ) << 16 ) | 0x0080 );
/* Write the new index and update FW that new data was submitted */
mlx_pci_mem_write ( utils, MlxPciWidthUint32, 0,
- ( mlx_uint64 ) & ( ptr->armcq_cq_ci_dword ), 1, &data );
+ ( mlx_uintn ) & ( ptr->armcq_cq_ci_dword ), 1, &data );
}
#endif
return 0;
@@ -96,6 +114,7 @@ static int flexboot_nodnic_create_cq ( struct ib_device *ibdev ,
struct flexboot_nodnic_port *port = &flexboot_nodnic->port[ibdev->port - 1];
struct flexboot_nodnic_completion_queue *flexboot_nodnic_cq;
mlx_status status = MLX_SUCCESS;
+ mlx_uint32 cqn;
flexboot_nodnic_cq = (struct flexboot_nodnic_completion_queue *)
zalloc(sizeof(*flexboot_nodnic_cq));
@@ -114,10 +133,18 @@ static int flexboot_nodnic_create_cq ( struct ib_device *ibdev ,
flexboot_nodnic->callbacks->cqe_set_owner(
flexboot_nodnic_cq->nodnic_completion_queue->cq_virt,
cq->num_cqes);
-
+ if ( flexboot_nodnic->device_priv.device_cap.support_bar_cq_ctrl ) {
+ status = nodnic_port_query(&port->port_priv,
+ nodnic_port_option_cq_n_index,
+ (mlx_uint32 *)&cqn );
+ MLX_FATAL_CHECK_STATUS(status, read_cqn_err,
+ "failed to query cqn");
+ cq->cqn = cqn;
+ }
ib_cq_set_drvdata ( cq, flexboot_nodnic_cq );
return status;
+read_cqn_err:
create_err:
free(flexboot_nodnic_cq);
qp_alloc_err:
@@ -450,6 +477,9 @@ static int flexboot_nodnic_post_send ( struct ib_device *ibdev,
status = port->port_priv.send_doorbell ( &port->port_priv,
&send_ring->nodnic_ring, ( mlx_uint16 ) wq->next_idx );
+ if ( flexboot_nodnic->callbacks->tx_uar_send_doorbell_fn ) {
+ flexboot_nodnic->callbacks->tx_uar_send_doorbell_fn ( ibdev, wqbb );
+ }
if ( status != 0 ) {
DBGC ( flexboot_nodnic, "flexboot_nodnic %p ring send doorbell failed\n", flexboot_nodnic );
}
@@ -1293,12 +1323,14 @@ int flexboot_nodnic_is_supported ( struct pci_device *pci ) {
mlx_pci_gw_teardown( &utils );
pci_gw_init_err:
+ mlx_utils_teardown(&utils);
utils_init_err:
DBG ( "%s: NODNIC is %s supported (status = %d)\n",
__FUNCTION__, ( is_supported ? "": "not" ), status );
return is_supported;
}
+
void flexboot_nodnic_copy_mac ( uint8_t mac_addr[], uint32_t low_byte,
uint16_t high_byte ) {
union mac_addr {
@@ -1329,13 +1361,14 @@ static mlx_status flexboot_nodnic_get_factory_mac (
status = mlx_vmac_query_virt_mac ( flexboot_nodnic_priv->device_priv.utils,
&virt_mac );
if ( ! status ) {
- DBGC ( flexboot_nodnic_priv, "NODNIC %p Failed to set the virtual MAC\n",
- flexboot_nodnic_priv );
+ DBGC ( flexboot_nodnic_priv, "NODNIC %p Failed to set the virtual MAC\n"
+ ,flexboot_nodnic_priv );
}
return status;
}
+
/**
* Set port masking
*
@@ -1361,6 +1394,79 @@ static int flexboot_nodnic_set_port_masking ( struct flexboot_nodnic *flexboot_n
return 0;
}
+int init_mlx_utils ( mlx_utils **utils, struct pci_device *pci ) {
+ int rc = 0;
+
+ *utils = ( mlx_utils * ) zalloc ( sizeof ( mlx_utils ) );
+ if ( *utils == NULL ) {
+ DBGC ( utils, "%s: Failed to allocate utils\n", __FUNCTION__ );
+ rc = -1;
+ goto err_utils_alloc;
+ }
+ if ( mlx_utils_init ( *utils, pci ) ) {
+ DBGC ( utils, "%s: mlx_utils_init failed\n", __FUNCTION__ );
+ rc = -1;
+ goto err_utils_init;
+ }
+ if ( mlx_pci_gw_init ( *utils ) ){
+ DBGC ( utils, "%s: mlx_pci_gw_init failed\n", __FUNCTION__ );
+ rc = -1;
+ goto err_cmd_init;
+ }
+
+ return 0;
+
+ mlx_pci_gw_teardown ( *utils );
+err_cmd_init:
+ mlx_utils_teardown ( *utils );
+err_utils_init:
+ free ( *utils );
+err_utils_alloc:
+ *utils = NULL;
+
+ return rc;
+}
+
+void free_mlx_utils ( mlx_utils **utils ) {
+
+ mlx_pci_gw_teardown ( *utils );
+ mlx_utils_teardown ( *utils );
+ free ( *utils );
+ *utils = NULL;
+}
+
+/**
+ * Initialise Nodnic PCI parameters
+ *
+ * @v hermon Nodnic device
+ */
+static int flexboot_nodnic_alloc_uar ( struct flexboot_nodnic *flexboot_nodnic ) {
+ mlx_status status = MLX_SUCCESS;
+ struct pci_device *pci = flexboot_nodnic->pci;
+ nodnic_uar *uar = &flexboot_nodnic->port[0].port_priv.device->uar;
+
+ if ( ! flexboot_nodnic->device_priv.utils ) {
+ uar->virt = NULL;
+ DBGC ( flexboot_nodnic, "%s: mlx_utils is not initialized \n", __FUNCTION__ );
+ return -EINVAL;
+ }
+
+ if ( ! flexboot_nodnic->device_priv.device_cap.support_uar_tx_db ) {
+ DBGC ( flexboot_nodnic, "%s: tx db using uar is not supported \n", __FUNCTION__ );
+ return -ENOTSUP;
+ }
+ /* read uar offset then allocate */
+ if ( ( status = nodnic_port_set_send_uar_offset ( &flexboot_nodnic->port[0].port_priv ) ) ) {
+ DBGC ( flexboot_nodnic, "%s: nodnic_port_set_send_uar_offset failed,"
+ "status = %d\n", __FUNCTION__, status );
+ return -EINVAL;
+ }
+ uar->phys = ( pci_bar_start ( pci, FLEXBOOT_NODNIC_HCA_BAR ) + (mlx_uint32)uar->offset );
+ uar->virt = ( void * )( ioremap ( uar->phys, FLEXBOOT_NODNIC_PAGE_SIZE ) );
+
+ return status;
+}
+
int flexboot_nodnic_probe ( struct pci_device *pci,
struct flexboot_nodnic_callbacks *callbacks,
void *drv_priv __unused ) {
@@ -1388,21 +1494,10 @@ int flexboot_nodnic_probe ( struct pci_device *pci,
pci_set_drvdata ( pci, flexboot_nodnic_priv );
device_priv = &flexboot_nodnic_priv->device_priv;
- device_priv->utils = (mlx_utils *)zalloc( sizeof ( mlx_utils ) );
- if ( device_priv->utils == NULL ) {
- DBGC ( flexboot_nodnic_priv, "%s: Failed to allocate utils\n", __FUNCTION__ );
- status = MLX_OUT_OF_RESOURCES;
- goto utils_err_alloc;
- }
-
- status = mlx_utils_init( device_priv->utils, pci );
- MLX_FATAL_CHECK_STATUS(status, utils_init_err,
- "mlx_utils_init failed");
-
- /* nodnic init*/
- status = mlx_pci_gw_init( device_priv->utils );
- MLX_FATAL_CHECK_STATUS(status, cmd_init_err,
- "mlx_pci_gw_init failed");
+ /* init mlx utils */
+ status = init_mlx_utils ( & device_priv->utils, pci );
+ MLX_FATAL_CHECK_STATUS(status, err_utils_init,
+ "init_mlx_utils failed");
/* init device */
status = nodnic_device_init( device_priv );
@@ -1426,6 +1521,11 @@ int flexboot_nodnic_probe ( struct pci_device *pci,
MLX_FATAL_CHECK_STATUS(status, err_thin_init_ports,
"flexboot_nodnic_thin_init_ports failed");
+ if ( ( status = flexboot_nodnic_alloc_uar ( flexboot_nodnic_priv ) ) ) {
+ DBGC(flexboot_nodnic_priv, "%s: flexboot_nodnic_pci_init failed"
+ " ( status = %d )\n",__FUNCTION__, status );
+ }
+
/* device reg */
status = flexboot_nodnic_set_ports_type( flexboot_nodnic_priv );
MLX_CHECK_STATUS( flexboot_nodnic_priv, status, err_set_ports_types,
@@ -1456,11 +1556,8 @@ err_set_masking:
get_cap_err:
nodnic_device_teardown ( device_priv );
device_init_err:
- mlx_pci_gw_teardown ( device_priv->utils );
-cmd_init_err:
-utils_init_err:
- free ( device_priv->utils );
-utils_err_alloc:
+ free_mlx_utils ( & device_priv->utils );
+err_utils_init:
free ( flexboot_nodnic_priv );
device_err_alloc:
return status;
@@ -1473,7 +1570,6 @@ void flexboot_nodnic_remove ( struct pci_device *pci )
flexboot_nodnic_ports_unregister_dev ( flexboot_nodnic_priv );
nodnic_device_teardown( device_priv );
- mlx_pci_gw_teardown( device_priv->utils );
- free( device_priv->utils );
+ free_mlx_utils ( & device_priv->utils );
free( flexboot_nodnic_priv );
}
diff --git a/src/drivers/infiniband/flexboot_nodnic.h b/src/drivers/infiniband/flexboot_nodnic.h
index 80272296..3020f745 100644
--- a/src/drivers/infiniband/flexboot_nodnic.h
+++ b/src/drivers/infiniband/flexboot_nodnic.h
@@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <ipxe/io.h>
#include <ipxe/infiniband.h>
#include <ipxe/netdevice.h>
+#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
/*
* If defined, use interrupts in NODNIC driver
@@ -37,6 +38,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define FLEXBOOT_NODNIC_PORT_BASE 1
#define FLEXBOOT_NODNIC_OPCODE_SEND 0xa
+#define FLEXBOOT_NODNIC_HCA_BAR PCI_BASE_ADDRESS_0 //BAR 0
+#define FLEXBOOT_NODNIC_PAGE_SHIFT 12
+#define FLEXBOOT_NODNIC_PAGE_SIZE (1 << FLEXBOOT_NODNIC_PAGE_SHIFT)
+#define FLEXBOOT_NODNIC_PAGE_MASK (FLEXBOOT_NODNIC_PAGE_SIZE - 1)
/* Port protocol */
enum flexboot_nodnic_protocol {
@@ -60,6 +65,7 @@ struct flexboot_nodnic_port {
struct ib_completion_queue *eth_cq;
/** Ethernet queue pair */
struct ib_queue_pair *eth_qp;
+ mlx_uint8 cmdsn;
};
@@ -136,6 +142,21 @@ struct cqe_data{
mlx_uint32 byte_cnt;
};
+union arm_cq_uar {
+ struct {
+ //big endian
+ mlx_uint32 reserved0 :2;
+ mlx_uint32 cmdn :2;
+ mlx_uint32 reserved1 :3;
+ mlx_uint32 cmd :1;
+ mlx_uint32 cq_ci :24;
+ mlx_uint32 reserved2 :8;
+ mlx_uint32 cq_n :24;
+ };
+ mlx_uint32 dword[2];
+ mlx_uint64 qword;
+};
+
struct flexboot_nodnic_callbacks {
mlx_status ( * fill_completion ) ( void *cqe, struct cqe_data *cqe_data );
mlx_status ( * cqe_set_owner ) ( void *cq, unsigned int num_cqes );
@@ -149,6 +170,10 @@ struct flexboot_nodnic_callbacks {
unsigned long wqe_idx
);
void ( * irq ) ( struct net_device *netdev, int enable );
+ mlx_status ( * tx_uar_send_doorbell_fn ) (
+ struct ib_device *ibdev,
+ struct nodnic_send_wqbb *wqbb
+ );
};
int flexboot_nodnic_probe ( struct pci_device *pci,
@@ -159,5 +184,6 @@ void flexboot_nodnic_eth_irq ( struct net_device *netdev, int enable );
int flexboot_nodnic_is_supported ( struct pci_device *pci );
void flexboot_nodnic_copy_mac ( uint8_t mac_addr[], uint32_t low_byte,
uint16_t high_byte );
-
+int init_mlx_utils ( mlx_utils **utils, struct pci_device *pci );
+void free_mlx_utils ( mlx_utils **utils );
#endif /* SRC_DRIVERS_INFINIBAND_FLEXBOOT_NODNIC_FLEXBOOT_NODNIC_H_ */
diff --git a/src/drivers/infiniband/golan.c b/src/drivers/infiniband/golan.c
index d410fdfb..b704a939 100755
--- a/src/drivers/infiniband/golan.c
+++ b/src/drivers/infiniband/golan.c
@@ -21,31 +21,32 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <errno.h>
#include <strings.h>
-#include <byteswap.h>
#include <ipxe/malloc.h>
#include <ipxe/umalloc.h>
#include <ipxe/infiniband.h>
#include <ipxe/ib_smc.h>
#include <ipxe/iobuf.h>
#include <ipxe/netdevice.h>
+#include "flexboot_nodnic.h"
#include <ipxe/ethernet.h>
#include <ipxe/if_ether.h>
+#include <usr/ifmgmt.h>
#include <ipxe/in.h>
+#include <byteswap.h>
+#include "mlx_utils/include/public/mlx_pci_gw.h"
+#include <config/general.h>
#include <ipxe/ipoib.h>
-#include "flexboot_nodnic.h"
+#include "mlx_nodnic/include/mlx_port.h"
#include "nodnic_shomron_prm.h"
#include "golan.h"
#include "mlx_utils/include/public/mlx_bail.h"
#include "mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h"
-#include "mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h"
-#include "mlx_utils/include/public/mlx_pci_gw.h"
-#include "mlx_nodnic/include/mlx_port.h"
+#define DEVICE_IS_CIB( device ) ( device == 0x1011 )
/******************************************************************************/
/************* Very simple memory management for umalloced pages **************/
/******* Temporary solution until full memory management is implemented *******/
/******************************************************************************/
-#define GOLAN_PAGES 20
struct golan_page {
struct list_head list;
userptr_t addr;
@@ -61,8 +62,7 @@ static void golan_free_pages ( struct list_head *head ) {
}
static int golan_init_pages ( struct list_head *head ) {
- struct golan_page *new_entry;
- int rc, i;
+ int rc = 0;
if ( !head ) {
rc = -EINVAL;
@@ -70,26 +70,8 @@ static int golan_init_pages ( struct list_head *head ) {
}
INIT_LIST_HEAD ( head );
+ return rc;
- for ( i = 0; i < GOLAN_PAGES; i++ ) {
- new_entry = zalloc ( sizeof ( *new_entry ) );
- if ( new_entry == NULL ) {
- rc = -ENOMEM;
- goto err_golan_init_pages_alloc_page;
- }
- new_entry->addr = umalloc ( GOLAN_PAGE_SIZE );
- if ( new_entry->addr == UNULL ) {
- free ( new_entry );
- rc = -ENOMEM;
- goto err_golan_init_pages_alloc_page;
- }
- list_add ( &new_entry->list, head );
- }
-
- return 0;
-
-err_golan_init_pages_alloc_page:
- golan_free_pages ( head );
err_golan_init_pages_bad_param:
return rc;
}
@@ -98,16 +80,42 @@ static userptr_t golan_get_page ( struct list_head *head ) {
struct golan_page *page;
userptr_t addr;
- if ( list_empty ( head ) )
- return UNULL;
-
- page = list_first_entry ( head, struct golan_page, list );
- list_del ( &page->list );
- addr = page->addr;
- free ( page );
+ if ( list_empty ( head ) ) {
+ addr = umalloc ( GOLAN_PAGE_SIZE );
+ if ( addr == UNULL ) {
+ goto err_golan_iget_page_alloc_page;
+ }
+ } else {
+ page = list_first_entry ( head, struct golan_page, list );
+ list_del ( &page->list );
+ addr = page->addr;
+ free ( page );
+ }
+err_golan_iget_page_alloc_page:
return addr;
}
+static int golan_return_page ( struct list_head *head,
+ userptr_t addr ) {
+ struct golan_page *new_entry;
+ int rc = 0;
+
+ if ( ! head ) {
+ rc = -EINVAL;
+ goto err_golan_return_page_bad_param;
+ }
+ new_entry = zalloc ( sizeof ( *new_entry ) );
+ if ( new_entry == NULL ) {
+ rc = -ENOMEM;
+ goto err_golan_return_page_alloc_page;
+ }
+ new_entry->addr = addr;
+ list_add_tail( &new_entry->list, head );
+
+err_golan_return_page_alloc_page:
+err_golan_return_page_bad_param:
+ return rc;
+}
/******************************************************************************/
const char *golan_qp_state_as_string[] = {
@@ -450,8 +458,8 @@ err_query_hca_cap:
static inline int golan_take_pages ( struct golan *golan, uint32_t pages, __be16 func_id ) {
uint32_t out_num_entries = 0;
- int size_ibox = sizeof(struct golan_manage_pages_inbox);
- int size_obox = sizeof(struct golan_manage_pages_outbox);
+ int size_ibox = 0;
+ int size_obox = 0;
int rc = 0;
DBGC(golan, "%s\n", __FUNCTION__);
@@ -463,8 +471,8 @@ static inline int golan_take_pages ( struct golan *golan, uint32_t pages, __be16
struct golan_manage_pages_inbox *in;
struct golan_manage_pages_outbox_data *out;
- size_ibox += (pas_num * GOLAN_PAS_SIZE);
- size_obox += (pas_num * GOLAN_PAS_SIZE);
+ size_ibox = sizeof(struct golan_manage_pages_inbox) + (pas_num * GOLAN_PAS_SIZE);
+ size_obox = sizeof(struct golan_manage_pages_outbox) + (pas_num * GOLAN_PAS_SIZE);
cmd = write_cmd(golan, MEM_CMD_IDX, GOLAN_CMD_OP_MANAGE_PAGES, GOLAN_PAGES_TAKE,
MEM_MBOX, MEM_MBOX,
@@ -480,7 +488,7 @@ static inline int golan_take_pages ( struct golan *golan, uint32_t pages, __be16
out = (struct golan_manage_pages_outbox_data *)GET_OUTBOX(golan, MEM_MBOX);
out_num_entries = be32_to_cpu(((struct golan_manage_pages_outbox *)(cmd->out))->num_entries);
for (i = 0; i < out_num_entries; ++i) {
- ufree(BE64_BUS_2_USR(out->pas[i]));
+ golan_return_page ( &golan->pages, ( BE64_BUS_2_USR( out->pas[i] ) ) );
}
} else {
if ( rc == -EBUSY ) {
@@ -503,8 +511,8 @@ static inline int golan_take_pages ( struct golan *golan, uint32_t pages, __be16
static inline int golan_provide_pages ( struct golan *golan , uint32_t pages, __be16 func_id ) {
struct mbox *mailbox;
- int size_ibox = sizeof(struct golan_manage_pages_inbox);
- int size_obox = sizeof(struct golan_manage_pages_outbox);
+ int size_ibox = 0;
+ int size_obox = 0;
int rc = 0;
DBGC(golan, "%s\n", __FUNCTION__);
@@ -517,8 +525,8 @@ static inline int golan_provide_pages ( struct golan *golan , uint32_t pages, __
userptr_t addr = 0;
mailbox = GET_INBOX(golan, MEM_MBOX);
- size_ibox += (pas_num * GOLAN_PAS_SIZE);
- size_obox += (pas_num * GOLAN_PAS_SIZE);
+ size_ibox = sizeof(struct golan_manage_pages_inbox) + (pas_num * GOLAN_PAS_SIZE);
+ size_obox = sizeof(struct golan_manage_pages_outbox) + (pas_num * GOLAN_PAS_SIZE);
cmd = write_cmd(golan, MEM_CMD_IDX, GOLAN_CMD_OP_MANAGE_PAGES, GOLAN_PAGES_GIVE,
MEM_MBOX, MEM_MBOX,
@@ -531,7 +539,7 @@ static inline int golan_provide_pages ( struct golan *golan , uint32_t pages, __
in->num_entries = cpu_to_be32(pas_num);
for ( i = 0 , j = MANAGE_PAGES_PSA_OFFSET; i < pas_num; ++i ,++j ) {
- if (!(addr = umalloc(GOLAN_PAGE_SIZE))) {
+ if ( ! ( addr = golan_get_page ( & golan->pages ) ) ) {
rc = -ENOMEM;
DBGC (golan ,"Couldnt allocated page \n");
goto malloc_dma_failed;
@@ -555,7 +563,7 @@ static inline int golan_provide_pages ( struct golan *golan , uint32_t pages, __
get_cmd( golan , MEM_CMD_IDX )->status_own,
be32_to_cpu(CMD_SYND(golan, MEM_CMD_IDX)), pas_num);
}
- ufree ( addr );
+ golan_return_page ( &golan->pages ,addr );
goto err_send_command;
}
}
@@ -834,7 +842,7 @@ static int golan_create_eq(struct golan *golan)
return 0;
err_create_eq_cmd:
- ufree(virt_to_user(golan->eq.eqes));
+ golan_return_page ( & golan->pages, virt_to_user ( eq->eqes ) );
err_create_eq_eqe_alloc:
DBGC (golan ,"%s [%d] out\n", __FUNCTION__, rc);
return rc;
@@ -859,7 +867,7 @@ static void golan_destory_eq(struct golan *golan)
rc = send_command_and_wait(golan, DEF_CMD_IDX, NO_MBOX, NO_MBOX, __FUNCTION__);
GOLAN_PRINT_RC_AND_CMD_STATUS;
- ufree(virt_to_user(golan->eq.eqes));
+ golan_return_page ( &golan->pages, virt_to_user ( golan->eq.eqes ) );
golan->eq.eqn = 0;
DBGC( golan, "%s Event queue (0x%x) was destroyed\n", __FUNCTION__, eqn);
@@ -1063,7 +1071,7 @@ static int golan_create_cq(struct ib_device *ibdev,
return 0;
err_create_cq_cmd:
- ufree(virt_to_user(golan_cq->cqes));
+ golan_return_page ( & golan->pages, virt_to_user ( golan_cq->cqes ) );
err_create_cq_cqe_alloc:
free_dma(golan_cq->doorbell_record, GOLAN_CQ_DB_RECORD_SIZE);
err_create_cq_db_alloc:
@@ -1100,7 +1108,7 @@ static void golan_destroy_cq(struct ib_device *ibdev,
cq->cqn = 0;
ib_cq_set_drvdata(cq, NULL);
- ufree(virt_to_user(golan_cq->cqes));
+ golan_return_page ( & golan->pages, virt_to_user ( golan_cq->cqes ) );
free_dma(golan_cq->doorbell_record, GOLAN_CQ_DB_RECORD_SIZE);
free(golan_cq);
@@ -1272,7 +1280,7 @@ static int golan_create_qp_aux(struct ib_device *ibdev,
err_create_qp_cmd:
free_dma(golan_qp->doorbell_record, sizeof(struct golan_qp_db));
err_create_qp_db_alloc:
- ufree((userptr_t)golan_qp->wqes);
+ golan_return_page ( & golan->pages, ( userptr_t ) golan_qp->wqes );
err_create_qp_wqe_alloc:
err_create_qp_sq_size:
err_create_qp_sq_wqe_size:
@@ -1326,7 +1334,7 @@ static int golan_modify_qp_rst_to_init(struct ib_device *ibdev,
in->ctx.pri_path.port = ibdev->port;
in->ctx.flags |= cpu_to_be32(GOLAN_QP_PM_MIGRATED << GOLAN_QP_CTX_PM_STATE_BIT);
- in->ctx.pri_path.pkey_index = 0; /* default index */
+ in->ctx.pri_path.pkey_index = 0;
/* QK is 0 */
/* QP cntr set 0 */
return rc;
@@ -1480,7 +1488,7 @@ static void golan_destroy_qp(struct ib_device *ibdev,
ib_qp_set_drvdata(qp, NULL);
free_dma(golan_qp->doorbell_record, sizeof(struct golan_qp_db));
- ufree((userptr_t)golan_qp->wqes);
+ golan_return_page ( & golan->pages, ( userptr_t ) golan_qp->wqes );
free(golan_qp);
DBGC( golan ,"%s QP 0x%lx was destroyed\n", __FUNCTION__, qpn);
@@ -1694,8 +1702,8 @@ err_query_vport_gid_cmd:
static int golan_query_vport_pkey ( struct ib_device *ibdev ) {
struct golan *golan = ib_get_drvdata ( ibdev );
struct golan_cmd_layout *cmd;
- struct golan_query_hca_vport_pkey_inbox *in;
//struct golan_query_hca_vport_pkey_data *pkey_table;
+ struct golan_query_hca_vport_pkey_inbox *in;
int pkey_table_size_in_entries = (1 << (7 + golan->caps.pkey_table_size));
int rc;
@@ -2244,26 +2252,24 @@ static inline void golan_bring_down(struct golan *golan)
}
static int golan_set_link_speed ( struct golan *golan ){
- mlx_utils utils;
mlx_status status;
int i = 0;
+ int utils_inited = 0;
- memset ( &utils, 0, sizeof ( utils ) );
-
- status = mlx_utils_init ( &utils, golan->pci );
- MLX_CHECK_STATUS ( golan->pci, status, utils_init_err, "mlx_utils_init failed" );
-
- status = mlx_pci_gw_init ( &utils );
- MLX_CHECK_STATUS ( golan->pci, status, pci_gw_init_err, "mlx_pci_gw_init failed" );
+ if ( ! golan->utils ) {
+ utils_inited = 1;
+ status = init_mlx_utils ( & golan->utils, golan->pci );
+ MLX_CHECK_STATUS ( golan->pci, status, utils_init_err, "mlx_utils_init failed" );
+ }
for ( i = 0; i < golan->caps.num_ports; ++i ) {
- status = mlx_set_link_speed( &utils, i + 1, LINK_SPEED_IB, LINK_SPEED_SDR );
+ status = mlx_set_link_speed ( golan->utils, i + 1, LINK_SPEED_IB, LINK_SPEED_SDR );
MLX_CHECK_STATUS ( golan->pci, status, set_link_speed_err, "mlx_set_link_speed failed" );
}
set_link_speed_err:
- mlx_pci_gw_teardown( &utils );
-pci_gw_init_err:
+if ( utils_inited )
+ free_mlx_utils ( & golan->utils );
utils_init_err:
return status;
}
@@ -2344,7 +2350,16 @@ out:
*
* @v ibdev Infiniband device
*/
-static void golan_ib_close ( struct ib_device *ibdev __unused ) {}
+static void golan_ib_close ( struct ib_device *ibdev ) {
+ struct golan *golan = NULL;
+
+ DBG ( "%s start\n", __FUNCTION__ );
+ if ( ! ibdev )
+ return;
+ golan = ib_get_drvdata ( ibdev );
+ golan_bring_down ( golan );
+ DBG ( "%s end\n", __FUNCTION__ );
+}
/**
* Initialise Infiniband link
@@ -2353,11 +2368,13 @@ static void golan_ib_close ( struct ib_device *ibdev __unused ) {}
* @ret rc Return status code
*/
static int golan_ib_open ( struct ib_device *ibdev ) {
+ struct golan *golan = NULL;
DBG ( "%s start\n", __FUNCTION__ );
if ( ! ibdev )
return -EINVAL;
-
+ golan = ib_get_drvdata ( ibdev );
+ golan_bring_up ( golan );
golan_ib_update ( ibdev );
DBG ( "%s end\n", __FUNCTION__ );
@@ -2417,6 +2434,12 @@ static int golan_probe_normal ( struct pci_device *pci ) {
goto err_golan_bringup;
}
+ if ( ! DEVICE_IS_CIB ( pci->device ) ) {
+ if ( init_mlx_utils ( & golan->utils, pci ) ) {
+ rc = -1;
+ goto err_utils_init;
+ }
+ }
/* Allocate Infiniband devices */
for (i = 0; i < golan->caps.num_ports; ++i) {
ibdev = alloc_ibdev( 0 );
@@ -2435,10 +2458,13 @@ static int golan_probe_normal ( struct pci_device *pci ) {
/* Register devices */
for ( i = 0; i < golan->caps.num_ports; ++i ) {
port = &golan->ports[i];
- if ((rc = golan_register_ibdev ( port ) ) != 0 )
+ if ((rc = golan_register_ibdev ( port ) ) != 0 ) {
goto err_golan_probe_register_ibdev;
+ }
}
+ golan_bring_down ( golan );
+
return 0;
i = golan->caps.num_ports;
@@ -2450,7 +2476,10 @@ err_golan_probe_register_ibdev:
err_golan_probe_alloc_ibdev:
for ( i-- ; ( signed int ) i >= 0 ; i-- )
ibdev_put ( golan->ports[i].ibdev );
-
+ if ( ! DEVICE_IS_CIB ( pci->device ) ) {
+ free_mlx_utils ( & golan->utils );
+ }
+err_utils_init:
golan_bring_down ( golan );
err_golan_bringup:
err_fw_ver_cmdif:
@@ -2476,13 +2505,13 @@ static void golan_remove_normal ( struct pci_device *pci ) {
}
for ( i = ( golan->caps.num_ports - 1 ) ; i >= 0 ; i-- ) {
netdev_nullify ( golan->ports[i].netdev );
- netdev_put ( golan->ports[i].netdev );
}
for ( i = ( golan->caps.num_ports - 1 ) ; i >= 0 ; i-- ) {
ibdev_put ( golan->ports[i].ibdev );
}
-
- golan_bring_down(golan);
+ if ( ! DEVICE_IS_CIB ( pci->device ) ) {
+ free_mlx_utils ( & golan->utils );
+ }
iounmap( golan->iseg );
golan_free_pages( &golan->pages );
free(golan);
@@ -2491,6 +2520,26 @@ static void golan_remove_normal ( struct pci_device *pci ) {
/***************************************************************************
* NODNIC operations
**************************************************************************/
+static mlx_status shomron_tx_uar_send_db ( struct ib_device *ibdev,
+ struct nodnic_send_wqbb *wqbb ) {
+ mlx_status status = MLX_SUCCESS;
+ struct flexboot_nodnic *flexboot_nodnic = ib_get_drvdata ( ibdev );
+ struct shomron_nodnic_eth_send_wqe *eth_wqe =
+ ( struct shomron_nodnic_eth_send_wqe * )wqbb;
+ struct shomronprm_wqe_segment_ctrl_send *ctrl;
+
+ if ( ! ibdev || ! eth_wqe || ! flexboot_nodnic->device_priv.uar.virt ) {
+ DBG("%s: Invalid parameters\n",__FUNCTION__);
+ status = MLX_FAILED;
+ goto err;
+ }
+ wmb();
+ ctrl = & eth_wqe->ctrl;
+ writeq(*((__be64 *)ctrl), flexboot_nodnic->device_priv.uar.virt + 0x800);
+err:
+ return status;
+}
+
static mlx_status shomron_fill_eth_send_wqe ( struct ib_device *ibdev,
struct ib_queue_pair *qp, struct ib_address_vector *av __unused,
struct io_buffer *iobuf, struct nodnic_send_wqbb *wqbb,
@@ -2599,12 +2648,13 @@ struct flexboot_nodnic_callbacks shomron_nodnic_callbacks = {
.fill_completion = shomron_fill_completion,
.cqe_set_owner = shomron_cqe_set_owner,
.irq = flexboot_nodnic_eth_irq,
+ .tx_uar_send_doorbell_fn = shomron_tx_uar_send_db,
};
static int shomron_nodnic_supported = 0;
static int shomron_nodnic_is_supported ( struct pci_device *pci ) {
- if ( pci->device == 0x1011 )
+ if ( DEVICE_IS_CIB ( pci->device ) )
return 0;
return flexboot_nodnic_is_supported ( pci );
@@ -2624,15 +2674,9 @@ static int golan_probe ( struct pci_device *pci ) {
shomron_nodnic_supported = shomron_nodnic_is_supported ( pci );
if ( shomron_nodnic_supported ) {
+ DBG ( "%s: Using NODNIC driver\n", __FUNCTION__ );
rc = flexboot_nodnic_probe ( pci, &shomron_nodnic_callbacks, NULL );
- if ( rc == 0 ) {
- DBG ( "%s: Using NODNIC driver\n", __FUNCTION__ );
- goto probe_done;
- }
- shomron_nodnic_supported = 0;
- }
-
- if ( ! shomron_nodnic_supported ) {
+ } else {
DBG ( "%s: Using normal driver\n", __FUNCTION__ );
rc = golan_probe_normal ( pci );
}
@@ -2662,6 +2706,8 @@ static struct pci_device_id golan_nics[] = {
PCI_ROM ( 0x15b3, 0x1011, "ConnectIB", "ConnectIB HCA driver: DevID 4113", 0 ),
PCI_ROM ( 0x15b3, 0x1013, "ConnectX-4", "ConnectX-4 HCA driver, DevID 4115", 0 ),
PCI_ROM ( 0x15b3, 0x1015, "ConnectX-4Lx", "ConnectX-4Lx HCA driver, DevID 4117", 0 ),
+ PCI_ROM ( 0x15b3, 0x1017, "ConnectX-5", "ConnectX-5 HCA driver, DevID 4119", 0 ),
+ PCI_ROM ( 0x15b3, 0x1019, "ConnectX-5EX", "ConnectX-5EX HCA driver, DevID 4121", 0 ),
};
struct pci_driver golan_driver __pci_driver = {
diff --git a/src/drivers/infiniband/golan.h b/src/drivers/infiniband/golan.h
index a6cb4e74..c5227dd7 100755
--- a/src/drivers/infiniband/golan.h
+++ b/src/drivers/infiniband/golan.h
@@ -22,14 +22,15 @@
FILE_LICENCE ( GPL2_OR_LATER );
+#include <ipxe/pci.h>
+#include <ipxe/pcibackup.h>
#include <byteswap.h>
#include <errno.h>
+#include <ipxe/io.h>
#include <stdio.h>
#include <unistd.h>
-#include <ipxe/io.h>
-#include <ipxe/pci.h>
-#include <ipxe/pcibackup.h>
#include "CIB_PRM.h"
+#include "mlx_utils/include/public/mlx_utils.h"
#define GOLAN_PCI_CONFIG_BAR_SIZE 0x100000//HERMON_PCI_CONFIG_BAR_SIZE //TODO: What is the BAR size?
@@ -319,6 +320,7 @@ struct golan {
uint32_t pdn;
u32 mkey;
u32 flags;
+ mlx_utils *utils;
struct golan_port ports[GOLAN_MAX_PORTS];
};
diff --git a/src/drivers/infiniband/mlx_nodnic/include/mlx_nodnic_data_structures.h b/src/drivers/infiniband/mlx_nodnic/include/mlx_nodnic_data_structures.h
index f58213b9..61f2c573 100644
--- a/src/drivers/infiniband/mlx_nodnic/include/mlx_nodnic_data_structures.h
+++ b/src/drivers/infiniband/mlx_nodnic/include/mlx_nodnic_data_structures.h
@@ -36,6 +36,8 @@ typedef struct _nodnic_device_capabilites nodnic_device_capabilites;
typedef struct _nodnic_qp nodnic_qp;
typedef struct _nodnic_cq nodnic_cq;
typedef struct _nodnic_eq nodnic_eq;
+typedef struct _nodnic_qp_db nodnic_qp_db;
+typedef struct _nodnic_arm_cq_db nodnic_arm_cq_db;
/* NODNIC Port states
* Bit 0 - port open/close
@@ -73,6 +75,12 @@ typedef enum {
struct nodnic_send_wqbb {
mlx_uint8 force_align[NODNIC_WQBB_SIZE];
};
+
+struct nodnic_doorbell {
+ mlx_physical_address doorbell_physical;
+ mlx_void *map;
+ nodnic_qp_db *qp_doorbell_record;
+};
struct nodnic_ring {
mlx_uint32 offset;
/** Work queue entries */
@@ -91,7 +99,8 @@ struct nodnic_ring {
mlx_uint32 num_wqes;
mlx_uint32 qpn;
mlx_uint32 next_idx;
- mlx_uint32 ring_pi;
+ struct nodnic_doorbell recv_doorbell;
+ struct nodnic_doorbell send_doorbell;
};
struct nodnic_send_ring{
@@ -117,6 +126,7 @@ struct _nodnic_cq{
mlx_void *map;
/** cq */
mlx_size cq_size;
+ struct nodnic_doorbell arm_cq_doorbell;
};
struct _nodnic_eq{
@@ -136,6 +146,10 @@ struct _nodnic_device_capabilites{
#ifdef DEVICE_CX3
mlx_uint8 crspace_doorbells;
#endif
+ mlx_uint8 support_rx_pi_dma;
+ mlx_uint8 support_uar_tx_db;
+ mlx_uint8 support_bar_cq_ctrl;
+ mlx_uint8 log_uar_page_size;
};
#ifdef DEVICE_CX3
@@ -151,6 +165,13 @@ struct _nodnic_port_data_flow_gw {
} __attribute__ ((packed));
#endif
+typedef struct _nodnic_uar_priv{
+ mlx_uint8 inited;
+ mlx_uint64 offset;
+ void *virt;
+ unsigned long phys;
+} nodnic_uar;
+
struct _nodnic_device_priv{
mlx_boolean is_initiailzied;
mlx_utils *utils;
@@ -169,6 +190,7 @@ struct _nodnic_device_priv{
#ifdef DEVICE_CX3
mlx_void *crspace_clear_int;
#endif
+ nodnic_uar uar;
};
struct _nodnic_port_priv{
@@ -181,6 +203,7 @@ struct _nodnic_port_priv{
mlx_uint8 port_num;
nodnic_eq eq;
mlx_mac_address mac_filters[5];
+ nodnic_arm_cq_db *arm_cq_doorbell_record;
mlx_status (*send_doorbell)(
IN nodnic_port_priv *port_priv,
IN struct nodnic_ring *ring,
@@ -197,5 +220,12 @@ struct _nodnic_port_priv{
#endif
};
+struct _nodnic_qp_db {
+ mlx_uint32 recv_db;
+ mlx_uint32 send_db;
+} __attribute ( ( packed ) );
+struct _nodnic_arm_cq_db {
+ mlx_uint32 dword[2];
+} __attribute ( ( packed ) );
#endif /* STUB_NODNIC_NODNICDATASTRUCTURES_H_ */
diff --git a/src/drivers/infiniband/mlx_nodnic/include/mlx_port.h b/src/drivers/infiniband/mlx_nodnic/include/mlx_port.h
index 4fd96a6d..bb302672 100644
--- a/src/drivers/infiniband/mlx_nodnic/include/mlx_port.h
+++ b/src/drivers/infiniband/mlx_nodnic/include/mlx_port.h
@@ -47,6 +47,9 @@ typedef enum {
#ifdef DEVICE_CX3
nodnic_port_option_crspace_en,
#endif
+ nodnic_port_option_send_ring0_uar_index,
+ nodnic_port_option_send_ring1_uar_index,
+ nodnic_port_option_cq_n_index,
}nodnic_port_option;
struct nodnic_port_data_entry{
@@ -226,4 +229,14 @@ nodnic_port_read_port_management_change_event(
IN nodnic_port_priv *port_priv,
OUT mlx_boolean *change_event
);
+mlx_status
+nodnic_port_set_send_uar_offset(
+ IN nodnic_port_priv *port_priv
+ );
+
+mlx_status
+nodnic_port_update_tx_db_func(
+ IN nodnic_device_priv *device_priv,
+ IN nodnic_port_priv *port_priv
+ );
#endif /* STUB_NODNIC_PORT_H_ */
diff --git a/src/drivers/infiniband/mlx_nodnic/src/mlx_device.c b/src/drivers/infiniband/mlx_nodnic/src/mlx_device.c
index 4acc94fa..f6fdacdb 100644
--- a/src/drivers/infiniband/mlx_nodnic/src/mlx_device.c
+++ b/src/drivers/infiniband/mlx_nodnic/src/mlx_device.c
@@ -169,11 +169,17 @@ nodnic_device_clear_int (
mlx_status status = MLX_SUCCESS;
mlx_uint32 disable = 1;
#ifndef DEVICE_CX3
- status = nodnic_cmd_write(device_priv, NODNIC_NIC_DISABLE_INT_OFFSET, disable);
+#define NODNIC_CLEAR_INT_BAR_OFFSET 0x100C
+ if ( device_priv->device_cap.support_bar_cq_ctrl ) {
+ status = mlx_pci_mem_write ( device_priv->utils, MlxPciWidthUint32, 0,
+ ( mlx_uint64 ) ( NODNIC_CLEAR_INT_BAR_OFFSET ), 1, &disable );
+ } else {
+ status = nodnic_cmd_write(device_priv, NODNIC_NIC_DISABLE_INT_OFFSET, disable);
+ }
MLX_CHECK_STATUS(device_priv, status, clear_int_done, "failed writing to disable_bit");
#else
mlx_utils *utils = device_priv->utils;
- mlx_uint64 clear_int = (mlx_uint64)(device_priv->crspace_clear_int);
+ mlx_uint64 clear_int = (mlx_uintn)(device_priv->crspace_clear_int);
mlx_uint32 swapped = 0;
if (device_priv->device_cap.crspace_doorbells == 0) {
@@ -303,6 +309,30 @@ nodnic_device_get_cap(
status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x14, (mlx_uint32*)&guid_l);
MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic guid_l");
device_priv->device_guid = guid_l | (guid_h << 32);
+
+#define NODNIC_DEVICE_SUPPORT_RX_PI_DMA_OFFSET 31
+#define NODNIC_DEVICE_SUPPORT_RX_PI_DMA_MASK 0x1
+#define NODNIC_DEVICE_SUPPORT_UAR_TRX_DB_OFFSET 29
+#define NODNIC_DEVICE_SUPPORT_UAR_TRX_DB_MASK 0x1
+#define NODNIC_DEVICE_SUPPORT_BAR_CQ_CONTROL_OFFSET 27
+#define NODNIC_DEVICE_SUPPORT_BAR_CQ_CONTROL_MASK 0x1
+ status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x1c, &buffer);
+ MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic support_rx_pi_dma");
+ if ( sizeof ( mlx_uintn ) == sizeof ( mlx_uint32 ) ) {
+ device_cap->support_rx_pi_dma = FALSE;
+ device_cap->support_uar_tx_db = FALSE;
+ device_cap->support_bar_cq_ctrl = FALSE;
+ } else {
+ device_cap->support_rx_pi_dma = CHECK_BIT(buffer, NODNIC_DEVICE_SUPPORT_RX_PI_DMA_OFFSET);
+ device_cap->support_uar_tx_db = CHECK_BIT(buffer, NODNIC_DEVICE_SUPPORT_UAR_TRX_DB_OFFSET);
+ device_cap->support_bar_cq_ctrl = CHECK_BIT(buffer, NODNIC_DEVICE_SUPPORT_BAR_CQ_CONTROL_OFFSET);
+ }
+
+#define NODNIC_DEVICE_LOG_UAR_PAGE_SIZE_OFFSET 0
+#define NODNIC_DEVICE_LOG_UAR_PAGE_SIZE_MASK 0xFF
+ status = nodnic_cmd_read(device_priv, device_priv->device_offset + 0x20, &buffer);
+ MLX_FATAL_CHECK_STATUS(status, read_err, "failed to read nodnic log_uar_page_size");
+ device_cap->log_uar_page_size = ( buffer >> NODNIC_DEVICE_LOG_UAR_PAGE_SIZE_OFFSET) & NODNIC_DEVICE_LOG_UAR_PAGE_SIZE_MASK;
read_err:
parm_err:
return status;
diff --git a/src/drivers/infiniband/mlx_nodnic/src/mlx_port.c b/src/drivers/infiniband/mlx_nodnic/src/mlx_port.c
index a7afdab6..efbd8ddf 100644
--- a/src/drivers/infiniband/mlx_nodnic/src/mlx_port.c
+++ b/src/drivers/infiniband/mlx_nodnic/src/mlx_port.c
@@ -55,11 +55,18 @@ struct nodnic_port_data_entry nodnic_port_data_table[] = {
PortDataEntry(nodnic_port_option_cq_addr_high, 0x68, 0, 0xFFFFFFFF),
PortDataEntry(nodnic_port_option_port_management_change_event, 0x0, 30, 0x1),
PortDataEntry(nodnic_port_option_port_promisc_en, 0x4, 29, 0x1),
+#ifndef DEVICE_CX3
+ PortDataEntry(nodnic_port_option_arm_cq, 0x78, 8, 0xffffff),
+#else
PortDataEntry(nodnic_port_option_arm_cq, 0x78, 8, 0xffff),
+#endif
PortDataEntry(nodnic_port_option_port_promisc_multicast_en, 0x4, 28, 0x1),
#ifdef DEVICE_CX3
PortDataEntry(nodnic_port_option_crspace_en, 0x4, 27, 0x1),
#endif
+ PortDataEntry(nodnic_port_option_send_ring0_uar_index, 0x108, 0, 0xFFFFFFFF),
+ PortDataEntry(nodnic_port_option_send_ring1_uar_index, 0x10c, 0, 0xFFFFFFFF),
+ PortDataEntry(nodnic_port_option_cq_n_index, 0x118, 0, 0xFFFFFF),
};
#define MAX_QP_DATA_ENTRIES 5
@@ -187,6 +194,30 @@ invalid_parm:
}
mlx_status
+nodnic_port_set_send_uar_offset(
+ IN nodnic_port_priv *port_priv
+ )
+{
+ mlx_status status = MLX_SUCCESS;
+ mlx_uint32 out = 0;
+
+ if ( ! port_priv->device->device_cap.support_uar_tx_db ) {
+ MLX_DEBUG_INFO1 ( port_priv, "nodnic_port_set_send_uar_offset: tx db using uar is not supported \n");
+ status = MLX_UNSUPPORTED;
+ goto uar_not_supported;
+ }
+
+ status = nodnic_port_query(port_priv,
+ nodnic_port_option_send_ring0_uar_index, &out);
+ MLX_CHECK_STATUS(port_priv->device, status, query_err,
+ "nodnic_port_query failed");
+ port_priv->device->uar.offset = out << port_priv->device->device_cap.log_uar_page_size;
+uar_not_supported:
+query_err:
+ return status;
+}
+
+mlx_status
nodnic_port_read_reset_needed(
IN nodnic_port_priv *port_priv,
OUT mlx_boolean *reset_needed
@@ -220,6 +251,111 @@ query_err:
return status;
}
+static
+mlx_status
+nodnic_port_allocate_dbr_dma (
+ IN nodnic_port_priv *port_priv,
+ IN struct nodnic_doorbell *nodnic_db,
+ IN mlx_uint32 dbr_addr_low_ofst,
+ IN mlx_uint32 dbr_addr_high_ofst,
+ IN void **dbr_addr,
+ IN mlx_size size,
+ IN void **map
+ )
+{
+ mlx_status status = MLX_SUCCESS;
+ mlx_uint64 address = 0;
+ nodnic_device_priv *device_priv = NULL;
+
+ if( port_priv == NULL || nodnic_db == NULL ){
+ status = MLX_INVALID_PARAMETER;
+ goto invalid_parm;
+ }
+
+ device_priv = port_priv->device;
+ status = mlx_memory_alloc_dma(device_priv->utils,
+ size,
+ NODNIC_MEMORY_ALIGN,
+ (void **)dbr_addr
+ );
+ MLX_FATAL_CHECK_STATUS(status, alloc_db_record_err,
+ "doorbell record dma allocation error");
+
+ status = mlx_memory_map_dma(device_priv->utils,
+ (void *)(*dbr_addr),
+ size,
+ &nodnic_db->doorbell_physical,
+ map//nodnic_ring->map
+ );
+ MLX_FATAL_CHECK_STATUS(status, map_db_record_err,
+ "doorbell record map dma error");
+
+ address = (mlx_uint64)nodnic_db->doorbell_physical;
+ status = nodnic_cmd_write(device_priv,
+ dbr_addr_low_ofst,
+ (mlx_uint32)address);
+ MLX_FATAL_CHECK_STATUS(status, set_err,
+ "failed to set doorbell addr low");
+
+ address = address >> 32;
+ status = nodnic_cmd_write(device_priv,
+ dbr_addr_high_ofst,
+ (mlx_uint32)address);
+ MLX_FATAL_CHECK_STATUS(status, set_err,
+ "failed to set doorbell addr high");
+
+ return status;
+
+set_err:
+ mlx_memory_ummap_dma(device_priv->utils, *map);
+map_db_record_err:
+ mlx_memory_free_dma(device_priv->utils, size,
+ (void **)dbr_addr);
+alloc_db_record_err:
+invalid_parm:
+ return status;
+}
+
+static
+mlx_status
+nodnic_port_cq_dbr_dma_init(
+ IN nodnic_port_priv *port_priv,
+ OUT nodnic_cq **cq
+ )
+{
+ mlx_status status = MLX_SUCCESS;
+ nodnic_device_priv *device_priv = NULL;
+
+ if( port_priv == NULL ){
+ status = MLX_INVALID_PARAMETER;
+ goto invalid_parm;
+ }
+
+ device_priv = port_priv->device;
+ if ( ! device_priv->device_cap.support_bar_cq_ctrl ) {
+ status = MLX_UNSUPPORTED;
+ goto uar_arm_cq_db_unsupported;
+ }
+
+#define NODNIC_PORT_ARM_CQ_DBR_ADDR_LOW_OFFSET 0x114
+#define NODNIC_PORT_ARM_CQ_DBR_ADDR_HIGH_OFFSET 0x110
+
+ status = nodnic_port_allocate_dbr_dma ( port_priv,&(*cq)->arm_cq_doorbell,
+ port_priv->port_offset + NODNIC_PORT_ARM_CQ_DBR_ADDR_LOW_OFFSET,
+ port_priv->port_offset + NODNIC_PORT_ARM_CQ_DBR_ADDR_HIGH_OFFSET,
+ (void **)&port_priv->arm_cq_doorbell_record ,
+ sizeof(nodnic_arm_cq_db),
+ (void **)&((*cq)->arm_cq_doorbell.map));
+ MLX_FATAL_CHECK_STATUS(status, alloc_dbr_dma_err,
+ "failed to allocate doorbell record dma");
+ return status;
+
+alloc_dbr_dma_err:
+uar_arm_cq_db_unsupported:
+invalid_parm:
+ return status;
+}
+
mlx_status
nodnic_port_create_cq(
IN nodnic_port_priv *port_priv,
@@ -257,17 +393,24 @@ nodnic_port_create_cq(
MLX_FATAL_CHECK_STATUS(status, cq_map_err,
"cq map error");
+ status = nodnic_port_cq_dbr_dma_init(port_priv,cq);
+
/* update cq address */
#define NODIC_CQ_ADDR_HIGH 0x68
#define NODIC_CQ_ADDR_LOW 0x6c
address = (mlx_uint64)(*cq)->cq_physical;
- nodnic_port_set(port_priv, nodnic_port_option_cq_addr_low,
- (mlx_uint32)(address >> 12));
+ status = nodnic_port_set(port_priv, nodnic_port_option_cq_addr_low,
+ (mlx_uint32)(address) >> 12);
+ MLX_FATAL_CHECK_STATUS(status, dma_set_addr_low_err,
+ "cq set addr low error");
address = address >> 32;
- nodnic_port_set(port_priv, nodnic_port_option_cq_addr_high,
+ status = nodnic_port_set(port_priv, nodnic_port_option_cq_addr_high,
(mlx_uint32)address);
-
+ MLX_FATAL_CHECK_STATUS(status, dma_set_addr_high_err,
+ "cq set addr high error");
return status;
+dma_set_addr_high_err:
+dma_set_addr_low_err:
mlx_memory_ummap_dma(device_priv->utils, (*cq)->map);
cq_map_err:
mlx_memory_free_dma(device_priv->utils, (*cq)->cq_size,
@@ -294,6 +437,21 @@ nodnic_port_destroy_cq(
}
device_priv = port_priv->device;
+ if ( device_priv->device_cap.support_bar_cq_ctrl ){
+ status = mlx_memory_ummap_dma(device_priv->utils,
+ cq->arm_cq_doorbell.map);
+ if( status != MLX_SUCCESS){
+ MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
+ }
+
+ status = mlx_memory_free_dma(device_priv->utils,
+ sizeof(nodnic_arm_cq_db),
+ (void **)&(port_priv->arm_cq_doorbell_record));
+ if( status != MLX_SUCCESS){
+ MLX_DEBUG_ERROR(device_priv, "mlx_memory_free_dma failed (Status = %d)\n", status);
+ }
+ }
+
mlx_memory_ummap_dma(device_priv->utils, cq->map);
mlx_memory_free_dma(device_priv->utils, cq->cq_size,
@@ -303,6 +461,126 @@ nodnic_port_destroy_cq(
invalid_parm:
return status;
}
+
+static
+mlx_status
+nodnic_port_allocate_ring_db_dma (
+ IN nodnic_port_priv *port_priv,
+ IN struct nodnic_ring *nodnic_ring,
+ IN struct nodnic_doorbell *nodnic_db
+ )
+{
+ mlx_status status = MLX_SUCCESS;
+
+ if( port_priv == NULL || nodnic_ring == NULL || nodnic_db == NULL ){
+ status = MLX_INVALID_PARAMETER;
+ goto invalid_parm;
+ }
+#define NODNIC_RING_DBR_ADDR_LOW_OFFSET 0x1C
+#define NODNIC_RING_DBR_ADDR_HIGH_OFFSET 0x18
+ status = nodnic_port_allocate_dbr_dma ( port_priv,nodnic_db,
+ nodnic_ring->offset + NODNIC_RING_DBR_ADDR_LOW_OFFSET,
+ nodnic_ring->offset + NODNIC_RING_DBR_ADDR_HIGH_OFFSET,
+ (void **)&nodnic_db->qp_doorbell_record,
+ sizeof(nodnic_qp_db),
+ (void **)&nodnic_ring->map );
+ MLX_FATAL_CHECK_STATUS(status, alloc_dbr_dma_err,
+ "failed to allocate doorbell record dma");
+
+ return status;
+alloc_dbr_dma_err:
+invalid_parm:
+ return status;
+}
+
+static
+mlx_status
+nodnic_port_rx_pi_dma_alloc(
+ IN nodnic_port_priv *port_priv,
+ OUT nodnic_qp **qp
+ )
+{
+ mlx_status status = MLX_SUCCESS;
+ nodnic_device_priv *device_priv = NULL;
+
+ if( port_priv == NULL || qp == NULL){
+ status = MLX_INVALID_PARAMETER;
+ goto invalid_parm;
+ }
+
+ device_priv = port_priv->device;
+
+ if ( ! device_priv->device_cap.support_rx_pi_dma ) {
+ goto rx_pi_dma_unsupported;
+ }
+
+ if ( device_priv->device_cap.support_rx_pi_dma ) {
+ status = nodnic_port_allocate_ring_db_dma(port_priv,
+ &(*qp)->receive.nodnic_ring,&(*qp)->receive.nodnic_ring.recv_doorbell);
+ MLX_FATAL_CHECK_STATUS(status, dma_alloc_err,
+ "rx doorbell dma allocation error");
+ }
+
+ return status;
+
+dma_alloc_err:
+rx_pi_dma_unsupported:
+invalid_parm:
+ return status;
+}
+
+static
+mlx_status
+nodnic_port_send_db_dma(
+ IN nodnic_port_priv *port_priv,
+ IN struct nodnic_ring *ring,
+ IN mlx_uint16 index
+ )
+{
+ mlx_uint32 swapped = 0;
+ mlx_uint32 index32 = index;
+ mlx_memory_cpu_to_be32(port_priv->device->utils, index32, &swapped);
+ ring->send_doorbell.qp_doorbell_record->send_db = swapped;
+
+ return MLX_SUCCESS;
+}
+
+static
+mlx_status
+nodnic_port_tx_dbr_dma_init(
+ IN nodnic_port_priv *port_priv,
+ OUT nodnic_qp **qp
+ )
+{
+ mlx_status status = MLX_SUCCESS;
+ nodnic_device_priv *device_priv = NULL;
+
+ if( port_priv == NULL || qp == NULL){
+ status = MLX_INVALID_PARAMETER;
+ goto invalid_parm;
+ }
+
+ device_priv = port_priv->device;
+
+ if ( ! device_priv->device_cap.support_uar_tx_db || ! device_priv->uar.offset ) {
+ status = MLX_UNSUPPORTED;
+ goto uar_tx_db_unsupported;
+ }
+ status = nodnic_port_allocate_ring_db_dma(port_priv,
+ &(*qp)->send.nodnic_ring,&(*qp)->send.nodnic_ring.send_doorbell);
+ MLX_FATAL_CHECK_STATUS(status, dma_alloc_err,
+ "tx doorbell dma allocation error");
+ port_priv->send_doorbell = nodnic_port_send_db_dma;
+
+ return status;
+
+dma_alloc_err:
+uar_tx_db_unsupported:
+invalid_parm:
+
+ return status;
+}
+
mlx_status
nodnic_port_create_qp(
IN nodnic_port_priv *port_priv,
@@ -376,6 +654,13 @@ nodnic_port_create_qp(
MLX_FATAL_CHECK_STATUS(status, receive_map_err,
"receive wq map error");
+ status = nodnic_port_rx_pi_dma_alloc(port_priv,qp);
+ MLX_FATAL_CHECK_STATUS(status, rx_pi_dma_alloc_err,
+ "receive db dma error");
+
+ status = nodnic_port_tx_dbr_dma_init(port_priv,qp);
+
+
(*qp)->send.nodnic_ring.wq_size = send_wq_size;
(*qp)->send.nodnic_ring.num_wqes = send_wqe_num;
(*qp)->receive.nodnic_ring.wq_size = receive_wq_size;
@@ -420,6 +705,7 @@ nodnic_port_create_qp(
write_recv_addr_err:
write_send_addr_err:
mlx_memory_ummap_dma(device_priv->utils, (*qp)->receive.nodnic_ring.map);
+rx_pi_dma_alloc_err:
receive_map_err:
mlx_memory_ummap_dma(device_priv->utils, (*qp)->send.nodnic_ring.map);
send_map_err:
@@ -457,6 +743,36 @@ nodnic_port_destroy_qp(
MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
}
+ if ( device_priv->device_cap.support_rx_pi_dma ){
+ status = mlx_memory_ummap_dma(device_priv->utils,
+ qp->receive.nodnic_ring.recv_doorbell.map);
+ if( status != MLX_SUCCESS){
+ MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
+ }
+
+ status = mlx_memory_free_dma(device_priv->utils,
+ sizeof(nodnic_qp_db),
+ (void **)&(qp->receive.nodnic_ring.recv_doorbell.qp_doorbell_record));
+ if( status != MLX_SUCCESS){
+ MLX_DEBUG_ERROR(device_priv, "mlx_memory_free_dma failed (Status = %d)\n", status);
+ }
+ }
+
+ if ( device_priv->device_cap.support_uar_tx_db || ! device_priv->uar.offset){
+ status = mlx_memory_ummap_dma(device_priv->utils,
+ qp->send.nodnic_ring.send_doorbell.map);
+ if( status != MLX_SUCCESS){
+ MLX_DEBUG_ERROR(device_priv, "mlx_memory_ummap_dma failed (Status = %d)\n", status);
+ }
+
+ status = mlx_memory_free_dma(device_priv->utils,
+ sizeof(nodnic_qp_db),
+ (void **)&(qp->send.nodnic_ring.send_doorbell.qp_doorbell_record));
+ if( status != MLX_SUCCESS){
+ MLX_DEBUG_ERROR(device_priv, "mlx_memory_free_dma failed (Status = %d)\n", status);
+ }
+ }
+
status = mlx_memory_free_dma(device_priv->utils,
qp->receive.nodnic_ring.wq_size,
(void **)&(qp->receive.wqe_virt));
@@ -520,7 +836,7 @@ nodnic_port_send_db_connectx3(
nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
mlx_uint32 index32 = index;
mlx_pci_mem_write(port_priv->device->utils, MlxPciWidthUint32, 0,
- (mlx_uint64)&(ptr->send_doorbell), 1, &index32);
+ (mlx_uintn)&(ptr->send_doorbell), 1, &index32);
return MLX_SUCCESS;
}
@@ -535,10 +851,24 @@ nodnic_port_recv_db_connectx3(
nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
mlx_uint32 index32 = index;
mlx_pci_mem_write(port_priv->device->utils, MlxPciWidthUint32, 0,
- (mlx_uint64)&(ptr->recv_doorbell), 1, &index32);
+ (mlx_uintn)&(ptr->recv_doorbell), 1, &index32);
return MLX_SUCCESS;
}
#endif
+static
+mlx_status
+nodnic_port_recv_db_dma(
+ IN nodnic_port_priv *port_priv __attribute__((unused)),
+ IN struct nodnic_ring *ring,
+ IN mlx_uint16 index
+ )
+{
+ mlx_uint32 swapped = 0;
+ mlx_uint32 index32 = index;
+ mlx_memory_cpu_to_be32(port_priv->device->utils, index32, &swapped);
+ ring->recv_doorbell.qp_doorbell_record->recv_db = swapped;
+ return MLX_SUCCESS;
+}
mlx_status
nodnic_port_update_ring_doorbell(
@@ -678,11 +1008,10 @@ nodnic_port_add_mac_filter(
goto bad_param;
}
- memset(&zero_mac, 0, sizeof(zero_mac));
-
device = port_priv->device;
utils = device->utils;
+ mlx_memory_set(utils, &zero_mac, 0, sizeof(zero_mac));
/* check if mac already exists */
for( ; index < NODNIC_MAX_MAC_FILTERS ; index ++) {
mlx_memory_cmp(utils, &port_priv->mac_filters[index], &mac,
@@ -759,11 +1088,10 @@ nodnic_port_remove_mac_filter(
goto bad_param;
}
- memset(&zero_mac, 0, sizeof(zero_mac));
-
device = port_priv->device;
utils = device->utils;
+ mlx_memory_set(utils, &zero_mac, 0, sizeof(zero_mac));
/* serch for mac filter */
for( ; index < NODNIC_MAX_MAC_FILTERS ; index ++) {
mlx_memory_cmp(utils, &port_priv->mac_filters[index], &mac,
@@ -832,7 +1160,7 @@ nodnic_port_set_dma_connectx3(
nodnic_port_data_flow_gw *ptr = port_priv->data_flow_gw;
mlx_uint32 data = (value ? 0xffffffff : 0x0);
mlx_pci_mem_write(utils, MlxPciWidthUint32, 0,
- (mlx_uint64)&(ptr->dma_en), 1, &data);
+ (mlx_uintn)&(ptr->dma_en), 1, &data);
return MLX_SUCCESS;
}
#endif
@@ -1029,6 +1357,10 @@ nodnic_port_thin_init(
port_priv->set_dma = nodnic_port_set_dma_connectx3;
}
#endif
+ if ( device_priv->device_cap.support_rx_pi_dma ) {
+ port_priv->recv_doorbell = nodnic_port_recv_db_dma;
+ }
+
/* clear reset_needed */
nodnic_port_read_reset_needed(port_priv, &reset_needed);
diff --git a/src/drivers/infiniband/mlx_utils/include/private/mlx_pci_priv.h b/src/drivers/infiniband/mlx_utils/include/private/mlx_pci_priv.h
index 89cad75e..cf35e5b7 100644
--- a/src/drivers/infiniband/mlx_utils/include/private/mlx_pci_priv.h
+++ b/src/drivers/infiniband/mlx_utils/include/private/mlx_pci_priv.h
@@ -31,6 +31,11 @@ mlx_pci_init_priv(
);
mlx_status
+mlx_pci_teardown_priv(
+ IN mlx_utils *utils
+ );
+
+mlx_status
mlx_pci_read_priv(
IN mlx_utils *utils,
IN mlx_pci_width width,
diff --git a/src/drivers/infiniband/mlx_utils/include/public/mlx_logging.h b/src/drivers/infiniband/mlx_utils/include/public/mlx_logging.h
index 7b7b852d..7ff06bbf 100644
--- a/src/drivers/infiniband/mlx_utils/include/public/mlx_logging.h
+++ b/src/drivers/infiniband/mlx_utils/include/public/mlx_logging.h
@@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include "../../../mlx_utils_flexboot/include/mlx_logging_priv.h"
+#define MLX_PRINT(...) MLX_PRINT_PRIVATE(__VA_ARGS__)
#define MLX_DEBUG_FATAL_ERROR(...) MLX_DEBUG_FATAL_ERROR_PRIVATE(__VA_ARGS__)
#define MLX_DEBUG_ERROR(...) MLX_DEBUG_ERROR_PRIVATE(__VA_ARGS__)
#define MLX_DEBUG_WARN(...) MLX_DEBUG_WARN_PRIVATE(__VA_ARGS__)
diff --git a/src/drivers/infiniband/mlx_utils/include/public/mlx_pci.h b/src/drivers/infiniband/mlx_utils/include/public/mlx_pci.h
index 416bdb66..60eb55d5 100644
--- a/src/drivers/infiniband/mlx_utils/include/public/mlx_pci.h
+++ b/src/drivers/infiniband/mlx_utils/include/public/mlx_pci.h
@@ -37,6 +37,11 @@ mlx_pci_init(
);
mlx_status
+mlx_pci_teardown(
+ IN mlx_utils *utils
+ );
+
+mlx_status
mlx_pci_read(
IN mlx_utils *utils,
IN mlx_pci_width width,
diff --git a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h
index 15b28f57..cb167d6a 100644
--- a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h
+++ b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h
@@ -124,6 +124,11 @@ struct mlx_link_speed {
/* -------------- */
mlx_uint32 ib_proto_oper :16;
mlx_uint32 ib_link_width_oper :16;
+ /* -------------- */
+ mlx_uint32 reserved7 :32;
+ /* -------------- */
+ mlx_uint32 eth_proto_lp_advertise :32;
+ mlx_uint32 reserved[3];
};
mlx_status
diff --git a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.c b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.c
index 2277e0c7..1ea68dd8 100644
--- a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.c
+++ b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.c
@@ -42,6 +42,7 @@ struct nvconfig_tlv_mapping nvconfig_tlv_mapping[] = {
TlvMappingEntry(0x2020, 0x2020, NVRAM_TLV_CLASS_PHYSICAL_PORT, FALSE),
TlvMappingEntry(0x2021, 0x221, NVRAM_TLV_CLASS_HOST, FALSE),
TlvMappingEntry(0x2023, 0x223, NVRAM_TLV_CLASS_HOST, FALSE),
+ TlvMappingEntry(0x2006, 0x206, NVRAM_TLV_CLASS_HOST, FALSE),
TlvMappingEntry(0x2100, 0x230, NVRAM_TLV_CLASS_HOST, FALSE),
TlvMappingEntry(0x2101, 0x231, NVRAM_TLV_CLASS_HOST, FALSE),
TlvMappingEntry(0x2102, 0x232, NVRAM_TLV_CLASS_HOST, FALSE),
@@ -53,6 +54,7 @@ struct nvconfig_tlv_mapping nvconfig_tlv_mapping[] = {
TlvMappingEntry(0x2108, 0x238, NVRAM_TLV_CLASS_HOST, FALSE),
TlvMappingEntry(0x2109, 0x239, NVRAM_TLV_CLASS_HOST, FALSE),
TlvMappingEntry(0x210A, 0x23A, NVRAM_TLV_CLASS_HOST, FALSE),
+ TlvMappingEntry(0x2022, 0x222, NVRAM_TLV_CLASS_HOST, FALSE),
TlvMappingEntry(0x2200, 0x240, NVRAM_TLV_CLASS_HOST, FALSE),
TlvMappingEntry(0x2201, 0x241, NVRAM_TLV_CLASS_HOST, FALSE),
TlvMappingEntry(0x2202, 0x242, NVRAM_TLV_CLASS_HOST, FALSE),
@@ -60,6 +62,11 @@ struct nvconfig_tlv_mapping nvconfig_tlv_mapping[] = {
TlvMappingEntry(0x2204, 0x244, NVRAM_TLV_CLASS_HOST, FALSE),
TlvMappingEntry(0x2205, 0x245, NVRAM_TLV_CLASS_HOST, FALSE),
TlvMappingEntry(0x2207, 0x247, NVRAM_TLV_CLASS_HOST, FALSE),
+ TlvMappingEntry(0x2002, 0x202, NVRAM_TLV_CLASS_HOST, FALSE),
+ TlvMappingEntry(0x2004, 0x204, NVRAM_TLV_CLASS_HOST, FALSE),
+ TlvMappingEntry(0x110, 0x110, NVRAM_TLV_CLASS_HOST, FALSE),
+ TlvMappingEntry(0x192, 0x192, NVRAM_TLV_CLASS_GLOBAL, FALSE),
+ TlvMappingEntry(0x101, 0x101, NVRAM_TLV_CLASS_GLOBAL, TRUE),
TlvMappingEntry(0, 0, 0, 0),
};
diff --git a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h
index 8333e836..0a99bb1b 100644
--- a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h
+++ b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h
@@ -107,6 +107,22 @@ struct nvconfig_nvda {
mlx_uint8 data[NVCONFIG_MAX_TLV_SIZE];
};
+struct nv_conf_cap {
+ /** WOL En/Dis **/
+ mlx_uint8 wol_en;
+ /** VPI En/Dis **/
+ mlx_uint8 vpi_en;
+};
+
+struct mlx_nvconfig_virt_net_addr {
+ mlx_uint32 reserved1 :29;
+ mlx_uint32 erase_on_powerup:1;
+ mlx_uint32 reserverd2 :1;
+ mlx_uint32 virtual_mac_en :1;
+ mlx_uint32 virtual_mac_high;
+ mlx_uint32 virtual_mac_low;
+};
+
mlx_status
nvconfig_query_capability(
diff --git a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.c b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.c
index 77eda8a5..f5b2f155 100644
--- a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.c
+++ b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.c
@@ -86,13 +86,13 @@ nvconfig_get_boot_ext_default_conf(
"TLV not found. Using hard-coded defaults ");
port_conf_def->linkup_timeout = nic_boot_ext_conf->linkup_timeout;
port_conf_def->ip_ver = nic_boot_ext_conf->ip_ver;
-
+ port_conf_def->undi_network_wait_to = nic_boot_ext_conf->undi_network_wait_to;
return MLX_SUCCESS;
nvdata_access_err:
port_conf_def->linkup_timeout = DEFAULT_BOOT_LINK_UP_TO;
port_conf_def->ip_ver = DEFAULT_BOOT_IP_VER;
-
+ port_conf_def->undi_network_wait_to = DEFAULT_BOOT_UNDI_NETWORK_WAIT_TO;
return status;
}
@@ -185,8 +185,12 @@ nvconfig_get_iscsi_gen_default_conf(
port_conf_def->iscsi_chap_auth_en = iscsi_gen->chap_auth_en;
port_conf_def->iscsi_lun_busy_retry_count = iscsi_gen->lun_busy_retry_count;
port_conf_def->iscsi_link_up_delay_time = iscsi_gen->link_up_delay_time;
+ port_conf_def->iscsi_drive_num = iscsi_gen->drive_num;
+
+ return MLX_SUCCESS;
nvdata_access_err:
+ port_conf_def->iscsi_drive_num = DEFAULT_ISCSI_DRIVE_NUM;
return status;
}
@@ -327,6 +331,27 @@ nvdata_access_err:
return status;
}
+static
+mlx_status
+nvconfig_get_rom_cap_default_conf( IN void *data,
+ IN int status, OUT void *def_struct) {
+ union mlx_nvconfig_rom_cap_conf *rom_cap_conf =
+ (union mlx_nvconfig_rom_cap_conf *) data;
+ struct mlx_nvconfig_conf_defaults *conf_def =
+ (struct mlx_nvconfig_conf_defaults *) def_struct;
+
+ MLX_CHECK_STATUS(NULL, status, nvdata_access_err,
+ "TLV not found. Using hard-coded defaults ");
+ conf_def->boot_ip_ver_en = rom_cap_conf->boot_ip_ver_en;
+
+ return MLX_SUCCESS;
+
+nvdata_access_err:
+ rom_cap_conf->boot_ip_ver_en = DEFAULT_BOOT_IP_VERSION_EN;
+
+ return status;
+}
+
static struct tlv_default tlv_port_defaults[] = {
TlvDefaultEntry(BOOT_SETTINGS_TYPE, union mlx_nvconfig_nic_boot_conf, &nvconfig_get_boot_default_conf),
TlvDefaultEntry(BOOT_SETTINGS_EXT_TYPE, union mlx_nvconfig_nic_boot_ext_conf, &nvconfig_get_boot_ext_default_conf),
@@ -343,6 +368,7 @@ static struct tlv_default tlv_general_defaults[] = {
TlvDefaultEntry(GLOPAL_PCI_CAPS_TYPE, union mlx_nvconfig_virt_caps, &nvconfig_get_nv_virt_caps_default_conf),
TlvDefaultEntry(GLOPAL_PCI_SETTINGS_TYPE, union mlx_nvconfig_virt_conf, &nvconfig_get_nv_virt_default_conf),
TlvDefaultEntry(OCSD_OCBB_TYPE, union mlx_nvconfig_ocsd_ocbb_conf, &nvconfig_get_ocsd_ocbb_default_conf),
+ TlvDefaultEntry(NV_ROM_CAP_TYPE, union mlx_nvconfig_rom_cap_conf, &nvconfig_get_rom_cap_default_conf),
};
static
diff --git a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h
index 163c2a35..48699c35 100644
--- a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h
+++ b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h
@@ -32,9 +32,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
#define DEFAULT_BOOT_VLAN 1
#define DEFAULT_ISCSI_DHCP_PARAM_EN 1
#define DEFAULT_ISCSI_IPV4_DHCP_EN 1
+#define DEFAULT_ISCSI_DRIVE_NUM 0x80
#define DEFAULT_OCSD_OCBB_EN 1
#define DEFAULT_BOOT_IP_VER 0
#define DEFAULT_BOOT_LINK_UP_TO 0
+#define DEFAULT_BOOT_UNDI_NETWORK_WAIT_TO 30
+#define DEFAULT_BOOT_IP_VERSION_EN 1
struct mlx_nvconfig_port_conf_defaults {
mlx_uint8 pptx;
@@ -56,11 +59,13 @@ struct mlx_nvconfig_port_conf_defaults {
mlx_boolean iscsi_ipv4_dhcp_en;
mlx_uint8 iscsi_lun_busy_retry_count;
mlx_uint8 iscsi_link_up_delay_time;
+ mlx_uint8 iscsi_drive_num;
mlx_uint8 client_identifier;
mlx_uint8 mac_admin_bit;
mlx_uint8 default_link_type;
mlx_uint8 linkup_timeout;
mlx_uint8 ip_ver;
+ mlx_uint8 undi_network_wait_to;
};
struct mlx_nvconfig_conf_defaults {
@@ -71,6 +76,7 @@ struct mlx_nvconfig_conf_defaults {
mlx_uint8 uar_bar_size;
mlx_uint8 flexboot_menu_to;
mlx_boolean ocsd_ocbb_en;
+ mlx_boolean boot_ip_ver_en;
};
mlx_status
diff --git a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h
index 5b3af1e7..7fd52acc 100644
--- a/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h
+++ b/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h
@@ -33,12 +33,15 @@ enum {
OCSD_OCBB_TYPE = 0x2011,
FLOW_CONTROL_TYPE = 0x2020,
BOOT_SETTINGS_TYPE = 0x2021,
+ NV_ROM_FLEXBOOT_DEBUG = 0x2004,
+
ISCSI_GENERAL_SETTINGS_TYPE = 0x2100,
IB_BOOT_SETTING_TYPE = 0x2022,
IB_DHCP_SETTINGS_TYPE = 0x2023,
GLOPAL_PCI_SETTINGS_TYPE = 0x80,
GLOPAL_PCI_CAPS_TYPE = 0x81,
GLOBAL_ROM_INI_TYPE = 0x100,
+ NV_VIRT_NET_ADDR = 0x110,
// Types for iSCSI strings
DHCP_VEND_ID = 0x2101,
@@ -59,6 +62,8 @@ enum {
FIRST_TGT_ISCSI_NAME = 0x2204,
FIRST_TGT_CHAP_ID = 0x2205,
FIRST_TGT_CHAP_PWD = 0x2207,
+ NV_ROM_DEBUG_LEVEL = 0x2002,
+ NV_ROM_CAP_TYPE = 0x101,
};
union mlx_nvconfig_nic_boot_conf {
@@ -78,7 +83,9 @@ union mlx_nvconfig_nic_boot_ext_conf {
struct {
mlx_uint32 linkup_timeout : 8;
mlx_uint32 ip_ver : 2;
- mlx_uint32 reserved0 : 22;
+ mlx_uint32 reserved0 : 6;
+ mlx_uint32 undi_network_wait_to : 8;
+ mlx_uint32 reserved1 : 8;
};
mlx_uint32 dword;
};
@@ -194,7 +201,8 @@ union mlx_nvconfig_iscsi_general {
/*-------------------*/
mlx_uint32 lun_busy_retry_count:8;
mlx_uint32 link_up_delay_time :8;
- mlx_uint32 reserved4 :16;
+ mlx_uint32 drive_num :8;
+ mlx_uint32 reserved4 :8;
};
mlx_uint32 dword[3];
};
@@ -226,34 +234,98 @@ union mlx_nvconfig_vpi_link_conf {
};
struct mlx_nvcofnig_romini {
- mlx_uint32 reserved0 :1;
+ mlx_uint32 reserved0 :1;
mlx_uint32 shared_memory_en :1;
- mlx_uint32 hii_vpi_en :1;
- mlx_uint32 tech_enum :1;
- mlx_uint32 reserved1 :4;
+ mlx_uint32 hii_vpi_en :1;
+ mlx_uint32 tech_enum :1;
+ mlx_uint32 reserved1 :4;
mlx_uint32 static_component_name_string :1;
mlx_uint32 hii_iscsi_configuration :1;
- mlx_uint32 hii_ibm_aim :1;
+ mlx_uint32 hii_ibm_aim :1;
mlx_uint32 hii_platform_setup :1;
mlx_uint32 hii_bdf_decimal :1;
mlx_uint32 hii_read_only :1;
- mlx_uint32 reserved2 :10;
+ mlx_uint32 reserved2 :10;
mlx_uint32 mac_enum :1;
- mlx_uint32 port_enum :1;
+ mlx_uint32 port_enum :1;
mlx_uint32 flash_en :1;
mlx_uint32 fmp_en :1;
mlx_uint32 bofm_en :1;
- mlx_uint32 platform_to_driver_en :1;
+ mlx_uint32 platform_to_driver_en:1;
mlx_uint32 hii_en :1;
mlx_uint32 undi_en :1;
/* -------------- */
mlx_uint64 dhcp_user_class;
/* -------------- */
- mlx_uint32 reserved3 :22;
+ mlx_uint32 reserved3 :10;
+ mlx_uint32 ucm_single_port :1;
+ mlx_uint32 tivoli_wa_en :1;
+ mlx_uint32 dhcp_pxe_discovery_control_dis :1;
+ mlx_uint32 hii_flexaddr_override:1;
+ mlx_uint32 hii_flexaddr_setting :1;
+ mlx_uint32 guided_ops :1;
+ mlx_uint32 hii_type :4;
+ mlx_uint32 hii_mriname2 :1;
+ mlx_uint32 hii_aim_ucm_ver2 :1;
mlx_uint32 uri_boot_retry_delay :4;
mlx_uint32 uri_boot_retry :4;
mlx_uint32 option_rom_debug :1;
mlx_uint32 promiscuous_vlan :1;
+
+} __attribute__ ((packed));
+
+union mlx_nvconfig_debug_conf {
+ struct {
+ mlx_uint32 dbg_log_en :1;
+ mlx_uint32 reserved1 :31;
+ /***************************************************/
+ mlx_uint32 stp_dbg_lvl :2;
+ mlx_uint32 romprefix_dbg_lvl :2;
+ mlx_uint32 dhcp_dbg_lvl :2;
+ mlx_uint32 dhcpv6_dbg_lvl :2;
+ mlx_uint32 arp_dbg_lvl :2;
+ mlx_uint32 neighbor_dbg_lvl :2;
+ mlx_uint32 ndp_dbg_lvl :2;
+ mlx_uint32 uri_dbg_lvl :2;
+ mlx_uint32 driver_dbg_lvl :2;
+ mlx_uint32 nodnic_dbg_lvl :2;
+ mlx_uint32 nodnic_cmd_dbg_lvl :2;
+ mlx_uint32 nodnic_device_dbg_lvl :2;
+ mlx_uint32 nodnic_port_dbg_lvl :2;
+ mlx_uint32 netdevice_dbg_lvl :2;
+ mlx_uint32 tftp_dbg_lvl :2;
+ mlx_uint32 udp_dbg_lvl :2;
+ /***************************************************/
+ mlx_uint32 tcp_dbg_lvl :2;
+ mlx_uint32 tcpip_dbg_lvl :2;
+ mlx_uint32 ipv4_dbg_lvl :2;
+ mlx_uint32 ipv6_dbg_lvl :2;
+ mlx_uint32 drv_set_dbg_lvl :2;
+ mlx_uint32 stat_update_dbg_lvl :2;
+ mlx_uint32 pxe_undi_dbg_lvl :2;
+ mlx_uint32 reserved2 :18;
+ };
+ mlx_uint32 dword[3];
+};
+
+union mlx_nvconfig_flexboot_debug {
+ struct {
+ mlx_uint32 reserved0 :29;
+ mlx_uint32 panic_behavior :2;
+ mlx_uint32 boot_to_shell :1;
+ };
+ mlx_uint32 dword;
+};
+
+union mlx_nvconfig_rom_cap_conf {
+ struct {
+ mlx_uint32 reserved0 :28;
+ mlx_uint32 uefi_logs_en :1;
+ mlx_uint32 flexboot_debug_en :1;
+ mlx_uint32 boot_debug_log_en :1;
+ mlx_uint32 boot_ip_ver_en :1;
+ };
+ mlx_uint32 dword;
};
#endif /* MLX_NVCONFIG_PRM_H_ */
diff --git a/src/drivers/infiniband/mlx_utils/src/public/mlx_icmd.c b/src/drivers/infiniband/mlx_utils/src/public/mlx_icmd.c
index f7d365de..e4ab5f0a 100644
--- a/src/drivers/infiniband/mlx_utils/src/public/mlx_icmd.c
+++ b/src/drivers/infiniband/mlx_utils/src/public/mlx_icmd.c
@@ -316,7 +316,7 @@ mlx_icmd_send_command(
)
{
mlx_status status = MLX_SUCCESS;
- mlx_uint32 icmd_status = MLX_FAILED;
+ mlx_uint32 icmd_status = 0;
if (utils == NULL || data == NULL) {
status = MLX_INVALID_PARAMETER;
diff --git a/src/drivers/infiniband/mlx_utils/src/public/mlx_pci.c b/src/drivers/infiniband/mlx_utils/src/public/mlx_pci.c
index 91c44d99..f9f9b2a1 100644
--- a/src/drivers/infiniband/mlx_utils/src/public/mlx_pci.c
+++ b/src/drivers/infiniband/mlx_utils/src/public/mlx_pci.c
@@ -20,6 +20,7 @@
FILE_LICENCE ( GPL2_OR_LATER );
#include <stddef.h>
+
#include "../../include/private/mlx_pci_priv.h"
#include "../../include/public/mlx_pci.h"
@@ -39,6 +40,21 @@ bail:
}
mlx_status
+mlx_pci_teardown(
+ IN mlx_utils *utils
+ )
+{
+ mlx_status status = MLX_SUCCESS;
+ if( utils == NULL){
+ status = MLX_INVALID_PARAMETER;
+ goto bail;
+ }
+ status = mlx_pci_teardown_priv(utils);
+bail:
+ return status;
+}
+
+mlx_status
mlx_pci_read(
IN mlx_utils *utils,
IN mlx_pci_width width,
diff --git a/src/drivers/infiniband/mlx_utils/src/public/mlx_utils.c b/src/drivers/infiniband/mlx_utils/src/public/mlx_utils.c
index c824b17e..7ae35355 100644
--- a/src/drivers/infiniband/mlx_utils/src/public/mlx_utils.c
+++ b/src/drivers/infiniband/mlx_utils/src/public/mlx_utils.c
@@ -20,10 +20,10 @@
FILE_LICENCE ( GPL2_OR_LATER );
#include <stddef.h>
+
#include "../../include/private/mlx_utils_priv.h"
#include "../../include/public/mlx_pci.h"
#include "../../include/public/mlx_utils.h"
-
mlx_status
mlx_utils_init(
IN mlx_utils *utils,
@@ -44,11 +44,12 @@ bail:
mlx_status
mlx_utils_teardown(
- IN mlx_utils *utils __attribute__ ((unused))
+ IN mlx_utils *utils
)
{
mlx_status status = MLX_SUCCESS;
mlx_utils_free_lock(utils);
+ mlx_pci_teardown(utils);
return status;
}
diff --git a/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_logging_priv.h b/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_logging_priv.h
index af7e86f4..3acc1d9d 100644
--- a/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_logging_priv.h
+++ b/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_logging_priv.h
@@ -12,8 +12,8 @@
#include <compiler.h>
#define MLX_DEBUG_FATAL_ERROR_PRIVATE(...) do { \
- DBG("%s: ",__func__); \
- DBG(__VA_ARGS__); \
+ printf("%s: ",__func__); \
+ printf(__VA_ARGS__); \
} while ( 0 )
#define MLX_DEBUG_ERROR_PRIVATE(id, ...) do { \
@@ -56,6 +56,7 @@
DBG2(__VA_ARGS__); \
} while ( 0 )
+#define MLX_PRINT_PRIVATE(...) printf(__VA_ARGS__)
#endif /* STUB_MLXUTILS_INCLUDE_PRIVATE_FLEXBOOT_DEBUG_H_ */
diff --git a/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_types_priv.h b/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_types_priv.h
index feaeae67..fe0d5c05 100644
--- a/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_types_priv.h
+++ b/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_types_priv.h
@@ -33,7 +33,7 @@ typedef uint8_t mlx_uint8;
typedef uint16_t mlx_uint16;
typedef uint32_t mlx_uint32;
typedef uint64_t mlx_uint64;
-typedef uint32_t mlx_uintn;
+typedef unsigned long mlx_uintn;
typedef int8_t mlx_int8;
typedef int16_t mlx_int16;;
diff --git a/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c b/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c
index f8caefdc..b474a4a6 100644
--- a/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c
+++ b/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c
@@ -6,6 +6,7 @@
*/
#include <ipxe/pci.h>
+
#include "../../mlx_utils/include/private/mlx_pci_priv.h"
@@ -121,6 +122,18 @@ mlx_pci_init_priv(
}
mlx_status
+mlx_pci_teardown_priv(
+ IN mlx_utils *utils __attribute__ ((unused))
+ )
+{
+ mlx_status status = MLX_SUCCESS;
+#ifdef DEVICE_CX3
+ iounmap( utils->config );
+#endif
+ return status;
+}
+
+mlx_status
mlx_pci_read_priv(
IN mlx_utils *utils,
IN mlx_pci_width width,