[IPoIB] Handle SM reregister/LID change without a reset
[mirror/winof/.git] / ulp / ipoib / kernel / ipoib_adapter.c
index 51ddd43..d4bfdd3 100644 (file)
@@ -229,7 +229,7 @@ ipoib_destroy_adapter(
        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
@@ -565,16 +565,23 @@ __ipoib_pnp_cb(
                /* 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
@@ -584,7 +591,7 @@ __ipoib_pnp_cb(
                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
@@ -614,7 +621,7 @@ __ipoib_pnp_cb(
                        }\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
@@ -633,10 +640,37 @@ __ipoib_pnp_cb(
        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
@@ -725,6 +759,9 @@ ipoib_reset_adapter(
 \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
@@ -921,6 +958,8 @@ ipoib_set_active(
                /* 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
@@ -930,9 +969,12 @@ ipoib_set_active(
                        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