From: ftillier Date: Wed, 19 Apr 2006 20:35:40 +0000 (+0000) Subject: [IPoIB] Handle SM reregister/LID change without a reset X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=69f70a4851977fd1a61a65082f458c7b34a15866;p=~shefty%2Frdma-win.git [IPoIB] Handle SM reregister/LID change without a reset git-svn-id: svn://openib.tc.cornell.edu/gen1@316 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- diff --git a/trunk/ulp/ipoib/kernel/ipoib_adapter.c b/trunk/ulp/ipoib/kernel/ipoib_adapter.c index 51ddd43f..d4bfdd39 100644 --- a/trunk/ulp/ipoib/kernel/ipoib_adapter.c +++ b/trunk/ulp/ipoib/kernel/ipoib_adapter.c @@ -229,7 +229,7 @@ ipoib_destroy_adapter( CL_ASSERT( p_adapter ); /* - * Flag the adapter as being removed. We use the IB_PNP_CA_REMOVE state + * Flag the adapter as being removed. We use the IB_PNP_PORT_REMOVE state * for this purpose. Note that we protect this state change with both the * mutex and the lock. The mutex provides synchronization as a whole * between destruction and AL callbacks (PnP, Query, Destruction). @@ -565,16 +565,23 @@ __ipoib_pnp_cb( /* Join multicast groups and put QP in RTS. */ CL_ASSERT( p_pnp_rec->context ); + cl_obj_lock( &p_adapter->obj ); + p_adapter->state = IB_PNP_PORT_INIT; + cl_obj_unlock( &p_adapter->obj ); ipoib_port_up( p_adapter->p_port, (ib_pnp_port_rec_t*)p_pnp_rec ); status = IB_SUCCESS; break; - case IB_PNP_PORT_INIT: case IB_PNP_PORT_ARMED: status = IB_SUCCESS; break; + case IB_PNP_PORT_INIT: + /* + * Init could happen if the SM brings the port down + * without changing the physical link. + */ case IB_PNP_PORT_DOWN: CL_ASSERT( p_pnp_rec->context ); @@ -584,7 +591,7 @@ __ipoib_pnp_cb( cl_obj_unlock( &p_adapter->obj ); status = IB_SUCCESS; - if( !p_adapter->registering /*&& old_state == IB_PNP_PORT_ACTIVE*/ ) + if( !p_adapter->registering && old_state != IB_PNP_PORT_DOWN ) { NdisMIndicateStatus( p_adapter->h_adapter, NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0 ); @@ -614,7 +621,7 @@ __ipoib_pnp_cb( } } - if( p_adapter->reset && p_adapter->state != IB_PNP_PORT_ACTIVE ) + if( p_adapter->reset && p_adapter->state != IB_PNP_PORT_INIT ) { p_adapter->reset = FALSE; NdisMResetComplete( @@ -633,10 +640,37 @@ __ipoib_pnp_cb( case IB_PNP_GID_CHANGE: case IB_PNP_LID_CHANGE: cl_obj_lock( &p_adapter->obj ); - if( p_adapter->state == IB_PNP_PORT_ACTIVE ) - p_adapter->hung = TRUE; + old_state = p_adapter->state; + switch( old_state ) + { + case IB_PNP_PORT_DOWN: + p_adapter->state = IB_PNP_PORT_INIT; + break; + + default: + p_adapter->state = IB_PNP_PORT_DOWN; + } cl_obj_unlock( &p_adapter->obj ); + status = IB_SUCCESS; + if( p_adapter->registering ) + break; + + switch( old_state ) + { + case IB_PNP_PORT_ACTIVE: + NdisMIndicateStatus( p_adapter->h_adapter, + NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0 ); + NdisMIndicateStatusComplete( p_adapter->h_adapter ); + + IPOIB_TRACE( IPOIB_DBG_INFO, ("Link DOWN!\n") ); + + ipoib_port_down( p_adapter->p_port ); + /* Fall through. */ + + case IB_PNP_PORT_DOWN: + ipoib_port_up( p_adapter->p_port, (ib_pnp_port_rec_t*)p_pnp_rec ); + } break; } @@ -725,6 +759,9 @@ ipoib_reset_adapter( IPOIB_ENTER( IPOIB_DBG_INIT ); + if( p_adapter->reset ) + return IB_INVALID_STATE; + p_adapter->hung = FALSE; p_adapter->reset = TRUE; @@ -921,6 +958,8 @@ ipoib_set_active( /* Register all existing addresses. */ ipoib_reg_addrs( p_adapter ); + ipoib_resume_oids( p_adapter ); + /* * Now that we're in the broadcast group, notify that * we have a link. @@ -930,9 +969,12 @@ ipoib_set_active( EVENT_IPOIB_PORT_UP + (p_adapter->rate/ONE_X_IN_100BPS), 1, p_adapter->rate ); - NdisMIndicateStatus( p_adapter->h_adapter, NDIS_STATUS_MEDIA_CONNECT, - NULL, 0 ); - NdisMIndicateStatusComplete( p_adapter->h_adapter ); + if( !p_adapter->reset ) + { + NdisMIndicateStatus( p_adapter->h_adapter, NDIS_STATUS_MEDIA_CONNECT, + NULL, 0 ); + NdisMIndicateStatusComplete( p_adapter->h_adapter ); + } } if( p_adapter->reset ) diff --git a/trunk/ulp/ipoib/kernel/ipoib_driver.c b/trunk/ulp/ipoib/kernel/ipoib_driver.c index d0cfd955..044b6d1a 100644 --- a/trunk/ulp/ipoib/kernel/ipoib_driver.c +++ b/trunk/ulp/ipoib/kernel/ipoib_driver.c @@ -726,9 +726,8 @@ ipoib_check_for_hang( if( p_adapter->reset ) { - p_adapter->reset = FALSE; - NdisMResetComplete( - p_adapter->h_adapter, NDIS_STATUS_SUCCESS, TRUE ); + IPOIB_EXIT( IPOIB_DBG_INIT ); + return FALSE; } IPOIB_EXIT( IPOIB_DBG_INIT ); @@ -961,6 +960,7 @@ ipoib_query_info( switch( p_adapter->state ) { case IB_PNP_PORT_ADD: + case IB_PNP_PORT_INIT: /* * Delay reporting media state until we know whether the port is * either up or down. @@ -1461,6 +1461,10 @@ ipoib_reset( *p_addr_reset = TRUE; return NDIS_STATUS_SUCCESS; + case IB_INVALID_STATE: + IPOIB_EXIT( IPOIB_DBG_INIT ); + return NDIS_STATUS_RESET_IN_PROGRESS; + default: IPOIB_EXIT( IPOIB_DBG_INIT ); return NDIS_STATUS_HARD_ERRORS;