]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[golan] Update Connect-IB, ConnectX-4 and ConnectX-4 Lx (Infiniband) support
authorRaed Salem <raeds@mellanox.com>
Thu, 8 Dec 2016 09:01:51 +0000 (11:01 +0200)
committerMichael Brown <mcb30@ipxe.org>
Thu, 8 Dec 2016 09:35:52 +0000 (09:35 +0000)
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>
23 files changed:
src/drivers/infiniband/flexboot_nodnic.c
src/drivers/infiniband/flexboot_nodnic.h
src/drivers/infiniband/golan.c
src/drivers/infiniband/golan.h
src/drivers/infiniband/mlx_nodnic/include/mlx_nodnic_data_structures.h
src/drivers/infiniband/mlx_nodnic/include/mlx_port.h
src/drivers/infiniband/mlx_nodnic/src/mlx_device.c
src/drivers/infiniband/mlx_nodnic/src/mlx_port.c
src/drivers/infiniband/mlx_utils/include/private/mlx_pci_priv.h
src/drivers/infiniband/mlx_utils/include/public/mlx_logging.h
src/drivers/infiniband/mlx_utils/include/public/mlx_pci.h
src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h
src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.c
src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h
src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.c
src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h
src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h
src/drivers/infiniband/mlx_utils/src/public/mlx_icmd.c
src/drivers/infiniband/mlx_utils/src/public/mlx_pci.c
src/drivers/infiniband/mlx_utils/src/public/mlx_utils.c
src/drivers/infiniband/mlx_utils_flexboot/include/mlx_logging_priv.h
src/drivers/infiniband/mlx_utils_flexboot/include/mlx_types_priv.h
src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c

index dea19ca690a766fd554a1b7c68eae0c570214ebe..1ee10f54bdcdf6057a8cc277c6f45057cfad6171 100644 (file)
@@ -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 );
 }
index 80272296c3910ebe100436102c9d65c59e721c88..3020f7455a2f53a8cad5d31886c12d3343e65a82 100644 (file)
@@ -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_ */
index d410fdfb968e0baf9a3b1678efc941e6130c9460..b704a939f9ac0e0b7acd7c63727790784a4b8dc1 100755 (executable)
@@ -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 = {
index a6cb4e7443714b976a1f21229ce713278d8e2365..c5227dd73dea9aba1184d922fd836e3f772d1940 100755 (executable)
 
 FILE_LICENCE ( GPL2_OR_LATER );
 
+#include <ipxe/pci.h>
+#include <ipxe/pcibackup.h>
 #include <byteswap.h>
 #include <errno.h>
+#include <ipxe/io.h>
 #include <stdio.h>
 #include <unistd.h>
-#include <ipxe/io.h>
-#include <ipxe/pci.h>
-#include <ipxe/pcibackup.h>
 #include "CIB_PRM.h"
+#include "mlx_utils/include/public/mlx_utils.h"
 
 #define GOLAN_PCI_CONFIG_BAR_SIZE      0x100000//HERMON_PCI_CONFIG_BAR_SIZE //TODO: What is the BAR size?
 
@@ -319,6 +320,7 @@ struct golan {
        uint32_t                        pdn;
        u32                             mkey;
        u32                             flags;
+       mlx_utils               *utils;
 
        struct golan_port               ports[GOLAN_MAX_PORTS];
 };
index f58213b98a8a59bedad8396c1b35470f33d9a1c0..61f2c5736ba77074a767f99bbe6670a9c6ba5926 100644 (file)
@@ -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_ */
index 4fd96a6dadc26ea702debd879d421d25c4e705b7..bb3026729ce90ce6d28e5f24ec01e6b93d6e4ed6 100644 (file)
@@ -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_ */
index 4acc94fa6aa1f6440e91dacfb9877c97fb92cdc8..f6fdacdbfc698e6d5203a2e5d716fd17f0fd1bd6 100644 (file)
@@ -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;
index a7afdab650540d21d2aa2f8e8e51aa5e50099fd0..efbd8ddf743ce8333e1ecf7a55230de9608700ff 100644 (file)
@@ -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);
 
index 89cad75eb21a2c02f88a7145878f73ce69d4c28f..cf35e5b73ea63242f4a9f18804df1c398fbb8c0a 100644 (file)
@@ -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,
index 7b7b852d11c2ee5bc637e47e07b8a81d0abb82a0..7ff06bbf5146883b68eade86517982c177356f5f 100644 (file)
@@ -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__)
index 416bdb66b5e81cdb26b1040a54f1e699ac49e569..60eb55d52e65601f529b48c00d2a366334cf0eab 100644 (file)
@@ -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,
index 15b28f57a1555a96ae1d85dbbb132df24306ec05..cb167d6aeafa45f2eca1ffc621af51688fa30a56 100644 (file)
@@ -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
index 2277e0c76e98ffc5f1804e831da0791a26294805..1ea68dd8a7a777e3c3251a06392a34df7736be96 100644 (file)
@@ -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),
 };
 
index 8333e83680cb15ba98d24d1dac769468483885e7..0a99bb1b55d21de60328aea32e533838e3ca773d 100644 (file)
@@ -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(
index 77eda8a5c1297aa55b4c94e30ffcea139538d5c2..f5b2f155f8fc7f702c9800dbff9f315354f438e2 100644 (file)
@@ -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
index 163c2a35f2c974f44220c697e25cf3aed71a675e..48699c3588bde71089d5e84e6dbf58f99c87147c 100644 (file)
@@ -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
index 5b3af1e78100bbd333a2a33b451c3594d94870e6..7fd52accc6109175f973a600d5ccfac17a92aa36 100644 (file)
@@ -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_ */
index f7d365deef719821c3a02f774a964cf282283044..e4ab5f0ad5f73a07ced9c8a2a95e52108ace8b8e 100644 (file)
@@ -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;
index 91c44d991a3ded0cf796022a50b51dc171cd0acf..f9f9b2a12f95a06bb1dab826d82ba14b582f41a9 100644 (file)
@@ -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,
index c824b17e9bf918b8f4e9e66bbe9b623390ab0dc3..7ae35355d1037295667e34de5a5621152bb4d382 100644 (file)
 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;
 }
 
index af7e86f44ca1cdcc79ff71a219252e42fde1a418..3acc1d9d8fa7940cd157dba702fd58789611f04a 100644 (file)
@@ -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_ */
index feaeae6795c33644f8f7aaf6f534ba9e33546899..fe0d5c0566c7628a3b267a2a8a4eec78e10500e1 100644 (file)
@@ -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;;
index f8caefdce9d1a4e181f11be07d7fb2261ad8d790..b474a4a634ac20b693b9b3815ea03601f6c630ba 100644 (file)
@@ -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,