#define MBC_SET_PORT_CONFIG            0x122   /* Set port configuration */
 #define MBC_GET_PORT_CONFIG            0x123   /* Get port configuration */
 
+/*
+ * ISP81xx mailbox commands
+ */
+#define MBC_WRITE_MPI_REGISTER         0x01    /* Write MPI Register. */
+
 /* Firmware return data sizes */
 #define FCAL_MAP_SIZE  128
 
 #define NPIV_CONFIG_NEEDED     16
 #define ISP_UNRECOVERABLE      17
 #define FCOE_CTX_RESET_NEEDED  18      /* Initiate FCoE context reset */
+#define MPI_RESET_NEEDED       19      /* Initiate MPI FW reset */
 
        uint32_t        device_flags;
 #define SWITCH_FOUND           BIT_0
 
 extern int
 qla2x00_write_ram_word(scsi_qla_host_t *, uint32_t, uint32_t);
 
+extern int
+qla81xx_write_mpi_register(scsi_qla_host_t *, uint16_t *);
 extern int qla2x00_get_data_rate(scsi_qla_host_t *);
 extern int qla24xx_set_fcp_prio(scsi_qla_host_t *, uint16_t, uint16_t,
        uint16_t *);
 
        spin_unlock_irqrestore(&ha->hardware_lock, flags);
 }
 
+/**
+ * qla81xx_reset_mpi() - Reset's MPI FW via Write MPI Register MBC.
+ *
+ * Returns 0 on success.
+ */
+int
+qla81xx_reset_mpi(scsi_qla_host_t *vha)
+{
+       uint16_t mb[4] = {0x1010, 0, 1, 0};
+
+       return qla81xx_write_mpi_register(vha, mb);
+}
+
 /**
  * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC.
  * @ha: HA context
        struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
        uint32_t cnt, d2;
        uint16_t wd;
+       static int abts_cnt; /* ISP abort retry counts */
 
        spin_lock_irqsave(&ha->hardware_lock, flags);
 
                barrier();
        }
 
+       /* If required, do an MPI FW reset now */
+       if (test_and_clear_bit(MPI_RESET_NEEDED, &vha->dpc_flags)) {
+               if (qla81xx_reset_mpi(vha) != QLA_SUCCESS) {
+                       if (++abts_cnt < 5) {
+                               set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+                               set_bit(MPI_RESET_NEEDED, &vha->dpc_flags);
+                       } else {
+                               /*
+                                * We exhausted the ISP abort retries. We have to
+                                * set the board offline.
+                                */
+                               abts_cnt = 0;
+                               vha->flags.online = 0;
+                       }
+               }
+       }
+
        WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET);
        RD_REG_DWORD(®->hccr);
 
 
                                    "Unrecoverable Hardware Error: adapter "
                                    "marked OFFLINE!\n");
                                vha->flags.online = 0;
-                       } else
+                       } else {
+                               /* Check to see if MPI timeout occured */
+                               if ((mbx & MBX_3) && (ha->flags.port0))
+                                       set_bit(MPI_RESET_NEEDED,
+                                           &vha->dpc_flags);
+
                                set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+                       }
                } else if (mb[1] == 0) {
                        qla_printk(KERN_INFO, ha,
                            "Unrecoverable Hardware Error: adapter marked "
 
        return rval;
 }
 
+int
+qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
+{
+       int rval;
+       uint32_t stat, timer;
+       uint16_t mb0 = 0;
+       struct qla_hw_data *ha = vha->hw;
+       struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+
+       rval = QLA_SUCCESS;
+
+       DEBUG11(qla_printk(KERN_INFO, ha,
+           "%s(%ld): entered.\n", __func__, vha->host_no));
+
+       clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
+
+       /* Write the MBC data to the registers */
+       WRT_REG_WORD(®->mailbox0, MBC_WRITE_MPI_REGISTER);
+       WRT_REG_WORD(®->mailbox1, mb[0]);
+       WRT_REG_WORD(®->mailbox2, mb[1]);
+       WRT_REG_WORD(®->mailbox3, mb[2]);
+       WRT_REG_WORD(®->mailbox4, mb[3]);
+
+       WRT_REG_DWORD(®->hccr, HCCRX_SET_HOST_INT);
+
+       /* Poll for MBC interrupt */
+       for (timer = 6000000; timer; timer--) {
+               /* Check for pending interrupts. */
+               stat = RD_REG_DWORD(®->host_status);
+               if (stat & HSRX_RISC_INT) {
+                       stat &= 0xff;
+
+                       if (stat == 0x1 || stat == 0x2 ||
+                           stat == 0x10 || stat == 0x11) {
+                               set_bit(MBX_INTERRUPT,
+                                   &ha->mbx_cmd_flags);
+                               mb0 = RD_REG_WORD(®->mailbox0);
+                               WRT_REG_DWORD(®->hccr,
+                                   HCCRX_CLR_RISC_INT);
+                               RD_REG_DWORD(®->hccr);
+                               break;
+                       }
+               }
+               udelay(5);
+       }
+
+       if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
+               rval = mb0 & MBS_MASK;
+       else
+               rval = QLA_FUNCTION_FAILED;
+
+       if (rval != QLA_SUCCESS) {
+               DEBUG2_3_11(printk(KERN_INFO "%s(%ld): failed=%x mb[0]=%x.\n",
+                   __func__, vha->host_no, rval, mb[0]));
+       } else {
+               DEBUG11(printk(KERN_INFO
+                   "%s(%ld): done.\n", __func__, vha->host_no));
+       }
+
+       return rval;
+}
 int
 qla2x00_get_data_rate(scsi_qla_host_t *vha)
 {