[SCSI] qla4xxx: Take E-port out of reset before disabling pause frames
authorManish Dusane <manish.dusane@qlogic.com>
Thu, 7 Mar 2013 10:43:07 +0000 (05:43 -0500)
committerJames Bottomley <JBottomley@Parallels.com>
Wed, 10 Apr 2013 18:31:01 +0000 (11:31 -0700)
Problem Description:
Disabling pause frames might cause hardware wedging needing a power cycle.
This might happen if the Eport is not initialized and is in reset.

Solution:
Before disabling pause frames ensure that eport is out of reset.

Signed-off-by: Manish Dusane <manish.dusane@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/qla4xxx/ql4_83xx.c
drivers/scsi/qla4xxx/ql4_83xx.h

index 5d8fe4f7565043a70ed623120c48bd0111f93840..d607eb8e24cbc6a925f0e9d9e73f9831ed32aa5c 100644 (file)
@@ -1629,9 +1629,37 @@ static void __qla4_83xx_disable_pause(struct scsi_qla_host *ha)
        ql4_printk(KERN_INFO, ha, "Disabled pause frames successfully.\n");
 }
 
+/**
+ * qla4_83xx_eport_init - Initialize EPort.
+ * @ha: Pointer to host adapter structure.
+ *
+ * If EPort hardware is in reset state before disabling pause, there would be
+ * serious hardware wedging issues. To prevent this perform eport init everytime
+ * before disabling pause frames.
+ **/
+static void qla4_83xx_eport_init(struct scsi_qla_host *ha)
+{
+       /* Clear the 8 registers */
+       qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_REG, 0x0);
+       qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT0, 0x0);
+       qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT1, 0x0);
+       qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT2, 0x0);
+       qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT3, 0x0);
+       qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_SRE_SHIM, 0x0);
+       qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_EPG_SHIM, 0x0);
+       qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_ETHER_PCS, 0x0);
+
+       /* Write any value to Reset Control register */
+       qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_CONTROL, 0xFF);
+
+       ql4_printk(KERN_INFO, ha, "EPORT is out of reset.\n");
+}
+
 void qla4_83xx_disable_pause(struct scsi_qla_host *ha)
 {
        ha->isp_ops->idc_lock(ha);
+       /* Before disabling pause frames, ensure that eport is not in reset */
+       qla4_83xx_eport_init(ha);
        qla4_83xx_dump_pause_control_regs(ha);
        __qla4_83xx_disable_pause(ha);
        ha->isp_ops->idc_unlock(ha);
index 6a00f903f2a6f584edc19ae3a65bca6fac56258d..fab237fa32cc777e405b5e9f84a85d9888581c46 100644 (file)
 #define QLA83XX_SET_PAUSE_VAL          0x0
 #define QLA83XX_SET_TC_MAX_CELL_VAL    0x03FF03FF
 
+#define QLA83XX_RESET_CONTROL          0x28084E50
+#define QLA83XX_RESET_REG              0x28084E60
+#define QLA83XX_RESET_PORT0            0x28084E70
+#define QLA83XX_RESET_PORT1            0x28084E80
+#define QLA83XX_RESET_PORT2            0x28084E90
+#define QLA83XX_RESET_PORT3            0x28084EA0
+#define QLA83XX_RESET_SRE_SHIM         0x28084EB0
+#define QLA83XX_RESET_EPG_SHIM         0x28084EC0
+#define QLA83XX_RESET_ETHER_PCS                0x28084ED0
+
 /* qla_83xx_reg_tbl registers */
 #define QLA83XX_PEG_HALT_STATUS1       0x34A8
 #define QLA83XX_PEG_HALT_STATUS2       0x34AC