/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
/*
* Hermon Channel Interface (CI) Routines
*
* Implements all the routines necessary to interface with the IBTF.
* Pointers to all of these functions are passed to the IBTF at attach()
* time in the ibc_operations_t structure. These functions include all
* of the necessary routines to implement the required InfiniBand "verbs"
* and additional IBTF-specific interfaces.
*/
extern uint32_t hermon_kernel_data_ro;
extern uint32_t hermon_user_data_ro;
/* HCA and port related operations */
/* Protection Domains */
ibc_pd_hdl_t *);
/* Reliable Datagram Domains */
ibc_rdd_hdl_t *);
/* Address Handles */
ibc_pd_hdl_t *, ibt_adds_vect_t *);
ibt_adds_vect_t *);
/* Queue Pairs */
ibc_qp_hdl_t *);
ibt_chan_sizes_t *, ibc_qp_hdl_t *);
/* Completion Queues */
/* EE Contexts */
/* Memory Registration */
ibc_mr_hdl_t *, ibt_mr_desc_t *);
ibt_mr_desc_t *);
ibt_mr_desc_t *);
/* Memory Windows */
/* Multicast Groups */
/* Work Request and Completion Processing */
/* CI Object Private Data */
ibt_object_type_t, void *, void *, size_t);
/* CI Object Private Data */
ibt_object_type_t, void *, void *, size_t);
/* Shared Receive Queues */
ibt_srq_sizes_t *);
/* Address translation */
ibt_all_wr_t *, ibc_mi_hdl_t *);
/* Allocate L_Key */
/* Physical Register Memory Region */
ibt_pmr_desc_t *);
/* Mellanox FMR */
/* Memory Allocation/Deallocation */
static ibt_status_t hermon_ci_not_supported();
/*
* This ibc_operations_t structure includes pointers to all the entry points
* provided by the Hermon driver. This structure is passed to the IBTF at
* driver attach time, using the ibc_attach() call.
*/
/* HCA and port related operations */
/* Protection Domains */
/* Reliable Datagram Domains */
/* Address Handles */
/* Queue Pairs */
/* Completion Queues */
/* EE Contexts */
/* Memory Registration */
/* Memory Windows */
/* Multicast Groups */
/* Work Request and Completion Processing */
/* CI Object Mapping Data */
/* Shared Receive Queue */
/* Address translation */
/* Allocate L_key */
/* Physical Register Memory Region */
/* Mellanox FMR */
/* Memory allocation */
/* XRC not yet supported */
hermon_ci_not_supported, /* ibc_alloc_xrc_domain */
hermon_ci_not_supported, /* ibc_free_xrc_domain */
hermon_ci_not_supported, /* ibc_alloc_xrc_srq */
hermon_ci_not_supported, /* ibc_free_xrc_srq */
hermon_ci_not_supported, /* ibc_query_xrc_srq */
hermon_ci_not_supported, /* ibc_modify_xrc_srq */
hermon_ci_not_supported, /* ibc_alloc_xrc_tgt_qp */
hermon_ci_not_supported, /* ibc_free_xrc_tgt_qp */
hermon_ci_not_supported, /* ibc_query_xrc_tgt_qp */
hermon_ci_not_supported, /* ibc_modify_xrc_tgt_qp */
/* Memory Region (physical) */
/* Next enhancements */
hermon_ci_not_supported, /* ibc_enhancement1 */
hermon_ci_not_supported, /* ibc_enhancement2 */
hermon_ci_not_supported, /* ibc_enhancement3 */
hermon_ci_not_supported, /* ibc_enhancement4 */
};
/*
* Not yet implemented OPS
*/
/* ARGSUSED */
static ibt_status_t
{
return (IBT_NOT_SUPPORTED);
}
/*
* hermon_ci_query_hca_ports()
* Returns HCA port attributes for either one or all of the HCA's ports.
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
/* Grab the Hermon softstate pointer */
/*
* If the specified port is zero, then we are supposed to query all
* ports. Otherwise, we query only the port number specified.
* Setup the start and end port numbers as appropriate for the loop
* below. Note: The first Hermon port is port number one (1).
*/
if (query_port == 0) {
start = 1;
} else {
}
/* Query the port(s) */
if (status != DDI_SUCCESS) {
return (status);
}
}
return (IBT_SUCCESS);
}
/*
* hermon_ci_modify_ports()
* Modify HCA port attributes
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer */
/* Modify the port(s) */
return (status);
}
/*
* hermon_ci_modify_system_image()
* Modify the System Image GUID
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
/*
* This is an unsupported interface for the Hermon driver. This
* interface is necessary to support modification of the System
* Image GUID. Hermon is only capable of modifying this parameter
* once (during driver initialization).
*/
return (IBT_NOT_SUPPORTED);
}
/*
* hermon_ci_alloc_pd()
* Allocate a Protection Domain
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer */
/* Allocate the PD */
if (status != DDI_SUCCESS) {
return (status);
}
/* Return the Hermon PD handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_free_pd()
* Free a Protection Domain
* Context: Can be called only from user or kernel context
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and PD handle */
/* Free the PD */
return (status);
}
/*
* hermon_ci_alloc_rdd()
* Allocate a Reliable Datagram Domain
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
/*
* This is an unsupported interface for the Hermon driver. This
* interface is necessary to support Reliable Datagram (RD)
* operations. Hermon does not support RD.
*/
return (IBT_NOT_SUPPORTED);
}
/*
* hermon_free_rdd()
* Free a Reliable Datagram Domain
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
/*
* This is an unsupported interface for the Hermon driver. This
* interface is necessary to support Reliable Datagram (RD)
* operations. Hermon does not support RD.
*/
return (IBT_NOT_SUPPORTED);
}
/*
* hermon_ci_alloc_ah()
* Allocate an Address Handle
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and PD handle */
/* Allocate the AH */
if (status != DDI_SUCCESS) {
return (status);
}
/* Return the Hermon AH handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_free_ah()
* Free an Address Handle
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and AH handle */
/* Free the AH */
return (status);
}
/*
* hermon_ci_query_ah()
* Return the Address Vector information for a specified Address Handle
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and AH handle */
/* Query the AH */
if (status != DDI_SUCCESS) {
return (status);
}
/* Return the Hermon PD handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_modify_ah()
* Modify the Address Vector information of a specified Address Handle
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and AH handle */
/* Modify the AH */
return (status);
}
/*
* hermon_ci_alloc_qp()
* Allocate a Queue Pair
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer */
/* Allocate the QP */
if (status != DDI_SUCCESS) {
return (status);
}
/* Return the Hermon QP handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_alloc_special_qp()
* Allocate a Special Queue Pair
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer */
/* Allocate the Special QP */
if (status != DDI_SUCCESS) {
return (status);
}
/* Return the Hermon QP handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_alloc_qp_range()
* Free a Queue Pair
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer */
/* Allocate the QP */
return (status);
}
/*
* hermon_ci_free_qp()
* Free a Queue Pair
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and QP handle */
/* Free the QP */
return (status);
}
/*
* hermon_ci_release_qpn()
* Release a Queue Pair Number (QPN)
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
/* Grab the Hermon softstate pointer and QP handle */
/* Release the QP number */
return (IBT_SUCCESS);
}
/*
* hermon_ci_query_qp()
* Query a Queue Pair
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and QP handle */
/* Query the QP */
return (status);
}
/*
* hermon_ci_modify_qp()
* Modify a Queue Pair
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and QP handle */
/* Modify the QP */
return (status);
}
/*
* hermon_ci_alloc_cq()
* Allocate a Completion Queue
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/* Allocate the CQ */
&cqhdl, HERMON_NOSLEEP);
if (status != DDI_SUCCESS) {
return (status);
}
/* Return the Hermon CQ handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_free_cq()
* Free a Completion Queue
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and CQ handle */
/* Free the CQ */
return (status);
}
/*
* hermon_ci_query_cq()
* Return the size of a Completion Queue
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
/* Grab the CQ handle */
/* Query the current CQ size */
return (IBT_SUCCESS);
}
/*
* hermon_ci_resize_cq()
* Change the size of a Completion Queue
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and CQ handle */
/* Resize the CQ */
if (status != DDI_SUCCESS) {
return (status);
}
return (IBT_SUCCESS);
}
/*
* hermon_ci_modify_cq()
* Change the interrupt moderation values of a Completion Queue
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and CQ handle */
/* Resize the CQ */
return (status);
}
/*
* hermon_ci_alloc_cq_sched()
* Reserve a CQ scheduling class resource
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
(hermon_cq_sched_t **)sched_hdl_p);
return (status);
}
/*
* hermon_ci_free_cq_sched()
* Free a CQ scheduling class resource
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
return (status);
}
static ibt_status_t
{
return (IBT_CQ_HID_INVALID);
return (IBT_INVALID_PARAM);
return (IBT_SUCCESS);
}
/*
* hermon_ci_alloc_eec()
* Allocate an End-to-End context
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
/*
* This is an unsupported interface for the Hermon driver. This
* interface is necessary to support Reliable Datagram (RD)
* operations. Hermon does not support RD.
*/
return (IBT_NOT_SUPPORTED);
}
/*
* hermon_ci_free_eec()
* Free an End-to-End context
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
/*
* This is an unsupported interface for the Hermon driver. This
* interface is necessary to support Reliable Datagram (RD)
* operations. Hermon does not support RD.
*/
return (IBT_NOT_SUPPORTED);
}
/*
* hermon_ci_query_eec()
* Query an End-to-End context
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
/*
* This is an unsupported interface for the Hermon driver. This
* interface is necessary to support Reliable Datagram (RD)
* operations. Hermon does not support RD.
*/
return (IBT_NOT_SUPPORTED);
}
/*
* hermon_ci_modify_eec()
* Modify an End-to-End context
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
/*
* This is an unsupported interface for the Hermon driver. This
* interface is necessary to support Reliable Datagram (RD)
* operations. Hermon does not support RD.
*/
return (IBT_NOT_SUPPORTED);
}
/*
* hermon_ci_register_mr()
* Prepare a virtually addressed Memory Region for use by an HCA
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/*
* Validate the access flags. Both Remote Write and Remote Atomic
* require the Local Write flag to be set
*/
return (IBT_MR_ACCESS_REQ_INVALID);
}
/* Grab the Hermon softstate pointer and PD handle */
/* Register the memory region */
op.mro_bind_override_addr = 0;
&op, HERMON_MPT_DMPT);
if (status != DDI_SUCCESS) {
return (status);
}
/* Fill in the mr_desc structure */
/* Only set RKey if remote access was requested */
}
/*
* If region is mapped for streaming (i.e. noncoherent), then set
* sync is required
*/
/* Return the Hermon MR handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_register_buf()
* Prepare a Memory Region specified by buf structure for use by an HCA
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/*
* Validate the access flags. Both Remote Write and Remote Atomic
* require the Local Write flag to be set
*/
if (((flags & IBT_MR_ENABLE_REMOTE_WRITE) ||
(flags & IBT_MR_ENABLE_REMOTE_ATOMIC)) &&
!(flags & IBT_MR_ENABLE_LOCAL_WRITE)) {
return (IBT_MR_ACCESS_REQ_INVALID);
}
/* Grab the Hermon softstate pointer and PD handle */
/* Register the memory region */
op.mro_bind_override_addr = 0;
if (status != DDI_SUCCESS) {
return (status);
}
/* Fill in the mr_desc structure */
/* Only set RKey if remote access was requested */
if ((flags & IBT_MR_ENABLE_REMOTE_ATOMIC) ||
(flags & IBT_MR_ENABLE_REMOTE_WRITE) ||
(flags & IBT_MR_ENABLE_REMOTE_READ)) {
}
/*
* If region is mapped for streaming (i.e. noncoherent), then set
* sync is required
*/
/* Return the Hermon MR handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_deregister_mr()
* Deregister a Memory Region from an HCA translation table
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer */
/*
* Deregister the memory region.
*/
return (status);
}
/*
* hermon_ci_query_mr()
* Retrieve information about a specified Memory Region
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and MR handle */
/* Query the memory region */
return (status);
}
/*
* hermon_ci_register_shared_mr()
* Create a shared memory region matching an existing Memory Region
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/*
* Validate the access flags. Both Remote Write and Remote Atomic
* require the Local Write flag to be set
*/
return (IBT_MR_ACCESS_REQ_INVALID);
}
/* Grab the Hermon softstate pointer and handles */
/* Register the shared memory region */
&mrhdl_new);
if (status != DDI_SUCCESS) {
return (status);
}
/* Fill in the mr_desc structure */
/* Only set RKey if remote access was requested */
}
/*
* If shared region is mapped for streaming (i.e. noncoherent), then
* set sync is required
*/
/* Return the Hermon MR handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_reregister_mr()
* Modify the attributes of an existing Memory Region
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer, mrhdl, and pdhdl */
/* Reregister the memory region */
if (status != DDI_SUCCESS) {
return (status);
}
/* Fill in the mr_desc structure */
/* Only set RKey if remote access was requested */
}
/*
* If region is mapped for streaming (i.e. noncoherent), then set
* sync is required
*/
/* Return the Hermon MR handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_reregister_buf()
* Modify the attributes of an existing Memory Region
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer, mrhdl, and pdhdl */
/* Reregister the memory region */
if (status != DDI_SUCCESS) {
return (status);
}
/* Fill in the mr_desc structure */
/* Only set RKey if remote access was requested */
if ((flags & IBT_MR_ENABLE_REMOTE_ATOMIC) ||
(flags & IBT_MR_ENABLE_REMOTE_WRITE) ||
(flags & IBT_MR_ENABLE_REMOTE_READ)) {
}
/*
* If region is mapped for streaming (i.e. noncoherent), then set
* sync is required
*/
/* Return the Hermon MR handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_sync_mr()
* Synchronize access to a Memory Region
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer */
/* Sync the memory region */
return (status);
}
/*
* hermon_ci_alloc_mw()
* Allocate a Memory Window
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and PD handle */
/* Allocate the memory window */
if (status != DDI_SUCCESS) {
return (status);
}
/* Return the MW handle and RKey */
return (IBT_SUCCESS);
}
/*
* hermon_ci_free_mw()
* Free a Memory Window
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and MW handle */
/* Free the memory window */
return (status);
}
/*
* hermon_ci_query_mw()
* Return the attributes of the specified Memory Window
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
/* Query the memory window pointer and fill in the return values */
return (IBT_SUCCESS);
}
/*
* hermon_ci_register_dma_mr()
* Allocate a memory region that maps physical addresses.
* Context: Can be called only from user or kernel context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/*
* Validate the access flags. Both Remote Write and Remote Atomic
* require the Local Write flag to be set
*/
return (IBT_MR_ACCESS_REQ_INVALID);
}
/* Grab the Hermon softstate pointer and PD handle */
if (status != DDI_SUCCESS) {
return (status);
}
/* Fill in the mr_desc structure */
/* Only set RKey if remote access was requested */
}
/*
* If region is mapped for streaming (i.e. noncoherent), then set
* sync is required
*/
/* Return the Hermon MR handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_attach_mcg()
* Attach a Queue Pair to a Multicast Group
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and QP handles */
/* Attach the QP to the multicast group */
return (status);
}
/*
* hermon_ci_detach_mcg()
* Detach a Queue Pair to a Multicast Group
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and QP handle */
/* Detach the QP from the multicast group */
return (status);
}
/*
* hermon_ci_post_send()
* Post send work requests to the send queue on the specified QP
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and QP handle */
/* Post the send WQEs */
return (status);
}
/*
* hermon_ci_post_recv()
* Post receive work requests to the receive queue on the specified QP
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Post the receive WQEs */
return (status);
}
/*
* hermon_ci_poll_cq()
* Poll for a work request completion
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Check for valid num_wc field */
if (num_wc == 0) {
return (IBT_INVALID_PARAM);
}
/* Grab the Hermon softstate pointer and CQ handle */
/* Poll for work request completions */
return (status);
}
/*
* hermon_ci_notify_cq()
* Enable notification events on the specified CQ
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and CQ handle */
/* Enable the CQ notification */
return (status);
}
/*
* hermon_ci_ci_data_in()
* Exchange CI-specific data.
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer */
/* Get the Hermon userland mapping information */
return (status);
}
/*
* hermon_ci_ci_data_out()
* Exchange CI-specific data.
* Context: Can be called only from user or kernel context.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer */
/* Get the Hermon userland mapping information */
return (status);
}
/*
* hermon_ci_alloc_srq()
* Allocate a Shared Receive Queue (SRQ)
* Context: Can be called only from user or kernel context
*/
static ibt_status_t
{
int status;
if (status != DDI_SUCCESS) {
return (status);
}
return (IBT_SUCCESS);
}
/*
* hermon_ci_free_srq()
* Free a Shared Receive Queue (SRQ)
* Context: Can be called only from user or kernel context
*/
static ibt_status_t
{
int status;
/* Check for valid SRQ handle pointer */
return (IBT_SRQ_HDL_INVALID);
}
/* Free the SRQ */
return (status);
}
/*
* hermon_ci_query_srq()
* Query properties of a Shared Receive Queue (SRQ)
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
return (IBT_SRQ_ERROR_STATE);
}
*limit_p = 0;
return (IBT_SUCCESS);
}
/*
* hermon_ci_modify_srq()
* Modify properties of a Shared Receive Queue (SRQ)
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/*
* Check Error State of SRQ.
* Also, while we are holding the lock we save away the current SRQ
* size for later use.
*/
return (IBT_SRQ_ERROR_STATE);
}
/*
* Setting the limit watermark is not currently supported. This is a
* hermon hardware (firmware) limitation. We return NOT_SUPPORTED here,
* and have the limit code commented out for now.
*
* XXX If we enable the limit watermark support, we need to do checks
* and set the 'srq->srq_wr_limit' here, instead of returning not
* supported. The 'hermon_srq_modify' operation below is for resizing
* the SRQ only, the limit work should be done here. If this is
* changed to use the 'limit' field, the 'ARGSUSED' comment for this
* function should also be removed at that time.
*/
if (flags & IBT_SRQ_SET_LIMIT) {
return (IBT_NOT_SUPPORTED);
}
/*
* Check the SET_SIZE flag. If not set, we simply return success here.
* However if it is set, we check if resize is supported and only then
* do we continue on with our resize processing.
*/
if (!(flags & IBT_SRQ_SET_SIZE)) {
return (IBT_SUCCESS);
}
return (IBT_NOT_SUPPORTED);
}
/*
* We do not support resizing an SRQ to be smaller than it's current
* size. If a smaller (or equal) size is requested, then we simply
* return success, and do nothing.
*/
if (size <= cur_srq_size) {
return (IBT_SUCCESS);
}
if (status != DDI_SUCCESS) {
/* Set return value to current SRQ size */
return (status);
}
return (IBT_SUCCESS);
}
/*
* hermon_ci_post_srq()
* Post a Work Request to the specified Shared Receive Queue (SRQ)
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
return (status);
}
/* Address translation */
struct ibc_ma_s {
int h_ma_addr_list_len;
void *h_ma_addr_list;
};
static ibt_status_t
{
int status;
int i, kmflag;
return (IBT_NOT_SUPPORTED); /* XXX - not yet implemented */
}
kmflag = KM_NOSLEEP;
} else {
}
return (IBT_INSUFF_RESOURCE);
}
#ifdef __sparc
#endif
if (status != DDI_SUCCESS) {
return (IBT_INSUFF_RESOURCE);
}
if (status != DDI_DMA_MAPPED) {
status = ibc_get_ci_failure(0);
goto marea_fail3;
}
goto marea_fail4;
}
i = 0;
len = 0;
while (cookie_cnt-- > 0) {
if (i >= list_len) {
goto marea_fail5;
}
i++;
if (addr == 0) {
do_once))
if (do_once) {
do_once = 0;
"dma_cookie address: map_mem_area");
}
break;
}
}
if (cookie_cnt != 0)
}
pmr->pmr_num_buf = i;
return (IBT_SUCCESS);
return (ibt_status);
}
/*
* hermon_ci_map_mem_area()
* Context: Can be called from user or base context.
*
* Creates the memory mapping suitable for a subsequent posting of an
* FRWR work request. All the info about the memory area for the
* FRWR work request (wr member of "union ibt_reg_req_u") is filled
* such that the client only needs to point wr.rc.rcwr.reg_pmr to it,
* and then fill in the additional information only it knows.
*
* Alternatively, creates the memory mapping for FMR.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
int i, j, kmflag;
/* delegate FMR and Physical Register to other function */
}
/* FRWR */
return (IBT_NOT_SUPPORTED);
#ifdef __sparc
#endif
kmflag = KM_NOSLEEP;
} else {
}
return (IBT_INSUFF_RESOURCE);
}
if (status != DDI_SUCCESS) {
goto marea_fail0;
}
if (status != DDI_SUCCESS) {
goto marea_fail1;
}
/*
* Entries in the list in the last slot on each page cannot be used,
* so 1 extra ibt_phys_addr_t is allocated per page. We add 1 more
* to deal with the possibility of a less than 1 page allocation
* across a page boundary.
*/
sizeof (ibt_phys_addr_t),
if (status != DDI_SUCCESS) {
goto marea_fail2;
}
&kcookie, &cookie_cnt);
if (status != DDI_SUCCESS) {
goto marea_fail3;
}
ibt_status = ibc_get_ci_failure(0);
goto marea_fail4;
}
} else {
}
if (status != DDI_DMA_MAPPED) {
ibt_status = ibc_get_ci_failure(0);
goto marea_fail4;
}
i = 0; /* count the number of pbl entries */
j = 0; /* count the number of links to next HERMON_PAGE */
len = 0;
while (cookie_cnt-- > 0) {
if (i >= list_len) {
goto marea_fail5;
}
/* Deal with last entry on page. */
} else {
}
j++;
}
i++;
if (addr == 0) {
do_once))
if (do_once) {
do_once = 0;
"dma_cookie address: map_mem_area");
}
break;
}
}
if (cookie_cnt != 0)
}
pmr->pmr_num_buf = i;
return (IBT_SUCCESS);
if (status != DDI_SUCCESS)
if (status != DDI_SUCCESS)
return (ibt_status);
}
/*
* hermon_ci_unmap_mem_area()
* Unmap the memory area
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
return (IBT_MA_HDL_INVALID);
}
if (status != DDI_SUCCESS)
} else {
}
if (status != DDI_SUCCESS)
return (IBT_SUCCESS);
}
struct ibc_mi_s {
int imh_len;
};
/*
* hermon_ci_map_mem_iov()
* Map the memory
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
int kmflag;
#ifdef __sparc
#endif
nds = 0;
if (iov_attr->iov_lso_hdr_sz)
0xf) >> 4; /* 0xf is for rounding up to a multiple of 16 */
} else {
kmflag = KM_NOSLEEP;
}
return (IBT_INSUFF_RESOURCE);
if (status != DDI_SUCCESS) {
return (IBT_INSUFF_RESOURCE);
}
&dmacookie, &cookie_cnt);
if (status != DDI_DMA_MAPPED) {
return (ibc_get_ci_failure(0));
}
while (cookie_cnt-- > 0) {
if (status != DDI_SUCCESS)
"unbind DMA mapping");
return (IBT_SGL_TOO_SMALL);
}
nds++;
if (cookie_cnt != 0)
}
return (IBT_SUCCESS);
}
else
for (i = 0, j = 0; j < len; j++) {
continue;
i++;
}
return (IBT_INSUFF_RESOURCE);
for (i = 0, j = 0; j < len; j++) {
continue;
if (status != DDI_SUCCESS) {
goto fail2;
}
&dmacookie, &cookie_cnt);
if (status != DDI_DMA_MAPPED) {
ibt_status = ibc_get_ci_failure(0);
goto fail1;
}
goto fail2;
}
while (cookie_cnt-- > 0) {
nds++;
if (cookie_cnt != 0)
}
i++;
}
else
return (IBT_SUCCESS);
while (--i >= 0) {
if (status != DDI_SUCCESS)
}
return (ibt_status);
}
/*
* hermon_ci_unmap_mem_iov()
* Unmap the memory
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status, i;
if (status != DDI_SUCCESS)
}
return (IBT_SUCCESS);
}
/*
* hermon_ci_alloc_lkey()
* Allocate an empty memory region for use with FRWR.
* Context: Can be called from user or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
return (IBT_NOT_SUPPORTED);
if (status != DDI_SUCCESS) {
return (status);
}
/* Fill in the mem_desc_p structure */
mem_desc_p->pmd_iova = 0;
/* Only set RKey if remote access was requested */
if (flags & IBT_KEY_REMOTE) {
}
/* Return the Hermon MR handle */
return (IBT_SUCCESS);
}
/* Physical Register Memory Region */
/*
* hermon_ci_register_physical_mr()
*/
/* ARGSUSED */
static ibt_status_t
{
return (IBT_NOT_SUPPORTED);
}
/*
* hermon_ci_reregister_physical_mr()
*/
/* ARGSUSED */
static ibt_status_t
{
return (IBT_NOT_SUPPORTED);
}
/* Mellanox FMR Support */
/*
* hermon_ci_create_fmr_pool()
* Creates a pool of memory regions suitable for FMR registration
* Context: Can be called from base context only
*/
static ibt_status_t
{
int status;
/* Check for valid PD handle pointer */
return (IBT_PD_HDL_INVALID);
}
/*
* Validate the access flags. Both Remote Write and Remote Atomic
* require the Local Write flag to be set
*/
return (IBT_MR_ACCESS_REQ_INVALID);
}
if (status != DDI_SUCCESS) {
return (status);
}
/* Set fmr_pool from hermon handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_destroy_fmr_pool()
* Free all resources associated with an FMR pool.
* Context: Can be called from base context only.
*/
static ibt_status_t
{
int status;
return (status);
}
/*
* hermon_ci_flush_fmr_pool()
* Force a flush of the memory tables, cleaning up used FMR resources.
* Context: Can be called from interrupt or base context.
*/
static ibt_status_t
{
int status;
return (status);
}
/*
* hermon_ci_register_physical_fmr()
* From the 'pool' of FMR regions passed in, performs register physical
* operation.
* Context: Can be called from interrupt or base context.
*/
/* ARGSUSED */
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer */
&mrhdl, mem_desc_p);
if (status != DDI_SUCCESS) {
return (status);
}
/*
* If region is mapped for streaming (i.e. noncoherent), then set
* sync is required
*/
/* Fill in DMA handle for future sync operations */
}
/* Return the Hermon MR handle */
return (IBT_SUCCESS);
}
/*
* hermon_ci_deregister_fmr()
* Moves an FMR (specified by 'mr') to the deregistered state.
* Context: Can be called from base context only.
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer */
/*
* Deregister the memory region, either "unmap" the FMR or deregister
* the normal memory region.
*/
return (status);
}
static int
{
int status;
/* Allocate a DMA handle */
if (status != DDI_SUCCESS) {
return (DDI_FAILURE);
}
/* Allocate DMA memory */
if (status != DDI_SUCCESS) {
return (DDI_FAILURE);
}
/* Package the hermon_dma_info contents and return */
if (mem_alloc_hdl == NULL) {
return (DDI_FAILURE);
}
*mem_hdl = mem_alloc_hdl;
return (DDI_SUCCESS);
}
/*
* hermon_ci_alloc_io_mem()
* Allocate dma-able memory
*
*/
static ibt_status_t
{
int status;
/* Grab the Hermon softstate pointer and mem handle */
/* Allocate the memory and handles */
if (status != DDI_SUCCESS) {
*mem_alloc_hdl_p = NULL;
return (status);
}
return (IBT_SUCCESS);
}
/*
* hermon_ci_free_io_mem()
* Unbind handl and free the memory
*/
/* ARGSUSED */
static ibt_status_t
{
/* Unbind the handles and free the memory */
return (IBT_SUCCESS);
}