CL_ASSERT( p_adapter );\r
\r
/*\r
- * Flag the adapter as being removed. We use the IB_PNP_CA_REMOVE state\r
+ * Flag the adapter as being removed. We use the IB_PNP_PORT_REMOVE state\r
* for this purpose. Note that we protect this state change with both the\r
* mutex and the lock. The mutex provides synchronization as a whole\r
* between destruction and AL callbacks (PnP, Query, Destruction).\r
/* Join multicast groups and put QP in RTS. */\r
CL_ASSERT( p_pnp_rec->context );\r
\r
+ cl_obj_lock( &p_adapter->obj );\r
+ p_adapter->state = IB_PNP_PORT_INIT;\r
+ cl_obj_unlock( &p_adapter->obj );\r
ipoib_port_up( p_adapter->p_port, (ib_pnp_port_rec_t*)p_pnp_rec );\r
\r
status = IB_SUCCESS;\r
break;\r
\r
- case IB_PNP_PORT_INIT:\r
case IB_PNP_PORT_ARMED:\r
status = IB_SUCCESS;\r
break;\r
\r
+ case IB_PNP_PORT_INIT:\r
+ /*\r
+ * Init could happen if the SM brings the port down\r
+ * without changing the physical link.\r
+ */\r
case IB_PNP_PORT_DOWN:\r
CL_ASSERT( p_pnp_rec->context );\r
\r
cl_obj_unlock( &p_adapter->obj );\r
status = IB_SUCCESS;\r
\r
- if( !p_adapter->registering /*&& old_state == IB_PNP_PORT_ACTIVE*/ )\r
+ if( !p_adapter->registering && old_state != IB_PNP_PORT_DOWN )\r
{\r
NdisMIndicateStatus( p_adapter->h_adapter,\r
NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0 );\r
}\r
}\r
\r
- if( p_adapter->reset && p_adapter->state != IB_PNP_PORT_ACTIVE )\r
+ if( p_adapter->reset && p_adapter->state != IB_PNP_PORT_INIT )\r
{\r
p_adapter->reset = FALSE;\r
NdisMResetComplete(\r
case IB_PNP_GID_CHANGE:\r
case IB_PNP_LID_CHANGE:\r
cl_obj_lock( &p_adapter->obj );\r
- if( p_adapter->state == IB_PNP_PORT_ACTIVE )\r
- p_adapter->hung = TRUE;\r
+ old_state = p_adapter->state;\r
+ switch( old_state )\r
+ {\r
+ case IB_PNP_PORT_DOWN:\r
+ p_adapter->state = IB_PNP_PORT_INIT;\r
+ break;\r
+\r
+ default:\r
+ p_adapter->state = IB_PNP_PORT_DOWN;\r
+ }\r
cl_obj_unlock( &p_adapter->obj );\r
+ \r
status = IB_SUCCESS;\r
+ if( p_adapter->registering )\r
+ break;\r
+\r
+ switch( old_state )\r
+ {\r
+ case IB_PNP_PORT_ACTIVE:\r
+ NdisMIndicateStatus( p_adapter->h_adapter,\r
+ NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0 );\r
+ NdisMIndicateStatusComplete( p_adapter->h_adapter );\r
+\r
+ IPOIB_TRACE( IPOIB_DBG_INFO, ("Link DOWN!\n") );\r
+\r
+ ipoib_port_down( p_adapter->p_port );\r
+ /* Fall through. */\r
+\r
+ case IB_PNP_PORT_DOWN:\r
+ ipoib_port_up( p_adapter->p_port, (ib_pnp_port_rec_t*)p_pnp_rec );\r
+ }\r
break;\r
}\r
\r
\r
IPOIB_ENTER( IPOIB_DBG_INIT );\r
\r
+ if( p_adapter->reset )\r
+ return IB_INVALID_STATE;\r
+\r
p_adapter->hung = FALSE;\r
p_adapter->reset = TRUE;\r
\r
/* Register all existing addresses. */\r
ipoib_reg_addrs( p_adapter );\r
\r
+ ipoib_resume_oids( p_adapter );\r
+\r
/*\r
* Now that we're in the broadcast group, notify that\r
* we have a link.\r
EVENT_IPOIB_PORT_UP + (p_adapter->rate/ONE_X_IN_100BPS),\r
1, p_adapter->rate );\r
\r
- NdisMIndicateStatus( p_adapter->h_adapter, NDIS_STATUS_MEDIA_CONNECT,\r
- NULL, 0 );\r
- NdisMIndicateStatusComplete( p_adapter->h_adapter );\r
+ if( !p_adapter->reset )\r
+ {\r
+ NdisMIndicateStatus( p_adapter->h_adapter, NDIS_STATUS_MEDIA_CONNECT,\r
+ NULL, 0 );\r
+ NdisMIndicateStatusComplete( p_adapter->h_adapter );\r
+ }\r
}\r
\r
if( p_adapter->reset )\r
\r
if( p_adapter->reset )\r
{\r
- p_adapter->reset = FALSE;\r
- NdisMResetComplete(\r
- p_adapter->h_adapter, NDIS_STATUS_SUCCESS, TRUE );\r
+ IPOIB_EXIT( IPOIB_DBG_INIT );\r
+ return FALSE;\r
}\r
\r
IPOIB_EXIT( IPOIB_DBG_INIT );\r
switch( p_adapter->state )\r
{\r
case IB_PNP_PORT_ADD:\r
+ case IB_PNP_PORT_INIT:\r
/*\r
* Delay reporting media state until we know whether the port is\r
* either up or down.\r
*p_addr_reset = TRUE;\r
return NDIS_STATUS_SUCCESS;\r
\r
+ case IB_INVALID_STATE:\r
+ IPOIB_EXIT( IPOIB_DBG_INIT );\r
+ return NDIS_STATUS_RESET_IN_PROGRESS;\r
+\r
default:\r
IPOIB_EXIT( IPOIB_DBG_INIT );\r
return NDIS_STATUS_HARD_ERRORS;\r