#include "ipoib_port.tmh"\r
#endif\r
\r
-/*\r
- * PR 102492 relates to the SA not accepting wildcard values for MCMemberRecord\r
- * Sets used to create/join Multicast groups. Defining this keyword causes all\r
- * member record fields to be hard coded to well known values.\r
- */\r
-//#define PR_102492\r
-\r
-/*\r
- * PR 102801 relates to the SA ignoring the MGID when doing a GET_TABLE\r
- * request that specifies an MGID. The ESM returns every McMemberRecord\r
- * instead.\r
- */\r
-//#define PR_102801\r
-\r
\r
/* Amount of physical memory to register. */\r
#define MEM_REG_SIZE 0xFFFFFFFFFFFFFFFF\r
* MCast operations.\r
*\r
******************************************************************************/\r
-static void\r
-__port_get_mcast(\r
+static ib_api_status_t\r
+__port_get_bcast(\r
IN ipoib_port_t* const p_port );\r
\r
-static void\r
+static ib_api_status_t\r
__port_join_bcast(\r
IN ipoib_port_t* const p_port,\r
IN ib_member_rec_t* const p_member_rec );\r
\r
-static void\r
+static ib_api_status_t\r
__port_create_bcast(\r
IN ipoib_port_t* const p_port );\r
\r
\r
__endpt_mgr_construct( p_port );\r
\r
+ KeInitializeEvent( &p_port->sa_event, NotificationEvent, TRUE );\r
+\r
IPOIB_EXIT( IPOIB_DBG_INIT );\r
}\r
\r
return status;\r
}\r
\r
- /* Add the broadcast endpoint to the enpoint map. */\r
+ /* Add the broadcast endpoint to the endpoint map. */\r
cl_memset( &bcast_mac, 0xFF, sizeof(bcast_mac) );\r
__endpt_mgr_insert_locked( p_port, bcast_mac, p_endpt );\r
\r
\r
IPOIB_ENTER( IPOIB_DBG_INIT );\r
\r
- /* Wait for all receives to get flushed. */\r
- while( p_port->recv_mgr.depth )\r
+ /* Wait for all work requests to get flushed. */\r
+ while( p_port->recv_mgr.depth || p_port->send_mgr.depth )\r
cl_thread_suspend( 0 );\r
\r
- p_port->state = IB_QPS_RTS;\r
+ cl_obj_lock( &p_port->obj );\r
+ p_port->state = IB_QPS_INIT;\r
+ KeResetEvent( &p_port->sa_event );\r
+ cl_obj_unlock( &p_port->obj );\r
\r
info.method = IB_MAD_METHOD_GET;\r
info.attr_id = IB_MAD_ATTR_PORTINFO_RECORD;\r
/* reference the object for the multicast query. */\r
cl_obj_ref( &p_port->obj );\r
\r
- status =\r
- p_port->p_adapter->p_ifc->query( p_port->p_adapter->h_al, &query, &p_port->ib_mgr.h_query );\r
+ status = p_port->p_adapter->p_ifc->query(\r
+ p_port->p_adapter->h_al, &query, &p_port->ib_mgr.h_query );\r
if( status != IB_SUCCESS )\r
{\r
- p_port->p_adapter->hung = TRUE;\r
+ KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );\r
+ ipoib_set_inactive( p_port->p_adapter );\r
cl_obj_deref( &p_port->obj );\r
IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
("ib_query returned %s\n", \r
av_attr.dlid = p_port_info->base_lid;\r
av_attr.static_rate = ib_port_info_compute_rate( p_port_info );\r
av_attr.path_bits = 0;\r
- status =\r
- p_port->p_adapter->p_ifc->create_av( p_port->ib_mgr.h_pd, &av_attr, &p_endpt->h_av );\r
+ status = p_port->p_adapter->p_ifc->create_av(\r
+ p_port->ib_mgr.h_pd, &av_attr, &p_endpt->h_av );\r
if( status != IB_SUCCESS )\r
{\r
cl_obj_destroy( &p_endpt->obj );\r
return status;\r
}\r
\r
- __endpt_mgr_insert_locked( p_port, p_port->p_adapter->mac, p_endpt );\r
+ /* __endpt_mgr_insert expects *one* reference to be held. */\r
+ cl_atomic_inc( &p_port->endpt_rdr );\r
+ __endpt_mgr_insert( p_port, p_port->p_adapter->mac, p_endpt );\r
+ cl_atomic_dec( &p_port->endpt_rdr );\r
\r
p_port->p_local_endpt = p_endpt;\r
\r
\r
cl_obj_lock( &p_port->obj );\r
p_port->ib_mgr.h_query = NULL;\r
- cl_obj_unlock( &p_port->obj );\r
\r
- switch( p_query_rec->status )\r
+ if( p_port->state != IB_QPS_INIT )\r
+ {\r
+ status = IB_CANCELED;\r
+ goto done;\r
+ }\r
+\r
+ status = p_query_rec->status;\r
+\r
+ switch( status )\r
{\r
case IB_SUCCESS:\r
/* Note that the we report the rate from the port info. */\r
p_port_rec->port_info.link_width_active,\r
ib_port_info_get_link_speed_active( &p_port_rec->port_info ) );\r
\r
- __port_get_mcast( p_port );\r
+ status = __port_get_bcast( p_port );\r
}\r
else\r
{\r
EVENT_IPOIB_PORT_INFO_TIMEOUT, 0 );\r
IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
("Port info query timed out.\n") );\r
- ipoib_set_inactive( p_port->p_adapter );\r
break;\r
\r
case IB_REMOTE_ERROR:\r
EVENT_IPOIB_PORT_INFO_REJECT, 0 );\r
IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
("Port info query rejected by SA.\n") );\r
- ipoib_set_inactive( p_port->p_adapter );\r
break;\r
\r
default:\r
/* Hopefully we'll get an SM change event that will restart things. */\r
IPOIB_PRINT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
("Port info query failed.\n") );\r
- ipoib_set_inactive( p_port->p_adapter );\r
+ }\r
+\r
+done:\r
+ cl_obj_unlock( &p_port->obj );\r
+\r
+ if( status != IB_SUCCESS )\r
+ {\r
+ if( status != IB_CANCELED )\r
+ ipoib_set_inactive( p_port->p_adapter );\r
+\r
+ KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );\r
}\r
\r
/* Return the response MAD to AL. */\r
}\r
\r
\r
-static void\r
-__port_get_mcast(\r
+static ib_api_status_t\r
+__port_get_bcast(\r
IN ipoib_port_t* const p_port )\r
{\r
ib_api_status_t status;\r
/* reference the object for the multicast query. */\r
cl_obj_ref( &p_port->obj );\r
\r
- status =\r
- p_port->p_adapter->p_ifc->query( p_port->p_adapter->h_al, &query, &p_port->ib_mgr.h_query );\r
+ status = p_port->p_adapter->p_ifc->query(\r
+ p_port->p_adapter->h_al, &query, &p_port->ib_mgr.h_query );\r
if( status != IB_SUCCESS )\r
{\r
cl_obj_deref( &p_port->obj );\r
- IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
("ib_query returned %s\n", \r
p_port->p_adapter->p_ifc->get_err_str( status )) );\r
- return;\r
}\r
\r
IPOIB_EXIT( IPOIB_DBG_MCAST );\r
+ return status;\r
}\r
\r
\r
{\r
ipoib_port_t *p_port;\r
ib_member_rec_t *p_mc_req;\r
-#ifdef PR_102801\r
- uint32_t i;\r
-#endif\r
+ ib_api_status_t status;\r
\r
IPOIB_ENTER( IPOIB_DBG_MCAST );\r
\r
\r
cl_obj_lock( &p_port->obj );\r
p_port->ib_mgr.h_query = NULL;\r
- cl_obj_unlock( &p_port->obj );\r
+ if( p_port->state != IB_QPS_INIT )\r
+ {\r
+ status = IB_CANCELED;\r
+ goto done;\r
+ }\r
\r
- switch( p_query_rec->status )\r
+ status = p_query_rec->status;\r
+\r
+ switch( status )\r
{\r
case IB_SUCCESS:\r
- if( !p_query_rec->result_cnt )\r
- {\r
- __port_create_bcast( p_port );\r
- break;\r
- }\r
-#ifdef PR_102801\r
- p_mc_req = NULL;\r
- /* Loop through the records until we find one with the proper MGID. */\r
- for( i = 0; i < p_query_rec->result_cnt; i++ )\r
+ if( p_query_rec->result_cnt )\r
{\r
p_mc_req = (ib_member_rec_t*)\r
- ib_get_query_result( p_query_rec->p_result_mad, i );\r
- if( cl_memcmp(\r
- &p_mc_req->mgid, &bcast_mgid_template, sizeof(ib_gid_t) ) == 0 )\r
- {\r
- break;\r
- }\r
- }\r
- /*\r
- * If we didn't get any records with the desired MGID,\r
- * create the group.\r
- */\r
- if( i == p_query_rec->result_cnt )\r
- {\r
- __port_create_bcast( p_port );\r
+ ib_get_query_result( p_query_rec->p_result_mad, 0 );\r
+\r
+ /* Join the broadcast group. */\r
+ status = __port_join_bcast( p_port, p_mc_req );\r
break;\r
}\r
-#else\r
- p_mc_req = (ib_member_rec_t*)\r
- ib_get_query_result( p_query_rec->p_result_mad, 0 );\r
-#endif\r
- /* Join the broadcast group. */\r
- __port_join_bcast( p_port, p_mc_req );\r
- break;\r
+ /* Fall through. */\r
\r
case IB_REMOTE_ERROR:\r
- /*\r
- * SA failed the query. Broadcast group doesn't exist, so create it.\r
- */\r
- __port_create_bcast( p_port );\r
+ /* SA failed the query. Broadcast group doesn't exist, create it. */\r
+ status = __port_create_bcast( p_port );\r
break;\r
\r
case IB_CANCELED:\r
IPOIB_PRINT(TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
("Instance destroying - Aborting.\n") );\r
- \r
+ break;\r
+\r
default:\r
NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,\r
EVENT_IPOIB_BCAST_GET, 1, p_query_rec->status );\r
- ipoib_set_inactive( p_port->p_adapter );\r
+ }\r
+\r
+done:\r
+ cl_obj_unlock( &p_port->obj );\r
+\r
+ if( status != IB_SUCCESS )\r
+ {\r
+ if( status != IB_CANCELED )\r
+ ipoib_set_inactive( p_port->p_adapter );\r
+\r
+ KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );\r
}\r
\r
/* Return the response MAD to AL. */\r
}\r
\r
\r
-static void\r
+static ib_api_status_t\r
__port_join_bcast(\r
IN ipoib_port_t* const p_port,\r
IN ib_member_rec_t* const p_member_rec )\r
EVENT_IPOIB_BCAST_RATE, 2,\r
(uint32_t)(p_member_rec->rate & 0x3F),\r
(uint32_t)p_port->ib_mgr.rate );\r
- return;\r
+ return IB_ERROR;\r
}\r
\r
/* Join the broadcast group. */\r
/* reference the object for the multicast join request. */\r
cl_obj_ref( &p_port->obj );\r
\r
- status = p_port->p_adapter->p_ifc->join_mcast( p_port->ib_mgr.h_qp, &mcast_req );\r
+ status = p_port->p_adapter->p_ifc->join_mcast(\r
+ p_port->ib_mgr.h_qp, &mcast_req );\r
if( status != IB_SUCCESS )\r
{\r
cl_obj_deref( &p_port->obj );\r
- IPOIB_PRINT_EXIT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
+ IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
("ib_join_mcast returned %s\n", \r
p_port->p_adapter->p_ifc->get_err_str( status )) );\r
- return;\r
}\r
IPOIB_EXIT( IPOIB_DBG_MCAST );\r
+ return status;\r
}\r
\r
\r
-static void\r
+static ib_api_status_t\r
__port_create_bcast(\r
IN ipoib_port_t* const p_port )\r
{\r
* IPOIB spec requires that the QKEY have the MSb set so that the QKEY\r
* from the QP is used rather than the QKEY in the send WR.\r
*/\r
-#ifdef PR_102492\r
- mcast_req.member_rec.qkey = CL_HTON32(0x80000B1B);\r
-#else\r
mcast_req.member_rec.qkey =\r
(uint32_t)(uintn_t)p_port | IB_QP_PRIVILEGED_Q_KEY;\r
-#endif\r
mcast_req.member_rec.mtu =\r
(IB_PATH_SELECTOR_EXACTLY << 6) | IB_MTU_2048;\r
\r
mcast_req.member_rec.pkey = IB_DEFAULT_PKEY;\r
\r
-#ifdef PR_102492\r
- mcast_req.member_rec.rate =\r
- (IB_PATH_SELECTOR_LARGEST << 6);// | IB_PATH_RECORD_RATE_10_GBS;\r
-#endif\r
mcast_req.member_rec.sl_flow_hop = ib_member_set_sl_flow_hop( 0, 0, 0 );\r
mcast_req.member_rec.scope_state =\r
ib_member_set_scope_state( 2, IB_MC_REC_STATE_FULL_MEMBER );\r
p_port->p_adapter->p_ifc->get_err_str( status )) );\r
}\r
IPOIB_EXIT( IPOIB_DBG_MCAST );\r
+ return status;\r
}\r
\r
\r
\r
if( p_port->ib_mgr.h_query )\r
{\r
- p_port->p_adapter->p_ifc->cancel_query( p_port->p_adapter->h_al, p_port->ib_mgr.h_query );\r
+ p_port->p_adapter->p_ifc->cancel_query(\r
+ p_port->p_adapter->h_al, p_port->ib_mgr.h_query );\r
p_port->ib_mgr.h_query = NULL;\r
}\r
cl_obj_unlock( &p_port->obj );\r
\r
+ KeWaitForSingleObject(\r
+ &p_port->sa_event, Executive, KernelMode, FALSE, NULL );\r
+\r
/*\r
* Put the QP in the error state. This removes the need to\r
* synchronize with send/receive callbacks.\r
p_port = (ipoib_port_t* __ptr64)p_mcast_rec->mcast_context;\r
\r
cl_obj_lock( &p_port->obj );\r
- if( p_port->state == IB_QPS_ERROR )\r
+ if( p_port->state != IB_QPS_INIT )\r
{\r
cl_obj_unlock( &p_port->obj );\r
+ if( p_mcast_rec->status == IB_SUCCESS )\r
+ p_port->p_adapter->p_ifc->leave_mcast( p_mcast_rec->h_mcast, NULL );\r
+\r
+ KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );\r
cl_obj_deref( &p_port->obj );\r
IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
- ("Instance destroying - Aborting.\n") );\r
+ ("Invalid state - Aborting.\n") );\r
return;\r
}\r
- cl_obj_unlock( &p_port->obj );\r
\r
- if( p_mcast_rec->status != IB_SUCCESS )\r
+ status = p_mcast_rec->status;\r
+\r
+ if( status != IB_SUCCESS )\r
{\r
IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
("Multicast join for broadcast group returned %s.\n",\r
p_port->p_adapter->p_ifc->get_err_str( p_mcast_rec->status )) );\r
- if( p_mcast_rec->status == IB_REMOTE_ERROR )\r
+ if( status == IB_REMOTE_ERROR )\r
{\r
/*\r
* Either:\r
* over with the Get.\r
*/\r
/* TODO: Assert is a place holder. Can we ever get here if the\r
- state isn't IB_PNP_PORT_ADD or PORT_DOWN? */\r
+ state isn't IB_PNP_PORT_ADD or PORT_DOWN or PORT_INIT? */\r
CL_ASSERT( p_port->p_adapter->state == IB_PNP_PORT_ADD ||\r
- p_port->p_adapter->state == IB_PNP_PORT_DOWN );\r
- __port_get_mcast( p_port );\r
+ p_port->p_adapter->state == IB_PNP_PORT_DOWN ||\r
+ p_port->p_adapter->state == IB_PNP_PORT_INIT );\r
+ status = __port_get_bcast( p_port );\r
}\r
else\r
{\r
NdisWriteErrorLogEntry( p_port->p_adapter->h_adapter,\r
EVENT_IPOIB_BCAST_JOIN, 1, p_mcast_rec->status );\r
- ipoib_set_inactive( p_port->p_adapter );\r
}\r
\r
+ cl_obj_unlock( &p_port->obj );\r
+ if( status != IB_SUCCESS )\r
+ {\r
+ ipoib_set_inactive( p_port->p_adapter );\r
+ KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );\r
+ }\r
cl_obj_deref( &p_port->obj );\r
IPOIB_EXIT( IPOIB_DBG_INIT );\r
return;\r
}\r
+ cl_obj_unlock( &p_port->obj );\r
\r
status = __endpt_mgr_add_bcast( p_port, p_mcast_rec );\r
if( status != IB_SUCCESS )\r
p_port->p_adapter->p_ifc->get_err_str( status )) );\r
status = p_port->p_adapter->p_ifc->leave_mcast( p_mcast_rec->h_mcast, NULL );\r
CL_ASSERT( status == IB_SUCCESS );\r
- /* Flag the adapter as hung. */\r
- p_port->p_adapter->hung = TRUE;\r
- cl_obj_deref( &p_port->obj );\r
- IPOIB_EXIT( IPOIB_DBG_INIT );\r
- return;\r
+ goto err;\r
}\r
\r
/* Get the QP ready for action. */\r
IPOIB_PRINT( TRACE_LEVEL_ERROR, IPOIB_DBG_ERROR,\r
("__ib_mgr_activate returned %s\n", \r
p_port->p_adapter->p_ifc->get_err_str( status )) );\r
+\r
+err:\r
/* Flag the adapter as hung. */\r
p_port->p_adapter->hung = TRUE;\r
+ KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );\r
cl_obj_deref( &p_port->obj );\r
IPOIB_EXIT( IPOIB_DBG_INIT );\r
return;\r
}\r
\r
+ cl_obj_lock( &p_port->obj );\r
+ /* Only change the state if we're still in INIT. */\r
+ if( p_port->state == IB_QPS_INIT )\r
+ p_port->state = IB_QPS_RTS;\r
+ cl_obj_unlock( &p_port->obj );\r
+\r
/* Notify the adapter that we now have an active connection. */\r
ipoib_set_active( p_port->p_adapter );\r
\r
+ KeSetEvent( &p_port->sa_event, EVENT_INCREMENT, FALSE );\r
cl_obj_deref( &p_port->obj );\r
IPOIB_EXIT( IPOIB_DBG_INIT );\r
}\r
{\r
UNUSED_PARAM( p_event_rec );\r
CL_ASSERT( p_event_rec->context );\r
- /* Place holder for proper error handler. */\r
- cl_msg_out( "Async QP event: %d\n", p_event_rec->code );\r
- CL_ASSERT( p_event_rec->code == IB_AE_UNKNOWN );\r
+ ((ipoib_port_t* __ptr64)p_event_rec->context)->p_adapter->hung = TRUE;\r
}\r
\r
\r
{\r
UNUSED_PARAM( p_event_rec );\r
CL_ASSERT( p_event_rec->context );\r
- /* Place holder for proper error handler. */\r
- CL_ASSERT( p_event_rec->code == IB_AE_UNKNOWN );\r
+ ((ipoib_port_t* __ptr64)p_event_rec->context)->p_adapter->hung = TRUE;\r
}\r
\r
\r
p_port = (ipoib_port_t* __ptr64)p_mcast_rec->mcast_context;\r
\r
cl_obj_lock( &p_port->obj );\r
- if( p_port->state == IB_QPS_ERROR )\r
+ if( p_port->state != IB_QPS_RTS )\r
{\r
cl_obj_unlock( &p_port->obj );\r
+ if( p_mcast_rec->status == IB_SUCCESS )\r
+ p_port->p_adapter->p_ifc->leave_mcast( p_mcast_rec->h_mcast, NULL );\r
+\r
cl_obj_deref( &p_port->obj );\r
IPOIB_PRINT_EXIT( TRACE_LEVEL_INFORMATION, IPOIB_DBG_INIT,\r
- ("Instance destroying - Aborting.\n") );\r
+ ("Invalid state - Aborting.\n") );\r
return;\r
}\r
cl_obj_unlock( &p_port->obj );\r