#endif\r
\r
\r
+static ib_api_status_t\r
+ual_get_gid_index(\r
+ IN struct _al_ci_ca *p_ci_ca,\r
+ IN uint8_t port_num,\r
+ IN ib_gid_t *p_gid,\r
+ OUT uint16_t *p_index)\r
+{\r
+ ib_port_attr_t *p_port_attr;\r
+ ib_api_status_t status = IB_INVALID_GID;\r
+ uint16_t i;\r
+\r
+ ci_ca_lock_attr( p_ci_ca );\r
+ p_port_attr = &p_ci_ca->p_user_attr->p_port_attr[port_num];\r
+ for( i = 0; i < p_port_attr->num_gids; i++ )\r
+ {\r
+ if( !cl_memcmp(p_gid, &p_port_attr->p_gid_table[i], sizeof(ib_gid_t)) )\r
+ {\r
+ *p_index = i;\r
+ status = IB_SUCCESS;\r
+ break;\r
+ }\r
+ }\r
+ ci_ca_unlock_attr( p_ci_ca );\r
+\r
+ return status;\r
+}\r
\r
ib_api_status_t\r
ual_create_av(\r
cl_status_t cl_status = CL_ERROR;\r
ib_api_status_t status = IB_ERROR;\r
uvp_interface_t uvp_intf = h_pd->obj.p_ci_ca->verbs.user_verbs;\r
+ ib_av_attr_t av_attr;\r
+ uint16_t index;\r
\r
AL_ENTER( AL_DBG_AV );\r
/* Clear the ioctl_buf */\r
cl_memclr( &ioctl_buf, sizeof(ioctl_buf) );\r
+ av_attr = *p_av_attr;\r
\r
/* Pre call to the UVP library */\r
if( h_pd->h_ci_pd && uvp_intf.pre_create_av )\r
{\r
+ if( p_av_attr->grh_valid )\r
+ {\r
+ status = ual_get_gid_index(h_pd->obj.p_ci_ca, av_attr.port_num,\r
+ &av_attr.grh.src_gid, &index);\r
+ if( status != IB_SUCCESS )\r
+ goto out;\r
+ av_attr.grh.resv1 = index;\r
+ }\r
+\r
status = uvp_intf.pre_create_av( h_pd->h_ci_pd,\r
- p_av_attr, &ioctl_buf.in.umv_buf, &h_av->h_ci_av );\r
+ &av_attr, &ioctl_buf.in.umv_buf, &h_av->h_ci_av );\r
if( status != IB_SUCCESS )\r
{\r
AL_EXIT( AL_DBG_AV );\r
status, &h_av->h_ci_av, &ioctl_buf.out.umv_buf);\r
}\r
\r
+out:\r
AL_EXIT( AL_DBG_AV );\r
return status;\r
}\r
ib_api_status_t status = IB_ERROR;\r
ib_av_t* p_av = (ib_av_t*) h_av;\r
uvp_interface_t uvp_intf = p_av->obj.p_ci_ca->verbs.user_verbs;\r
+ ib_av_attr_t av_attr;\r
+ uint16_t index;\r
\r
AL_ENTER( AL_DBG_AV );\r
/* Clear the ioctl_buf */\r
cl_memclr( &ioctl_buf, sizeof(ioctl_buf) );\r
+ av_attr = *p_av_attr;\r
\r
/* Call the uvp pre call if the vendor library provided a valid ca handle */\r
if( p_av->h_ci_av && uvp_intf.pre_modify_av )\r
{\r
+ if( p_av_attr->grh_valid )\r
+ {\r
+ status = ual_get_gid_index(p_av->obj.p_ci_ca, av_attr.port_num,\r
+ &av_attr.grh.src_gid, &index);\r
+ if( status != IB_SUCCESS )\r
+ goto out;\r
+ av_attr.grh.resv1 = index;\r
+ }\r
+\r
/* Pre call to the UVP library */\r
status = uvp_intf.pre_modify_av( p_av->h_ci_av,\r
- p_av_attr, &ioctl_buf.in.umv_buf );\r
+ &av_attr, &ioctl_buf.in.umv_buf );\r
if( status == IB_VERBS_PROCESSING_DONE )\r
{\r
/* Modification is done in user mode. Issue the post call */\r
p_av->h_ci_av, status, &ioctl_buf.out.umv_buf );\r
}\r
\r
+out:\r
AL_EXIT( AL_DBG_AV );\r
return status;\r
}\r
\r
GetSystemInfo(&sys_info);\r
context->ibv_ctx.page_size = sys_info.dwPageSize;\r
- context->ibv_ctx.p_hca_attr = NULL;\r
\r
return &context->ibv_ctx;\r
\r
CloseHandle(context->xrc_srq_table_mutex);\r
#endif\r
CloseHandle(context->qp_table_mutex);\r
- if (context->ibv_ctx.p_hca_attr)\r
- cl_free(context->ibv_ctx.p_hca_attr);\r
cl_free(context);\r
}\r
\r
{\r
p_uvp->pre_open_ca = mlx4_pre_open_ca;\r
p_uvp->post_open_ca = mlx4_post_open_ca;\r
- p_uvp->pre_query_ca = mlx4_pre_query_ca;\r
- p_uvp->post_query_ca = mlx4_post_query_ca;\r
+ p_uvp->pre_query_ca = NULL;\r
+ p_uvp->post_query_ca = NULL;\r
p_uvp->pre_modify_ca = NULL;\r
p_uvp->post_modify_ca = NULL;\r
p_uvp->pre_close_ca = NULL;\r
return status;\r
}\r
\r
-ib_api_status_t\r
-mlx4_pre_query_ca (\r
- IN ib_ca_handle_t h_uvp_ca,\r
- IN ib_ca_attr_t *p_ca_attr,\r
- IN size_t byte_count,\r
- IN ci_umv_buf_t *p_umv_buf )\r
-{\r
- ib_api_status_t status = IB_SUCCESS;\r
-\r
- UNREFERENCED_PARAMETER(h_uvp_ca);\r
-\r
- /* Note that query_ca calls *always* get their attributes from the kernel.\r
- *\r
- * Assume if user buffer is valid then byte_cnt is valid too \r
- * so we can preallocate ca attr buffer for post ioctl data saving\r
- *\r
- * Note that we squirrel the buffer away into the umv_buf and only\r
- * set it into the HCA if the query is successful.\r
- */\r
- if ( p_ca_attr != NULL )\r
- {\r
- p_umv_buf->p_inout_buf = (ULONG_PTR)cl_malloc(byte_count);\r
- if ( !p_umv_buf->p_inout_buf )\r
- {\r
- status = IB_INSUFFICIENT_RESOURCES;\r
- goto end;\r
- }\r
- }\r
-\r
-end:\r
- return status;\r
-}\r
-\r
-void\r
-__fixup_ca_attr(\r
- IN ib_ca_attr_t* const p_dest,\r
- IN const ib_ca_attr_t* const p_src )\r
-{\r
- uint8_t i;\r
- uintn_t offset = (uintn_t)p_dest - (uintn_t)p_src;\r
- ib_port_attr_t *p_tmp_port_attr = NULL;\r
-\r
- CL_ASSERT( p_dest );\r
- CL_ASSERT( p_src );\r
-\r
- /* Fix up the pointers to point within the destination buffer. */\r
- p_dest->p_page_size =\r
- (uint32_t*)(((uint8_t*)p_dest->p_page_size) + offset);\r
-\r
- p_tmp_port_attr =\r
- (ib_port_attr_t*)(((uint8_t*)p_dest->p_port_attr) + offset);\r
-\r
- /* Fix up each port attribute's gid and pkey table pointers. */\r
- for( i = 0; i < p_dest->num_ports; i++ )\r
- {\r
- p_tmp_port_attr[i].p_gid_table = (ib_gid_t*)\r
- (((uint8_t*)p_tmp_port_attr[i].p_gid_table) + offset);\r
-\r
- p_tmp_port_attr[i].p_pkey_table =(ib_net16_t*)\r
- (((uint8_t*)p_tmp_port_attr[i].p_pkey_table) + offset);\r
- }\r
- p_dest->p_port_attr = p_tmp_port_attr;\r
-}\r
-\r
-void\r
-mlx4_post_query_ca (\r
- IN ib_ca_handle_t h_uvp_ca,\r
- IN ib_api_status_t ioctl_status,\r
- IN ib_ca_attr_t *p_ca_attr,\r
- IN size_t byte_count,\r
- IN ci_umv_buf_t *p_umv_buf )\r
-{\r
- struct ibv_context *context = (struct ibv_context *)h_uvp_ca;\r
- \r
- CL_ASSERT(context && p_umv_buf);\r
-\r
- if ( ioctl_status == IB_SUCCESS && p_ca_attr && byte_count)\r
- {\r
- CL_ASSERT( byte_count >= p_ca_attr->size );\r
-\r
- pthread_mutex_lock(&context->mutex);\r
-\r
- if (context->p_hca_attr)\r
- cl_free(context->p_hca_attr);\r
- context->p_hca_attr = (ib_ca_attr_t*)(ULONG_PTR)p_umv_buf->p_inout_buf;\r
- cl_memcpy( context->p_hca_attr, p_ca_attr, p_ca_attr->size );\r
- __fixup_ca_attr( context->p_hca_attr, p_ca_attr );\r
- \r
- pthread_mutex_unlock(&context->mutex);\r
- }\r
- else if (p_umv_buf->p_inout_buf) \r
- {\r
- cl_free( (void*)(ULONG_PTR)p_umv_buf->p_inout_buf );\r
- }\r
-}\r
-\r
ib_api_status_t\r
mlx4_post_close_ca (\r
IN ib_ca_handle_t h_uvp_ca,\r
return __from_qp_state(ibv_qp->state);\r
}\r
\r
-static uint8_t\r
-__gid_to_index_lookup (\r
- IN ib_ca_attr_t *p_ca_attr,\r
- IN uint8_t port_num,\r
- IN uint8_t *raw_gid )\r
-{\r
- ib_gid_t *p_gid_table = NULL;\r
- uint8_t i, index = 0;\r
- uint16_t num_gids;\r
-\r
- p_gid_table = p_ca_attr->p_port_attr[port_num-1].p_gid_table;\r
- CL_ASSERT (p_gid_table);\r
-\r
- num_gids = p_ca_attr->p_port_attr[port_num-1].num_gids;\r
-\r
- for (i = 0; i < num_gids; i++)\r
- {\r
- if (cl_memcmp (raw_gid, p_gid_table[i].raw, 16))\r
- {\r
- index = i;\r
- break;\r
- }\r
- }\r
- return index;\r
-}\r
-\r
static enum ibv_rate __to_rate(uint8_t rate)\r
{\r
if (rate == IB_PATH_RECORD_RATE_2_5_GBS) return IBV_RATE_2_5_GBPS;\r
\r
static ib_api_status_t\r
__to_ah (\r
- IN ib_ca_attr_t *p_ca_attr,\r
IN const ib_av_attr_t *p_av_attr,\r
OUT struct ibv_ah_attr *p_attr )\r
{\r
- if (p_av_attr->port_num == 0 || \r
- p_av_attr->port_num > p_ca_attr->num_ports) {\r
- MLX4_PRINT(TRACE_LEVEL_WARNING ,MLX4_DBG_AV ,\r
- (" invalid port number specified (%d)\n",p_av_attr->port_num));\r
- return IB_INVALID_PORT;\r
- }\r
-\r
p_attr->port_num = p_av_attr->port_num;\r
p_attr->sl = p_av_attr->sl;\r
p_attr->dlid = cl_ntoh16 (p_av_attr->dlid);\r
p_attr->grh.hop_limit = p_av_attr->grh.hop_limit;\r
__grh_get_ver_class_flow( p_av_attr->grh.ver_class_flow, NULL,\r
&p_attr->grh.traffic_class, &p_attr->grh.flow_label );\r
- p_attr->grh.sgid_index = __gid_to_index_lookup (p_ca_attr, p_av_attr->port_num,\r
- (uint8_t *) p_av_attr->grh.src_gid.raw); \r
+ p_attr->grh.sgid_index = (uint8_t) p_av_attr->grh.resv1;\r
cl_memcpy (p_attr->grh.dgid.raw, p_av_attr->grh.dest_gid.raw, 16);\r
}\r
else\r
\r
UNREFERENCED_PARAMETER(p_umv_buf);\r
\r
- if (pd->context->p_hca_attr == NULL) {\r
- status = IB_ERROR;\r
- goto end;\r
- }\r
-\r
ah = cl_malloc(sizeof *ah);\r
if (!ah) {\r
status = IB_INSUFFICIENT_MEMORY;\r
goto end;\r
}\r
\r
- // sanity check\r
- if (p_av_attr->port_num == 0 || \r
- p_av_attr->port_num > pd->context->p_hca_attr->num_ports)\r
- {\r
- status = IB_INVALID_PORT;\r
- goto end;\r
- }\r
-\r
// convert parameters \r
cl_memset(&attr, 0, sizeof(attr));\r
- status = __to_ah(pd->context->p_hca_attr, p_av_attr, &attr);\r
+ status = __to_ah(p_av_attr, &attr);\r
if (status)\r
goto end;\r
\r
\r
CL_ASSERT (h_uvp_av);\r
\r
- status = __to_ah(ah->context->p_hca_attr, p_addr_vector, &attr);\r
+ status = __to_ah(p_addr_vector, &attr);\r
if (status)\r
return status;\r
\r
};\r
\r
struct ibv_context {\r
- ib_ca_attr_t *p_hca_attr;\r
int page_size;\r
pthread_mutex_t mutex;\r
};\r
IN OUT ib_ca_handle_t *ph_uvp_ca,\r
IN ci_umv_buf_t *p_umv_buf );\r
\r
-ib_api_status_t\r
-mlx4_pre_query_ca (\r
- IN ib_ca_handle_t h_uvp_ca,\r
- IN ib_ca_attr_t *p_ca_attr,\r
- IN size_t byte_count,\r
- IN ci_umv_buf_t *p_umv_buf );\r
-\r
-void\r
-mlx4_post_query_ca (\r
- IN ib_ca_handle_t h_uvp_ca,\r
- IN ib_api_status_t ioctl_status,\r
- IN ib_ca_attr_t *p_ca_attr,\r
- IN size_t byte_count,\r
- IN ci_umv_buf_t *p_umv_buf );\r
-\r
ib_api_status_t\r
mlx4_post_close_ca (\r
IN ib_ca_handle_t h_uvp_ca,\r
IN OUT ci_umv_buf_t *p_umv_buf);\r
\r
\r
-uint8_t\r
-gid_to_index_lookup (\r
- IN ib_ca_attr_t *p_ca_attr,\r
- IN uint8_t port_num,\r
- IN uint8_t *raw_gid)\r
-{\r
- ib_gid_t *p_gid_table = NULL;\r
- uint8_t i, index = 0;\r
- uint16_t num_gids;\r
-\r
- p_gid_table = p_ca_attr->p_port_attr[port_num-1].p_gid_table;\r
- CL_ASSERT (p_gid_table);\r
-\r
- num_gids = p_ca_attr->p_port_attr[port_num-1].num_gids;\r
- UVP_PRINT(TRACE_LEVEL_INFORMATION, UVP_DBG_AV, \r
- ("Port %d has %d gids\n", port_num, num_gids));\r
-\r
- for (i = 0; i < num_gids; i++)\r
- {\r
- if (cl_memcmp (raw_gid, p_gid_table[i].raw, sizeof (ib_gid_t)))\r
- {\r
- UVP_PRINT(TRACE_LEVEL_INFORMATION ,UVP_DBG_AV ,\r
- ("found GID at index %d\n", i));\r
- index = i;\r
- break;\r
- }\r
- }\r
- return index;\r
-}\r
-\r
ib_api_status_t\r
map_itom_av_attr (\r
- IN ib_ca_attr_t *p_ca_attr,\r
IN const ib_av_attr_t *p_av_attr,\r
OUT struct ibv_ah_attr *p_attr)\r
{\r
-\r
-\r
ib_api_status_t status = IB_SUCCESS;\r
- if (p_av_attr->port_num == 0 || \r
- p_av_attr->port_num > p_ca_attr->num_ports) {\r
- UVP_PRINT(TRACE_LEVEL_WARNING ,UVP_DBG_AV ,\r
- (" invalid port number specified (%d)\n",p_av_attr->port_num));\r
- return IB_INVALID_PORT;\r
- }\r
\r
p_attr->sl = p_av_attr->sl;\r
p_attr->port_num = p_av_attr->port_num;\r
p_attr->grh.hop_limit = p_av_attr->grh.hop_limit;\r
ib_grh_get_ver_class_flow( p_av_attr->grh.ver_class_flow, NULL,\r
&p_attr->grh.traffic_class, &p_attr->grh.flow_label );\r
- p_attr->grh.sgid_index = gid_to_index_lookup (p_ca_attr, \r
- p_av_attr->port_num, (uint8_t *) p_av_attr->grh.src_gid.raw); \r
+ p_attr->grh.sgid_index = (uint8_t) p_av_attr->grh.resv1;\r
cl_memcpy (p_attr->grh.dgid.raw, p_av_attr->grh.dest_gid.raw, \r
sizeof (IB_gid_t));\r
}else{\r
\r
CL_ASSERT(p_umv_buf);\r
\r
- // sanity check\r
- if (p_av_attr->port_num == 0 || p_av_attr->port_num > p_hobul->p_hca_attr->num_ports) {\r
- UVP_PRINT(TRACE_LEVEL_WARNING ,UVP_DBG_AV ,\r
- (" invalid port number specified (%d)\n",p_av_attr->port_num));\r
- status = IB_INVALID_PORT;\r
- goto end;\r
- }\r
-\r
// convert parameters \r
cl_memset( &attr, 0, sizeof(attr));\r
- status = map_itom_av_attr (p_hobul->p_hca_attr, p_av_attr, &attr);\r
+ status = map_itom_av_attr (p_av_attr, &attr);\r
if(status != IB_SUCCESS ) \r
goto end;\r
\r
p_hobul = p_pd_info->p_hobul;\r
CL_ASSERT (p_hobul);\r
\r
- status = map_itom_av_attr (p_hobul->p_hca_attr, p_addr_vector, &attr);\r
+ status = map_itom_av_attr (p_addr_vector, &attr);\r
if(status != IB_SUCCESS) return status;\r
\r
mthca_set_av_params( mthca_ah, &attr);\r
\r
/* return results */\r
new_ca->ibv_ctx = ibvcontext;\r
- new_ca->p_hca_attr = NULL;\r
*ph_uvp_ca = (ib_ca_handle_t)new_ca;\r
}\r
\r
return status;\r
}\r
\r
-static ib_api_status_t\r
-__pre_query_ca (\r
- IN ib_ca_handle_t h_uvp_ca,\r
- IN ib_ca_attr_t *p_ca_attr,\r
- IN size_t byte_count,\r
- IN ci_umv_buf_t *p_umv_buf )\r
-{\r
- ib_api_status_t status = IB_SUCCESS;\r
-\r
- UVP_ENTER(UVP_DBG_SHIM);\r
-\r
- CL_ASSERT(h_uvp_ca);\r
-\r
- /*\r
- * First time call query_ca - populate our internal cached attributes\r
- * so we can access the GID table. Note that query_ca calls *always*\r
- * get their attributes from the kernel.\r
- */\r
- if ( !h_uvp_ca->p_hca_attr )\r
- {\r
- /*\r
- * Assume if user buffer is valid then byte_cnt is valid too \r
- * so we can preallocate ca attr buffer for post ioctl data saving\r
- *\r
- * Note that we squirel the buffer away into the umv_buf and only\r
- * set it into the HCA if the query is successful.\r
- */\r
- if ( p_ca_attr != NULL )\r
- {\r
- p_umv_buf->p_inout_buf = (ULONG_PTR)cl_zalloc(byte_count);\r
- if ( !p_umv_buf->p_inout_buf )\r
- {\r
- UVP_PRINT(TRACE_LEVEL_ERROR ,UVP_DBG_SHIM ,\r
- ("Failed to alloc new_ca\n"));\r
- status = IB_INSUFFICIENT_RESOURCES;\r
- return status;\r
- }\r
- }\r
- p_umv_buf->input_size = p_umv_buf->output_size = 0;\r
- }\r
-\r
- UVP_EXIT(UVP_DBG_SHIM);\r
- return status;\r
-}\r
-\r
-\r
-static void\r
-__post_query_ca (\r
- IN ib_ca_handle_t h_uvp_ca,\r
- IN ib_api_status_t ioctl_status,\r
- IN ib_ca_attr_t *p_ca_attr,\r
- IN size_t byte_count,\r
- IN ci_umv_buf_t *p_umv_buf )\r
-{\r
- UVP_ENTER(UVP_DBG_SHIM);\r
-\r
- CL_ASSERT(h_uvp_ca);\r
- CL_ASSERT(p_umv_buf);\r
-\r
- if ( ioctl_status == IB_SUCCESS && p_ca_attr &&\r
- byte_count && !h_uvp_ca->p_hca_attr )\r
- {\r
- CL_ASSERT( byte_count >= p_ca_attr->size );\r
- h_uvp_ca->p_hca_attr = (ib_ca_attr_t*)(ULONG_PTR)p_umv_buf->p_inout_buf;\r
- ib_copy_ca_attr( h_uvp_ca->p_hca_attr, p_ca_attr );\r
- }\r
- else if (p_umv_buf->p_inout_buf) \r
- {\r
- cl_free( (void*)(ULONG_PTR)p_umv_buf->p_inout_buf );\r
- }\r
-\r
- UVP_EXIT(UVP_DBG_SHIM);\r
- return;\r
-}\r
-\r
\r
static ib_api_status_t\r
__pre_modify_ca (\r
p_hobul->ibv_ctx = NULL;\r
}\r
\r
- if (p_hobul->p_hca_attr) {\r
- cl_free( p_hobul->p_hca_attr);\r
- p_hobul->p_hca_attr = NULL;\r
- }\r
-\r
cl_free(p_hobul);\r
}\r
\r
p_uvp->post_open_ca = __post_open_ca;\r
\r
\r
- p_uvp->pre_query_ca = __pre_query_ca;\r
- p_uvp->post_query_ca = __post_query_ca;\r
+ p_uvp->pre_query_ca = NULL;\r
+ p_uvp->post_query_ca = NULL;\r
\r
p_uvp->pre_modify_ca = NULL;\r
p_uvp->post_modify_ca = NULL;\r
typedef struct _ib_ca\r
{\r
struct ibv_context *ibv_ctx;\r
- ib_ca_attr_t *p_hca_attr;\r
} mlnx_ual_hobul_t;\r
\r
\r
typedef struct _ib_grh\r
{\r
ib_net32_t ver_class_flow;\r
- ib_net16_t resv1;\r
+ uint16_t resv1;\r
uint8_t resv2;\r
uint8_t hop_limit;\r
ib_gid_t src_gid;\r
* [in] Vendor's user-mode library handle to the Protection domain\r
* to which this AV is associated.\r
* p_addr_vector\r
-* [in] Parameters to create the address vector.\r
+* [in] Parameters to create the address vector. If the grh of the\r
+* address vector is valid, then the grh resv1 field should be set to\r
+* the index of the src_gid.\r
* p_umv_buf\r
* [in out] On input, UAL provides this buffer template.\r
* On return from this function, p_umv_buf contains\r
* h_uvp_av\r
* [in] Vendor's AV handle in user-mode library.\r
* p_addr_vector\r
-* [in] Parameters to modify the address vector handle\r
+* [in] Parameters to modify the address vector handle. If the grh of the\r
+* address vector is valid, then the grh resv1 field should be set to\r
+* the index of the src_gid.\r
* p_umv_buf\r
* [in out] On input, UAL provides this buffer template.\r
* On return from this function, p_umv_buf contains\r