mirror of https://github.com/ipxe/ipxe.git
[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>pull/55/head^2
parent
5cf5ffea28
commit
26050fd4c8
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -22,14 +22,15 @@
|
|||
|
||||
FILE_LICENCE ( GPL2_OR_LATER );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <ipxe/io.h>
|
||||
#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 "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];
|
||||
};
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
@ -186,6 +193,30 @@ invalid_parm:
|
|||
return status;
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -30,6 +30,11 @@ mlx_pci_init_priv(
|
|||
IN mlx_utils *utils
|
||||
);
|
||||
|
||||
mlx_status
|
||||
mlx_pci_teardown_priv(
|
||||
IN mlx_utils *utils
|
||||
);
|
||||
|
||||
mlx_status
|
||||
mlx_pci_read_priv(
|
||||
IN mlx_utils *utils,
|
||||
|
|
|
@ -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__)
|
||||
|
|
|
@ -36,6 +36,11 @@ mlx_pci_init(
|
|||
IN mlx_utils *utils
|
||||
);
|
||||
|
||||
mlx_status
|
||||
mlx_pci_teardown(
|
||||
IN mlx_utils *utils
|
||||
);
|
||||
|
||||
mlx_status
|
||||
mlx_pci_read(
|
||||
IN mlx_utils *utils,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
@ -38,6 +39,21 @@ bail:
|
|||
return status;
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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;;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <ipxe/pci.h>
|
||||
|
||||
#include "../../mlx_utils/include/private/mlx_pci_priv.h"
|
||||
|
||||
|
||||
|
@ -120,6 +121,18 @@ mlx_pci_init_priv(
|
|||
return status;
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
Loading…
Reference in New Issue