david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[golan] Update Connect-IB, ConnectX-4 and ConnectX-4 Lx (Infiniband) support

Updates:
- Nodnic: Support for arm cq doorbell via the UAR BAR
- Ensure hardware is quiescent when no interface is open - WinPE WA
- Support for clear interrupt via BAR
- Nodnic: Support for send TX doorbells via the UAR BAR
- Added ConnectX-5EX device
- Added ConnectX-5 device

Signed-off-by: Raed Salem <raeds@mellanox.com>
Modified-by: Michael Brown <mcb30@ipxe.org>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Raed Salem 2016-12-08 11:01:51 +02:00 committed by Michael Brown
parent 5cf5ffea28
commit 26050fd4c8
23 changed files with 903 additions and 154 deletions

View 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 );
}

View 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_ */

View File

@ -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 = {

View File

@ -22,14 +22,15 @@
FILE_LICENCE ( GPL2_OR_LATER );
#include <byteswap.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <ipxe/io.h>
#include <ipxe/pci.h>
#include <ipxe/pcibackup.h>
#include <byteswap.h>
#include <errno.h>
#include <ipxe/io.h>
#include <stdio.h>
#include <unistd.h>
#include "CIB_PRM.h"
#include "mlx_utils/include/public/mlx_utils.h"
#define GOLAN_PCI_CONFIG_BAR_SIZE 0x100000//HERMON_PCI_CONFIG_BAR_SIZE //TODO: What is the BAR size?
@ -319,6 +320,7 @@ struct golan {
uint32_t pdn;
u32 mkey;
u32 flags;
mlx_utils *utils;
struct golan_port ports[GOLAN_MAX_PORTS];
};

View 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_ */

View 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_ */

View 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;

View 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);

View 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,

View 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__)

View 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,

View 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

View 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),
};

View 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(

View 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

View 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

View 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_ */

View 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;

View 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,

View File

@ -20,10 +20,10 @@
FILE_LICENCE ( GPL2_OR_LATER );
#include <stddef.h>
#include "../../include/private/mlx_utils_priv.h"
#include "../../include/public/mlx_pci.h"
#include "../../include/public/mlx_utils.h"
mlx_status
mlx_utils_init(
IN mlx_utils *utils,
@ -44,11 +44,12 @@ bail:
mlx_status
mlx_utils_teardown(
IN mlx_utils *utils __attribute__ ((unused))
IN mlx_utils *utils
)
{
mlx_status status = MLX_SUCCESS;
mlx_utils_free_lock(utils);
mlx_pci_teardown(utils);
return status;
}

View 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_ */

View 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;;

View 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,