summaryrefslogtreecommitdiffstats
path: root/src/drivers/infiniband/flexboot_nodnic.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/infiniband/flexboot_nodnic.c')
-rw-r--r--src/drivers/infiniband/flexboot_nodnic.c166
1 files changed, 131 insertions, 35 deletions
diff --git a/src/drivers/infiniband/flexboot_nodnic.c b/src/drivers/infiniband/flexboot_nodnic.c
index dea19ca69..1ee10f54b 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 );
}