aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTej Parkash <tej.parkash@qlogic.com>2012-09-20 07:35:12 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-09-24 04:49:00 -0400
commit546fef27c3a798fbcece2705c1eda9e249e22226 (patch)
tree3e10b8a6f7daeff5ecc0fddc8985e5da09ce730f
parent48a859d29f3d7a855093819633abcc9c877108ef (diff)
[SCSI] qla4xxx: Disable generating pause frames for ISP83XX
In case of FW hung ISP83XX generates continuous pause frames which causes switch to disable port. Added fix to disable generating pause frames in case of FW hung Signed-off-by: Tej Parkash <tej.parkash@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/qla4xxx/ql4_83xx.c144
-rw-r--r--drivers/scsi/qla4xxx/ql4_83xx.h13
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h1
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c4
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c15
5 files changed, 177 insertions, 0 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_83xx.c b/drivers/scsi/qla4xxx/ql4_83xx.c
index 8b367efb7239..6e9af20be12f 100644
--- a/drivers/scsi/qla4xxx/ql4_83xx.c
+++ b/drivers/scsi/qla4xxx/ql4_83xx.c
@@ -1465,3 +1465,147 @@ exit_isp_reset:
1465 1465
1466 return rval; 1466 return rval;
1467} 1467}
1468
1469static void qla4_83xx_dump_pause_control_regs(struct scsi_qla_host *ha)
1470{
1471 u32 val = 0, val1 = 0;
1472 int i, status = QLA_SUCCESS;
1473
1474 status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_SRE_SHIM_CONTROL, &val);
1475 DEBUG2(ql4_printk(KERN_INFO, ha, "SRE-Shim Ctrl:0x%x\n", val));
1476
1477 /* Port 0 Rx Buffer Pause Threshold Registers. */
1478 DEBUG2(ql4_printk(KERN_INFO, ha,
1479 "Port 0 Rx Buffer Pause Threshold Registers[TC7..TC0]:"));
1480 for (i = 0; i < 8; i++) {
1481 status = qla4_83xx_rd_reg_indirect(ha,
1482 QLA83XX_PORT0_RXB_PAUSE_THRS + (i * 0x4), &val);
1483 DEBUG2(pr_info("0x%x ", val));
1484 }
1485
1486 DEBUG2(pr_info("\n"));
1487
1488 /* Port 1 Rx Buffer Pause Threshold Registers. */
1489 DEBUG2(ql4_printk(KERN_INFO, ha,
1490 "Port 1 Rx Buffer Pause Threshold Registers[TC7..TC0]:"));
1491 for (i = 0; i < 8; i++) {
1492 status = qla4_83xx_rd_reg_indirect(ha,
1493 QLA83XX_PORT1_RXB_PAUSE_THRS + (i * 0x4), &val);
1494 DEBUG2(pr_info("0x%x ", val));
1495 }
1496
1497 DEBUG2(pr_info("\n"));
1498
1499 /* Port 0 RxB Traffic Class Max Cell Registers. */
1500 DEBUG2(ql4_printk(KERN_INFO, ha,
1501 "Port 0 RxB Traffic Class Max Cell Registers[3..0]:"));
1502 for (i = 0; i < 4; i++) {
1503 status = qla4_83xx_rd_reg_indirect(ha,
1504 QLA83XX_PORT0_RXB_TC_MAX_CELL + (i * 0x4), &val);
1505 DEBUG2(pr_info("0x%x ", val));
1506 }
1507
1508 DEBUG2(pr_info("\n"));
1509
1510 /* Port 1 RxB Traffic Class Max Cell Registers. */
1511 DEBUG2(ql4_printk(KERN_INFO, ha,
1512 "Port 1 RxB Traffic Class Max Cell Registers[3..0]:"));
1513 for (i = 0; i < 4; i++) {
1514 status = qla4_83xx_rd_reg_indirect(ha,
1515 QLA83XX_PORT1_RXB_TC_MAX_CELL + (i * 0x4), &val);
1516 DEBUG2(pr_info("0x%x ", val));
1517 }
1518
1519 DEBUG2(pr_info("\n"));
1520
1521 /* Port 0 RxB Rx Traffic Class Stats. */
1522 DEBUG2(ql4_printk(KERN_INFO, ha,
1523 "Port 0 RxB Rx Traffic Class Stats [TC7..TC0]"));
1524 for (i = 7; i >= 0; i--) {
1525 status = qla4_83xx_rd_reg_indirect(ha,
1526 QLA83XX_PORT0_RXB_TC_STATS,
1527 &val);
1528 val &= ~(0x7 << 29); /* Reset bits 29 to 31 */
1529 qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT0_RXB_TC_STATS,
1530 (val | (i << 29)));
1531 status = qla4_83xx_rd_reg_indirect(ha,
1532 QLA83XX_PORT0_RXB_TC_STATS,
1533 &val);
1534 DEBUG2(pr_info("0x%x ", val));
1535 }
1536
1537 DEBUG2(pr_info("\n"));
1538
1539 /* Port 1 RxB Rx Traffic Class Stats. */
1540 DEBUG2(ql4_printk(KERN_INFO, ha,
1541 "Port 1 RxB Rx Traffic Class Stats [TC7..TC0]"));
1542 for (i = 7; i >= 0; i--) {
1543 status = qla4_83xx_rd_reg_indirect(ha,
1544 QLA83XX_PORT1_RXB_TC_STATS,
1545 &val);
1546 val &= ~(0x7 << 29); /* Reset bits 29 to 31 */
1547 qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT1_RXB_TC_STATS,
1548 (val | (i << 29)));
1549 status = qla4_83xx_rd_reg_indirect(ha,
1550 QLA83XX_PORT1_RXB_TC_STATS,
1551 &val);
1552 DEBUG2(pr_info("0x%x ", val));
1553 }
1554
1555 DEBUG2(pr_info("\n"));
1556
1557 status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_PORT2_IFB_PAUSE_THRS,
1558 &val);
1559 status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_PORT3_IFB_PAUSE_THRS,
1560 &val1);
1561
1562 DEBUG2(ql4_printk(KERN_INFO, ha,
1563 "IFB-Pause Thresholds: Port 2:0x%x, Port 3:0x%x\n",
1564 val, val1));
1565}
1566
1567static void __qla4_83xx_disable_pause(struct scsi_qla_host *ha)
1568{
1569 int i;
1570
1571 /* set SRE-Shim Control Register */
1572 qla4_83xx_wr_reg_indirect(ha, QLA83XX_SRE_SHIM_CONTROL,
1573 QLA83XX_SET_PAUSE_VAL);
1574
1575 for (i = 0; i < 8; i++) {
1576 /* Port 0 Rx Buffer Pause Threshold Registers. */
1577 qla4_83xx_wr_reg_indirect(ha,
1578 QLA83XX_PORT0_RXB_PAUSE_THRS + (i * 0x4),
1579 QLA83XX_SET_PAUSE_VAL);
1580 /* Port 1 Rx Buffer Pause Threshold Registers. */
1581 qla4_83xx_wr_reg_indirect(ha,
1582 QLA83XX_PORT1_RXB_PAUSE_THRS + (i * 0x4),
1583 QLA83XX_SET_PAUSE_VAL);
1584 }
1585
1586 for (i = 0; i < 4; i++) {
1587 /* Port 0 RxB Traffic Class Max Cell Registers. */
1588 qla4_83xx_wr_reg_indirect(ha,
1589 QLA83XX_PORT0_RXB_TC_MAX_CELL + (i * 0x4),
1590 QLA83XX_SET_TC_MAX_CELL_VAL);
1591 /* Port 1 RxB Traffic Class Max Cell Registers. */
1592 qla4_83xx_wr_reg_indirect(ha,
1593 QLA83XX_PORT1_RXB_TC_MAX_CELL + (i * 0x4),
1594 QLA83XX_SET_TC_MAX_CELL_VAL);
1595 }
1596
1597 qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT2_IFB_PAUSE_THRS,
1598 QLA83XX_SET_PAUSE_VAL);
1599 qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT3_IFB_PAUSE_THRS,
1600 QLA83XX_SET_PAUSE_VAL);
1601
1602 ql4_printk(KERN_INFO, ha, "Disabled pause frames successfully.\n");
1603}
1604
1605void qla4_83xx_disable_pause(struct scsi_qla_host *ha)
1606{
1607 ha->isp_ops->idc_lock(ha);
1608 qla4_83xx_dump_pause_control_regs(ha);
1609 __qla4_83xx_disable_pause(ha);
1610 ha->isp_ops->idc_unlock(ha);
1611}
diff --git a/drivers/scsi/qla4xxx/ql4_83xx.h b/drivers/scsi/qla4xxx/ql4_83xx.h
index 18d86abbf276..6a00f903f2a6 100644
--- a/drivers/scsi/qla4xxx/ql4_83xx.h
+++ b/drivers/scsi/qla4xxx/ql4_83xx.h
@@ -41,6 +41,19 @@
41#define QLA83XX_CRB_IDC_VER_MINOR 0x3798 41#define QLA83XX_CRB_IDC_VER_MINOR 0x3798
42#define QLA83XX_IDC_DRV_CTRL 0x3790 42#define QLA83XX_IDC_DRV_CTRL 0x3790
43#define QLA83XX_IDC_DRV_AUDIT 0x3794 43#define QLA83XX_IDC_DRV_AUDIT 0x3794
44#define QLA83XX_SRE_SHIM_CONTROL 0x0D200284
45#define QLA83XX_PORT0_RXB_PAUSE_THRS 0x0B2003A4
46#define QLA83XX_PORT1_RXB_PAUSE_THRS 0x0B2013A4
47#define QLA83XX_PORT0_RXB_TC_MAX_CELL 0x0B200388
48#define QLA83XX_PORT1_RXB_TC_MAX_CELL 0x0B201388
49#define QLA83XX_PORT0_RXB_TC_STATS 0x0B20039C
50#define QLA83XX_PORT1_RXB_TC_STATS 0x0B20139C
51#define QLA83XX_PORT2_IFB_PAUSE_THRS 0x0B200704
52#define QLA83XX_PORT3_IFB_PAUSE_THRS 0x0B201704
53
54/* set value to pause threshold value */
55#define QLA83XX_SET_PAUSE_VAL 0x0
56#define QLA83XX_SET_TC_MAX_CELL_VAL 0x03FF03FF
44 57
45/* qla_83xx_reg_tbl registers */ 58/* qla_83xx_reg_tbl registers */
46#define QLA83XX_PEG_HALT_STATUS1 0x34A8 59#define QLA83XX_PEG_HALT_STATUS1 0x34A8
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 3eb5fd957c4a..57a5a3cf5770 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -258,6 +258,7 @@ int qla4_8xxx_mbx_intr_enable(struct scsi_qla_host *ha);
258int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param); 258int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param);
259int qla4_8xxx_update_idc_reg(struct scsi_qla_host *ha); 259int qla4_8xxx_update_idc_reg(struct scsi_qla_host *ha);
260int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha); 260int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha);
261void qla4_83xx_disable_pause(struct scsi_qla_host *ha);
261 262
262extern int ql4xextended_error_logging; 263extern int ql4xextended_error_logging;
263extern int ql4xdontresethba; 264extern int ql4xdontresethba;
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 0d3d641f891b..3d41034191f0 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -204,6 +204,10 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
204 qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98, 204 qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
205 CRB_NIU_XG_PAUSE_CTL_P0 | 205 CRB_NIU_XG_PAUSE_CTL_P0 |
206 CRB_NIU_XG_PAUSE_CTL_P1); 206 CRB_NIU_XG_PAUSE_CTL_P1);
207 } else if (is_qla8032(ha)) {
208 ql4_printk(KERN_INFO, ha, " %s: disabling pause transmit on port 0 & 1.\n",
209 __func__);
210 qla4_83xx_disable_pause(ha);
207 } 211 }
208 goto mbox_exit; 212 goto mbox_exit;
209 } 213 }
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 35546807c9f7..ad2da9cd7000 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -2946,6 +2946,14 @@ static int qla4xxx_recover_adapter(struct scsi_qla_host *ha)
2946 2946
2947 set_bit(DPC_RESET_ACTIVE, &ha->dpc_flags); 2947 set_bit(DPC_RESET_ACTIVE, &ha->dpc_flags);
2948 2948
2949 if (is_qla8032(ha) &&
2950 !test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags)) {
2951 ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n",
2952 __func__);
2953 /* disable pause frame for ISP83xx */
2954 qla4_83xx_disable_pause(ha);
2955 }
2956
2949 iscsi_host_for_each_session(ha->host, qla4xxx_fail_session); 2957 iscsi_host_for_each_session(ha->host, qla4xxx_fail_session);
2950 2958
2951 if (test_bit(DPC_RESET_HA, &ha->dpc_flags)) 2959 if (test_bit(DPC_RESET_HA, &ha->dpc_flags))
@@ -3391,6 +3399,13 @@ static void qla4xxx_do_dpc(struct work_struct *work)
3391 3399
3392 if (is_qla80XX(ha)) { 3400 if (is_qla80XX(ha)) {
3393 if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) { 3401 if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
3402 if (is_qla8032(ha)) {
3403 ql4_printk(KERN_INFO, ha, "%s: disabling pause transmit on port 0 & 1.\n",
3404 __func__);
3405 /* disable pause frame for ISP83xx */
3406 qla4_83xx_disable_pause(ha);
3407 }
3408
3394 ha->isp_ops->idc_lock(ha); 3409 ha->isp_ops->idc_lock(ha);
3395 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, 3410 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
3396 QLA8XXX_DEV_FAILED); 3411 QLA8XXX_DEV_FAILED);