static void bnxt_re_remove_device(struct bnxt_re_dev *rdev);
 static void bnxt_re_dealloc_driver(struct ib_device *ib_dev);
 static void bnxt_re_stop_irq(void *handle);
+static void bnxt_re_dev_stop(struct bnxt_re_dev *rdev);
 
 static void bnxt_re_set_drv_mode(struct bnxt_re_dev *rdev, u8 mode)
 {
 /* for handling bnxt_en callbacks later */
 static void bnxt_re_stop(void *p)
 {
+       struct bnxt_re_dev *rdev = p;
+       struct bnxt *bp;
+
+       if (!rdev)
+               return;
+       ASSERT_RTNL();
+
+       /* L2 driver invokes this callback during device error/crash or device
+        * reset. Current RoCE driver doesn't recover the device in case of
+        * error. Handle the error by dispatching fatal events to all qps
+        * ie. by calling bnxt_re_dev_stop and release the MSIx vectors as
+        * L2 driver want to modify the MSIx table.
+        */
+       bp = netdev_priv(rdev->netdev);
+
+       ibdev_info(&rdev->ibdev, "Handle device stop call from L2 driver");
+       /* Check the current device state from L2 structure and move the
+        * device to detached state if FW_FATAL_COND is set.
+        * This prevents more commands to HW during clean-up,
+        * in case the device is already in error.
+        */
+       if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
+               set_bit(ERR_DEVICE_DETACHED, &rdev->rcfw.cmdq.flags);
+
+       bnxt_re_dev_stop(rdev);
+       bnxt_re_stop_irq(rdev);
+       /* Move the device states to detached and  avoid sending any more
+        * commands to HW
+        */
+       set_bit(BNXT_RE_FLAG_ERR_DEVICE_DETACHED, &rdev->flags);
+       set_bit(ERR_DEVICE_DETACHED, &rdev->rcfw.cmdq.flags);
 }
 
 static void bnxt_re_start(void *p)
        if (!rdev)
                return;
 
+       if (test_bit(BNXT_RE_FLAG_ERR_DEVICE_DETACHED, &rdev->flags))
+               return;
        rdev->num_vfs = num_vfs;
        if (!bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx)) {
                bnxt_re_set_resource_limits(rdev);
        if (!en_dev)
                return rc;
 
+       if (test_bit(BNXT_RE_FLAG_ERR_DEVICE_DETACHED, &rdev->flags))
+               return 0;
+
        memset(&fw_msg, 0, sizeof(fw_msg));
 
        bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_FREE, -1, -1);
        if (!en_dev)
                return rc;
 
+       if (test_bit(BNXT_RE_FLAG_ERR_DEVICE_DETACHED, &rdev->flags))
+               return 0;
+
        memset(&fw_msg, 0, sizeof(fw_msg));
 
        bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_STAT_CTX_FREE, -1, -1);