From 26050fd4c87c50503d5bd573b2ec91703676e211 Mon Sep 17 00:00:00 2001 From: Raed Salem Date: Thu, 8 Dec 2016 11:01:51 +0200 Subject: [PATCH] [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 Modified-by: Michael Brown Signed-off-by: Michael Brown --- src/drivers/infiniband/flexboot_nodnic.c | 166 ++++++-- src/drivers/infiniband/flexboot_nodnic.h | 28 +- src/drivers/infiniband/golan.c | 206 ++++++---- src/drivers/infiniband/golan.h | 12 +- .../include/mlx_nodnic_data_structures.h | 32 +- .../infiniband/mlx_nodnic/include/mlx_port.h | 13 + .../infiniband/mlx_nodnic/src/mlx_device.c | 34 +- .../infiniband/mlx_nodnic/src/mlx_port.c | 354 +++++++++++++++++- .../mlx_utils/include/private/mlx_pci_priv.h | 5 + .../mlx_utils/include/public/mlx_logging.h | 1 + .../mlx_utils/include/public/mlx_pci.h | 5 + .../mlx_lib/mlx_link_speed/mlx_link_speed.h | 5 + .../mlx_lib/mlx_nvconfig/mlx_nvconfig.c | 7 + .../mlx_lib/mlx_nvconfig/mlx_nvconfig.h | 16 + .../mlx_nvconfig/mlx_nvconfig_defaults.c | 30 +- .../mlx_nvconfig/mlx_nvconfig_defaults.h | 6 + .../mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h | 94 ++++- .../mlx_utils/src/public/mlx_icmd.c | 2 +- .../infiniband/mlx_utils/src/public/mlx_pci.c | 16 + .../mlx_utils/src/public/mlx_utils.c | 5 +- .../include/mlx_logging_priv.h | 5 +- .../include/mlx_types_priv.h | 2 +- .../mlx_utils_flexboot/src/mlx_pci_priv.c | 13 + 23 files changed, 903 insertions(+), 154 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 #include #include -#include #include #include #include @@ -31,10 +30,6 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #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 +#include +#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 #include #include +#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 #include -#include #include #include #include #include #include #include +#include "flexboot_nodnic.h" #include #include +#include #include +#include +#include "mlx_utils/include/public/mlx_pci_gw.h" +#include #include -#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 -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include #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 @@ -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); 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 @@ -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, 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 @@ -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, 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 + #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, 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 + #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 #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 + #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,