aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx
diff options
context:
space:
mode:
authorAtul Deshmukh <atul.deshmukh@qlogic.com>2013-08-27 01:37:28 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-09-03 10:28:00 -0400
commit7ec0effd30bb4b1379cd2f5ed1a7bd6b9ec49cfd (patch)
treee249c7e5d1a3ae11eeeb2e0aef0883872d7e74ce /drivers/scsi/qla2xxx
parent7b8335589035b47504f98c1a22547f514386a48c (diff)
[SCSI] qla2xxx: Add support for ISP8044.
[jejb: checkpatch fixes] Signed-off-by: Atul Deshmukh <atul.deshmukh@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r--drivers/scsi/qla2xxx/Makefile2
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c29
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c12
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c16
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h16
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h64
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c55
-rw-r--r--drivers/scsi/qla2xxx/qla_inline.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c26
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c78
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c95
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.h10
-rw-r--r--drivers/scsi/qla2xxx/qla_nx2.c3708
-rw-r--r--drivers/scsi/qla2xxx/qla_nx2.h551
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c175
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c162
18 files changed, 4849 insertions, 158 deletions
diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile
index c37b244cf8ae..ff0fc7c7812f 100644
--- a/drivers/scsi/qla2xxx/Makefile
+++ b/drivers/scsi/qla2xxx/Makefile
@@ -1,6 +1,6 @@
1qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ 1qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \
2 qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \ 2 qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \
3 qla_nx.o qla_mr.o qla_target.o 3 qla_nx.o qla_mr.o qla_nx2.o qla_target.o
4 4
5obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o 5obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o
6obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o 6obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index d7a99ae7f39d..8e8b50ee9a0e 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -29,7 +29,7 @@ qla2x00_sysfs_read_fw_dump(struct file *filp, struct kobject *kobj,
29 if (!(ha->fw_dump_reading || ha->mctp_dump_reading)) 29 if (!(ha->fw_dump_reading || ha->mctp_dump_reading))
30 return 0; 30 return 0;
31 31
32 if (IS_QLA82XX(ha)) { 32 if (IS_P3P_TYPE(ha)) {
33 if (off < ha->md_template_size) { 33 if (off < ha->md_template_size) {
34 rval = memory_read_from_buffer(buf, count, 34 rval = memory_read_from_buffer(buf, count,
35 &off, ha->md_tmplt_hdr, ha->md_template_size); 35 &off, ha->md_tmplt_hdr, ha->md_template_size);
@@ -71,7 +71,7 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
71 ql_log(ql_log_info, vha, 0x705d, 71 ql_log(ql_log_info, vha, 0x705d,
72 "Firmware dump cleared on (%ld).\n", vha->host_no); 72 "Firmware dump cleared on (%ld).\n", vha->host_no);
73 73
74 if (IS_QLA82XX(vha->hw)) { 74 if (IS_P3P_TYPE(ha)) {
75 qla82xx_md_free(vha); 75 qla82xx_md_free(vha);
76 qla82xx_md_prep(vha); 76 qla82xx_md_prep(vha);
77 } 77 }
@@ -95,11 +95,15 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
95 qla82xx_idc_lock(ha); 95 qla82xx_idc_lock(ha);
96 qla82xx_set_reset_owner(vha); 96 qla82xx_set_reset_owner(vha);
97 qla82xx_idc_unlock(ha); 97 qla82xx_idc_unlock(ha);
98 } else if (IS_QLA8044(ha)) {
99 qla8044_idc_lock(ha);
100 qla82xx_set_reset_owner(vha);
101 qla8044_idc_unlock(ha);
98 } else 102 } else
99 qla2x00_system_error(vha); 103 qla2x00_system_error(vha);
100 break; 104 break;
101 case 4: 105 case 4:
102 if (IS_QLA82XX(ha)) { 106 if (IS_P3P_TYPE(ha)) {
103 if (ha->md_tmplt_hdr) 107 if (ha->md_tmplt_hdr)
104 ql_dbg(ql_dbg_user, vha, 0x705b, 108 ql_dbg(ql_dbg_user, vha, 0x705b,
105 "MiniDump supported with this firmware.\n"); 109 "MiniDump supported with this firmware.\n");
@@ -109,7 +113,7 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
109 } 113 }
110 break; 114 break;
111 case 5: 115 case 5:
112 if (IS_QLA82XX(ha)) 116 if (IS_P3P_TYPE(ha))
113 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 117 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
114 break; 118 break;
115 case 6: 119 case 6:
@@ -597,14 +601,23 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
597 "Issuing ISP reset.\n"); 601 "Issuing ISP reset.\n");
598 602
599 scsi_block_requests(vha->host); 603 scsi_block_requests(vha->host);
600 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
601 if (IS_QLA82XX(ha)) { 604 if (IS_QLA82XX(ha)) {
602 ha->flags.isp82xx_no_md_cap = 1; 605 ha->flags.isp82xx_no_md_cap = 1;
603 qla82xx_idc_lock(ha); 606 qla82xx_idc_lock(ha);
604 qla82xx_set_reset_owner(vha); 607 qla82xx_set_reset_owner(vha);
605 qla82xx_idc_unlock(ha); 608 qla82xx_idc_unlock(ha);
609 } else if (IS_QLA8044(ha)) {
610 qla8044_idc_lock(ha);
611 idc_control = qla8044_rd_reg(ha,
612 QLA8044_IDC_DRV_CTRL);
613 qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL,
614 (idc_control | GRACEFUL_RESET_BIT1));
615 qla82xx_set_reset_owner(vha);
616 qla8044_idc_unlock(ha);
617 } else {
618 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
619 qla2xxx_wake_dpc(vha);
606 } 620 }
607 qla2xxx_wake_dpc(vha);
608 qla2x00_wait_for_chip_reset(vha); 621 qla2x00_wait_for_chip_reset(vha);
609 scsi_unblock_requests(vha->host); 622 scsi_unblock_requests(vha->host);
610 break; 623 break;
@@ -640,7 +653,7 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
640 break; 653 break;
641 } 654 }
642 case 0x2025e: 655 case 0x2025e:
643 if (!IS_QLA82XX(ha) || vha != base_vha) { 656 if (!IS_P3P_TYPE(ha) || vha != base_vha) {
644 ql_log(ql_log_info, vha, 0x7071, 657 ql_log(ql_log_info, vha, 0x7071,
645 "FCoE ctx reset no supported.\n"); 658 "FCoE ctx reset no supported.\n");
646 return -EPERM; 659 return -EPERM;
@@ -1212,7 +1225,7 @@ qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
1212 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); 1225 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
1213 struct qla_hw_data *ha = vha->hw; 1226 struct qla_hw_data *ha = vha->hw;
1214 1227
1215 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 1228 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
1216 return snprintf(buf, PAGE_SIZE, "\n"); 1229 return snprintf(buf, PAGE_SIZE, "\n");
1217 1230
1218 return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n", 1231 return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index 2dbae0719d6a..ffcad26af968 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -125,7 +125,7 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
125 uint32_t len; 125 uint32_t len;
126 uint32_t oper; 126 uint32_t oper;
127 127
128 if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA82XX(ha))) { 128 if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_P3P_TYPE(ha))) {
129 ret = -EINVAL; 129 ret = -EINVAL;
130 goto exit_fcp_prio_cfg; 130 goto exit_fcp_prio_cfg;
131 } 131 }
@@ -559,7 +559,7 @@ qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
559 uint16_t new_config[4]; 559 uint16_t new_config[4];
560 struct qla_hw_data *ha = vha->hw; 560 struct qla_hw_data *ha = vha->hw;
561 561
562 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 562 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
563 goto done_reset_internal; 563 goto done_reset_internal;
564 564
565 memset(new_config, 0 , sizeof(new_config)); 565 memset(new_config, 0 , sizeof(new_config));
@@ -629,7 +629,7 @@ qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
629 int rval = 0; 629 int rval = 0;
630 struct qla_hw_data *ha = vha->hw; 630 struct qla_hw_data *ha = vha->hw;
631 631
632 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 632 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
633 goto done_set_internal; 633 goto done_set_internal;
634 634
635 if (mode == INTERNAL_LOOPBACK) 635 if (mode == INTERNAL_LOOPBACK)
@@ -773,7 +773,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
773 773
774 if (atomic_read(&vha->loop_state) == LOOP_READY && 774 if (atomic_read(&vha->loop_state) == LOOP_READY &&
775 (ha->current_topology == ISP_CFG_F || 775 (ha->current_topology == ISP_CFG_F ||
776 ((IS_QLA81XX(ha) || IS_QLA8031(ha)) && 776 ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) &&
777 le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE 777 le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE
778 && req_data_len == MAX_ELS_FRAME_PAYLOAD)) && 778 && req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
779 elreq.options == EXTERNAL_LOOPBACK) { 779 elreq.options == EXTERNAL_LOOPBACK) {
@@ -783,7 +783,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
783 command_sent = INT_DEF_LB_ECHO_CMD; 783 command_sent = INT_DEF_LB_ECHO_CMD;
784 rval = qla2x00_echo_test(vha, &elreq, response); 784 rval = qla2x00_echo_test(vha, &elreq, response);
785 } else { 785 } else {
786 if (IS_QLA81XX(ha) || IS_QLA8031(ha)) { 786 if (IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) {
787 memset(config, 0, sizeof(config)); 787 memset(config, 0, sizeof(config));
788 memset(new_config, 0, sizeof(new_config)); 788 memset(new_config, 0, sizeof(new_config));
789 789
@@ -806,7 +806,7 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
806 "elreq.options=%04x\n", elreq.options); 806 "elreq.options=%04x\n", elreq.options);
807 807
808 if (elreq.options == EXTERNAL_LOOPBACK) 808 if (elreq.options == EXTERNAL_LOOPBACK)
809 if (IS_QLA8031(ha)) 809 if (IS_QLA8031(ha) || IS_QLA8044(ha))
810 rval = qla81xx_set_loopback_mode(vha, 810 rval = qla81xx_set_loopback_mode(vha,
811 config, new_config, elreq.options); 811 config, new_config, elreq.options);
812 else 812 else
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index df132fec6d86..6ed98f933719 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -11,7 +11,7 @@
11 * ---------------------------------------------------------------------- 11 * ----------------------------------------------------------------------
12 * | Level | Last Value Used | Holes | 12 * | Level | Last Value Used | Holes |
13 * ---------------------------------------------------------------------- 13 * ----------------------------------------------------------------------
14 * | Module Init and Probe | 0x014f | 0x4b,0xba,0xfa | 14 * | Module Init and Probe | 0x0151 | 0x4b,0xba,0xfa |
15 * | Mailbox commands | 0x117a | 0x111a-0x111b | 15 * | Mailbox commands | 0x117a | 0x111a-0x111b |
16 * | | | 0x1155-0x1158 | 16 * | | | 0x1155-0x1158 |
17 * | Device Discovery | 0x2095 | 0x2020-0x2022, | 17 * | Device Discovery | 0x2095 | 0x2020-0x2022, |
@@ -42,7 +42,15 @@
42 * | | | 0x800b,0x8039 | 42 * | | | 0x800b,0x8039 |
43 * | AER/EEH | 0x9011 | | 43 * | AER/EEH | 0x9011 | |
44 * | Virtual Port | 0xa007 | | 44 * | Virtual Port | 0xa007 | |
45 * | ISP82XX Specific | 0xb086 | 0xb002,0xb024 | 45 * | ISP82XX Specific | 0xb14c | 0xb002,0xb024 |
46 * | | | 0xb09e,0xb0ae |
47 * | | | 0xb0e0-0xb0ef |
48 * | | | 0xb085,0xb0dc |
49 * | | | 0xb107,0xb108 |
50 * | | | 0xb111,0xb11e |
51 * | | | 0xb12c,0xb12d |
52 * | | | 0xb13a,0xb142 |
53 * | | | 0xb13c-0xb140 |
46 * | MultiQ | 0xc00c | | 54 * | MultiQ | 0xc00c | |
47 * | Misc | 0xd010 | | 55 * | Misc | 0xd010 | |
48 * | Target Mode | 0xe070 | | 56 * | Target Mode | 0xe070 | |
@@ -941,7 +949,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
941 uint32_t *last_chain = NULL; 949 uint32_t *last_chain = NULL;
942 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 950 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
943 951
944 if (IS_QLA82XX(ha)) 952 if (IS_P3P_TYPE(ha))
945 return; 953 return;
946 954
947 risc_address = ext_mem_cnt = 0; 955 risc_address = ext_mem_cnt = 0;
@@ -2530,7 +2538,7 @@ ql_dump_regs(uint32_t level, scsi_qla_host_t *vha, int32_t id)
2530 if (!ql_mask_match(level)) 2538 if (!ql_mask_match(level))
2531 return; 2539 return;
2532 2540
2533 if (IS_QLA82XX(ha)) 2541 if (IS_P3P_TYPE(ha))
2534 mbx_reg = &reg82->mailbox_in[0]; 2542 mbx_reg = &reg82->mailbox_in[0];
2535 else if (IS_FWI2_CAPABLE(ha)) 2543 else if (IS_FWI2_CAPABLE(ha))
2536 mbx_reg = &reg24->mailbox0; 2544 mbx_reg = &reg24->mailbox0;
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 95ca32a71e75..c0a1a713b564 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -35,6 +35,7 @@
35 35
36#include "qla_bsg.h" 36#include "qla_bsg.h"
37#include "qla_nx.h" 37#include "qla_nx.h"
38#include "qla_nx2.h"
38#define QLA2XXX_DRIVER_NAME "qla2xxx" 39#define QLA2XXX_DRIVER_NAME "qla2xxx"
39#define QLA2XXX_APIDEV "ql2xapidev" 40#define QLA2XXX_APIDEV "ql2xapidev"
40#define QLA2XXX_MANUFACTURER "QLogic Corporation" 41#define QLA2XXX_MANUFACTURER "QLogic Corporation"
@@ -2935,7 +2936,8 @@ struct qla_hw_data {
2935#define DT_ISP2031 BIT_15 2936#define DT_ISP2031 BIT_15
2936#define DT_ISP8031 BIT_16 2937#define DT_ISP8031 BIT_16
2937#define DT_ISPFX00 BIT_17 2938#define DT_ISPFX00 BIT_17
2938#define DT_ISP_LAST (DT_ISPFX00 << 1) 2939#define DT_ISP8044 BIT_18
2940#define DT_ISP_LAST (DT_ISP8044 << 1)
2939 2941
2940#define DT_T10_PI BIT_25 2942#define DT_T10_PI BIT_25
2941#define DT_IIDMA BIT_26 2943#define DT_IIDMA BIT_26
@@ -2961,6 +2963,7 @@ struct qla_hw_data {
2961#define IS_QLA8001(ha) (DT_MASK(ha) & DT_ISP8001) 2963#define IS_QLA8001(ha) (DT_MASK(ha) & DT_ISP8001)
2962#define IS_QLA81XX(ha) (IS_QLA8001(ha)) 2964#define IS_QLA81XX(ha) (IS_QLA8001(ha))
2963#define IS_QLA82XX(ha) (DT_MASK(ha) & DT_ISP8021) 2965#define IS_QLA82XX(ha) (DT_MASK(ha) & DT_ISP8021)
2966#define IS_QLA8044(ha) (DT_MASK(ha) & DT_ISP8044)
2964#define IS_QLA2031(ha) (DT_MASK(ha) & DT_ISP2031) 2967#define IS_QLA2031(ha) (DT_MASK(ha) & DT_ISP2031)
2965#define IS_QLA8031(ha) (DT_MASK(ha) & DT_ISP8031) 2968#define IS_QLA8031(ha) (DT_MASK(ha) & DT_ISP8031)
2966#define IS_QLAFX00(ha) (DT_MASK(ha) & DT_ISPFX00) 2969#define IS_QLAFX00(ha) (DT_MASK(ha) & DT_ISPFX00)
@@ -2975,10 +2978,12 @@ struct qla_hw_data {
2975#define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \ 2978#define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \
2976 IS_QLA84XX(ha)) 2979 IS_QLA84XX(ha))
2977#define IS_CNA_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA82XX(ha) || \ 2980#define IS_CNA_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA82XX(ha) || \
2978 IS_QLA8031(ha)) 2981 IS_QLA8031(ha) || IS_QLA8044(ha))
2982#define IS_P3P_TYPE(ha) (IS_QLA82XX(ha) || IS_QLA8044(ha))
2979#define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \ 2983#define IS_QLA2XXX_MIDTYPE(ha) (IS_QLA24XX(ha) || IS_QLA84XX(ha) || \
2980 IS_QLA25XX(ha) || IS_QLA81XX(ha) || \ 2984 IS_QLA25XX(ha) || IS_QLA81XX(ha) || \
2981 IS_QLA82XX(ha) || IS_QLA83XX(ha)) 2985 IS_QLA82XX(ha) || IS_QLA83XX(ha) || \
2986 IS_QLA8044(ha))
2982#define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha)) 2987#define IS_MSIX_NACK_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA83XX(ha))
2983#define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha) || \ 2988#define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha) || \
2984 IS_QLA83XX(ha)) && (ha)->flags.msix_enabled) 2989 IS_QLA83XX(ha)) && (ha)->flags.msix_enabled)
@@ -3187,10 +3192,12 @@ struct qla_hw_data {
3187 uint32_t nvram_data_off; 3192 uint32_t nvram_data_off;
3188 3193
3189 uint32_t fdt_wrt_disable; 3194 uint32_t fdt_wrt_disable;
3195 uint32_t fdt_wrt_enable;
3190 uint32_t fdt_erase_cmd; 3196 uint32_t fdt_erase_cmd;
3191 uint32_t fdt_block_size; 3197 uint32_t fdt_block_size;
3192 uint32_t fdt_unprotect_sec_cmd; 3198 uint32_t fdt_unprotect_sec_cmd;
3193 uint32_t fdt_protect_sec_cmd; 3199 uint32_t fdt_protect_sec_cmd;
3200 uint32_t fdt_wrt_sts_reg_cmd;
3194 3201
3195 uint32_t flt_region_flt; 3202 uint32_t flt_region_flt;
3196 uint32_t flt_region_fdt; 3203 uint32_t flt_region_fdt;
@@ -3402,7 +3409,7 @@ typedef struct scsi_qla_host {
3402 uint16_t fcoe_fcf_idx; 3409 uint16_t fcoe_fcf_idx;
3403 uint8_t fcoe_vn_port_mac[6]; 3410 uint8_t fcoe_vn_port_mac[6];
3404 3411
3405 uint32_t vp_abort_cnt; 3412 uint32_t vp_abort_cnt;
3406 3413
3407 struct fc_vport *fc_vport; /* holds fc_vport * for each vport */ 3414 struct fc_vport *fc_vport; /* holds fc_vport * for each vport */
3408 uint16_t vp_idx; /* vport ID */ 3415 uint16_t vp_idx; /* vport ID */
@@ -3435,6 +3442,7 @@ typedef struct scsi_qla_host {
3435 struct bidi_statistics bidi_stats; 3442 struct bidi_statistics bidi_stats;
3436 3443
3437 atomic_t vref_count; 3444 atomic_t vref_count;
3445 struct qla8044_reset_template reset_tmplt;
3438} scsi_qla_host_t; 3446} scsi_qla_host_t;
3439 3447
3440#define SET_VP_IDX 1 3448#define SET_VP_IDX 1
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index 1ac2b0e3a0e1..610d3aa905a0 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1387,6 +1387,8 @@ struct qla_flt_header {
1387#define FLT_REG_GOLD_FW 0x2f 1387#define FLT_REG_GOLD_FW 0x2f
1388#define FLT_REG_FCP_PRIO_0 0x87 1388#define FLT_REG_FCP_PRIO_0 0x87
1389#define FLT_REG_FCP_PRIO_1 0x88 1389#define FLT_REG_FCP_PRIO_1 0x88
1390#define FLT_REG_CNA_FW 0x97
1391#define FLT_REG_BOOT_CODE_8044 0xA2
1390#define FLT_REG_FCOE_FW 0xA4 1392#define FLT_REG_FCOE_FW 0xA4
1391#define FLT_REG_FCOE_NVRAM_0 0xAA 1393#define FLT_REG_FCOE_NVRAM_0 0xAA
1392#define FLT_REG_FCOE_NVRAM_1 0xAC 1394#define FLT_REG_FCOE_NVRAM_1 0xAC
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 2d98232a08eb..2fba354409ef 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -435,19 +435,19 @@ qla2x00_process_completed_request(struct scsi_qla_host *, struct req_que *,
435 */ 435 */
436extern void qla2x00_release_nvram_protection(scsi_qla_host_t *); 436extern void qla2x00_release_nvram_protection(scsi_qla_host_t *);
437extern uint32_t *qla24xx_read_flash_data(scsi_qla_host_t *, uint32_t *, 437extern uint32_t *qla24xx_read_flash_data(scsi_qla_host_t *, uint32_t *,
438 uint32_t, uint32_t); 438 uint32_t, uint32_t);
439extern uint8_t *qla2x00_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, 439extern uint8_t *qla2x00_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
440 uint32_t); 440 uint32_t);
441extern uint8_t *qla24xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, 441extern uint8_t *qla24xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
442 uint32_t); 442 uint32_t);
443extern int qla2x00_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, 443extern int qla2x00_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
444 uint32_t); 444 uint32_t);
445extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, 445extern int qla24xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
446 uint32_t); 446 uint32_t);
447extern uint8_t *qla25xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, 447extern uint8_t *qla25xx_read_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
448 uint32_t); 448 uint32_t);
449extern int qla25xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t, 449extern int qla25xx_write_nvram_data(scsi_qla_host_t *, uint8_t *, uint32_t,
450 uint32_t); 450 uint32_t);
451extern int qla2x00_is_a_vp_did(scsi_qla_host_t *, uint32_t); 451extern int qla2x00_is_a_vp_did(scsi_qla_host_t *, uint32_t);
452 452
453extern int qla2x00_beacon_on(struct scsi_qla_host *); 453extern int qla2x00_beacon_on(struct scsi_qla_host *);
@@ -463,21 +463,25 @@ extern int qla83xx_wr_reg(scsi_qla_host_t *, uint32_t, uint32_t);
463extern int qla83xx_rd_reg(scsi_qla_host_t *, uint32_t, uint32_t *); 463extern int qla83xx_rd_reg(scsi_qla_host_t *, uint32_t, uint32_t *);
464extern int qla83xx_restart_nic_firmware(scsi_qla_host_t *); 464extern int qla83xx_restart_nic_firmware(scsi_qla_host_t *);
465extern int qla83xx_access_control(scsi_qla_host_t *, uint16_t, uint32_t, 465extern int qla83xx_access_control(scsi_qla_host_t *, uint16_t, uint32_t,
466 uint32_t, uint16_t *); 466 uint32_t, uint16_t *);
467 467
468extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *, 468extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *,
469 uint32_t, uint32_t); 469 uint32_t, uint32_t);
470extern int qla2x00_write_optrom_data(struct scsi_qla_host *, uint8_t *, 470extern int qla2x00_write_optrom_data(struct scsi_qla_host *, uint8_t *,
471 uint32_t, uint32_t); 471 uint32_t, uint32_t);
472extern uint8_t *qla24xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, 472extern uint8_t *qla24xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
473 uint32_t, uint32_t); 473 uint32_t, uint32_t);
474extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, 474extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
475 uint32_t, uint32_t); 475 uint32_t, uint32_t);
476extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, 476extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
477 uint32_t, uint32_t); 477 uint32_t, uint32_t);
478extern uint8_t *qla8044_read_optrom_data(struct scsi_qla_host *,
479 uint8_t *, uint32_t, uint32_t);
480extern void qla8044_watchdog(struct scsi_qla_host *vha);
478 481
479extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); 482extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *);
480extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); 483extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
484extern int qla82xx_get_flash_version(scsi_qla_host_t *, void *);
481 485
482extern int qla2xxx_get_flash_info(scsi_qla_host_t *); 486extern int qla2xxx_get_flash_info(scsi_qla_host_t *);
483extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t); 487extern int qla2xxx_get_vpd_field(scsi_qla_host_t *, char *, char *, size_t);
@@ -498,7 +502,7 @@ extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
498extern void qla2x00_dump_buffer_zipped(uint8_t *, uint32_t); 502extern void qla2x00_dump_buffer_zipped(uint8_t *, uint32_t);
499extern void ql_dump_regs(uint32_t, scsi_qla_host_t *, int32_t); 503extern void ql_dump_regs(uint32_t, scsi_qla_host_t *, int32_t);
500extern void ql_dump_buffer(uint32_t, scsi_qla_host_t *, int32_t, 504extern void ql_dump_buffer(uint32_t, scsi_qla_host_t *, int32_t,
501 uint8_t *, uint32_t); 505 uint8_t *, uint32_t);
502extern void qla2xxx_dump_post_process(scsi_qla_host_t *, int); 506extern void qla2xxx_dump_post_process(scsi_qla_host_t *, int);
503 507
504/* 508/*
@@ -619,9 +623,9 @@ extern int qla82xx_start_firmware(scsi_qla_host_t *);
619/* Firmware and flash related functions */ 623/* Firmware and flash related functions */
620extern int qla82xx_load_risc(scsi_qla_host_t *, uint32_t *); 624extern int qla82xx_load_risc(scsi_qla_host_t *, uint32_t *);
621extern uint8_t *qla82xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, 625extern uint8_t *qla82xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
622 uint32_t, uint32_t); 626 uint32_t, uint32_t);
623extern int qla82xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, 627extern int qla82xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
624 uint32_t, uint32_t); 628 uint32_t, uint32_t);
625 629
626/* Mailbox related functions */ 630/* Mailbox related functions */
627extern int qla82xx_abort_isp(scsi_qla_host_t *); 631extern int qla82xx_abort_isp(scsi_qla_host_t *);
@@ -662,7 +666,7 @@ extern void qla8xxx_dev_failed_handler(scsi_qla_host_t *);
662extern void qla82xx_clear_qsnt_ready(scsi_qla_host_t *); 666extern void qla82xx_clear_qsnt_ready(scsi_qla_host_t *);
663 667
664extern void qla2x00_set_model_info(scsi_qla_host_t *, uint8_t *, 668extern void qla2x00_set_model_info(scsi_qla_host_t *, uint8_t *,
665 size_t, char *); 669 size_t, char *);
666extern int qla82xx_mbx_intr_enable(scsi_qla_host_t *); 670extern int qla82xx_mbx_intr_enable(scsi_qla_host_t *);
667extern int qla82xx_mbx_intr_disable(scsi_qla_host_t *); 671extern int qla82xx_mbx_intr_disable(scsi_qla_host_t *);
668extern void qla82xx_start_iocbs(scsi_qla_host_t *); 672extern void qla82xx_start_iocbs(scsi_qla_host_t *);
@@ -695,5 +699,31 @@ extern void qla82xx_md_free(scsi_qla_host_t *);
695extern int qla82xx_md_collect(scsi_qla_host_t *); 699extern int qla82xx_md_collect(scsi_qla_host_t *);
696extern void qla82xx_md_prep(scsi_qla_host_t *); 700extern void qla82xx_md_prep(scsi_qla_host_t *);
697extern void qla82xx_set_reset_owner(scsi_qla_host_t *); 701extern void qla82xx_set_reset_owner(scsi_qla_host_t *);
702extern int qla82xx_validate_template_chksum(scsi_qla_host_t *vha);
703
704/* Function declarations for ISP8044 */
705extern int qla8044_idc_lock(struct qla_hw_data *ha);
706extern void qla8044_idc_unlock(struct qla_hw_data *ha);
707extern uint32_t qla8044_rd_reg(struct qla_hw_data *ha, ulong addr);
708extern void qla8044_wr_reg(struct qla_hw_data *ha, ulong addr, uint32_t val);
709extern void qla8044_read_reset_template(struct scsi_qla_host *ha);
710extern void qla8044_set_idc_dontreset(struct scsi_qla_host *ha);
711extern int qla8044_rd_direct(struct scsi_qla_host *vha, const uint32_t crb_reg);
712extern void qla8044_wr_direct(struct scsi_qla_host *vha,
713 const uint32_t crb_reg, const uint32_t value);
714extern inline void qla8044_set_qsnt_ready(struct scsi_qla_host *vha);
715extern inline void qla8044_need_reset_handler(struct scsi_qla_host *vha);
716extern int qla8044_device_state_handler(struct scsi_qla_host *vha);
717extern void qla8044_clear_qsnt_ready(struct scsi_qla_host *vha);
718extern void qla8044_clear_drv_active(struct scsi_qla_host *vha);
719void qla8044_get_minidump(struct scsi_qla_host *vha);
720int qla8044_collect_md_data(struct scsi_qla_host *vha);
721extern int qla8044_md_get_template(scsi_qla_host_t *);
722extern int qla8044_write_optrom_data(struct scsi_qla_host *, uint8_t *,
723 uint32_t, uint32_t);
724extern irqreturn_t qla8044_intr_handler(int, void *);
725extern void qla82xx_mbx_completion(scsi_qla_host_t *, uint16_t);
726extern int qla8044_abort_isp(scsi_qla_host_t *);
727extern int qla8044_check_fw_alive(struct scsi_qla_host *);
698 728
699#endif /* _QLA_GBL_H */ 729#endif /* _QLA_GBL_H */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index d60e2c1ac442..a92b166a73e2 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -552,7 +552,18 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
552 if (rval) { 552 if (rval) {
553 ql_log(ql_log_fatal, vha, 0x004f, 553 ql_log(ql_log_fatal, vha, 0x004f,
554 "Unable to validate FLASH data.\n"); 554 "Unable to validate FLASH data.\n");
555 return (rval); 555 return rval;
556 }
557
558 if (IS_QLA8044(ha)) {
559 qla8044_read_reset_template(vha);
560
561 /* NOTE: If ql2xdontresethba==1, set IDC_CTRL DONTRESET_BIT0.
562 * If DONRESET_BIT0 is set, drivers should not set dev_state
563 * to NEED_RESET. But if NEED_RESET is set, drivers should
564 * should honor the reset. */
565 if (ql2xdontresethba == 1)
566 qla8044_set_idc_dontreset(vha);
556 } 567 }
557 568
558 ha->isp_ops->get_flash_version(vha, req->ring); 569 ha->isp_ops->get_flash_version(vha, req->ring);
@@ -1327,7 +1338,7 @@ qla24xx_chip_diag(scsi_qla_host_t *vha)
1327 struct qla_hw_data *ha = vha->hw; 1338 struct qla_hw_data *ha = vha->hw;
1328 struct req_que *req = ha->req_q_map[0]; 1339 struct req_que *req = ha->req_q_map[0];
1329 1340
1330 if (IS_QLA82XX(ha)) 1341 if (IS_P3P_TYPE(ha))
1331 return QLA_SUCCESS; 1342 return QLA_SUCCESS;
1332 1343
1333 ha->fw_transfer_size = REQUEST_ENTRY_SIZE * req->length; 1344 ha->fw_transfer_size = REQUEST_ENTRY_SIZE * req->length;
@@ -1610,7 +1621,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
1610 unsigned long flags; 1621 unsigned long flags;
1611 uint16_t fw_major_version; 1622 uint16_t fw_major_version;
1612 1623
1613 if (IS_QLA82XX(ha)) { 1624 if (IS_P3P_TYPE(ha)) {
1614 rval = ha->isp_ops->load_risc(vha, &srisc_address); 1625 rval = ha->isp_ops->load_risc(vha, &srisc_address);
1615 if (rval == QLA_SUCCESS) { 1626 if (rval == QLA_SUCCESS) {
1616 qla2x00_stop_firmware(vha); 1627 qla2x00_stop_firmware(vha);
@@ -1646,7 +1657,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
1646 if (rval == QLA_SUCCESS) { 1657 if (rval == QLA_SUCCESS) {
1647enable_82xx_npiv: 1658enable_82xx_npiv:
1648 fw_major_version = ha->fw_major_version; 1659 fw_major_version = ha->fw_major_version;
1649 if (IS_QLA82XX(ha)) 1660 if (IS_P3P_TYPE(ha))
1650 qla82xx_check_md_needed(vha); 1661 qla82xx_check_md_needed(vha);
1651 else 1662 else
1652 rval = qla2x00_get_fw_version(vha); 1663 rval = qla2x00_get_fw_version(vha);
@@ -1676,7 +1687,7 @@ enable_82xx_npiv:
1676 goto failed; 1687 goto failed;
1677 1688
1678 if (!fw_major_version && ql2xallocfwdump 1689 if (!fw_major_version && ql2xallocfwdump
1679 && !IS_QLA82XX(ha)) 1690 && !(IS_P3P_TYPE(ha)))
1680 qla2x00_alloc_fw_dump(vha); 1691 qla2x00_alloc_fw_dump(vha);
1681 } 1692 }
1682 } else { 1693 } else {
@@ -1844,7 +1855,7 @@ qla24xx_update_fw_options(scsi_qla_host_t *vha)
1844 int rval; 1855 int rval;
1845 struct qla_hw_data *ha = vha->hw; 1856 struct qla_hw_data *ha = vha->hw;
1846 1857
1847 if (IS_QLA82XX(ha)) 1858 if (IS_P3P_TYPE(ha))
1848 return; 1859 return;
1849 1860
1850 /* Update Serial Link options. */ 1861 /* Update Serial Link options. */
@@ -3993,10 +4004,18 @@ qla83xx_reset_ownership(scsi_qla_host_t *vha)
3993 uint32_t class_type_mask = 0x3; 4004 uint32_t class_type_mask = 0x3;
3994 uint16_t fcoe_other_function = 0xffff, i; 4005 uint16_t fcoe_other_function = 0xffff, i;
3995 4006
3996 qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence); 4007 if (IS_QLA8044(ha)) {
3997 4008 drv_presence = qla8044_rd_direct(vha,
3998 qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO1, &dev_part_info1); 4009 QLA8044_CRB_DRV_ACTIVE_INDEX);
3999 qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO2, &dev_part_info2); 4010 dev_part_info1 = qla8044_rd_direct(vha,
4011 QLA8044_CRB_DEV_PART_INFO_INDEX);
4012 dev_part_info2 = qla8044_rd_direct(vha,
4013 QLA8044_CRB_DEV_PART_INFO2);
4014 } else {
4015 qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
4016 qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO1, &dev_part_info1);
4017 qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO2, &dev_part_info2);
4018 }
4000 for (i = 0; i < 8; i++) { 4019 for (i = 0; i < 8; i++) {
4001 class_type = ((dev_part_info1 >> (i * 4)) & class_type_mask); 4020 class_type = ((dev_part_info1 >> (i * 4)) & class_type_mask);
4002 if ((class_type == QLA83XX_CLASS_TYPE_FCOE) && 4021 if ((class_type == QLA83XX_CLASS_TYPE_FCOE) &&
@@ -4333,7 +4352,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
4333 /* For ISP82XX, driver waits for completion of the commands. 4352 /* For ISP82XX, driver waits for completion of the commands.
4334 * online flag should be set. 4353 * online flag should be set.
4335 */ 4354 */
4336 if (!IS_QLA82XX(ha)) 4355 if (!(IS_P3P_TYPE(ha)))
4337 vha->flags.online = 0; 4356 vha->flags.online = 0;
4338 ha->flags.chip_reset_done = 0; 4357 ha->flags.chip_reset_done = 0;
4339 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 4358 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -4346,7 +4365,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
4346 * Driver waits for the completion of the commands. 4365 * Driver waits for the completion of the commands.
4347 * the interrupts need to be enabled. 4366 * the interrupts need to be enabled.
4348 */ 4367 */
4349 if (!IS_QLA82XX(ha)) 4368 if (!(IS_P3P_TYPE(ha)))
4350 ha->isp_ops->reset_chip(vha); 4369 ha->isp_ops->reset_chip(vha);
4351 4370
4352 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); 4371 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
@@ -4389,7 +4408,7 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
4389 4408
4390 if (!ha->flags.eeh_busy) { 4409 if (!ha->flags.eeh_busy) {
4391 /* Make sure for ISP 82XX IO DMA is complete */ 4410 /* Make sure for ISP 82XX IO DMA is complete */
4392 if (IS_QLA82XX(ha)) { 4411 if (IS_P3P_TYPE(ha)) {
4393 qla82xx_chip_reset_cleanup(vha); 4412 qla82xx_chip_reset_cleanup(vha);
4394 ql_log(ql_log_info, vha, 0x00b4, 4413 ql_log(ql_log_info, vha, 0x00b4,
4395 "Done chip reset cleanup.\n"); 4414 "Done chip reset cleanup.\n");
@@ -4709,7 +4728,7 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha)
4709 struct qla_hw_data *ha = vha->hw; 4728 struct qla_hw_data *ha = vha->hw;
4710 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 4729 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
4711 4730
4712 if (IS_QLA82XX(ha)) 4731 if (IS_P3P_TYPE(ha))
4713 return; 4732 return;
4714 4733
4715 vha->flags.online = 0; 4734 vha->flags.online = 0;
@@ -4775,8 +4794,6 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
4775 } 4794 }
4776 ha->nvram_size = sizeof(struct nvram_24xx); 4795 ha->nvram_size = sizeof(struct nvram_24xx);
4777 ha->vpd_size = FA_NVRAM_VPD_SIZE; 4796 ha->vpd_size = FA_NVRAM_VPD_SIZE;
4778 if (IS_QLA82XX(ha))
4779 ha->vpd_size = FA_VPD_SIZE_82XX;
4780 4797
4781 /* Get VPD data into cache */ 4798 /* Get VPD data into cache */
4782 ha->vpd = ha->nvram + VPD_OFFSET; 4799 ha->vpd = ha->nvram + VPD_OFFSET;
@@ -5538,6 +5555,8 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
5538 /* Determine NVRAM starting address. */ 5555 /* Determine NVRAM starting address. */
5539 ha->nvram_size = sizeof(struct nvram_81xx); 5556 ha->nvram_size = sizeof(struct nvram_81xx);
5540 ha->vpd_size = FA_NVRAM_VPD_SIZE; 5557 ha->vpd_size = FA_NVRAM_VPD_SIZE;
5558 if (IS_P3P_TYPE(ha) || IS_QLA8031(ha))
5559 ha->vpd_size = FA_VPD_SIZE_82XX;
5541 5560
5542 /* Get VPD data into cache */ 5561 /* Get VPD data into cache */
5543 ha->vpd = ha->nvram + VPD_OFFSET; 5562 ha->vpd = ha->nvram + VPD_OFFSET;
@@ -5720,7 +5739,7 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
5720 5739
5721 /* Link Down Timeout = 0: 5740 /* Link Down Timeout = 0:
5722 * 5741 *
5723 * When Port Down timer expires we will start returning 5742 * When Port Down timer expires we will start returning
5724 * I/O's to OS with "DID_NO_CONNECT". 5743 * I/O's to OS with "DID_NO_CONNECT".
5725 * 5744 *
5726 * Link Down Timeout != 0: 5745 * Link Down Timeout != 0:
@@ -6047,7 +6066,7 @@ qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *vha, fc_port_t *fcport)
6047 if (priority < 0) 6066 if (priority < 0)
6048 return QLA_FUNCTION_FAILED; 6067 return QLA_FUNCTION_FAILED;
6049 6068
6050 if (IS_QLA82XX(vha->hw)) { 6069 if (IS_P3P_TYPE(vha->hw)) {
6051 fcport->fcp_prio = priority & 0xf; 6070 fcport->fcp_prio = priority & 0xf;
6052 return QLA_SUCCESS; 6071 return QLA_SUCCESS;
6053 } 6072 }
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index 28c38b4929ce..957088b04611 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -59,7 +59,7 @@ qla2x00_poll(struct rsp_que *rsp)
59 unsigned long flags; 59 unsigned long flags;
60 struct qla_hw_data *ha = rsp->hw; 60 struct qla_hw_data *ha = rsp->hw;
61 local_irq_save(flags); 61 local_irq_save(flags);
62 if (IS_QLA82XX(ha)) 62 if (IS_P3P_TYPE(ha))
63 qla82xx_poll(0, rsp); 63 qla82xx_poll(0, rsp);
64 else 64 else
65 ha->isp_ops->intr_handler(0, rsp); 65 ha->isp_ops->intr_handler(0, rsp);
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index ef0a5481b9dd..e2a7d2dbbc3f 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -474,7 +474,7 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req)
474 struct qla_hw_data *ha = vha->hw; 474 struct qla_hw_data *ha = vha->hw;
475 device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id); 475 device_reg_t __iomem *reg = ISP_QUE_REG(ha, req->id);
476 476
477 if (IS_QLA82XX(ha)) { 477 if (IS_P3P_TYPE(ha)) {
478 qla82xx_start_iocbs(vha); 478 qla82xx_start_iocbs(vha);
479 } else { 479 } else {
480 /* Adjust ring index. */ 480 /* Adjust ring index. */
@@ -1844,7 +1844,7 @@ skip_cmd_array:
1844 if (req->cnt < req_cnt) { 1844 if (req->cnt < req_cnt) {
1845 if (ha->mqenable || IS_QLA83XX(ha)) 1845 if (ha->mqenable || IS_QLA83XX(ha))
1846 cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out); 1846 cnt = RD_REG_DWORD(&reg->isp25mq.req_q_out);
1847 else if (IS_QLA82XX(ha)) 1847 else if (IS_P3P_TYPE(ha))
1848 cnt = RD_REG_DWORD(&reg->isp82.req_q_out); 1848 cnt = RD_REG_DWORD(&reg->isp82.req_q_out);
1849 else if (IS_FWI2_CAPABLE(ha)) 1849 else if (IS_FWI2_CAPABLE(ha))
1850 cnt = RD_REG_DWORD(&reg->isp24.req_q_out); 1850 cnt = RD_REG_DWORD(&reg->isp24.req_q_out);
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index e779506fda75..b4fb8a6b8aa0 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -691,7 +691,8 @@ skip_rio:
691 case MBA_LOOP_DOWN: /* Loop Down Event */ 691 case MBA_LOOP_DOWN: /* Loop Down Event */
692 mbx = (IS_QLA81XX(ha) || IS_QLA8031(ha)) 692 mbx = (IS_QLA81XX(ha) || IS_QLA8031(ha))
693 ? RD_REG_WORD(&reg24->mailbox4) : 0; 693 ? RD_REG_WORD(&reg24->mailbox4) : 0;
694 mbx = IS_QLA82XX(ha) ? RD_REG_WORD(&reg82->mailbox_out[4]) : mbx; 694 mbx = (IS_P3P_TYPE(ha)) ? RD_REG_WORD(&reg82->mailbox_out[4])
695 : mbx;
695 ql_dbg(ql_dbg_async, vha, 0x500b, 696 ql_dbg(ql_dbg_async, vha, 0x500b,
696 "LOOP DOWN detected (%x %x %x %x).\n", 697 "LOOP DOWN detected (%x %x %x %x).\n",
697 mb[1], mb[2], mb[3], mbx); 698 mb[1], mb[2], mb[3], mbx);
@@ -740,7 +741,7 @@ skip_rio:
740 if (IS_QLA2100(ha)) 741 if (IS_QLA2100(ha))
741 break; 742 break;
742 743
743 if (IS_QLA81XX(ha) || IS_QLA82XX(ha) || IS_QLA8031(ha)) { 744 if (IS_CNA_CAPABLE(ha)) {
744 ql_dbg(ql_dbg_async, vha, 0x500d, 745 ql_dbg(ql_dbg_async, vha, 0x500d,
745 "DCBX Completed -- %04x %04x %04x.\n", 746 "DCBX Completed -- %04x %04x %04x.\n",
746 mb[1], mb[2], mb[3]); 747 mb[1], mb[2], mb[3]);
@@ -1002,7 +1003,7 @@ skip_rio:
1002 mb[1], mb[2], mb[3]); 1003 mb[1], mb[2], mb[3]);
1003 break; 1004 break;
1004 case MBA_IDC_NOTIFY: 1005 case MBA_IDC_NOTIFY:
1005 if (IS_QLA8031(vha->hw)) { 1006 if (IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
1006 mb[4] = RD_REG_WORD(&reg24->mailbox4); 1007 mb[4] = RD_REG_WORD(&reg24->mailbox4);
1007 if (((mb[2] & 0x7fff) == MBC_PORT_RESET || 1008 if (((mb[2] & 0x7fff) == MBC_PORT_RESET ||
1008 (mb[2] & 0x7fff) == MBC_SET_PORT_CONFIG) && 1009 (mb[2] & 0x7fff) == MBC_SET_PORT_CONFIG) &&
@@ -1022,7 +1023,8 @@ skip_rio:
1022 complete(&ha->lb_portup_comp); 1023 complete(&ha->lb_portup_comp);
1023 /* Fallthru */ 1024 /* Fallthru */
1024 case MBA_IDC_TIME_EXT: 1025 case MBA_IDC_TIME_EXT:
1025 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw)) 1026 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) ||
1027 IS_QLA8044(ha))
1026 qla81xx_idc_event(vha, mb[0], mb[1]); 1028 qla81xx_idc_event(vha, mb[0], mb[1]);
1027 break; 1029 break;
1028 1030
@@ -1063,7 +1065,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
1063 ql_log(ql_log_warn, vha, 0x3014, 1065 ql_log(ql_log_warn, vha, 0x3014,
1064 "Invalid SCSI command index (%x).\n", index); 1066 "Invalid SCSI command index (%x).\n", index);
1065 1067
1066 if (IS_QLA82XX(ha)) 1068 if (IS_P3P_TYPE(ha))
1067 set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); 1069 set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
1068 else 1070 else
1069 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 1071 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -1080,7 +1082,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
1080 } else { 1082 } else {
1081 ql_log(ql_log_warn, vha, 0x3016, "Invalid SCSI SRB.\n"); 1083 ql_log(ql_log_warn, vha, 0x3016, "Invalid SCSI SRB.\n");
1082 1084
1083 if (IS_QLA82XX(ha)) 1085 if (IS_P3P_TYPE(ha))
1084 set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); 1086 set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
1085 else 1087 else
1086 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 1088 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -1100,7 +1102,7 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
1100 if (index >= req->num_outstanding_cmds) { 1102 if (index >= req->num_outstanding_cmds) {
1101 ql_log(ql_log_warn, vha, 0x5031, 1103 ql_log(ql_log_warn, vha, 0x5031,
1102 "Invalid command index (%x).\n", index); 1104 "Invalid command index (%x).\n", index);
1103 if (IS_QLA82XX(ha)) 1105 if (IS_P3P_TYPE(ha))
1104 set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); 1106 set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
1105 else 1107 else
1106 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 1108 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -1949,7 +1951,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1949 ql_dbg(ql_dbg_io, vha, 0x3017, 1951 ql_dbg(ql_dbg_io, vha, 0x3017,
1950 "Invalid status handle (0x%x).\n", sts->handle); 1952 "Invalid status handle (0x%x).\n", sts->handle);
1951 1953
1952 if (IS_QLA82XX(ha)) 1954 if (IS_P3P_TYPE(ha))
1953 set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); 1955 set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
1954 else 1956 else
1955 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 1957 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -2321,7 +2323,7 @@ fatal:
2321 ql_log(ql_log_warn, vha, 0x5030, 2323 ql_log(ql_log_warn, vha, 0x5030,
2322 "Error entry - invalid handle/queue.\n"); 2324 "Error entry - invalid handle/queue.\n");
2323 2325
2324 if (IS_QLA82XX(ha)) 2326 if (IS_P3P_TYPE(ha))
2325 set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); 2327 set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
2326 else 2328 else
2327 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 2329 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
@@ -2449,7 +2451,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
2449 } 2451 }
2450 2452
2451 /* Adjust ring index */ 2453 /* Adjust ring index */
2452 if (IS_QLA82XX(ha)) { 2454 if (IS_P3P_TYPE(ha)) {
2453 struct device_reg_82xx __iomem *reg = &ha->iobase->isp82; 2455 struct device_reg_82xx __iomem *reg = &ha->iobase->isp82;
2454 WRT_REG_DWORD(&reg->rsp_q_out[0], rsp->ring_index); 2456 WRT_REG_DWORD(&reg->rsp_q_out[0], rsp->ring_index);
2455 } else 2457 } else
@@ -2862,7 +2864,7 @@ msix_failed:
2862 ret = request_irq(qentry->vector, 2864 ret = request_irq(qentry->vector,
2863 qla83xx_msix_entries[i].handler, 2865 qla83xx_msix_entries[i].handler,
2864 0, qla83xx_msix_entries[i].name, rsp); 2866 0, qla83xx_msix_entries[i].name, rsp);
2865 } else if (IS_QLA82XX(ha)) { 2867 } else if (IS_P3P_TYPE(ha)) {
2866 ret = request_irq(qentry->vector, 2868 ret = request_irq(qentry->vector,
2867 qla82xx_msix_entries[i].handler, 2869 qla82xx_msix_entries[i].handler,
2868 0, qla82xx_msix_entries[i].name, rsp); 2870 0, qla82xx_msix_entries[i].name, rsp);
@@ -2947,7 +2949,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
2947skip_msix: 2949skip_msix:
2948 2950
2949 if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && 2951 if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) &&
2950 !IS_QLA8001(ha) && !IS_QLA82XX(ha) && !IS_QLAFX00(ha)) 2952 !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha))
2951 goto skip_msi; 2953 goto skip_msi;
2952 2954
2953 ret = pci_enable_msi(ha->pdev); 2955 ret = pci_enable_msi(ha->pdev);
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 7257c3c4f2d0..98e8a16edacd 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -75,7 +75,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
75 return QLA_FUNCTION_TIMEOUT; 75 return QLA_FUNCTION_TIMEOUT;
76 } 76 }
77 77
78 if (IS_QLA82XX(ha) && ha->flags.isp82xx_fw_hung) { 78 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
79 /* Setting Link-Down error */ 79 /* Setting Link-Down error */
80 mcp->mb[0] = MBS_LINK_DOWN_ERROR; 80 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
81 ql_log(ql_log_warn, vha, 0x1004, 81 ql_log(ql_log_warn, vha, 0x1004,
@@ -106,9 +106,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
106 spin_lock_irqsave(&ha->hardware_lock, flags); 106 spin_lock_irqsave(&ha->hardware_lock, flags);
107 107
108 /* Load mailbox registers. */ 108 /* Load mailbox registers. */
109 if (IS_QLA82XX(ha)) 109 if (IS_P3P_TYPE(ha))
110 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0]; 110 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
111 else if (IS_FWI2_CAPABLE(ha) && !IS_QLA82XX(ha)) 111 else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))
112 optr = (uint16_t __iomem *)&reg->isp24.mailbox0; 112 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
113 else 113 else
114 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0); 114 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
@@ -159,7 +159,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
159 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) { 159 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
160 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); 160 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
161 161
162 if (IS_QLA82XX(ha)) { 162 if (IS_P3P_TYPE(ha)) {
163 if (RD_REG_DWORD(&reg->isp82.hint) & 163 if (RD_REG_DWORD(&reg->isp82.hint) &
164 HINT_MBX_INT_PENDING) { 164 HINT_MBX_INT_PENDING) {
165 spin_unlock_irqrestore(&ha->hardware_lock, 165 spin_unlock_irqrestore(&ha->hardware_lock,
@@ -189,7 +189,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
189 ql_dbg(ql_dbg_mbx, vha, 0x1011, 189 ql_dbg(ql_dbg_mbx, vha, 0x1011,
190 "Cmd=%x Polling Mode.\n", command); 190 "Cmd=%x Polling Mode.\n", command);
191 191
192 if (IS_QLA82XX(ha)) { 192 if (IS_P3P_TYPE(ha)) {
193 if (RD_REG_DWORD(&reg->isp82.hint) & 193 if (RD_REG_DWORD(&reg->isp82.hint) &
194 HINT_MBX_INT_PENDING) { 194 HINT_MBX_INT_PENDING) {
195 spin_unlock_irqrestore(&ha->hardware_lock, 195 spin_unlock_irqrestore(&ha->hardware_lock,
@@ -236,7 +236,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
236 ha->flags.mbox_int = 0; 236 ha->flags.mbox_int = 0;
237 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 237 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
238 238
239 if ((IS_QLA82XX(ha) && ha->flags.isp82xx_fw_hung)) { 239 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
240 ha->flags.mbox_busy = 0; 240 ha->flags.mbox_busy = 0;
241 /* Setting Link-Down error */ 241 /* Setting Link-Down error */
242 mcp->mb[0] = MBS_LINK_DOWN_ERROR; 242 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
@@ -537,7 +537,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
537 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION; 537 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
538 mcp->out_mb = MBX_0; 538 mcp->out_mb = MBX_0;
539 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 539 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
540 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha)) 540 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha))
541 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8; 541 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
542 if (IS_FWI2_CAPABLE(ha)) 542 if (IS_FWI2_CAPABLE(ha))
543 mcp->in_mb |= MBX_17|MBX_16|MBX_15; 543 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
@@ -556,7 +556,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha)
556 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */ 556 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
557 else 557 else
558 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4]; 558 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
559 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw)) { 559 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
560 ha->mpi_version[0] = mcp->mb[10] & 0xff; 560 ha->mpi_version[0] = mcp->mb[10] & 0xff;
561 ha->mpi_version[1] = mcp->mb[11] >> 8; 561 ha->mpi_version[1] = mcp->mb[11] >> 8;
562 ha->mpi_version[2] = mcp->mb[11] & 0xff; 562 ha->mpi_version[2] = mcp->mb[11] & 0xff;
@@ -1201,7 +1201,7 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
1201 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c, 1201 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,
1202 "Entered %s.\n", __func__); 1202 "Entered %s.\n", __func__);
1203 1203
1204 if (IS_QLA82XX(ha) && ql2xdbwr) 1204 if (IS_P3P_TYPE(ha) && ql2xdbwr)
1205 qla82xx_wr_32(ha, ha->nxdb_wr_ptr, 1205 qla82xx_wr_32(ha, ha->nxdb_wr_ptr,
1206 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16))); 1206 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1207 1207
@@ -4407,7 +4407,7 @@ qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4407 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109, 4407 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
4408 "Entered %s.\n", __func__); 4408 "Entered %s.\n", __func__);
4409 4409
4410 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) 4410 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha))
4411 return QLA_FUNCTION_FAILED; 4411 return QLA_FUNCTION_FAILED;
4412 mcp->mb[0] = MBC_GET_PORT_CONFIG; 4412 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4413 mcp->out_mb = MBX_0; 4413 mcp->out_mb = MBX_0;
@@ -4595,7 +4595,7 @@ qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4595 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d, 4595 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
4596 "Entered %s.\n", __func__); 4596 "Entered %s.\n", __func__);
4597 4597
4598 if (!IS_QLA82XX(ha)) 4598 if (!IS_P3P_TYPE(ha))
4599 return QLA_FUNCTION_FAILED; 4599 return QLA_FUNCTION_FAILED;
4600 4600
4601 memset(mcp, 0, sizeof(mbx_cmd_t)); 4601 memset(mcp, 0, sizeof(mbx_cmd_t));
@@ -4713,6 +4713,60 @@ qla82xx_md_get_template(scsi_qla_host_t *vha)
4713} 4713}
4714 4714
4715int 4715int
4716qla8044_md_get_template(scsi_qla_host_t *vha)
4717{
4718 struct qla_hw_data *ha = vha->hw;
4719 mbx_cmd_t mc;
4720 mbx_cmd_t *mcp = &mc;
4721 int rval = QLA_FUNCTION_FAILED;
4722 int offset = 0, size = MINIDUMP_SIZE_36K;
4723 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,
4724 "Entered %s.\n", __func__);
4725
4726 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4727 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4728 if (!ha->md_tmplt_hdr) {
4729 ql_log(ql_log_warn, vha, 0xb11b,
4730 "Unable to allocate memory for Minidump template.\n");
4731 return rval;
4732 }
4733
4734 memset(mcp->mb, 0 , sizeof(mcp->mb));
4735 while (offset < ha->md_template_size) {
4736 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4737 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4738 mcp->mb[2] = LSW(RQST_TMPLT);
4739 mcp->mb[3] = MSW(RQST_TMPLT);
4740 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));
4741 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));
4742 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));
4743 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));
4744 mcp->mb[8] = LSW(size);
4745 mcp->mb[9] = MSW(size);
4746 mcp->mb[10] = offset & 0x0000FFFF;
4747 mcp->mb[11] = offset & 0xFFFF0000;
4748 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4749 mcp->tov = MBX_TOV_SECONDS;
4750 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4751 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4752 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4753 rval = qla2x00_mailbox_command(vha, mcp);
4754
4755 if (rval != QLA_SUCCESS) {
4756 ql_dbg(ql_dbg_mbx, vha, 0xb11c,
4757 "mailbox command FAILED=0x%x, subcode=%x.\n",
4758 ((mcp->mb[1] << 16) | mcp->mb[0]),
4759 ((mcp->mb[3] << 16) | mcp->mb[2]));
4760 return rval;
4761 } else
4762 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,
4763 "Done %s.\n", __func__);
4764 offset = offset + size;
4765 }
4766 return rval;
4767}
4768
4769int
4716qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg) 4770qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4717{ 4771{
4718 int rval; 4772 int rval;
@@ -4808,7 +4862,7 @@ qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
4808 mbx_cmd_t mc; 4862 mbx_cmd_t mc;
4809 mbx_cmd_t *mcp = &mc; 4863 mbx_cmd_t *mcp = &mc;
4810 4864
4811 if (!IS_QLA82XX(ha)) 4865 if (!IS_P3P_TYPE(ha))
4812 return QLA_FUNCTION_FAILED; 4866 return QLA_FUNCTION_FAILED;
4813 4867
4814 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127, 4868 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index cce0cd0d7ec4..01b72e0a8187 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -848,7 +848,6 @@ qla82xx_rom_lock(struct qla_hw_data *ha)
848{ 848{
849 int done = 0, timeout = 0; 849 int done = 0, timeout = 0;
850 uint32_t lock_owner = 0; 850 uint32_t lock_owner = 0;
851 scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
852 851
853 while (!done) { 852 while (!done) {
854 /* acquire semaphore2 from PCI HW block */ 853 /* acquire semaphore2 from PCI HW block */
@@ -857,9 +856,6 @@ qla82xx_rom_lock(struct qla_hw_data *ha)
857 break; 856 break;
858 if (timeout >= qla82xx_rom_lock_timeout) { 857 if (timeout >= qla82xx_rom_lock_timeout) {
859 lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID); 858 lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID);
860 ql_dbg(ql_dbg_p3p, vha, 0xb085,
861 "Failed to acquire rom lock, acquired by %d.\n",
862 lock_owner);
863 return -1; 859 return -1;
864 } 860 }
865 timeout++; 861 timeout++;
@@ -1666,8 +1662,14 @@ qla82xx_iospace_config(struct qla_hw_data *ha)
1666 } 1662 }
1667 1663
1668 /* Mapping of IO base pointer */ 1664 /* Mapping of IO base pointer */
1669 ha->iobase = (device_reg_t __iomem *)((uint8_t *)ha->nx_pcibase + 1665 if (IS_QLA8044(ha)) {
1670 0xbc000 + (ha->pdev->devfn << 11)); 1666 ha->iobase =
1667 (device_reg_t __iomem *)((uint8_t *)ha->nx_pcibase);
1668 } else if (IS_QLA82XX(ha)) {
1669 ha->iobase =
1670 (device_reg_t __iomem *)((uint8_t *)ha->nx_pcibase +
1671 0xbc000 + (ha->pdev->devfn << 11));
1672 }
1671 1673
1672 if (!ql2xdbwr) { 1674 if (!ql2xdbwr) {
1673 ha->nxdb_wr_ptr = 1675 ha->nxdb_wr_ptr =
@@ -1967,7 +1969,7 @@ static struct qla82xx_legacy_intr_set legacy_intr[] = \
1967 * @ha: SCSI driver HA context 1969 * @ha: SCSI driver HA context
1968 * @mb0: Mailbox0 register 1970 * @mb0: Mailbox0 register
1969 */ 1971 */
1970static void 1972void
1971qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) 1973qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
1972{ 1974{
1973 uint16_t cnt; 1975 uint16_t cnt;
@@ -2247,7 +2249,10 @@ qla82xx_enable_intrs(struct qla_hw_data *ha)
2247 scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); 2249 scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
2248 qla82xx_mbx_intr_enable(vha); 2250 qla82xx_mbx_intr_enable(vha);
2249 spin_lock_irq(&ha->hardware_lock); 2251 spin_lock_irq(&ha->hardware_lock);
2250 qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff); 2252 if (IS_QLA8044(ha))
2253 qla8044_wr_reg(ha, LEG_INTR_MASK_OFFSET, 0);
2254 else
2255 qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
2251 spin_unlock_irq(&ha->hardware_lock); 2256 spin_unlock_irq(&ha->hardware_lock);
2252 ha->interrupts_on = 1; 2257 ha->interrupts_on = 1;
2253} 2258}
@@ -2258,7 +2263,10 @@ qla82xx_disable_intrs(struct qla_hw_data *ha)
2258 scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); 2263 scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
2259 qla82xx_mbx_intr_disable(vha); 2264 qla82xx_mbx_intr_disable(vha);
2260 spin_lock_irq(&ha->hardware_lock); 2265 spin_lock_irq(&ha->hardware_lock);
2261 qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400); 2266 if (IS_QLA8044(ha))
2267 qla8044_wr_reg(ha, LEG_INTR_MASK_OFFSET, 1);
2268 else
2269 qla82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0x0400);
2262 spin_unlock_irq(&ha->hardware_lock); 2270 spin_unlock_irq(&ha->hardware_lock);
2263 ha->interrupts_on = 0; 2271 ha->interrupts_on = 0;
2264} 2272}
@@ -3008,6 +3016,9 @@ qla8xxx_dev_failed_handler(scsi_qla_host_t *vha)
3008 if (IS_QLA82XX(ha)) { 3016 if (IS_QLA82XX(ha)) {
3009 qla82xx_clear_drv_active(ha); 3017 qla82xx_clear_drv_active(ha);
3010 qla82xx_idc_unlock(ha); 3018 qla82xx_idc_unlock(ha);
3019 } else if (IS_QLA8044(ha)) {
3020 qla8044_clear_drv_active(vha);
3021 qla8044_idc_unlock(ha);
3011 } 3022 }
3012 3023
3013 /* Set DEV_FAILED flag to disable timer */ 3024 /* Set DEV_FAILED flag to disable timer */
@@ -3134,7 +3145,7 @@ qla82xx_check_md_needed(scsi_qla_host_t *vha)
3134 if (fw_major_version != ha->fw_major_version || 3145 if (fw_major_version != ha->fw_major_version ||
3135 fw_minor_version != ha->fw_minor_version || 3146 fw_minor_version != ha->fw_minor_version ||
3136 fw_subminor_version != ha->fw_subminor_version) { 3147 fw_subminor_version != ha->fw_subminor_version) {
3137 ql_log(ql_log_info, vha, 0xb02d, 3148 ql_dbg(ql_dbg_p3p, vha, 0xb02d,
3138 "Firmware version differs " 3149 "Firmware version differs "
3139 "Previous version: %d:%d:%d - " 3150 "Previous version: %d:%d:%d - "
3140 "New version: %d:%d:%d\n", 3151 "New version: %d:%d:%d\n",
@@ -3423,8 +3434,18 @@ void qla82xx_watchdog(scsi_qla_host_t *vha)
3423 3434
3424int qla82xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) 3435int qla82xx_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
3425{ 3436{
3426 int rval; 3437 int rval = -1;
3427 rval = qla82xx_device_state_handler(vha); 3438 struct qla_hw_data *ha = vha->hw;
3439
3440 if (IS_QLA82XX(ha))
3441 rval = qla82xx_device_state_handler(vha);
3442 else if (IS_QLA8044(ha)) {
3443 qla8044_idc_lock(ha);
3444 /* Decide the reset ownership */
3445 qla83xx_reset_ownership(vha);
3446 qla8044_idc_unlock(ha);
3447 rval = qla8044_device_state_handler(vha);
3448 }
3428 return rval; 3449 return rval;
3429} 3450}
3430 3451
@@ -3432,17 +3453,25 @@ void
3432qla82xx_set_reset_owner(scsi_qla_host_t *vha) 3453qla82xx_set_reset_owner(scsi_qla_host_t *vha)
3433{ 3454{
3434 struct qla_hw_data *ha = vha->hw; 3455 struct qla_hw_data *ha = vha->hw;
3435 uint32_t dev_state; 3456 uint32_t dev_state = 0;
3457
3458 if (IS_QLA82XX(ha))
3459 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
3460 else if (IS_QLA8044(ha))
3461 dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
3436 3462
3437 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
3438 if (dev_state == QLA8XXX_DEV_READY) { 3463 if (dev_state == QLA8XXX_DEV_READY) {
3439 ql_log(ql_log_info, vha, 0xb02f, 3464 ql_log(ql_log_info, vha, 0xb02f,
3440 "HW State: NEED RESET\n"); 3465 "HW State: NEED RESET\n");
3441 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 3466 if (IS_QLA82XX(ha)) {
3442 QLA8XXX_DEV_NEED_RESET); 3467 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
3443 ha->flags.nic_core_reset_owner = 1; 3468 QLA8XXX_DEV_NEED_RESET);
3444 ql_dbg(ql_dbg_p3p, vha, 0xb030, 3469 ha->flags.nic_core_reset_owner = 1;
3445 "reset_owner is 0x%x\n", ha->portnum); 3470 ql_dbg(ql_dbg_p3p, vha, 0xb030,
3471 "reset_owner is 0x%x\n", ha->portnum);
3472 } else if (IS_QLA8044(ha))
3473 qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
3474 QLA8XXX_DEV_NEED_RESET);
3446 } else 3475 } else
3447 ql_log(ql_log_info, vha, 0xb031, 3476 ql_log(ql_log_info, vha, 0xb031,
3448 "Device state is 0x%x = %s.\n", 3477 "Device state is 0x%x = %s.\n",
@@ -3463,7 +3492,7 @@ qla82xx_set_reset_owner(scsi_qla_host_t *vha)
3463int 3492int
3464qla82xx_abort_isp(scsi_qla_host_t *vha) 3493qla82xx_abort_isp(scsi_qla_host_t *vha)
3465{ 3494{
3466 int rval; 3495 int rval = -1;
3467 struct qla_hw_data *ha = vha->hw; 3496 struct qla_hw_data *ha = vha->hw;
3468 3497
3469 if (vha->device_flags & DFLG_DEV_FAILED) { 3498 if (vha->device_flags & DFLG_DEV_FAILED) {
@@ -3477,7 +3506,15 @@ qla82xx_abort_isp(scsi_qla_host_t *vha)
3477 qla82xx_set_reset_owner(vha); 3506 qla82xx_set_reset_owner(vha);
3478 qla82xx_idc_unlock(ha); 3507 qla82xx_idc_unlock(ha);
3479 3508
3480 rval = qla82xx_device_state_handler(vha); 3509 if (IS_QLA82XX(ha))
3510 rval = qla82xx_device_state_handler(vha);
3511 else if (IS_QLA8044(ha)) {
3512 qla8044_idc_lock(ha);
3513 /* Decide the reset ownership */
3514 qla83xx_reset_ownership(vha);
3515 qla8044_idc_unlock(ha);
3516 rval = qla8044_device_state_handler(vha);
3517 }
3481 3518
3482 qla82xx_idc_lock(ha); 3519 qla82xx_idc_lock(ha);
3483 qla82xx_clear_rst_ready(ha); 3520 qla82xx_clear_rst_ready(ha);
@@ -3597,7 +3634,7 @@ int qla2x00_wait_for_fcoe_ctx_reset(scsi_qla_host_t *vha)
3597void 3634void
3598qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha) 3635qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
3599{ 3636{
3600 int i; 3637 int i, fw_state = 0;
3601 unsigned long flags; 3638 unsigned long flags;
3602 struct qla_hw_data *ha = vha->hw; 3639 struct qla_hw_data *ha = vha->hw;
3603 3640
@@ -3608,7 +3645,11 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
3608 if (!ha->flags.isp82xx_fw_hung) { 3645 if (!ha->flags.isp82xx_fw_hung) {
3609 for (i = 0; i < 2; i++) { 3646 for (i = 0; i < 2; i++) {
3610 msleep(1000); 3647 msleep(1000);
3611 if (qla82xx_check_fw_alive(vha)) { 3648 if (IS_QLA82XX(ha))
3649 fw_state = qla82xx_check_fw_alive(vha);
3650 else if (IS_QLA8044(ha))
3651 fw_state = qla8044_check_fw_alive(vha);
3652 if (fw_state) {
3612 ha->flags.isp82xx_fw_hung = 1; 3653 ha->flags.isp82xx_fw_hung = 1;
3613 qla82xx_clear_pending_mbx(vha); 3654 qla82xx_clear_pending_mbx(vha);
3614 break; 3655 break;
@@ -4072,7 +4113,7 @@ qla82xx_minidump_process_rdmem(scsi_qla_host_t *vha,
4072 return QLA_SUCCESS; 4113 return QLA_SUCCESS;
4073} 4114}
4074 4115
4075static int 4116int
4076qla82xx_validate_template_chksum(scsi_qla_host_t *vha) 4117qla82xx_validate_template_chksum(scsi_qla_host_t *vha)
4077{ 4118{
4078 struct qla_hw_data *ha = vha->hw; 4119 struct qla_hw_data *ha = vha->hw;
@@ -4384,7 +4425,11 @@ qla82xx_md_prep(scsi_qla_host_t *vha)
4384 ha->md_template_size / 1024); 4425 ha->md_template_size / 1024);
4385 4426
4386 /* Get Minidump template */ 4427 /* Get Minidump template */
4387 rval = qla82xx_md_get_template(vha); 4428 if (IS_QLA8044(ha))
4429 rval = qla8044_md_get_template(vha);
4430 else
4431 rval = qla82xx_md_get_template(vha);
4432
4388 if (rval == QLA_SUCCESS) { 4433 if (rval == QLA_SUCCESS) {
4389 ql_dbg(ql_dbg_p3p, vha, 0xb04b, 4434 ql_dbg(ql_dbg_p3p, vha, 0xb04b,
4390 "MiniDump Template obtained\n"); 4435 "MiniDump Template obtained\n");
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h
index d268e8406fdb..1bb93dbbccbb 100644
--- a/drivers/scsi/qla2xxx/qla_nx.h
+++ b/drivers/scsi/qla2xxx/qla_nx.h
@@ -589,6 +589,7 @@
589 * The PCI VendorID and DeviceID for our board. 589 * The PCI VendorID and DeviceID for our board.
590 */ 590 */
591#define PCI_DEVICE_ID_QLOGIC_ISP8021 0x8021 591#define PCI_DEVICE_ID_QLOGIC_ISP8021 0x8021
592#define PCI_DEVICE_ID_QLOGIC_ISP8044 0x8044
592 593
593#define QLA82XX_MSIX_TBL_SPACE 8192 594#define QLA82XX_MSIX_TBL_SPACE 8192
594#define QLA82XX_PCI_REG_MSIX_TBL 0x44 595#define QLA82XX_PCI_REG_MSIX_TBL 0x44
@@ -954,6 +955,11 @@ struct ct6_dsd {
954#define QLA82XX_CNTRL 98 955#define QLA82XX_CNTRL 98
955#define QLA82XX_TLHDR 99 956#define QLA82XX_TLHDR 99
956#define QLA82XX_RDEND 255 957#define QLA82XX_RDEND 255
958#define QLA8044_POLLRD 35
959#define QLA8044_RDMUX2 36
960#define QLA8044_L1DTG 8
961#define QLA8044_L1ITG 9
962#define QLA8044_POLLRDMWR 37
957 963
958/* 964/*
959 * Opcodes for Control Entries. 965 * Opcodes for Control Entries.
@@ -1191,4 +1197,8 @@ enum {
1191 QLA82XX_TEMP_WARN, /* Sound alert, temperature getting high */ 1197 QLA82XX_TEMP_WARN, /* Sound alert, temperature getting high */
1192 QLA82XX_TEMP_PANIC /* Fatal error, hardware has shut down. */ 1198 QLA82XX_TEMP_PANIC /* Fatal error, hardware has shut down. */
1193}; 1199};
1200
1201#define LEG_INTR_PTR_OFFSET 0x38C0
1202#define LEG_INTR_TRIG_OFFSET 0x38C4
1203#define LEG_INTR_MASK_OFFSET 0x38C8
1194#endif 1204#endif
diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c
new file mode 100644
index 000000000000..1be440cd550e
--- /dev/null
+++ b/drivers/scsi/qla2xxx/qla_nx2.c
@@ -0,0 +1,3708 @@
1/*
2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2013 QLogic Corporation
4 *
5 * See LICENSE.qla2xxx for copyright and licensing details.
6 */
7
8#include <linux/vmalloc.h>
9
10#include "qla_def.h"
11#include "qla_gbl.h"
12
13#include <linux/delay.h>
14
15/* 8044 Flash Read/Write functions */
16uint32_t
17qla8044_rd_reg(struct qla_hw_data *ha, ulong addr)
18{
19 return readl((void __iomem *) (ha->nx_pcibase + addr));
20}
21
22void
23qla8044_wr_reg(struct qla_hw_data *ha, ulong addr, uint32_t val)
24{
25 writel(val, (void __iomem *)((ha)->nx_pcibase + addr));
26}
27
28int
29qla8044_rd_direct(struct scsi_qla_host *vha,
30 const uint32_t crb_reg)
31{
32 struct qla_hw_data *ha = vha->hw;
33
34 if (crb_reg < CRB_REG_INDEX_MAX)
35 return qla8044_rd_reg(ha, qla8044_reg_tbl[crb_reg]);
36 else
37 return QLA_FUNCTION_FAILED;
38}
39
40void
41qla8044_wr_direct(struct scsi_qla_host *vha,
42 const uint32_t crb_reg,
43 const uint32_t value)
44{
45 struct qla_hw_data *ha = vha->hw;
46
47 if (crb_reg < CRB_REG_INDEX_MAX)
48 qla8044_wr_reg(ha, qla8044_reg_tbl[crb_reg], value);
49}
50
51static int
52qla8044_set_win_base(scsi_qla_host_t *vha, uint32_t addr)
53{
54 uint32_t val;
55 int ret_val = QLA_SUCCESS;
56 struct qla_hw_data *ha = vha->hw;
57
58 qla8044_wr_reg(ha, QLA8044_CRB_WIN_FUNC(ha->portnum), addr);
59 val = qla8044_rd_reg(ha, QLA8044_CRB_WIN_FUNC(ha->portnum));
60
61 if (val != addr) {
62 ql_log(ql_log_warn, vha, 0xb087,
63 "%s: Failed to set register window : "
64 "addr written 0x%x, read 0x%x!\n",
65 __func__, addr, val);
66 ret_val = QLA_FUNCTION_FAILED;
67 }
68 return ret_val;
69}
70
71static int
72qla8044_rd_reg_indirect(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
73{
74 int ret_val = QLA_SUCCESS;
75 struct qla_hw_data *ha = vha->hw;
76
77 ret_val = qla8044_set_win_base(vha, addr);
78 if (!ret_val)
79 *data = qla8044_rd_reg(ha, QLA8044_WILDCARD);
80 else
81 ql_log(ql_log_warn, vha, 0xb088,
82 "%s: failed read of addr 0x%x!\n", __func__, addr);
83 return ret_val;
84}
85
86static int
87qla8044_wr_reg_indirect(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)
88{
89 int ret_val = QLA_SUCCESS;
90 struct qla_hw_data *ha = vha->hw;
91
92 ret_val = qla8044_set_win_base(vha, addr);
93 if (!ret_val)
94 qla8044_wr_reg(ha, QLA8044_WILDCARD, data);
95 else
96 ql_log(ql_log_warn, vha, 0xb089,
97 "%s: failed wrt to addr 0x%x, data 0x%x\n",
98 __func__, addr, data);
99 return ret_val;
100}
101
102/*
103 * qla8044_read_write_crb_reg - Read from raddr and write value to waddr.
104 *
105 * @ha : Pointer to adapter structure
106 * @raddr : CRB address to read from
107 * @waddr : CRB address to write to
108 *
109 */
110static void
111qla8044_read_write_crb_reg(struct scsi_qla_host *vha,
112 uint32_t raddr, uint32_t waddr)
113{
114 uint32_t value;
115
116 qla8044_rd_reg_indirect(vha, raddr, &value);
117 qla8044_wr_reg_indirect(vha, waddr, value);
118}
119
120/*
121 * qla8044_rmw_crb_reg - Read value from raddr, AND with test_mask,
122 * Shift Left,Right/OR/XOR with values RMW header and write value to waddr.
123 *
124 * @vha : Pointer to adapter structure
125 * @raddr : CRB address to read from
126 * @waddr : CRB address to write to
127 * @p_rmw_hdr : header with shift/or/xor values.
128 *
129 */
130static void
131qla8044_rmw_crb_reg(struct scsi_qla_host *vha,
132 uint32_t raddr, uint32_t waddr, struct qla8044_rmw *p_rmw_hdr)
133{
134 uint32_t value;
135
136 if (p_rmw_hdr->index_a)
137 value = vha->reset_tmplt.array[p_rmw_hdr->index_a];
138 else
139 qla8044_rd_reg_indirect(vha, raddr, &value);
140 value &= p_rmw_hdr->test_mask;
141 value <<= p_rmw_hdr->shl;
142 value >>= p_rmw_hdr->shr;
143 value |= p_rmw_hdr->or_value;
144 value ^= p_rmw_hdr->xor_value;
145 qla8044_wr_reg_indirect(vha, waddr, value);
146 return;
147}
148
149inline void
150qla8044_set_qsnt_ready(struct scsi_qla_host *vha)
151{
152 uint32_t qsnt_state;
153 struct qla_hw_data *ha = vha->hw;
154
155 qsnt_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
156 qsnt_state |= (1 << ha->portnum);
157 qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, qsnt_state);
158 ql_log(ql_log_info, vha, 0xb08e, "%s(%ld): qsnt_state: 0x%08x\n",
159 __func__, vha->host_no, qsnt_state);
160}
161
162void
163qla8044_clear_qsnt_ready(struct scsi_qla_host *vha)
164{
165 uint32_t qsnt_state;
166 struct qla_hw_data *ha = vha->hw;
167
168 qsnt_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
169 qsnt_state &= ~(1 << ha->portnum);
170 qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, qsnt_state);
171 ql_log(ql_log_info, vha, 0xb08f, "%s(%ld): qsnt_state: 0x%08x\n",
172 __func__, vha->host_no, qsnt_state);
173}
174
175/**
176 *
177 * qla8044_lock_recovery - Recovers the idc_lock.
178 * @ha : Pointer to adapter structure
179 *
180 * Lock Recovery Register
181 * 5-2 Lock recovery owner: Function ID of driver doing lock recovery,
182 * valid if bits 1..0 are set by driver doing lock recovery.
183 * 1-0 1 - Driver intends to force unlock the IDC lock.
184 * 2 - Driver is moving forward to unlock the IDC lock. Driver clears
185 * this field after force unlocking the IDC lock.
186 *
187 * Lock Recovery process
188 * a. Read the IDC_LOCK_RECOVERY register. If the value in bits 1..0 is
189 * greater than 0, then wait for the other driver to unlock otherwise
190 * move to the next step.
191 * b. Indicate intent to force-unlock by writing 1h to the IDC_LOCK_RECOVERY
192 * register bits 1..0 and also set the function# in bits 5..2.
193 * c. Read the IDC_LOCK_RECOVERY register again after a delay of 200ms.
194 * Wait for the other driver to perform lock recovery if the function
195 * number in bits 5..2 has changed, otherwise move to the next step.
196 * d. Write a value of 2h to the IDC_LOCK_RECOVERY register bits 1..0
197 * leaving your function# in bits 5..2.
198 * e. Force unlock using the DRIVER_UNLOCK register and immediately clear
199 * the IDC_LOCK_RECOVERY bits 5..0 by writing 0.
200 **/
201static int
202qla8044_lock_recovery(struct scsi_qla_host *vha)
203{
204 uint32_t lock = 0, lockid;
205 struct qla_hw_data *ha = vha->hw;
206
207 lockid = qla8044_rd_reg(ha, QLA8044_DRV_LOCKRECOVERY);
208
209 /* Check for other Recovery in progress, go wait */
210 if ((lockid & IDC_LOCK_RECOVERY_STATE_MASK) != 0)
211 return QLA_FUNCTION_FAILED;
212
213 /* Intent to Recover */
214 qla8044_wr_reg(ha, QLA8044_DRV_LOCKRECOVERY,
215 (ha->portnum <<
216 IDC_LOCK_RECOVERY_STATE_SHIFT_BITS) | INTENT_TO_RECOVER);
217 msleep(200);
218
219 /* Check Intent to Recover is advertised */
220 lockid = qla8044_rd_reg(ha, QLA8044_DRV_LOCKRECOVERY);
221 if ((lockid & IDC_LOCK_RECOVERY_OWNER_MASK) != (ha->portnum <<
222 IDC_LOCK_RECOVERY_STATE_SHIFT_BITS))
223 return QLA_FUNCTION_FAILED;
224
225 ql_dbg(ql_dbg_p3p, vha, 0xb08B, "%s:%d: IDC Lock recovery initiated\n"
226 , __func__, ha->portnum);
227
228 /* Proceed to Recover */
229 qla8044_wr_reg(ha, QLA8044_DRV_LOCKRECOVERY,
230 (ha->portnum << IDC_LOCK_RECOVERY_STATE_SHIFT_BITS) |
231 PROCEED_TO_RECOVER);
232
233 /* Force Unlock() */
234 qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, 0xFF);
235 qla8044_rd_reg(ha, QLA8044_DRV_UNLOCK);
236
237 /* Clear bits 0-5 in IDC_RECOVERY register*/
238 qla8044_wr_reg(ha, QLA8044_DRV_LOCKRECOVERY, 0);
239
240 /* Get lock() */
241 lock = qla8044_rd_reg(ha, QLA8044_DRV_LOCK);
242 if (lock) {
243 lockid = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
244 lockid = ((lockid + (1 << 8)) & ~0xFF) | ha->portnum;
245 qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, lockid);
246 return QLA_SUCCESS;
247 } else
248 return QLA_FUNCTION_FAILED;
249}
250
251int
252qla8044_idc_lock(struct qla_hw_data *ha)
253{
254 uint32_t ret_val = QLA_SUCCESS, timeout = 0, status = 0;
255 uint32_t lock_id, lock_cnt, func_num, tmo_owner = 0, first_owner = 0;
256 scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
257
258 while (status == 0) {
259 /* acquire semaphore5 from PCI HW block */
260 status = qla8044_rd_reg(ha, QLA8044_DRV_LOCK);
261
262 if (status) {
263 /* Increment Counter (8-31) and update func_num (0-7) on
264 * getting a successful lock */
265 lock_id = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
266 lock_id = ((lock_id + (1 << 8)) & ~0xFF) | ha->portnum;
267 qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, lock_id);
268 break;
269 }
270
271 if (timeout == 0)
272 first_owner = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
273
274 if (++timeout >=
275 (QLA8044_DRV_LOCK_TIMEOUT / QLA8044_DRV_LOCK_MSLEEP)) {
276 tmo_owner = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
277 func_num = tmo_owner & 0xFF;
278 lock_cnt = tmo_owner >> 8;
279 ql_log(ql_log_warn, vha, 0xb114,
280 "%s: Lock by func %d failed after 2s, lock held "
281 "by func %d, lock count %d, first_owner %d\n",
282 __func__, ha->portnum, func_num, lock_cnt,
283 (first_owner & 0xFF));
284 if (first_owner != tmo_owner) {
285 /* Some other driver got lock,
286 * OR same driver got lock again (counter
287 * value changed), when we were waiting for
288 * lock. Retry for another 2 sec */
289 ql_dbg(ql_dbg_p3p, vha, 0xb115,
290 "%s: %d: IDC lock failed\n",
291 __func__, ha->portnum);
292 timeout = 0;
293 } else {
294 /* Same driver holding lock > 2sec.
295 * Force Recovery */
296 if (qla8044_lock_recovery(vha) == QLA_SUCCESS) {
297 /* Recovered and got lock */
298 ret_val = QLA_SUCCESS;
299 ql_dbg(ql_dbg_p3p, vha, 0xb116,
300 "%s:IDC lock Recovery by %d"
301 "successful...\n", __func__,
302 ha->portnum);
303 }
304 /* Recovery Failed, some other function
305 * has the lock, wait for 2secs
306 * and retry
307 */
308 ql_dbg(ql_dbg_p3p, vha, 0xb08a,
309 "%s: IDC lock Recovery by %d "
310 "failed, Retrying timout\n", __func__,
311 ha->portnum);
312 timeout = 0;
313 }
314 }
315 msleep(QLA8044_DRV_LOCK_MSLEEP);
316 }
317 return ret_val;
318}
319
320void
321qla8044_idc_unlock(struct qla_hw_data *ha)
322{
323 int id;
324 scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
325
326 id = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
327
328 if ((id & 0xFF) != ha->portnum) {
329 ql_log(ql_log_warn, vha, 0xb118,
330 "%s: IDC Unlock by %d failed, lock owner is %d!\n",
331 __func__, ha->portnum, (id & 0xFF));
332 return;
333 }
334
335 /* Keep lock counter value, update the ha->func_num to 0xFF */
336 qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, (id | 0xFF));
337 qla8044_rd_reg(ha, QLA8044_DRV_UNLOCK);
338}
339
340/* 8044 Flash Lock/Unlock functions */
341static int
342qla8044_flash_lock(scsi_qla_host_t *vha)
343{
344 int lock_owner;
345 int timeout = 0;
346 uint32_t lock_status = 0;
347 int ret_val = QLA_SUCCESS;
348 struct qla_hw_data *ha = vha->hw;
349
350 while (lock_status == 0) {
351 lock_status = qla8044_rd_reg(ha, QLA8044_FLASH_LOCK);
352 if (lock_status)
353 break;
354
355 if (++timeout >= QLA8044_FLASH_LOCK_TIMEOUT / 20) {
356 lock_owner = qla8044_rd_reg(ha,
357 QLA8044_FLASH_LOCK_ID);
358 ql_log(ql_log_warn, vha, 0xb113,
359 "%s: flash lock by %d failed, held by %d\n",
360 __func__, ha->portnum, lock_owner);
361 ret_val = QLA_FUNCTION_FAILED;
362 break;
363 }
364 msleep(20);
365 }
366 qla8044_wr_reg(ha, QLA8044_FLASH_LOCK_ID, ha->portnum);
367 return ret_val;
368}
369
370static void
371qla8044_flash_unlock(scsi_qla_host_t *vha)
372{
373 int ret_val;
374 struct qla_hw_data *ha = vha->hw;
375
376 /* Reading FLASH_UNLOCK register unlocks the Flash */
377 qla8044_wr_reg(ha, QLA8044_FLASH_LOCK_ID, 0xFF);
378 ret_val = qla8044_rd_reg(ha, QLA8044_FLASH_UNLOCK);
379}
380
381
382static
383void qla8044_flash_lock_recovery(struct scsi_qla_host *vha)
384{
385
386 if (qla8044_flash_lock(vha)) {
387 /* Someone else is holding the lock. */
388 ql_log(ql_log_warn, vha, 0xb120, "Resetting flash_lock\n");
389 }
390
391 /*
392 * Either we got the lock, or someone
393 * else died while holding it.
394 * In either case, unlock.
395 */
396 qla8044_flash_unlock(vha);
397}
398
399/*
400 * Address and length are byte address
401 */
402static int
403qla8044_read_flash_data(scsi_qla_host_t *vha, uint8_t *p_data,
404 uint32_t flash_addr, int u32_word_count)
405{
406 int i, ret_val = QLA_SUCCESS;
407 uint32_t u32_word;
408
409 if (qla8044_flash_lock(vha) != QLA_SUCCESS) {
410 ret_val = QLA_FUNCTION_FAILED;
411 goto exit_lock_error;
412 }
413
414 if (flash_addr & 0x03) {
415 ql_log(ql_log_warn, vha, 0xb117,
416 "%s: Illegal addr = 0x%x\n", __func__, flash_addr);
417 ret_val = QLA_FUNCTION_FAILED;
418 goto exit_flash_read;
419 }
420
421 for (i = 0; i < u32_word_count; i++) {
422 if (qla8044_wr_reg_indirect(vha, QLA8044_FLASH_DIRECT_WINDOW,
423 (flash_addr & 0xFFFF0000))) {
424 ql_log(ql_log_warn, vha, 0xb119,
425 "%s: failed to write addr 0x%x to "
426 "FLASH_DIRECT_WINDOW\n! ",
427 __func__, flash_addr);
428 ret_val = QLA_FUNCTION_FAILED;
429 goto exit_flash_read;
430 }
431
432 ret_val = qla8044_rd_reg_indirect(vha,
433 QLA8044_FLASH_DIRECT_DATA(flash_addr),
434 &u32_word);
435 if (ret_val != QLA_SUCCESS) {
436 ql_log(ql_log_warn, vha, 0xb08c,
437 "%s: failed to read addr 0x%x!\n",
438 __func__, flash_addr);
439 goto exit_flash_read;
440 }
441
442 *(uint32_t *)p_data = u32_word;
443 p_data = p_data + 4;
444 flash_addr = flash_addr + 4;
445 }
446
447exit_flash_read:
448 qla8044_flash_unlock(vha);
449
450exit_lock_error:
451 return ret_val;
452}
453
454/*
455 * Address and length are byte address
456 */
457uint8_t *
458qla8044_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
459 uint32_t offset, uint32_t length)
460{
461 scsi_block_requests(vha->host);
462 if (qla8044_read_flash_data(vha, (uint8_t *)buf, offset, length / 4)
463 != QLA_SUCCESS) {
464 ql_log(ql_log_warn, vha, 0xb08d,
465 "%s: Failed to read from flash\n",
466 __func__);
467 }
468 scsi_unblock_requests(vha->host);
469 return buf;
470}
471
472inline int
473qla8044_need_reset(struct scsi_qla_host *vha)
474{
475 uint32_t drv_state, drv_active;
476 int rval;
477 struct qla_hw_data *ha = vha->hw;
478
479 drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
480 drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
481
482 rval = drv_state & (1 << ha->portnum);
483
484 if (ha->flags.eeh_busy && drv_active)
485 rval = 1;
486 return rval;
487}
488
489/*
490 * qla8044_write_list - Write the value (p_entry->arg2) to address specified
491 * by p_entry->arg1 for all entries in header with delay of p_hdr->delay between
492 * entries.
493 *
494 * @vha : Pointer to adapter structure
495 * @p_hdr : reset_entry header for WRITE_LIST opcode.
496 *
497 */
498static void
499qla8044_write_list(struct scsi_qla_host *vha,
500 struct qla8044_reset_entry_hdr *p_hdr)
501{
502 struct qla8044_entry *p_entry;
503 uint32_t i;
504
505 p_entry = (struct qla8044_entry *)((char *)p_hdr +
506 sizeof(struct qla8044_reset_entry_hdr));
507
508 for (i = 0; i < p_hdr->count; i++, p_entry++) {
509 qla8044_wr_reg_indirect(vha, p_entry->arg1, p_entry->arg2);
510 if (p_hdr->delay)
511 udelay((uint32_t)(p_hdr->delay));
512 }
513}
514
515/*
516 * qla8044_read_write_list - Read from address specified by p_entry->arg1,
517 * write value read to address specified by p_entry->arg2, for all entries in
518 * header with delay of p_hdr->delay between entries.
519 *
520 * @vha : Pointer to adapter structure
521 * @p_hdr : reset_entry header for READ_WRITE_LIST opcode.
522 *
523 */
524static void
525qla8044_read_write_list(struct scsi_qla_host *vha,
526 struct qla8044_reset_entry_hdr *p_hdr)
527{
528 struct qla8044_entry *p_entry;
529 uint32_t i;
530
531 p_entry = (struct qla8044_entry *)((char *)p_hdr +
532 sizeof(struct qla8044_reset_entry_hdr));
533
534 for (i = 0; i < p_hdr->count; i++, p_entry++) {
535 qla8044_read_write_crb_reg(vha, p_entry->arg1,
536 p_entry->arg2);
537 if (p_hdr->delay)
538 udelay((uint32_t)(p_hdr->delay));
539 }
540}
541
542/*
543 * qla8044_poll_reg - Poll the given CRB addr for duration msecs till
544 * value read ANDed with test_mask is equal to test_result.
545 *
546 * @ha : Pointer to adapter structure
547 * @addr : CRB register address
548 * @duration : Poll for total of "duration" msecs
549 * @test_mask : Mask value read with "test_mask"
550 * @test_result : Compare (value&test_mask) with test_result.
551 *
552 * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
553 */
554static int
555qla8044_poll_reg(struct scsi_qla_host *vha, uint32_t addr,
556 int duration, uint32_t test_mask, uint32_t test_result)
557{
558 uint32_t value;
559 int timeout_error;
560 uint8_t retries;
561 int ret_val = QLA_SUCCESS;
562
563 ret_val = qla8044_rd_reg_indirect(vha, addr, &value);
564 if (ret_val == QLA_FUNCTION_FAILED) {
565 timeout_error = 1;
566 goto exit_poll_reg;
567 }
568
569 /* poll every 1/10 of the total duration */
570 retries = duration/10;
571
572 do {
573 if ((value & test_mask) != test_result) {
574 timeout_error = 1;
575 msleep(duration/10);
576 ret_val = qla8044_rd_reg_indirect(vha, addr, &value);
577 if (ret_val == QLA_FUNCTION_FAILED) {
578 timeout_error = 1;
579 goto exit_poll_reg;
580 }
581 } else {
582 timeout_error = 0;
583 break;
584 }
585 } while (retries--);
586
587exit_poll_reg:
588 if (timeout_error) {
589 vha->reset_tmplt.seq_error++;
590 ql_log(ql_log_fatal, vha, 0xb090,
591 "%s: Poll Failed: 0x%08x 0x%08x 0x%08x\n",
592 __func__, value, test_mask, test_result);
593 }
594
595 return timeout_error;
596}
597
598/*
599 * qla8044_poll_list - For all entries in the POLL_LIST header, poll read CRB
600 * register specified by p_entry->arg1 and compare (value AND test_mask) with
601 * test_result to validate it. Wait for p_hdr->delay between processing entries.
602 *
603 * @ha : Pointer to adapter structure
604 * @p_hdr : reset_entry header for POLL_LIST opcode.
605 *
606 */
607static void
608qla8044_poll_list(struct scsi_qla_host *vha,
609 struct qla8044_reset_entry_hdr *p_hdr)
610{
611 long delay;
612 struct qla8044_entry *p_entry;
613 struct qla8044_poll *p_poll;
614 uint32_t i;
615 uint32_t value;
616
617 p_poll = (struct qla8044_poll *)
618 ((char *)p_hdr + sizeof(struct qla8044_reset_entry_hdr));
619
620 /* Entries start after 8 byte qla8044_poll, poll header contains
621 * the test_mask, test_value.
622 */
623 p_entry = (struct qla8044_entry *)((char *)p_poll +
624 sizeof(struct qla8044_poll));
625
626 delay = (long)p_hdr->delay;
627
628 if (!delay) {
629 for (i = 0; i < p_hdr->count; i++, p_entry++)
630 qla8044_poll_reg(vha, p_entry->arg1,
631 delay, p_poll->test_mask, p_poll->test_value);
632 } else {
633 for (i = 0; i < p_hdr->count; i++, p_entry++) {
634 if (delay) {
635 if (qla8044_poll_reg(vha,
636 p_entry->arg1, delay,
637 p_poll->test_mask,
638 p_poll->test_value)) {
639 /*If
640 * (data_read&test_mask != test_value)
641 * read TIMEOUT_ADDR (arg1) and
642 * ADDR (arg2) registers
643 */
644 qla8044_rd_reg_indirect(vha,
645 p_entry->arg1, &value);
646 qla8044_rd_reg_indirect(vha,
647 p_entry->arg2, &value);
648 }
649 }
650 }
651 }
652}
653
654/*
655 * qla8044_poll_write_list - Write dr_value, ar_value to dr_addr/ar_addr,
656 * read ar_addr, if (value& test_mask != test_mask) re-read till timeout
657 * expires.
658 *
659 * @vha : Pointer to adapter structure
660 * @p_hdr : reset entry header for POLL_WRITE_LIST opcode.
661 *
662 */
663static void
664qla8044_poll_write_list(struct scsi_qla_host *vha,
665 struct qla8044_reset_entry_hdr *p_hdr)
666{
667 long delay;
668 struct qla8044_quad_entry *p_entry;
669 struct qla8044_poll *p_poll;
670 uint32_t i;
671
672 p_poll = (struct qla8044_poll *)((char *)p_hdr +
673 sizeof(struct qla8044_reset_entry_hdr));
674
675 p_entry = (struct qla8044_quad_entry *)((char *)p_poll +
676 sizeof(struct qla8044_poll));
677
678 delay = (long)p_hdr->delay;
679
680 for (i = 0; i < p_hdr->count; i++, p_entry++) {
681 qla8044_wr_reg_indirect(vha,
682 p_entry->dr_addr, p_entry->dr_value);
683 qla8044_wr_reg_indirect(vha,
684 p_entry->ar_addr, p_entry->ar_value);
685 if (delay) {
686 if (qla8044_poll_reg(vha,
687 p_entry->ar_addr, delay,
688 p_poll->test_mask,
689 p_poll->test_value)) {
690 ql_dbg(ql_dbg_p3p, vha, 0xb091,
691 "%s: Timeout Error: poll list, ",
692 __func__);
693 ql_dbg(ql_dbg_p3p, vha, 0xb092,
694 "item_num %d, entry_num %d\n", i,
695 vha->reset_tmplt.seq_index);
696 }
697 }
698 }
699}
700
701/*
702 * qla8044_read_modify_write - Read value from p_entry->arg1, modify the
703 * value, write value to p_entry->arg2. Process entries with p_hdr->delay
704 * between entries.
705 *
706 * @vha : Pointer to adapter structure
707 * @p_hdr : header with shift/or/xor values.
708 *
709 */
710static void
711qla8044_read_modify_write(struct scsi_qla_host *vha,
712 struct qla8044_reset_entry_hdr *p_hdr)
713{
714 struct qla8044_entry *p_entry;
715 struct qla8044_rmw *p_rmw_hdr;
716 uint32_t i;
717
718 p_rmw_hdr = (struct qla8044_rmw *)((char *)p_hdr +
719 sizeof(struct qla8044_reset_entry_hdr));
720
721 p_entry = (struct qla8044_entry *)((char *)p_rmw_hdr +
722 sizeof(struct qla8044_rmw));
723
724 for (i = 0; i < p_hdr->count; i++, p_entry++) {
725 qla8044_rmw_crb_reg(vha, p_entry->arg1,
726 p_entry->arg2, p_rmw_hdr);
727 if (p_hdr->delay)
728 udelay((uint32_t)(p_hdr->delay));
729 }
730}
731
732/*
733 * qla8044_pause - Wait for p_hdr->delay msecs, called between processing
734 * two entries of a sequence.
735 *
736 * @vha : Pointer to adapter structure
737 * @p_hdr : Common reset entry header.
738 *
739 */
740static
741void qla8044_pause(struct scsi_qla_host *vha,
742 struct qla8044_reset_entry_hdr *p_hdr)
743{
744 if (p_hdr->delay)
745 mdelay((uint32_t)((long)p_hdr->delay));
746}
747
748/*
749 * qla8044_template_end - Indicates end of reset sequence processing.
750 *
751 * @vha : Pointer to adapter structure
752 * @p_hdr : Common reset entry header.
753 *
754 */
755static void
756qla8044_template_end(struct scsi_qla_host *vha,
757 struct qla8044_reset_entry_hdr *p_hdr)
758{
759 vha->reset_tmplt.template_end = 1;
760
761 if (vha->reset_tmplt.seq_error == 0) {
762 ql_dbg(ql_dbg_p3p, vha, 0xb093,
763 "%s: Reset sequence completed SUCCESSFULLY.\n", __func__);
764 } else {
765 ql_log(ql_log_fatal, vha, 0xb094,
766 "%s: Reset sequence completed with some timeout "
767 "errors.\n", __func__);
768 }
769}
770
771/*
772 * qla8044_poll_read_list - Write ar_value to ar_addr register, read ar_addr,
773 * if (value & test_mask != test_value) re-read till timeout value expires,
774 * read dr_addr register and assign to reset_tmplt.array.
775 *
776 * @vha : Pointer to adapter structure
777 * @p_hdr : Common reset entry header.
778 *
779 */
780static void
781qla8044_poll_read_list(struct scsi_qla_host *vha,
782 struct qla8044_reset_entry_hdr *p_hdr)
783{
784 long delay;
785 int index;
786 struct qla8044_quad_entry *p_entry;
787 struct qla8044_poll *p_poll;
788 uint32_t i;
789 uint32_t value;
790
791 p_poll = (struct qla8044_poll *)
792 ((char *)p_hdr + sizeof(struct qla8044_reset_entry_hdr));
793
794 p_entry = (struct qla8044_quad_entry *)
795 ((char *)p_poll + sizeof(struct qla8044_poll));
796
797 delay = (long)p_hdr->delay;
798
799 for (i = 0; i < p_hdr->count; i++, p_entry++) {
800 qla8044_wr_reg_indirect(vha, p_entry->ar_addr,
801 p_entry->ar_value);
802 if (delay) {
803 if (qla8044_poll_reg(vha, p_entry->ar_addr, delay,
804 p_poll->test_mask, p_poll->test_value)) {
805 ql_dbg(ql_dbg_p3p, vha, 0xb095,
806 "%s: Timeout Error: poll "
807 "list, ", __func__);
808 ql_dbg(ql_dbg_p3p, vha, 0xb096,
809 "Item_num %d, "
810 "entry_num %d\n", i,
811 vha->reset_tmplt.seq_index);
812 } else {
813 index = vha->reset_tmplt.array_index;
814 qla8044_rd_reg_indirect(vha,
815 p_entry->dr_addr, &value);
816 vha->reset_tmplt.array[index++] = value;
817 if (index == QLA8044_MAX_RESET_SEQ_ENTRIES)
818 vha->reset_tmplt.array_index = 1;
819 }
820 }
821 }
822}
823
824/*
825 * qla8031_process_reset_template - Process all entries in reset template
826 * till entry with SEQ_END opcode, which indicates end of the reset template
827 * processing. Each entry has a Reset Entry header, entry opcode/command, with
828 * size of the entry, number of entries in sub-sequence and delay in microsecs
829 * or timeout in millisecs.
830 *
831 * @ha : Pointer to adapter structure
832 * @p_buff : Common reset entry header.
833 *
834 */
835static void
836qla8044_process_reset_template(struct scsi_qla_host *vha,
837 char *p_buff)
838{
839 int index, entries;
840 struct qla8044_reset_entry_hdr *p_hdr;
841 char *p_entry = p_buff;
842
843 vha->reset_tmplt.seq_end = 0;
844 vha->reset_tmplt.template_end = 0;
845 entries = vha->reset_tmplt.hdr->entries;
846 index = vha->reset_tmplt.seq_index;
847
848 for (; (!vha->reset_tmplt.seq_end) && (index < entries); index++) {
849 p_hdr = (struct qla8044_reset_entry_hdr *)p_entry;
850 switch (p_hdr->cmd) {
851 case OPCODE_NOP:
852 break;
853 case OPCODE_WRITE_LIST:
854 qla8044_write_list(vha, p_hdr);
855 break;
856 case OPCODE_READ_WRITE_LIST:
857 qla8044_read_write_list(vha, p_hdr);
858 break;
859 case OPCODE_POLL_LIST:
860 qla8044_poll_list(vha, p_hdr);
861 break;
862 case OPCODE_POLL_WRITE_LIST:
863 qla8044_poll_write_list(vha, p_hdr);
864 break;
865 case OPCODE_READ_MODIFY_WRITE:
866 qla8044_read_modify_write(vha, p_hdr);
867 break;
868 case OPCODE_SEQ_PAUSE:
869 qla8044_pause(vha, p_hdr);
870 break;
871 case OPCODE_SEQ_END:
872 vha->reset_tmplt.seq_end = 1;
873 break;
874 case OPCODE_TMPL_END:
875 qla8044_template_end(vha, p_hdr);
876 break;
877 case OPCODE_POLL_READ_LIST:
878 qla8044_poll_read_list(vha, p_hdr);
879 break;
880 default:
881 ql_log(ql_log_fatal, vha, 0xb097,
882 "%s: Unknown command ==> 0x%04x on "
883 "entry = %d\n", __func__, p_hdr->cmd, index);
884 break;
885 }
886 /*
887 *Set pointer to next entry in the sequence.
888 */
889 p_entry += p_hdr->size;
890 }
891 vha->reset_tmplt.seq_index = index;
892}
893
894static void
895qla8044_process_init_seq(struct scsi_qla_host *vha)
896{
897 qla8044_process_reset_template(vha,
898 vha->reset_tmplt.init_offset);
899 if (vha->reset_tmplt.seq_end != 1)
900 ql_log(ql_log_fatal, vha, 0xb098,
901 "%s: Abrupt INIT Sub-Sequence end.\n",
902 __func__);
903}
904
905static void
906qla8044_process_stop_seq(struct scsi_qla_host *vha)
907{
908 vha->reset_tmplt.seq_index = 0;
909 qla8044_process_reset_template(vha, vha->reset_tmplt.stop_offset);
910 if (vha->reset_tmplt.seq_end != 1)
911 ql_log(ql_log_fatal, vha, 0xb099,
912 "%s: Abrupt STOP Sub-Sequence end.\n", __func__);
913}
914
915static void
916qla8044_process_start_seq(struct scsi_qla_host *vha)
917{
918 qla8044_process_reset_template(vha, vha->reset_tmplt.start_offset);
919 if (vha->reset_tmplt.template_end != 1)
920 ql_log(ql_log_fatal, vha, 0xb09a,
921 "%s: Abrupt START Sub-Sequence end.\n",
922 __func__);
923}
924
925static int
926qla8044_lockless_flash_read_u32(struct scsi_qla_host *vha,
927 uint32_t flash_addr, uint8_t *p_data, int u32_word_count)
928{
929 uint32_t i;
930 uint32_t u32_word;
931 uint32_t flash_offset;
932 uint32_t addr = flash_addr;
933 int ret_val = QLA_SUCCESS;
934
935 flash_offset = addr & (QLA8044_FLASH_SECTOR_SIZE - 1);
936
937 if (addr & 0x3) {
938 ql_log(ql_log_fatal, vha, 0xb09b, "%s: Illegal addr = 0x%x\n",
939 __func__, addr);
940 ret_val = QLA_FUNCTION_FAILED;
941 goto exit_lockless_read;
942 }
943
944 ret_val = qla8044_wr_reg_indirect(vha,
945 QLA8044_FLASH_DIRECT_WINDOW, (addr));
946
947 if (ret_val != QLA_SUCCESS) {
948 ql_log(ql_log_fatal, vha, 0xb09c,
949 "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW!\n",
950 __func__, addr);
951 goto exit_lockless_read;
952 }
953
954 /* Check if data is spread across multiple sectors */
955 if ((flash_offset + (u32_word_count * sizeof(uint32_t))) >
956 (QLA8044_FLASH_SECTOR_SIZE - 1)) {
957 /* Multi sector read */
958 for (i = 0; i < u32_word_count; i++) {
959 ret_val = qla8044_rd_reg_indirect(vha,
960 QLA8044_FLASH_DIRECT_DATA(addr), &u32_word);
961 if (ret_val != QLA_SUCCESS) {
962 ql_log(ql_log_fatal, vha, 0xb09d,
963 "%s: failed to read addr 0x%x!\n",
964 __func__, addr);
965 goto exit_lockless_read;
966 }
967 *(uint32_t *)p_data = u32_word;
968 p_data = p_data + 4;
969 addr = addr + 4;
970 flash_offset = flash_offset + 4;
971 if (flash_offset > (QLA8044_FLASH_SECTOR_SIZE - 1)) {
972 /* This write is needed once for each sector */
973 ret_val = qla8044_wr_reg_indirect(vha,
974 QLA8044_FLASH_DIRECT_WINDOW, (addr));
975 if (ret_val != QLA_SUCCESS) {
976 ql_log(ql_log_fatal, vha, 0xb09f,
977 "%s: failed to write addr "
978 "0x%x to FLASH_DIRECT_WINDOW!\n",
979 __func__, addr);
980 goto exit_lockless_read;
981 }
982 flash_offset = 0;
983 }
984 }
985 } else {
986 /* Single sector read */
987 for (i = 0; i < u32_word_count; i++) {
988 ret_val = qla8044_rd_reg_indirect(vha,
989 QLA8044_FLASH_DIRECT_DATA(addr), &u32_word);
990 if (ret_val != QLA_SUCCESS) {
991 ql_log(ql_log_fatal, vha, 0xb0a0,
992 "%s: failed to read addr 0x%x!\n",
993 __func__, addr);
994 goto exit_lockless_read;
995 }
996 *(uint32_t *)p_data = u32_word;
997 p_data = p_data + 4;
998 addr = addr + 4;
999 }
1000 }
1001
1002exit_lockless_read:
1003 return ret_val;
1004}
1005
1006/*
1007 * qla8044_ms_mem_write_128b - Writes data to MS/off-chip memory
1008 *
1009 * @vha : Pointer to adapter structure
1010 * addr : Flash address to write to
1011 * data : Data to be written
1012 * count : word_count to be written
1013 *
1014 * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
1015 */
1016static int
1017qla8044_ms_mem_write_128b(struct scsi_qla_host *vha,
1018 uint64_t addr, uint32_t *data, uint32_t count)
1019{
1020 int i, j, ret_val = QLA_SUCCESS;
1021 uint32_t agt_ctrl;
1022 unsigned long flags;
1023 struct qla_hw_data *ha = vha->hw;
1024
1025 /* Only 128-bit aligned access */
1026 if (addr & 0xF) {
1027 ret_val = QLA_FUNCTION_FAILED;
1028 goto exit_ms_mem_write;
1029 }
1030 write_lock_irqsave(&ha->hw_lock, flags);
1031
1032 /* Write address */
1033 ret_val = qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_ADDR_HI, 0);
1034 if (ret_val == QLA_FUNCTION_FAILED) {
1035 ql_log(ql_log_fatal, vha, 0xb0a1,
1036 "%s: write to AGT_ADDR_HI failed!\n", __func__);
1037 goto exit_ms_mem_write_unlock;
1038 }
1039
1040 for (i = 0; i < count; i++, addr += 16) {
1041 if (!((QLA8044_ADDR_IN_RANGE(addr, QLA8044_ADDR_QDR_NET,
1042 QLA8044_ADDR_QDR_NET_MAX)) ||
1043 (QLA8044_ADDR_IN_RANGE(addr, QLA8044_ADDR_DDR_NET,
1044 QLA8044_ADDR_DDR_NET_MAX)))) {
1045 ret_val = QLA_FUNCTION_FAILED;
1046 goto exit_ms_mem_write_unlock;
1047 }
1048
1049 ret_val = qla8044_wr_reg_indirect(vha,
1050 MD_MIU_TEST_AGT_ADDR_LO, addr);
1051
1052 /* Write data */
1053 ret_val += qla8044_wr_reg_indirect(vha,
1054 MD_MIU_TEST_AGT_WRDATA_LO, *data++);
1055 ret_val += qla8044_wr_reg_indirect(vha,
1056 MD_MIU_TEST_AGT_WRDATA_HI, *data++);
1057 ret_val += qla8044_wr_reg_indirect(vha,
1058 MD_MIU_TEST_AGT_WRDATA_ULO, *data++);
1059 ret_val += qla8044_wr_reg_indirect(vha,
1060 MD_MIU_TEST_AGT_WRDATA_UHI, *data++);
1061 if (ret_val == QLA_FUNCTION_FAILED) {
1062 ql_log(ql_log_fatal, vha, 0xb0a2,
1063 "%s: write to AGT_WRDATA failed!\n",
1064 __func__);
1065 goto exit_ms_mem_write_unlock;
1066 }
1067
1068 /* Check write status */
1069 ret_val = qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL,
1070 MIU_TA_CTL_WRITE_ENABLE);
1071 ret_val += qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL,
1072 MIU_TA_CTL_WRITE_START);
1073 if (ret_val == QLA_FUNCTION_FAILED) {
1074 ql_log(ql_log_fatal, vha, 0xb0a3,
1075 "%s: write to AGT_CTRL failed!\n", __func__);
1076 goto exit_ms_mem_write_unlock;
1077 }
1078
1079 for (j = 0; j < MAX_CTL_CHECK; j++) {
1080 ret_val = qla8044_rd_reg_indirect(vha,
1081 MD_MIU_TEST_AGT_CTRL, &agt_ctrl);
1082 if (ret_val == QLA_FUNCTION_FAILED) {
1083 ql_log(ql_log_fatal, vha, 0xb0a4,
1084 "%s: failed to read "
1085 "MD_MIU_TEST_AGT_CTRL!\n", __func__);
1086 goto exit_ms_mem_write_unlock;
1087 }
1088 if ((agt_ctrl & MIU_TA_CTL_BUSY) == 0)
1089 break;
1090 }
1091
1092 /* Status check failed */
1093 if (j >= MAX_CTL_CHECK) {
1094 ql_log(ql_log_fatal, vha, 0xb0a5,
1095 "%s: MS memory write failed!\n",
1096 __func__);
1097 ret_val = QLA_FUNCTION_FAILED;
1098 goto exit_ms_mem_write_unlock;
1099 }
1100 }
1101
1102exit_ms_mem_write_unlock:
1103 write_unlock_irqrestore(&ha->hw_lock, flags);
1104
1105exit_ms_mem_write:
1106 return ret_val;
1107}
1108
1109static int
1110qla8044_copy_bootloader(struct scsi_qla_host *vha)
1111{
1112 uint8_t *p_cache;
1113 uint32_t src, count, size;
1114 uint64_t dest;
1115 int ret_val = QLA_SUCCESS;
1116 struct qla_hw_data *ha = vha->hw;
1117
1118 src = QLA8044_BOOTLOADER_FLASH_ADDR;
1119 dest = qla8044_rd_reg(ha, QLA8044_BOOTLOADER_ADDR);
1120 size = qla8044_rd_reg(ha, QLA8044_BOOTLOADER_SIZE);
1121
1122 /* 128 bit alignment check */
1123 if (size & 0xF)
1124 size = (size + 16) & ~0xF;
1125
1126 /* 16 byte count */
1127 count = size/16;
1128
1129 p_cache = vmalloc(size);
1130 if (p_cache == NULL) {
1131 ql_log(ql_log_fatal, vha, 0xb0a6,
1132 "%s: Failed to allocate memory for "
1133 "boot loader cache\n", __func__);
1134 ret_val = QLA_FUNCTION_FAILED;
1135 goto exit_copy_bootloader;
1136 }
1137
1138 ret_val = qla8044_lockless_flash_read_u32(vha, src,
1139 p_cache, size/sizeof(uint32_t));
1140 if (ret_val == QLA_FUNCTION_FAILED) {
1141 ql_log(ql_log_fatal, vha, 0xb0a7,
1142 "%s: Error reading F/W from flash!!!\n", __func__);
1143 goto exit_copy_error;
1144 }
1145 ql_dbg(ql_dbg_p3p, vha, 0xb0a8, "%s: Read F/W from flash!\n",
1146 __func__);
1147
1148 /* 128 bit/16 byte write to MS memory */
1149 ret_val = qla8044_ms_mem_write_128b(vha, dest,
1150 (uint32_t *)p_cache, count);
1151 if (ret_val == QLA_FUNCTION_FAILED) {
1152 ql_log(ql_log_fatal, vha, 0xb0a9,
1153 "%s: Error writing F/W to MS !!!\n", __func__);
1154 goto exit_copy_error;
1155 }
1156 ql_dbg(ql_dbg_p3p, vha, 0xb0aa,
1157 "%s: Wrote F/W (size %d) to MS !!!\n",
1158 __func__, size);
1159
1160exit_copy_error:
1161 vfree(p_cache);
1162
1163exit_copy_bootloader:
1164 return ret_val;
1165}
1166
1167static int
1168qla8044_restart(struct scsi_qla_host *vha)
1169{
1170 int ret_val = QLA_SUCCESS;
1171 struct qla_hw_data *ha = vha->hw;
1172
1173 qla8044_process_stop_seq(vha);
1174
1175 /* Collect minidump */
1176 if (ql2xmdenable)
1177 qla8044_get_minidump(vha);
1178 else
1179 ql_log(ql_log_fatal, vha, 0xb14c,
1180 "Minidump disabled.\n");
1181
1182 qla8044_process_init_seq(vha);
1183
1184 if (qla8044_copy_bootloader(vha)) {
1185 ql_log(ql_log_fatal, vha, 0xb0ab,
1186 "%s: Copy bootloader, firmware restart failed!\n",
1187 __func__);
1188 ret_val = QLA_FUNCTION_FAILED;
1189 goto exit_restart;
1190 }
1191
1192 /*
1193 * Loads F/W from flash
1194 */
1195 qla8044_wr_reg(ha, QLA8044_FW_IMAGE_VALID, QLA8044_BOOT_FROM_FLASH);
1196
1197 qla8044_process_start_seq(vha);
1198
1199exit_restart:
1200 return ret_val;
1201}
1202
1203/*
1204 * qla8044_check_cmd_peg_status - Check peg status to see if Peg is
1205 * initialized.
1206 *
1207 * @ha : Pointer to adapter structure
1208 *
1209 * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
1210 */
1211static int
1212qla8044_check_cmd_peg_status(struct scsi_qla_host *vha)
1213{
1214 uint32_t val, ret_val = QLA_FUNCTION_FAILED;
1215 int retries = CRB_CMDPEG_CHECK_RETRY_COUNT;
1216 struct qla_hw_data *ha = vha->hw;
1217
1218 do {
1219 val = qla8044_rd_reg(ha, QLA8044_CMDPEG_STATE);
1220 if (val == PHAN_INITIALIZE_COMPLETE) {
1221 ql_dbg(ql_dbg_p3p, vha, 0xb0ac,
1222 "%s: Command Peg initialization "
1223 "complete! state=0x%x\n", __func__, val);
1224 ret_val = QLA_SUCCESS;
1225 break;
1226 }
1227 msleep(CRB_CMDPEG_CHECK_DELAY);
1228 } while (--retries);
1229
1230 return ret_val;
1231}
1232
1233static int
1234qla8044_start_firmware(struct scsi_qla_host *vha)
1235{
1236 int ret_val = QLA_SUCCESS;
1237
1238 if (qla8044_restart(vha)) {
1239 ql_log(ql_log_fatal, vha, 0xb0ad,
1240 "%s: Restart Error!!!, Need Reset!!!\n",
1241 __func__);
1242 ret_val = QLA_FUNCTION_FAILED;
1243 goto exit_start_fw;
1244 } else
1245 ql_dbg(ql_dbg_p3p, vha, 0xb0af,
1246 "%s: Restart done!\n", __func__);
1247
1248 ret_val = qla8044_check_cmd_peg_status(vha);
1249 if (ret_val) {
1250 ql_log(ql_log_fatal, vha, 0xb0b0,
1251 "%s: Peg not initialized!\n", __func__);
1252 ret_val = QLA_FUNCTION_FAILED;
1253 }
1254
1255exit_start_fw:
1256 return ret_val;
1257}
1258
1259void
1260qla8044_clear_drv_active(struct scsi_qla_host *vha)
1261{
1262 uint32_t drv_active;
1263 struct qla_hw_data *ha = vha->hw;
1264
1265 drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
1266 drv_active &= ~(1 << (ha->portnum));
1267
1268 ql_log(ql_log_info, vha, 0xb0b1,
1269 "%s(%ld): drv_active: 0x%08x\n",
1270 __func__, vha->host_no, drv_active);
1271
1272 qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, drv_active);
1273}
1274
1275/*
1276 * qla8044_device_bootstrap - Initialize device, set DEV_READY, start fw
1277 * @ha: pointer to adapter structure
1278 *
1279 * Note: IDC lock must be held upon entry
1280 **/
1281static int
1282qla8044_device_bootstrap(struct scsi_qla_host *vha)
1283{
1284 int rval = QLA_FUNCTION_FAILED;
1285 int i;
1286 uint32_t old_count = 0, count = 0;
1287 int need_reset = 0;
1288 uint32_t idc_ctrl;
1289 struct qla_hw_data *ha = vha->hw;
1290
1291 need_reset = qla8044_need_reset(vha);
1292
1293 if (!need_reset) {
1294 old_count = qla8044_rd_direct(vha,
1295 QLA8044_PEG_ALIVE_COUNTER_INDEX);
1296
1297 for (i = 0; i < 10; i++) {
1298 msleep(200);
1299
1300 count = qla8044_rd_direct(vha,
1301 QLA8044_PEG_ALIVE_COUNTER_INDEX);
1302 if (count != old_count) {
1303 rval = QLA_SUCCESS;
1304 goto dev_ready;
1305 }
1306 }
1307 qla8044_flash_lock_recovery(vha);
1308 } else {
1309 /* We are trying to perform a recovery here. */
1310 if (ha->flags.isp82xx_fw_hung)
1311 qla8044_flash_lock_recovery(vha);
1312 }
1313
1314 /* set to DEV_INITIALIZING */
1315 ql_log(ql_log_info, vha, 0xb0b2,
1316 "%s: HW State: INITIALIZING\n", __func__);
1317 qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
1318 QLA8XXX_DEV_INITIALIZING);
1319
1320 qla8044_idc_unlock(ha);
1321 rval = qla8044_start_firmware(vha);
1322 qla8044_idc_lock(ha);
1323
1324 if (rval != QLA_SUCCESS) {
1325 ql_log(ql_log_info, vha, 0xb0b3,
1326 "%s: HW State: FAILED\n", __func__);
1327 qla8044_clear_drv_active(vha);
1328 qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
1329 QLA8XXX_DEV_FAILED);
1330 return rval;
1331 }
1332
1333 /* For ISP8044, If IDC_CTRL GRACEFUL_RESET_BIT1 is set , reset it after
1334 * device goes to INIT state. */
1335 idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
1336 if (idc_ctrl & GRACEFUL_RESET_BIT1) {
1337 qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL,
1338 (idc_ctrl & ~GRACEFUL_RESET_BIT1));
1339 ha->fw_dumped = 0;
1340 }
1341
1342dev_ready:
1343 ql_log(ql_log_info, vha, 0xb0b4,
1344 "%s: HW State: READY\n", __func__);
1345 qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX, QLA8XXX_DEV_READY);
1346
1347 return rval;
1348}
1349
1350/*-------------------------Reset Sequence Functions-----------------------*/
1351static void
1352qla8044_dump_reset_seq_hdr(struct scsi_qla_host *vha)
1353{
1354 u8 *phdr;
1355
1356 if (!vha->reset_tmplt.buff) {
1357 ql_log(ql_log_fatal, vha, 0xb0b5,
1358 "%s: Error Invalid reset_seq_template\n", __func__);
1359 return;
1360 }
1361
1362 phdr = vha->reset_tmplt.buff;
1363 ql_dbg(ql_dbg_p3p, vha, 0xb0b6,
1364 "Reset Template :\n\t0x%X 0x%X 0x%X 0x%X"
1365 "0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n"
1366 "\t0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n\n",
1367 *phdr, *(phdr+1), *(phdr+2), *(phdr+3), *(phdr+4),
1368 *(phdr+5), *(phdr+6), *(phdr+7), *(phdr + 8),
1369 *(phdr+9), *(phdr+10), *(phdr+11), *(phdr+12),
1370 *(phdr+13), *(phdr+14), *(phdr+15));
1371}
1372
1373/*
1374 * qla8044_reset_seq_checksum_test - Validate Reset Sequence template.
1375 *
1376 * @ha : Pointer to adapter structure
1377 *
1378 * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
1379 */
1380static int
1381qla8044_reset_seq_checksum_test(struct scsi_qla_host *vha)
1382{
1383 uint32_t sum = 0;
1384 uint16_t *buff = (uint16_t *)vha->reset_tmplt.buff;
1385 int u16_count = vha->reset_tmplt.hdr->size / sizeof(uint16_t);
1386
1387 while (u16_count-- > 0)
1388 sum += *buff++;
1389
1390 while (sum >> 16)
1391 sum = (sum & 0xFFFF) + (sum >> 16);
1392
1393 /* checksum of 0 indicates a valid template */
1394 if (~sum) {
1395 return QLA_SUCCESS;
1396 } else {
1397 ql_log(ql_log_fatal, vha, 0xb0b7,
1398 "%s: Reset seq checksum failed\n", __func__);
1399 return QLA_FUNCTION_FAILED;
1400 }
1401}
1402
1403/*
1404 * qla8044_read_reset_template - Read Reset Template from Flash, validate
1405 * the template and store offsets of stop/start/init offsets in ha->reset_tmplt.
1406 *
1407 * @ha : Pointer to adapter structure
1408 */
1409void
1410qla8044_read_reset_template(struct scsi_qla_host *vha)
1411{
1412 uint8_t *p_buff;
1413 uint32_t addr, tmplt_hdr_def_size, tmplt_hdr_size;
1414
1415 vha->reset_tmplt.seq_error = 0;
1416 vha->reset_tmplt.buff = vmalloc(QLA8044_RESTART_TEMPLATE_SIZE);
1417 if (vha->reset_tmplt.buff == NULL) {
1418 ql_log(ql_log_fatal, vha, 0xb0b8,
1419 "%s: Failed to allocate reset template resources\n",
1420 __func__);
1421 goto exit_read_reset_template;
1422 }
1423
1424 p_buff = vha->reset_tmplt.buff;
1425 addr = QLA8044_RESET_TEMPLATE_ADDR;
1426
1427 tmplt_hdr_def_size =
1428 sizeof(struct qla8044_reset_template_hdr) / sizeof(uint32_t);
1429
1430 ql_dbg(ql_dbg_p3p, vha, 0xb0b9,
1431 "%s: Read template hdr size %d from Flash\n",
1432 __func__, tmplt_hdr_def_size);
1433
1434 /* Copy template header from flash */
1435 if (qla8044_read_flash_data(vha, p_buff, addr, tmplt_hdr_def_size)) {
1436 ql_log(ql_log_fatal, vha, 0xb0ba,
1437 "%s: Failed to read reset template\n", __func__);
1438 goto exit_read_template_error;
1439 }
1440
1441 vha->reset_tmplt.hdr =
1442 (struct qla8044_reset_template_hdr *) vha->reset_tmplt.buff;
1443
1444 /* Validate the template header size and signature */
1445 tmplt_hdr_size = vha->reset_tmplt.hdr->hdr_size/sizeof(uint32_t);
1446 if ((tmplt_hdr_size != tmplt_hdr_def_size) ||
1447 (vha->reset_tmplt.hdr->signature != RESET_TMPLT_HDR_SIGNATURE)) {
1448 ql_log(ql_log_fatal, vha, 0xb0bb,
1449 "%s: Template Header size invalid %d "
1450 "tmplt_hdr_def_size %d!!!\n", __func__,
1451 tmplt_hdr_size, tmplt_hdr_def_size);
1452 goto exit_read_template_error;
1453 }
1454
1455 addr = QLA8044_RESET_TEMPLATE_ADDR + vha->reset_tmplt.hdr->hdr_size;
1456 p_buff = vha->reset_tmplt.buff + vha->reset_tmplt.hdr->hdr_size;
1457 tmplt_hdr_def_size = (vha->reset_tmplt.hdr->size -
1458 vha->reset_tmplt.hdr->hdr_size)/sizeof(uint32_t);
1459
1460 ql_dbg(ql_dbg_p3p, vha, 0xb0bc,
1461 "%s: Read rest of the template size %d\n",
1462 __func__, vha->reset_tmplt.hdr->size);
1463
1464 /* Copy rest of the template */
1465 if (qla8044_read_flash_data(vha, p_buff, addr, tmplt_hdr_def_size)) {
1466 ql_log(ql_log_fatal, vha, 0xb0bd,
1467 "%s: Failed to read reset tempelate\n", __func__);
1468 goto exit_read_template_error;
1469 }
1470
1471 /* Integrity check */
1472 if (qla8044_reset_seq_checksum_test(vha)) {
1473 ql_log(ql_log_fatal, vha, 0xb0be,
1474 "%s: Reset Seq checksum failed!\n", __func__);
1475 goto exit_read_template_error;
1476 }
1477
1478 ql_dbg(ql_dbg_p3p, vha, 0xb0bf,
1479 "%s: Reset Seq checksum passed! Get stop, "
1480 "start and init seq offsets\n", __func__);
1481
1482 /* Get STOP, START, INIT sequence offsets */
1483 vha->reset_tmplt.init_offset = vha->reset_tmplt.buff +
1484 vha->reset_tmplt.hdr->init_seq_offset;
1485
1486 vha->reset_tmplt.start_offset = vha->reset_tmplt.buff +
1487 vha->reset_tmplt.hdr->start_seq_offset;
1488
1489 vha->reset_tmplt.stop_offset = vha->reset_tmplt.buff +
1490 vha->reset_tmplt.hdr->hdr_size;
1491
1492 qla8044_dump_reset_seq_hdr(vha);
1493
1494 goto exit_read_reset_template;
1495
1496exit_read_template_error:
1497 vfree(vha->reset_tmplt.buff);
1498
1499exit_read_reset_template:
1500 return;
1501}
1502
1503void
1504qla8044_set_idc_dontreset(struct scsi_qla_host *vha)
1505{
1506 uint32_t idc_ctrl;
1507 struct qla_hw_data *ha = vha->hw;
1508
1509 idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
1510 idc_ctrl |= DONTRESET_BIT0;
1511 ql_dbg(ql_dbg_p3p, vha, 0xb0c0,
1512 "%s: idc_ctrl = %d\n", __func__, idc_ctrl);
1513 qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL, idc_ctrl);
1514}
1515
1516inline void
1517qla8044_set_rst_ready(struct scsi_qla_host *vha)
1518{
1519 uint32_t drv_state;
1520 struct qla_hw_data *ha = vha->hw;
1521
1522 drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
1523
1524 /* For ISP8044, drv_active register has 1 bit per function,
1525 * shift 1 by func_num to set a bit for the function.*/
1526 drv_state |= (1 << ha->portnum);
1527
1528 ql_log(ql_log_info, vha, 0xb0c1,
1529 "%s(%ld): drv_state: 0x%08x\n",
1530 __func__, vha->host_no, drv_state);
1531 qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, drv_state);
1532}
1533
1534/**
1535 * qla8044_need_reset_handler - Code to start reset sequence
1536 * @ha: pointer to adapter structure
1537 *
1538 * Note: IDC lock must be held upon entry
1539 **/
1540static void
1541qla8044_need_reset_handler(struct scsi_qla_host *vha)
1542{
1543 uint32_t dev_state = 0, drv_state, drv_active;
1544 unsigned long reset_timeout, dev_init_timeout;
1545 struct qla_hw_data *ha = vha->hw;
1546
1547 ql_log(ql_log_fatal, vha, 0xb0c2,
1548 "%s: Performing ISP error recovery\n", __func__);
1549
1550 if (vha->flags.online) {
1551 qla8044_idc_unlock(ha);
1552 qla2x00_abort_isp_cleanup(vha);
1553 ha->isp_ops->get_flash_version(vha, vha->req->ring);
1554 ha->isp_ops->nvram_config(vha);
1555 qla8044_idc_lock(ha);
1556 }
1557
1558 if (!ha->flags.nic_core_reset_owner) {
1559 ql_dbg(ql_dbg_p3p, vha, 0xb0c3,
1560 "%s(%ld): reset acknowledged\n",
1561 __func__, vha->host_no);
1562 qla8044_set_rst_ready(vha);
1563
1564 /* Non-reset owners ACK Reset and wait for device INIT state
1565 * as part of Reset Recovery by Reset Owner
1566 */
1567 dev_init_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
1568
1569 do {
1570 if (time_after_eq(jiffies, dev_init_timeout)) {
1571 ql_log(ql_log_info, vha, 0xb0c4,
1572 "%s: Non Reset owner DEV INIT "
1573 "TIMEOUT!\n", __func__);
1574 break;
1575 }
1576
1577 qla8044_idc_unlock(ha);
1578 msleep(1000);
1579 qla8044_idc_lock(ha);
1580
1581 dev_state = qla8044_rd_direct(vha,
1582 QLA8044_CRB_DEV_STATE_INDEX);
1583 } while (dev_state == QLA8XXX_DEV_NEED_RESET);
1584 } else {
1585 qla8044_set_rst_ready(vha);
1586
1587 /* wait for 10 seconds for reset ack from all functions */
1588 reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
1589
1590 drv_state = qla8044_rd_direct(vha,
1591 QLA8044_CRB_DRV_STATE_INDEX);
1592 drv_active = qla8044_rd_direct(vha,
1593 QLA8044_CRB_DRV_ACTIVE_INDEX);
1594
1595 ql_log(ql_log_info, vha, 0xb0c5,
1596 "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
1597 __func__, vha->host_no, drv_state, drv_active);
1598
1599 while (drv_state != drv_active) {
1600 if (time_after_eq(jiffies, reset_timeout)) {
1601 ql_log(ql_log_info, vha, 0xb0c6,
1602 "%s: RESET TIMEOUT!"
1603 "drv_state: 0x%08x, drv_active: 0x%08x\n",
1604 QLA2XXX_DRIVER_NAME, drv_state, drv_active);
1605 break;
1606 }
1607
1608 qla8044_idc_unlock(ha);
1609 msleep(1000);
1610 qla8044_idc_lock(ha);
1611
1612 drv_state = qla8044_rd_direct(vha,
1613 QLA8044_CRB_DRV_STATE_INDEX);
1614 drv_active = qla8044_rd_direct(vha,
1615 QLA8044_CRB_DRV_ACTIVE_INDEX);
1616 }
1617
1618 if (drv_state != drv_active) {
1619 ql_log(ql_log_info, vha, 0xb0c7,
1620 "%s(%ld): Reset_owner turning off drv_active "
1621 "of non-acking function 0x%x\n", __func__,
1622 vha->host_no, (drv_active ^ drv_state));
1623 drv_active = drv_active & drv_state;
1624 qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX,
1625 drv_active);
1626 }
1627
1628 /*
1629 * Clear RESET OWNER, will be set at next reset
1630 * by next RST_OWNER
1631 */
1632 ha->flags.nic_core_reset_owner = 0;
1633
1634 /* Start Reset Recovery */
1635 qla8044_device_bootstrap(vha);
1636 }
1637}
1638
1639static void
1640qla8044_set_drv_active(struct scsi_qla_host *vha)
1641{
1642 uint32_t drv_active;
1643 struct qla_hw_data *ha = vha->hw;
1644
1645 drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
1646
1647 /* For ISP8044, drv_active register has 1 bit per function,
1648 * shift 1 by func_num to set a bit for the function.*/
1649 drv_active |= (1 << ha->portnum);
1650
1651 ql_log(ql_log_info, vha, 0xb0c8,
1652 "%s(%ld): drv_active: 0x%08x\n",
1653 __func__, vha->host_no, drv_active);
1654 qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, drv_active);
1655}
1656
1657static void
1658qla8044_clear_idc_dontreset(struct scsi_qla_host *vha)
1659{
1660 uint32_t idc_ctrl;
1661 struct qla_hw_data *ha = vha->hw;
1662
1663 idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
1664 idc_ctrl &= ~DONTRESET_BIT0;
1665 ql_log(ql_log_info, vha, 0xb0c9,
1666 "%s: idc_ctrl = %d\n", __func__,
1667 idc_ctrl);
1668 qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL, idc_ctrl);
1669}
1670
1671static int
1672qla8044_set_idc_ver(struct scsi_qla_host *vha)
1673{
1674 int idc_ver;
1675 uint32_t drv_active;
1676 int rval = QLA_SUCCESS;
1677 struct qla_hw_data *ha = vha->hw;
1678
1679 drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
1680 if (drv_active == (1 << ha->portnum)) {
1681 idc_ver = qla8044_rd_direct(vha,
1682 QLA8044_CRB_DRV_IDC_VERSION_INDEX);
1683 idc_ver &= (~0xFF);
1684 idc_ver |= QLA8044_IDC_VER_MAJ_VALUE;
1685 qla8044_wr_direct(vha, QLA8044_CRB_DRV_IDC_VERSION_INDEX,
1686 idc_ver);
1687 ql_log(ql_log_info, vha, 0xb0ca,
1688 "%s: IDC version updated to %d\n",
1689 __func__, idc_ver);
1690 } else {
1691 idc_ver = qla8044_rd_direct(vha,
1692 QLA8044_CRB_DRV_IDC_VERSION_INDEX);
1693 idc_ver &= 0xFF;
1694 if (QLA8044_IDC_VER_MAJ_VALUE != idc_ver) {
1695 ql_log(ql_log_info, vha, 0xb0cb,
1696 "%s: qla4xxx driver IDC version %d "
1697 "is not compatible with IDC version %d "
1698 "of other drivers!\n",
1699 __func__, QLA8044_IDC_VER_MAJ_VALUE,
1700 idc_ver);
1701 rval = QLA_FUNCTION_FAILED;
1702 goto exit_set_idc_ver;
1703 }
1704 }
1705
1706 /* Update IDC_MINOR_VERSION */
1707 idc_ver = qla8044_rd_reg(ha, QLA8044_CRB_IDC_VER_MINOR);
1708 idc_ver &= ~(0x03 << (ha->portnum * 2));
1709 idc_ver |= (QLA8044_IDC_VER_MIN_VALUE << (ha->portnum * 2));
1710 qla8044_wr_reg(ha, QLA8044_CRB_IDC_VER_MINOR, idc_ver);
1711
1712exit_set_idc_ver:
1713 return rval;
1714}
1715
1716static int
1717qla8044_update_idc_reg(struct scsi_qla_host *vha)
1718{
1719 uint32_t drv_active;
1720 int rval = QLA_SUCCESS;
1721 struct qla_hw_data *ha = vha->hw;
1722
1723 if (vha->flags.init_done)
1724 goto exit_update_idc_reg;
1725
1726 qla8044_idc_lock(ha);
1727 qla8044_set_drv_active(vha);
1728
1729 drv_active = qla8044_rd_direct(vha,
1730 QLA8044_CRB_DRV_ACTIVE_INDEX);
1731
1732 /* If we are the first driver to load and
1733 * ql2xdontresethba is not set, clear IDC_CTRL BIT0. */
1734 if ((drv_active == (1 << ha->portnum)) && !ql2xdontresethba)
1735 qla8044_clear_idc_dontreset(vha);
1736
1737 rval = qla8044_set_idc_ver(vha);
1738 if (rval == QLA_FUNCTION_FAILED)
1739 qla8044_clear_drv_active(vha);
1740 qla8044_idc_unlock(ha);
1741
1742exit_update_idc_reg:
1743 return rval;
1744}
1745
1746/**
1747 * qla8044_need_qsnt_handler - Code to start qsnt
1748 * @ha: pointer to adapter structure
1749 **/
1750static void
1751qla8044_need_qsnt_handler(struct scsi_qla_host *vha)
1752{
1753 unsigned long qsnt_timeout;
1754 uint32_t drv_state, drv_active, dev_state;
1755 struct qla_hw_data *ha = vha->hw;
1756
1757 if (vha->flags.online)
1758 qla2x00_quiesce_io(vha);
1759 else
1760 return;
1761
1762 qla8044_set_qsnt_ready(vha);
1763
1764 /* Wait for 30 secs for all functions to ack qsnt mode */
1765 qsnt_timeout = jiffies + (QSNT_ACK_TOV * HZ);
1766 drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
1767 drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
1768
1769 /* Shift drv_active by 1 to match drv_state. As quiescent ready bit
1770 position is at bit 1 and drv active is at bit 0 */
1771 drv_active = drv_active << 1;
1772
1773 while (drv_state != drv_active) {
1774 if (time_after_eq(jiffies, qsnt_timeout)) {
1775 /* Other functions did not ack, changing state to
1776 * DEV_READY
1777 */
1778 clear_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
1779 qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
1780 QLA8XXX_DEV_READY);
1781 qla8044_clear_qsnt_ready(vha);
1782 ql_log(ql_log_info, vha, 0xb0cc,
1783 "Timeout waiting for quiescent ack!!!\n");
1784 return;
1785 }
1786 qla8044_idc_unlock(ha);
1787 msleep(1000);
1788 qla8044_idc_lock(ha);
1789
1790 drv_state = qla8044_rd_direct(vha,
1791 QLA8044_CRB_DRV_STATE_INDEX);
1792 drv_active = qla8044_rd_direct(vha,
1793 QLA8044_CRB_DRV_ACTIVE_INDEX);
1794 drv_active = drv_active << 1;
1795 }
1796
1797 /* All functions have Acked. Set quiescent state */
1798 dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
1799
1800 if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT) {
1801 qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
1802 QLA8XXX_DEV_QUIESCENT);
1803 ql_log(ql_log_info, vha, 0xb0cd,
1804 "%s: HW State: QUIESCENT\n", __func__);
1805 }
1806}
1807
1808/*
1809 * qla8044_device_state_handler - Adapter state machine
1810 * @ha: pointer to host adapter structure.
1811 *
1812 * Note: IDC lock must be UNLOCKED upon entry
1813 **/
1814int
1815qla8044_device_state_handler(struct scsi_qla_host *vha)
1816{
1817 uint32_t dev_state;
1818 int rval = QLA_SUCCESS;
1819 unsigned long dev_init_timeout;
1820 struct qla_hw_data *ha = vha->hw;
1821
1822 rval = qla8044_update_idc_reg(vha);
1823 if (rval == QLA_FUNCTION_FAILED)
1824 goto exit_error;
1825
1826 dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
1827 ql_dbg(ql_dbg_p3p, vha, 0xb0ce,
1828 "Device state is 0x%x = %s\n",
1829 dev_state, dev_state < MAX_STATES ?
1830 qdev_state(dev_state) : "Unknown");
1831
1832 /* wait for 30 seconds for device to go ready */
1833 dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout * HZ);
1834
1835 qla8044_idc_lock(ha);
1836
1837 while (1) {
1838 if (time_after_eq(jiffies, dev_init_timeout)) {
1839 ql_log(ql_log_warn, vha, 0xb0cf,
1840 "%s: Device Init Failed 0x%x = %s\n",
1841 QLA2XXX_DRIVER_NAME, dev_state,
1842 dev_state < MAX_STATES ?
1843 qdev_state(dev_state) : "Unknown");
1844
1845 qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
1846 QLA8XXX_DEV_FAILED);
1847 }
1848
1849 dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
1850 ql_log(ql_log_info, vha, 0xb0d0,
1851 "Device state is 0x%x = %s\n",
1852 dev_state, dev_state < MAX_STATES ?
1853 qdev_state(dev_state) : "Unknown");
1854
1855 /* NOTE: Make sure idc unlocked upon exit of switch statement */
1856 switch (dev_state) {
1857 case QLA8XXX_DEV_READY:
1858 ha->flags.nic_core_reset_owner = 0;
1859 goto exit;
1860 case QLA8XXX_DEV_COLD:
1861 rval = qla8044_device_bootstrap(vha);
1862 goto exit;
1863 case QLA8XXX_DEV_INITIALIZING:
1864 qla8044_idc_unlock(ha);
1865 msleep(1000);
1866 qla8044_idc_lock(ha);
1867 break;
1868 case QLA8XXX_DEV_NEED_RESET:
1869 /* For ISP8044, if NEED_RESET is set by any driver,
1870 * it should be honored, irrespective of IDC_CTRL
1871 * DONTRESET_BIT0 */
1872 qla8044_need_reset_handler(vha);
1873 break;
1874 case QLA8XXX_DEV_NEED_QUIESCENT:
1875 /* idc locked/unlocked in handler */
1876 qla8044_need_qsnt_handler(vha);
1877
1878 /* Reset the init timeout after qsnt handler */
1879 dev_init_timeout = jiffies +
1880 (ha->fcoe_reset_timeout * HZ);
1881 break;
1882 case QLA8XXX_DEV_QUIESCENT:
1883 ql_log(ql_log_info, vha, 0xb0d1,
1884 "HW State: QUIESCENT\n");
1885
1886 qla8044_idc_unlock(ha);
1887 msleep(1000);
1888 qla8044_idc_lock(ha);
1889
1890 /* Reset the init timeout after qsnt handler */
1891 dev_init_timeout = jiffies +
1892 (ha->fcoe_reset_timeout * HZ);
1893 break;
1894 case QLA8XXX_DEV_FAILED:
1895 ha->flags.nic_core_reset_owner = 0;
1896 qla8044_idc_unlock(ha);
1897 qla8xxx_dev_failed_handler(vha);
1898 rval = QLA_FUNCTION_FAILED;
1899 qla8044_idc_lock(ha);
1900 goto exit;
1901 default:
1902 qla8044_idc_unlock(ha);
1903 qla8xxx_dev_failed_handler(vha);
1904 rval = QLA_FUNCTION_FAILED;
1905 qla8044_idc_lock(ha);
1906 goto exit;
1907 }
1908 }
1909exit:
1910 qla8044_idc_unlock(ha);
1911
1912exit_error:
1913 return rval;
1914}
1915
1916/**
1917 * qla4_8xxx_check_temp - Check the ISP82XX temperature.
1918 * @ha: adapter block pointer.
1919 *
1920 * Note: The caller should not hold the idc lock.
1921 **/
1922static int
1923qla8044_check_temp(struct scsi_qla_host *vha)
1924{
1925 uint32_t temp, temp_state, temp_val;
1926 int status = QLA_SUCCESS;
1927
1928 temp = qla8044_rd_direct(vha, QLA8044_CRB_TEMP_STATE_INDEX);
1929 temp_state = qla82xx_get_temp_state(temp);
1930 temp_val = qla82xx_get_temp_val(temp);
1931
1932 if (temp_state == QLA82XX_TEMP_PANIC) {
1933 ql_log(ql_log_warn, vha, 0xb0d2,
1934 "Device temperature %d degrees C"
1935 " exceeds maximum allowed. Hardware has been shut"
1936 " down\n", temp_val);
1937 status = QLA_FUNCTION_FAILED;
1938 return status;
1939 } else if (temp_state == QLA82XX_TEMP_WARN) {
1940 ql_log(ql_log_warn, vha, 0xb0d3,
1941 "Device temperature %d"
1942 " degrees C exceeds operating range."
1943 " Immediate action needed.\n", temp_val);
1944 }
1945 return 0;
1946}
1947
1948/**
1949 * qla8044_check_fw_alive - Check firmware health
1950 * @ha: Pointer to host adapter structure.
1951 *
1952 * Context: Interrupt
1953 **/
1954int
1955qla8044_check_fw_alive(struct scsi_qla_host *vha)
1956{
1957 uint32_t fw_heartbeat_counter;
1958 uint32_t halt_status1, halt_status2;
1959 int status = QLA_SUCCESS;
1960
1961 fw_heartbeat_counter = qla8044_rd_direct(vha,
1962 QLA8044_PEG_ALIVE_COUNTER_INDEX);
1963
1964 /* If PEG_ALIVE_COUNTER is 0xffffffff, AER/EEH is in progress, ignore */
1965 if (fw_heartbeat_counter == 0xffffffff) {
1966 ql_dbg(ql_dbg_p3p, vha, 0xb0d4,
1967 "scsi%ld: %s: Device in frozen "
1968 "state, QLA82XX_PEG_ALIVE_COUNTER is 0xffffffff\n",
1969 vha->host_no, __func__);
1970 return status;
1971 }
1972
1973 if (vha->fw_heartbeat_counter == fw_heartbeat_counter) {
1974 vha->seconds_since_last_heartbeat++;
1975 /* FW not alive after 2 seconds */
1976 if (vha->seconds_since_last_heartbeat == 2) {
1977 vha->seconds_since_last_heartbeat = 0;
1978 halt_status1 = qla8044_rd_direct(vha,
1979 QLA8044_PEG_HALT_STATUS1_INDEX);
1980 halt_status2 = qla8044_rd_direct(vha,
1981 QLA8044_PEG_HALT_STATUS2_INDEX);
1982
1983 ql_log(ql_log_info, vha, 0xb0d5,
1984 "scsi(%ld): %s, ISP8044 "
1985 "Dumping hw/fw registers:\n"
1986 " PEG_HALT_STATUS1: 0x%x, "
1987 "PEG_HALT_STATUS2: 0x%x,\n",
1988 vha->host_no, __func__, halt_status1,
1989 halt_status2);
1990 status = QLA_FUNCTION_FAILED;
1991 }
1992 } else
1993 vha->seconds_since_last_heartbeat = 0;
1994
1995 vha->fw_heartbeat_counter = fw_heartbeat_counter;
1996 return status;
1997}
1998
1999void
2000qla8044_watchdog(struct scsi_qla_host *vha)
2001{
2002 uint32_t dev_state, halt_status;
2003 int halt_status_unrecoverable = 0;
2004 struct qla_hw_data *ha = vha->hw;
2005
2006 /* don't poll if reset is going on or FW hang in quiescent state */
2007 if (!(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
2008 test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
2009 test_bit(ISP_ABORT_RETRY, &vha->dpc_flags) ||
2010 test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags))) {
2011 dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
2012
2013 if (qla8044_check_temp(vha)) {
2014 set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);
2015 ha->flags.isp82xx_fw_hung = 1;
2016 qla2xxx_wake_dpc(vha);
2017 } else if (dev_state == QLA8XXX_DEV_NEED_RESET &&
2018 !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) {
2019 ql_log(ql_log_info, vha, 0xb0d6,
2020 "%s: HW State: NEED RESET!\n",
2021 __func__);
2022 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
2023 qla2xxx_wake_dpc(vha);
2024 } else if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT &&
2025 !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) {
2026 ql_log(ql_log_info, vha, 0xb0d7,
2027 "%s: HW State: NEED QUIES detected!\n",
2028 __func__);
2029 set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
2030 qla2xxx_wake_dpc(vha);
2031 } else {
2032 /* Check firmware health */
2033 if (qla8044_check_fw_alive(vha)) {
2034 halt_status = qla8044_rd_direct(vha,
2035 QLA8044_PEG_HALT_STATUS1_INDEX);
2036 if (halt_status &
2037 QLA8044_HALT_STATUS_FW_RESET) {
2038 ql_log(ql_log_fatal, vha,
2039 0xb0d8, "%s: Firmware "
2040 "error detected device "
2041 "is being reset\n",
2042 __func__);
2043 } else if (halt_status &
2044 QLA8044_HALT_STATUS_UNRECOVERABLE) {
2045 halt_status_unrecoverable = 1;
2046 }
2047
2048 /* Since we cannot change dev_state in interrupt
2049 * context, set appropriate DPC flag then wakeup
2050 * DPC */
2051 if (halt_status_unrecoverable) {
2052 set_bit(ISP_UNRECOVERABLE,
2053 &vha->dpc_flags);
2054 } else {
2055 if (dev_state ==
2056 QLA8XXX_DEV_QUIESCENT) {
2057 set_bit(FCOE_CTX_RESET_NEEDED,
2058 &vha->dpc_flags);
2059 ql_log(ql_log_info, vha, 0xb0d9,
2060 "%s: FW CONTEXT Reset "
2061 "needed!\n", __func__);
2062 } else {
2063 ql_log(ql_log_info, vha,
2064 0xb0da, "%s: "
2065 "detect abort needed\n",
2066 __func__);
2067 set_bit(ISP_ABORT_NEEDED,
2068 &vha->dpc_flags);
2069 qla82xx_clear_pending_mbx(vha);
2070 }
2071 }
2072 ha->flags.isp82xx_fw_hung = 1;
2073 ql_log(ql_log_warn, vha, 0xb10a,
2074 "Firmware hung.\n");
2075 qla2xxx_wake_dpc(vha);
2076 }
2077 }
2078
2079 }
2080}
2081
2082static int
2083qla8044_minidump_process_control(struct scsi_qla_host *vha,
2084 struct qla8044_minidump_entry_hdr *entry_hdr)
2085{
2086 struct qla8044_minidump_entry_crb *crb_entry;
2087 uint32_t read_value, opcode, poll_time, addr, index;
2088 uint32_t crb_addr, rval = QLA_SUCCESS;
2089 unsigned long wtime;
2090 struct qla8044_minidump_template_hdr *tmplt_hdr;
2091 int i;
2092 struct qla_hw_data *ha = vha->hw;
2093
2094 ql_dbg(ql_dbg_p3p, vha, 0xb0dd, "Entering fn: %s\n", __func__);
2095 tmplt_hdr = (struct qla8044_minidump_template_hdr *)
2096 ha->md_tmplt_hdr;
2097 crb_entry = (struct qla8044_minidump_entry_crb *)entry_hdr;
2098
2099 crb_addr = crb_entry->addr;
2100 for (i = 0; i < crb_entry->op_count; i++) {
2101 opcode = crb_entry->crb_ctrl.opcode;
2102
2103 if (opcode & QLA82XX_DBG_OPCODE_WR) {
2104 qla8044_wr_reg_indirect(vha, crb_addr,
2105 crb_entry->value_1);
2106 opcode &= ~QLA82XX_DBG_OPCODE_WR;
2107 }
2108
2109 if (opcode & QLA82XX_DBG_OPCODE_RW) {
2110 qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
2111 qla8044_wr_reg_indirect(vha, crb_addr, read_value);
2112 opcode &= ~QLA82XX_DBG_OPCODE_RW;
2113 }
2114
2115 if (opcode & QLA82XX_DBG_OPCODE_AND) {
2116 qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
2117 read_value &= crb_entry->value_2;
2118 opcode &= ~QLA82XX_DBG_OPCODE_AND;
2119 if (opcode & QLA82XX_DBG_OPCODE_OR) {
2120 read_value |= crb_entry->value_3;
2121 opcode &= ~QLA82XX_DBG_OPCODE_OR;
2122 }
2123 qla8044_wr_reg_indirect(vha, crb_addr, read_value);
2124 }
2125 if (opcode & QLA82XX_DBG_OPCODE_OR) {
2126 qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
2127 read_value |= crb_entry->value_3;
2128 qla8044_wr_reg_indirect(vha, crb_addr, read_value);
2129 opcode &= ~QLA82XX_DBG_OPCODE_OR;
2130 }
2131 if (opcode & QLA82XX_DBG_OPCODE_POLL) {
2132 poll_time = crb_entry->crb_strd.poll_timeout;
2133 wtime = jiffies + poll_time;
2134 qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
2135
2136 do {
2137 if ((read_value & crb_entry->value_2) ==
2138 crb_entry->value_1) {
2139 break;
2140 } else if (time_after_eq(jiffies, wtime)) {
2141 /* capturing dump failed */
2142 rval = QLA_FUNCTION_FAILED;
2143 break;
2144 } else {
2145 qla8044_rd_reg_indirect(vha,
2146 crb_addr, &read_value);
2147 }
2148 } while (1);
2149 opcode &= ~QLA82XX_DBG_OPCODE_POLL;
2150 }
2151
2152 if (opcode & QLA82XX_DBG_OPCODE_RDSTATE) {
2153 if (crb_entry->crb_strd.state_index_a) {
2154 index = crb_entry->crb_strd.state_index_a;
2155 addr = tmplt_hdr->saved_state_array[index];
2156 } else {
2157 addr = crb_addr;
2158 }
2159
2160 qla8044_rd_reg_indirect(vha, addr, &read_value);
2161 index = crb_entry->crb_ctrl.state_index_v;
2162 tmplt_hdr->saved_state_array[index] = read_value;
2163 opcode &= ~QLA82XX_DBG_OPCODE_RDSTATE;
2164 }
2165
2166 if (opcode & QLA82XX_DBG_OPCODE_WRSTATE) {
2167 if (crb_entry->crb_strd.state_index_a) {
2168 index = crb_entry->crb_strd.state_index_a;
2169 addr = tmplt_hdr->saved_state_array[index];
2170 } else {
2171 addr = crb_addr;
2172 }
2173
2174 if (crb_entry->crb_ctrl.state_index_v) {
2175 index = crb_entry->crb_ctrl.state_index_v;
2176 read_value =
2177 tmplt_hdr->saved_state_array[index];
2178 } else {
2179 read_value = crb_entry->value_1;
2180 }
2181
2182 qla8044_wr_reg_indirect(vha, addr, read_value);
2183 opcode &= ~QLA82XX_DBG_OPCODE_WRSTATE;
2184 }
2185
2186 if (opcode & QLA82XX_DBG_OPCODE_MDSTATE) {
2187 index = crb_entry->crb_ctrl.state_index_v;
2188 read_value = tmplt_hdr->saved_state_array[index];
2189 read_value <<= crb_entry->crb_ctrl.shl;
2190 read_value >>= crb_entry->crb_ctrl.shr;
2191 if (crb_entry->value_2)
2192 read_value &= crb_entry->value_2;
2193 read_value |= crb_entry->value_3;
2194 read_value += crb_entry->value_1;
2195 tmplt_hdr->saved_state_array[index] = read_value;
2196 opcode &= ~QLA82XX_DBG_OPCODE_MDSTATE;
2197 }
2198 crb_addr += crb_entry->crb_strd.addr_stride;
2199 }
2200 return rval;
2201}
2202
2203static void
2204qla8044_minidump_process_rdcrb(struct scsi_qla_host *vha,
2205 struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2206{
2207 uint32_t r_addr, r_stride, loop_cnt, i, r_value;
2208 struct qla8044_minidump_entry_crb *crb_hdr;
2209 uint32_t *data_ptr = *d_ptr;
2210
2211 ql_dbg(ql_dbg_p3p, vha, 0xb0de, "Entering fn: %s\n", __func__);
2212 crb_hdr = (struct qla8044_minidump_entry_crb *)entry_hdr;
2213 r_addr = crb_hdr->addr;
2214 r_stride = crb_hdr->crb_strd.addr_stride;
2215 loop_cnt = crb_hdr->op_count;
2216
2217 for (i = 0; i < loop_cnt; i++) {
2218 qla8044_rd_reg_indirect(vha, r_addr, &r_value);
2219 *data_ptr++ = r_addr;
2220 *data_ptr++ = r_value;
2221 r_addr += r_stride;
2222 }
2223 *d_ptr = data_ptr;
2224}
2225
2226static int
2227qla8044_minidump_process_rdmem(struct scsi_qla_host *vha,
2228 struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2229{
2230 uint32_t r_addr, r_value, r_data;
2231 uint32_t i, j, loop_cnt;
2232 struct qla8044_minidump_entry_rdmem *m_hdr;
2233 unsigned long flags;
2234 uint32_t *data_ptr = *d_ptr;
2235 struct qla_hw_data *ha = vha->hw;
2236
2237 ql_dbg(ql_dbg_p3p, vha, 0xb0df, "Entering fn: %s\n", __func__);
2238 m_hdr = (struct qla8044_minidump_entry_rdmem *)entry_hdr;
2239 r_addr = m_hdr->read_addr;
2240 loop_cnt = m_hdr->read_data_size/16;
2241
2242 ql_dbg(ql_dbg_p3p, vha, 0xb0f0,
2243 "[%s]: Read addr: 0x%x, read_data_size: 0x%x\n",
2244 __func__, r_addr, m_hdr->read_data_size);
2245
2246 if (r_addr & 0xf) {
2247 ql_dbg(ql_dbg_p3p, vha, 0xb0f1,
2248 "[%s]: Read addr 0x%x not 16 bytes alligned\n",
2249 __func__, r_addr);
2250 return QLA_FUNCTION_FAILED;
2251 }
2252
2253 if (m_hdr->read_data_size % 16) {
2254 ql_dbg(ql_dbg_p3p, vha, 0xb0f2,
2255 "[%s]: Read data[0x%x] not multiple of 16 bytes\n",
2256 __func__, m_hdr->read_data_size);
2257 return QLA_FUNCTION_FAILED;
2258 }
2259
2260 ql_dbg(ql_dbg_p3p, vha, 0xb0f3,
2261 "[%s]: rdmem_addr: 0x%x, read_data_size: 0x%x, loop_cnt: 0x%x\n",
2262 __func__, r_addr, m_hdr->read_data_size, loop_cnt);
2263
2264 write_lock_irqsave(&ha->hw_lock, flags);
2265 for (i = 0; i < loop_cnt; i++) {
2266 qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_ADDR_LO, r_addr);
2267 r_value = 0;
2268 qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_ADDR_HI, r_value);
2269 r_value = MIU_TA_CTL_ENABLE;
2270 qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL, r_value);
2271 r_value = MIU_TA_CTL_START_ENABLE;
2272 qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL, r_value);
2273
2274 for (j = 0; j < MAX_CTL_CHECK; j++) {
2275 qla8044_rd_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL,
2276 &r_value);
2277 if ((r_value & MIU_TA_CTL_BUSY) == 0)
2278 break;
2279 }
2280
2281 if (j >= MAX_CTL_CHECK) {
2282 printk_ratelimited(KERN_ERR
2283 "%s: failed to read through agent\n", __func__);
2284 write_unlock_irqrestore(&ha->hw_lock, flags);
2285 return QLA_SUCCESS;
2286 }
2287
2288 for (j = 0; j < 4; j++) {
2289 qla8044_rd_reg_indirect(vha, MD_MIU_TEST_AGT_RDDATA[j],
2290 &r_data);
2291 *data_ptr++ = r_data;
2292 }
2293
2294 r_addr += 16;
2295 }
2296 write_unlock_irqrestore(&ha->hw_lock, flags);
2297
2298 ql_dbg(ql_dbg_p3p, vha, 0xb0f4,
2299 "Leaving fn: %s datacount: 0x%x\n",
2300 __func__, (loop_cnt * 16));
2301
2302 *d_ptr = data_ptr;
2303 return QLA_SUCCESS;
2304}
2305
2306/* ISP83xx flash read for _RDROM _BOARD */
2307static uint32_t
2308qla8044_minidump_process_rdrom(struct scsi_qla_host *vha,
2309 struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2310{
2311 uint32_t fl_addr, u32_count, rval;
2312 struct qla8044_minidump_entry_rdrom *rom_hdr;
2313 uint32_t *data_ptr = *d_ptr;
2314
2315 rom_hdr = (struct qla8044_minidump_entry_rdrom *)entry_hdr;
2316 fl_addr = rom_hdr->read_addr;
2317 u32_count = (rom_hdr->read_data_size)/sizeof(uint32_t);
2318
2319 ql_dbg(ql_dbg_p3p, vha, 0xb0f5, "[%s]: fl_addr: 0x%x, count: 0x%x\n",
2320 __func__, fl_addr, u32_count);
2321
2322 rval = qla8044_lockless_flash_read_u32(vha, fl_addr,
2323 (u8 *)(data_ptr), u32_count);
2324
2325 if (rval != QLA_SUCCESS) {
2326 ql_log(ql_log_fatal, vha, 0xb0f6,
2327 "%s: Flash Read Error,Count=%d\n", __func__, u32_count);
2328 return QLA_FUNCTION_FAILED;
2329 } else {
2330 data_ptr += u32_count;
2331 *d_ptr = data_ptr;
2332 return QLA_SUCCESS;
2333 }
2334}
2335
2336static void
2337qla8044_mark_entry_skipped(struct scsi_qla_host *vha,
2338 struct qla8044_minidump_entry_hdr *entry_hdr, int index)
2339{
2340 entry_hdr->d_ctrl.driver_flags |= QLA82XX_DBG_SKIPPED_FLAG;
2341
2342 ql_log(ql_log_info, vha, 0xb0f7,
2343 "scsi(%ld): Skipping entry[%d]: ETYPE[0x%x]-ELEVEL[0x%x]\n",
2344 vha->host_no, index, entry_hdr->entry_type,
2345 entry_hdr->d_ctrl.entry_capture_mask);
2346}
2347
2348static int
2349qla8044_minidump_process_l2tag(struct scsi_qla_host *vha,
2350 struct qla8044_minidump_entry_hdr *entry_hdr,
2351 uint32_t **d_ptr)
2352{
2353 uint32_t addr, r_addr, c_addr, t_r_addr;
2354 uint32_t i, k, loop_count, t_value, r_cnt, r_value;
2355 unsigned long p_wait, w_time, p_mask;
2356 uint32_t c_value_w, c_value_r;
2357 struct qla8044_minidump_entry_cache *cache_hdr;
2358 int rval = QLA_FUNCTION_FAILED;
2359 uint32_t *data_ptr = *d_ptr;
2360
2361 ql_dbg(ql_dbg_p3p, vha, 0xb0f8, "Entering fn: %s\n", __func__);
2362 cache_hdr = (struct qla8044_minidump_entry_cache *)entry_hdr;
2363
2364 loop_count = cache_hdr->op_count;
2365 r_addr = cache_hdr->read_addr;
2366 c_addr = cache_hdr->control_addr;
2367 c_value_w = cache_hdr->cache_ctrl.write_value;
2368
2369 t_r_addr = cache_hdr->tag_reg_addr;
2370 t_value = cache_hdr->addr_ctrl.init_tag_value;
2371 r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
2372 p_wait = cache_hdr->cache_ctrl.poll_wait;
2373 p_mask = cache_hdr->cache_ctrl.poll_mask;
2374
2375 for (i = 0; i < loop_count; i++) {
2376 qla8044_wr_reg_indirect(vha, t_r_addr, t_value);
2377 if (c_value_w)
2378 qla8044_wr_reg_indirect(vha, c_addr, c_value_w);
2379
2380 if (p_mask) {
2381 w_time = jiffies + p_wait;
2382 do {
2383 qla8044_rd_reg_indirect(vha, c_addr,
2384 &c_value_r);
2385 if ((c_value_r & p_mask) == 0) {
2386 break;
2387 } else if (time_after_eq(jiffies, w_time)) {
2388 /* capturing dump failed */
2389 return rval;
2390 }
2391 } while (1);
2392 }
2393
2394 addr = r_addr;
2395 for (k = 0; k < r_cnt; k++) {
2396 qla8044_rd_reg_indirect(vha, addr, &r_value);
2397 *data_ptr++ = r_value;
2398 addr += cache_hdr->read_ctrl.read_addr_stride;
2399 }
2400 t_value += cache_hdr->addr_ctrl.tag_value_stride;
2401 }
2402 *d_ptr = data_ptr;
2403 return QLA_SUCCESS;
2404}
2405
2406static void
2407qla8044_minidump_process_l1cache(struct scsi_qla_host *vha,
2408 struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2409{
2410 uint32_t addr, r_addr, c_addr, t_r_addr;
2411 uint32_t i, k, loop_count, t_value, r_cnt, r_value;
2412 uint32_t c_value_w;
2413 struct qla8044_minidump_entry_cache *cache_hdr;
2414 uint32_t *data_ptr = *d_ptr;
2415
2416 cache_hdr = (struct qla8044_minidump_entry_cache *)entry_hdr;
2417 loop_count = cache_hdr->op_count;
2418 r_addr = cache_hdr->read_addr;
2419 c_addr = cache_hdr->control_addr;
2420 c_value_w = cache_hdr->cache_ctrl.write_value;
2421
2422 t_r_addr = cache_hdr->tag_reg_addr;
2423 t_value = cache_hdr->addr_ctrl.init_tag_value;
2424 r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
2425
2426 for (i = 0; i < loop_count; i++) {
2427 qla8044_wr_reg_indirect(vha, t_r_addr, t_value);
2428 qla8044_wr_reg_indirect(vha, c_addr, c_value_w);
2429 addr = r_addr;
2430 for (k = 0; k < r_cnt; k++) {
2431 qla8044_rd_reg_indirect(vha, addr, &r_value);
2432 *data_ptr++ = r_value;
2433 addr += cache_hdr->read_ctrl.read_addr_stride;
2434 }
2435 t_value += cache_hdr->addr_ctrl.tag_value_stride;
2436 }
2437 *d_ptr = data_ptr;
2438}
2439
2440static void
2441qla8044_minidump_process_rdocm(struct scsi_qla_host *vha,
2442 struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2443{
2444 uint32_t r_addr, r_stride, loop_cnt, i, r_value;
2445 struct qla8044_minidump_entry_rdocm *ocm_hdr;
2446 uint32_t *data_ptr = *d_ptr;
2447 struct qla_hw_data *ha = vha->hw;
2448
2449 ql_dbg(ql_dbg_p3p, vha, 0xb0f9, "Entering fn: %s\n", __func__);
2450
2451 ocm_hdr = (struct qla8044_minidump_entry_rdocm *)entry_hdr;
2452 r_addr = ocm_hdr->read_addr;
2453 r_stride = ocm_hdr->read_addr_stride;
2454 loop_cnt = ocm_hdr->op_count;
2455
2456 ql_dbg(ql_dbg_p3p, vha, 0xb0fa,
2457 "[%s]: r_addr: 0x%x, r_stride: 0x%x, loop_cnt: 0x%x\n",
2458 __func__, r_addr, r_stride, loop_cnt);
2459
2460 for (i = 0; i < loop_cnt; i++) {
2461 r_value = readl((void __iomem *)(r_addr + ha->nx_pcibase));
2462 *data_ptr++ = r_value;
2463 r_addr += r_stride;
2464 }
2465 ql_dbg(ql_dbg_p3p, vha, 0xb0fb, "Leaving fn: %s datacount: 0x%lx\n",
2466 __func__, (long unsigned int) (loop_cnt * sizeof(uint32_t)));
2467
2468 *d_ptr = data_ptr;
2469}
2470
2471static void
2472qla8044_minidump_process_rdmux(struct scsi_qla_host *vha,
2473 struct qla8044_minidump_entry_hdr *entry_hdr,
2474 uint32_t **d_ptr)
2475{
2476 uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value;
2477 struct qla8044_minidump_entry_mux *mux_hdr;
2478 uint32_t *data_ptr = *d_ptr;
2479
2480 ql_dbg(ql_dbg_p3p, vha, 0xb0fc, "Entering fn: %s\n", __func__);
2481
2482 mux_hdr = (struct qla8044_minidump_entry_mux *)entry_hdr;
2483 r_addr = mux_hdr->read_addr;
2484 s_addr = mux_hdr->select_addr;
2485 s_stride = mux_hdr->select_value_stride;
2486 s_value = mux_hdr->select_value;
2487 loop_cnt = mux_hdr->op_count;
2488
2489 for (i = 0; i < loop_cnt; i++) {
2490 qla8044_wr_reg_indirect(vha, s_addr, s_value);
2491 qla8044_rd_reg_indirect(vha, r_addr, &r_value);
2492 *data_ptr++ = s_value;
2493 *data_ptr++ = r_value;
2494 s_value += s_stride;
2495 }
2496 *d_ptr = data_ptr;
2497}
2498
2499static void
2500qla8044_minidump_process_queue(struct scsi_qla_host *vha,
2501 struct qla8044_minidump_entry_hdr *entry_hdr,
2502 uint32_t **d_ptr)
2503{
2504 uint32_t s_addr, r_addr;
2505 uint32_t r_stride, r_value, r_cnt, qid = 0;
2506 uint32_t i, k, loop_cnt;
2507 struct qla8044_minidump_entry_queue *q_hdr;
2508 uint32_t *data_ptr = *d_ptr;
2509
2510 ql_dbg(ql_dbg_p3p, vha, 0xb0fd, "Entering fn: %s\n", __func__);
2511 q_hdr = (struct qla8044_minidump_entry_queue *)entry_hdr;
2512 s_addr = q_hdr->select_addr;
2513 r_cnt = q_hdr->rd_strd.read_addr_cnt;
2514 r_stride = q_hdr->rd_strd.read_addr_stride;
2515 loop_cnt = q_hdr->op_count;
2516
2517 for (i = 0; i < loop_cnt; i++) {
2518 qla8044_wr_reg_indirect(vha, s_addr, qid);
2519 r_addr = q_hdr->read_addr;
2520 for (k = 0; k < r_cnt; k++) {
2521 qla8044_rd_reg_indirect(vha, r_addr, &r_value);
2522 *data_ptr++ = r_value;
2523 r_addr += r_stride;
2524 }
2525 qid += q_hdr->q_strd.queue_id_stride;
2526 }
2527 *d_ptr = data_ptr;
2528}
2529
2530/* ISP83xx functions to process new minidump entries... */
2531static uint32_t
2532qla8044_minidump_process_pollrd(struct scsi_qla_host *vha,
2533 struct qla8044_minidump_entry_hdr *entry_hdr,
2534 uint32_t **d_ptr)
2535{
2536 uint32_t r_addr, s_addr, s_value, r_value, poll_wait, poll_mask;
2537 uint16_t s_stride, i;
2538 struct qla8044_minidump_entry_pollrd *pollrd_hdr;
2539 uint32_t *data_ptr = *d_ptr;
2540
2541 pollrd_hdr = (struct qla8044_minidump_entry_pollrd *) entry_hdr;
2542 s_addr = pollrd_hdr->select_addr;
2543 r_addr = pollrd_hdr->read_addr;
2544 s_value = pollrd_hdr->select_value;
2545 s_stride = pollrd_hdr->select_value_stride;
2546
2547 poll_wait = pollrd_hdr->poll_wait;
2548 poll_mask = pollrd_hdr->poll_mask;
2549
2550 for (i = 0; i < pollrd_hdr->op_count; i++) {
2551 qla8044_wr_reg_indirect(vha, s_addr, s_value);
2552 poll_wait = pollrd_hdr->poll_wait;
2553 while (1) {
2554 qla8044_rd_reg_indirect(vha, s_addr, &r_value);
2555 if ((r_value & poll_mask) != 0) {
2556 break;
2557 } else {
2558 usleep_range(1000, 1100);
2559 if (--poll_wait == 0) {
2560 ql_log(ql_log_fatal, vha, 0xb0fe,
2561 "%s: TIMEOUT\n", __func__);
2562 goto error;
2563 }
2564 }
2565 }
2566 qla8044_rd_reg_indirect(vha, r_addr, &r_value);
2567 *data_ptr++ = s_value;
2568 *data_ptr++ = r_value;
2569
2570 s_value += s_stride;
2571 }
2572 *d_ptr = data_ptr;
2573 return QLA_SUCCESS;
2574
2575error:
2576 return QLA_FUNCTION_FAILED;
2577}
2578
2579static void
2580qla8044_minidump_process_rdmux2(struct scsi_qla_host *vha,
2581 struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2582{
2583 uint32_t sel_val1, sel_val2, t_sel_val, data, i;
2584 uint32_t sel_addr1, sel_addr2, sel_val_mask, read_addr;
2585 struct qla8044_minidump_entry_rdmux2 *rdmux2_hdr;
2586 uint32_t *data_ptr = *d_ptr;
2587
2588 rdmux2_hdr = (struct qla8044_minidump_entry_rdmux2 *) entry_hdr;
2589 sel_val1 = rdmux2_hdr->select_value_1;
2590 sel_val2 = rdmux2_hdr->select_value_2;
2591 sel_addr1 = rdmux2_hdr->select_addr_1;
2592 sel_addr2 = rdmux2_hdr->select_addr_2;
2593 sel_val_mask = rdmux2_hdr->select_value_mask;
2594 read_addr = rdmux2_hdr->read_addr;
2595
2596 for (i = 0; i < rdmux2_hdr->op_count; i++) {
2597 qla8044_wr_reg_indirect(vha, sel_addr1, sel_val1);
2598 t_sel_val = sel_val1 & sel_val_mask;
2599 *data_ptr++ = t_sel_val;
2600
2601 qla8044_wr_reg_indirect(vha, sel_addr2, t_sel_val);
2602 qla8044_rd_reg_indirect(vha, read_addr, &data);
2603
2604 *data_ptr++ = data;
2605
2606 qla8044_wr_reg_indirect(vha, sel_addr1, sel_val2);
2607 t_sel_val = sel_val2 & sel_val_mask;
2608 *data_ptr++ = t_sel_val;
2609
2610 qla8044_wr_reg_indirect(vha, sel_addr2, t_sel_val);
2611 qla8044_rd_reg_indirect(vha, read_addr, &data);
2612
2613 *data_ptr++ = data;
2614
2615 sel_val1 += rdmux2_hdr->select_value_stride;
2616 sel_val2 += rdmux2_hdr->select_value_stride;
2617 }
2618
2619 *d_ptr = data_ptr;
2620}
2621
2622static uint32_t
2623qla8044_minidump_process_pollrdmwr(struct scsi_qla_host *vha,
2624 struct qla8044_minidump_entry_hdr *entry_hdr,
2625 uint32_t **d_ptr)
2626{
2627 uint32_t poll_wait, poll_mask, r_value, data;
2628 uint32_t addr_1, addr_2, value_1, value_2;
2629 struct qla8044_minidump_entry_pollrdmwr *poll_hdr;
2630 uint32_t *data_ptr = *d_ptr;
2631
2632 poll_hdr = (struct qla8044_minidump_entry_pollrdmwr *) entry_hdr;
2633 addr_1 = poll_hdr->addr_1;
2634 addr_2 = poll_hdr->addr_2;
2635 value_1 = poll_hdr->value_1;
2636 value_2 = poll_hdr->value_2;
2637 poll_mask = poll_hdr->poll_mask;
2638
2639 qla8044_wr_reg_indirect(vha, addr_1, value_1);
2640
2641 poll_wait = poll_hdr->poll_wait;
2642 while (1) {
2643 qla8044_rd_reg_indirect(vha, addr_1, &r_value);
2644
2645 if ((r_value & poll_mask) != 0) {
2646 break;
2647 } else {
2648 usleep_range(1000, 1100);
2649 if (--poll_wait == 0) {
2650 ql_log(ql_log_fatal, vha, 0xb0ff,
2651 "%s: TIMEOUT\n", __func__);
2652 goto error;
2653 }
2654 }
2655 }
2656
2657 qla8044_rd_reg_indirect(vha, addr_2, &data);
2658 data &= poll_hdr->modify_mask;
2659 qla8044_wr_reg_indirect(vha, addr_2, data);
2660 qla8044_wr_reg_indirect(vha, addr_1, value_2);
2661
2662 poll_wait = poll_hdr->poll_wait;
2663 while (1) {
2664 qla8044_rd_reg_indirect(vha, addr_1, &r_value);
2665
2666 if ((r_value & poll_mask) != 0) {
2667 break;
2668 } else {
2669 usleep_range(1000, 1100);
2670 if (--poll_wait == 0) {
2671 ql_log(ql_log_fatal, vha, 0xb100,
2672 "%s: TIMEOUT2\n", __func__);
2673 goto error;
2674 }
2675 }
2676 }
2677
2678 *data_ptr++ = addr_2;
2679 *data_ptr++ = data;
2680
2681 *d_ptr = data_ptr;
2682
2683 return QLA_SUCCESS;
2684
2685error:
2686 return QLA_FUNCTION_FAILED;
2687}
2688
2689#define ISP8044_PEX_DMA_ENGINE_INDEX 8
2690#define ISP8044_PEX_DMA_BASE_ADDRESS 0x77320000
2691#define ISP8044_PEX_DMA_NUM_OFFSET 0x10000
2692#define ISP8044_PEX_DMA_CMD_ADDR_LOW 0x0
2693#define ISP8044_PEX_DMA_CMD_ADDR_HIGH 0x04
2694#define ISP8044_PEX_DMA_CMD_STS_AND_CNTRL 0x08
2695
2696#define ISP8044_PEX_DMA_READ_SIZE (16 * 1024)
2697#define ISP8044_PEX_DMA_MAX_WAIT (100 * 100) /* Max wait of 100 msecs */
2698
2699static int
2700qla8044_check_dma_engine_state(struct scsi_qla_host *vha)
2701{
2702 struct qla_hw_data *ha = vha->hw;
2703 int rval = QLA_SUCCESS;
2704 uint32_t dma_eng_num = 0, cmd_sts_and_cntrl = 0;
2705 uint64_t dma_base_addr = 0;
2706 struct qla8044_minidump_template_hdr *tmplt_hdr = NULL;
2707
2708 tmplt_hdr = ha->md_tmplt_hdr;
2709 dma_eng_num =
2710 tmplt_hdr->saved_state_array[ISP8044_PEX_DMA_ENGINE_INDEX];
2711 dma_base_addr = ISP8044_PEX_DMA_BASE_ADDRESS +
2712 (dma_eng_num * ISP8044_PEX_DMA_NUM_OFFSET);
2713
2714 /* Read the pex-dma's command-status-and-control register. */
2715 rval = qla8044_rd_reg_indirect(vha,
2716 (dma_base_addr + ISP8044_PEX_DMA_CMD_STS_AND_CNTRL),
2717 &cmd_sts_and_cntrl);
2718 if (rval)
2719 return QLA_FUNCTION_FAILED;
2720
2721 /* Check if requested pex-dma engine is available. */
2722 if (cmd_sts_and_cntrl & BIT_31)
2723 return QLA_SUCCESS;
2724
2725 return QLA_FUNCTION_FAILED;
2726}
2727
2728static int
2729qla8044_start_pex_dma(struct scsi_qla_host *vha,
2730 struct qla8044_minidump_entry_rdmem_pex_dma *m_hdr)
2731{
2732 struct qla_hw_data *ha = vha->hw;
2733 int rval = QLA_SUCCESS, wait = 0;
2734 uint32_t dma_eng_num = 0, cmd_sts_and_cntrl = 0;
2735 uint64_t dma_base_addr = 0;
2736 struct qla8044_minidump_template_hdr *tmplt_hdr = NULL;
2737
2738 tmplt_hdr = ha->md_tmplt_hdr;
2739 dma_eng_num =
2740 tmplt_hdr->saved_state_array[ISP8044_PEX_DMA_ENGINE_INDEX];
2741 dma_base_addr = ISP8044_PEX_DMA_BASE_ADDRESS +
2742 (dma_eng_num * ISP8044_PEX_DMA_NUM_OFFSET);
2743
2744 rval = qla8044_wr_reg_indirect(vha,
2745 dma_base_addr + ISP8044_PEX_DMA_CMD_ADDR_LOW,
2746 m_hdr->desc_card_addr);
2747 if (rval)
2748 goto error_exit;
2749
2750 rval = qla8044_wr_reg_indirect(vha,
2751 dma_base_addr + ISP8044_PEX_DMA_CMD_ADDR_HIGH, 0);
2752 if (rval)
2753 goto error_exit;
2754
2755 rval = qla8044_wr_reg_indirect(vha,
2756 dma_base_addr + ISP8044_PEX_DMA_CMD_STS_AND_CNTRL,
2757 m_hdr->start_dma_cmd);
2758 if (rval)
2759 goto error_exit;
2760
2761 /* Wait for dma operation to complete. */
2762 for (wait = 0; wait < ISP8044_PEX_DMA_MAX_WAIT; wait++) {
2763 rval = qla8044_rd_reg_indirect(vha,
2764 (dma_base_addr + ISP8044_PEX_DMA_CMD_STS_AND_CNTRL),
2765 &cmd_sts_and_cntrl);
2766 if (rval)
2767 goto error_exit;
2768
2769 if ((cmd_sts_and_cntrl & BIT_1) == 0)
2770 break;
2771
2772 udelay(10);
2773 }
2774
2775 /* Wait a max of 100 ms, otherwise fallback to rdmem entry read */
2776 if (wait >= ISP8044_PEX_DMA_MAX_WAIT) {
2777 rval = QLA_FUNCTION_FAILED;
2778 goto error_exit;
2779 }
2780
2781error_exit:
2782 return rval;
2783}
2784
2785static int
2786qla8044_minidump_pex_dma_read(struct scsi_qla_host *vha,
2787 struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2788{
2789 struct qla_hw_data *ha = vha->hw;
2790 int rval = QLA_SUCCESS;
2791 struct qla8044_minidump_entry_rdmem_pex_dma *m_hdr = NULL;
2792 uint32_t chunk_size, read_size;
2793 uint8_t *data_ptr = (uint8_t *)*d_ptr;
2794 void *rdmem_buffer = NULL;
2795 dma_addr_t rdmem_dma;
2796 struct qla8044_pex_dma_descriptor dma_desc;
2797
2798 rval = qla8044_check_dma_engine_state(vha);
2799 if (rval != QLA_SUCCESS) {
2800 ql_dbg(ql_dbg_p3p, vha, 0xb147,
2801 "DMA engine not available. Fallback to rdmem-read.\n");
2802 return QLA_FUNCTION_FAILED;
2803 }
2804
2805 m_hdr = (void *)entry_hdr;
2806
2807 rdmem_buffer = dma_alloc_coherent(&ha->pdev->dev,
2808 ISP8044_PEX_DMA_READ_SIZE, &rdmem_dma, GFP_KERNEL);
2809 if (!rdmem_buffer) {
2810 ql_dbg(ql_dbg_p3p, vha, 0xb148,
2811 "Unable to allocate rdmem dma buffer\n");
2812 return QLA_FUNCTION_FAILED;
2813 }
2814
2815 /* Prepare pex-dma descriptor to be written to MS memory. */
2816 /* dma-desc-cmd layout:
2817 * 0-3: dma-desc-cmd 0-3
2818 * 4-7: pcid function number
2819 * 8-15: dma-desc-cmd 8-15
2820 * dma_bus_addr: dma buffer address
2821 * cmd.read_data_size: amount of data-chunk to be read.
2822 */
2823 dma_desc.cmd.dma_desc_cmd = (m_hdr->dma_desc_cmd & 0xff0f);
2824 dma_desc.cmd.dma_desc_cmd |=
2825 ((PCI_FUNC(ha->pdev->devfn) & 0xf) << 0x4);
2826
2827 dma_desc.dma_bus_addr = rdmem_dma;
2828 dma_desc.cmd.read_data_size = chunk_size = ISP8044_PEX_DMA_READ_SIZE;
2829 read_size = 0;
2830
2831 /*
2832 * Perform rdmem operation using pex-dma.
2833 * Prepare dma in chunks of ISP8044_PEX_DMA_READ_SIZE.
2834 */
2835 while (read_size < m_hdr->read_data_size) {
2836 if (m_hdr->read_data_size - read_size <
2837 ISP8044_PEX_DMA_READ_SIZE) {
2838 chunk_size = (m_hdr->read_data_size - read_size);
2839 dma_desc.cmd.read_data_size = chunk_size;
2840 }
2841
2842 dma_desc.src_addr = m_hdr->read_addr + read_size;
2843
2844 /* Prepare: Write pex-dma descriptor to MS memory. */
2845 rval = qla8044_ms_mem_write_128b(vha,
2846 m_hdr->desc_card_addr, (void *)&dma_desc,
2847 (sizeof(struct qla8044_pex_dma_descriptor)/16));
2848 if (rval) {
2849 ql_log(ql_log_warn, vha, 0xb14a,
2850 "%s: Error writing rdmem-dma-init to MS !!!\n",
2851 __func__);
2852 goto error_exit;
2853 }
2854 ql_dbg(ql_dbg_p3p, vha, 0xb14b,
2855 "%s: Dma-descriptor: Instruct for rdmem dma "
2856 "(chunk_size 0x%x).\n", __func__, chunk_size);
2857
2858 /* Execute: Start pex-dma operation. */
2859 rval = qla8044_start_pex_dma(vha, m_hdr);
2860 if (rval)
2861 goto error_exit;
2862
2863 memcpy(data_ptr, rdmem_buffer, chunk_size);
2864 data_ptr += chunk_size;
2865 read_size += chunk_size;
2866 }
2867
2868 *d_ptr = (void *)data_ptr;
2869
2870error_exit:
2871 if (rdmem_buffer)
2872 dma_free_coherent(&ha->pdev->dev, ISP8044_PEX_DMA_READ_SIZE,
2873 rdmem_buffer, rdmem_dma);
2874
2875 return rval;
2876}
2877
2878/*
2879 *
2880 * qla8044_collect_md_data - Retrieve firmware minidump data.
2881 * @ha: pointer to adapter structure
2882 **/
2883int
2884qla8044_collect_md_data(struct scsi_qla_host *vha)
2885{
2886 int num_entry_hdr = 0;
2887 struct qla8044_minidump_entry_hdr *entry_hdr;
2888 struct qla8044_minidump_template_hdr *tmplt_hdr;
2889 uint32_t *data_ptr;
2890 uint32_t data_collected = 0, f_capture_mask;
2891 int i, rval = QLA_FUNCTION_FAILED;
2892 uint64_t now;
2893 uint32_t timestamp, idc_control;
2894 struct qla_hw_data *ha = vha->hw;
2895
2896 if (!ha->md_dump) {
2897 ql_log(ql_log_info, vha, 0xb101,
2898 "%s(%ld) No buffer to dump\n",
2899 __func__, vha->host_no);
2900 return rval;
2901 }
2902
2903 if (ha->fw_dumped) {
2904 ql_log(ql_log_warn, vha, 0xb10d,
2905 "Firmware has been previously dumped (%p) "
2906 "-- ignoring request.\n", ha->fw_dump);
2907 goto md_failed;
2908 }
2909
2910 ha->fw_dumped = 0;
2911
2912 if (!ha->md_tmplt_hdr || !ha->md_dump) {
2913 ql_log(ql_log_warn, vha, 0xb10e,
2914 "Memory not allocated for minidump capture\n");
2915 goto md_failed;
2916 }
2917
2918 qla8044_idc_lock(ha);
2919 idc_control = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
2920 if (idc_control & GRACEFUL_RESET_BIT1) {
2921 ql_log(ql_log_warn, vha, 0xb112,
2922 "Forced reset from application, "
2923 "ignore minidump capture\n");
2924 qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL,
2925 (idc_control & ~GRACEFUL_RESET_BIT1));
2926 qla8044_idc_unlock(ha);
2927
2928 goto md_failed;
2929 }
2930 qla8044_idc_unlock(ha);
2931
2932 if (qla82xx_validate_template_chksum(vha)) {
2933 ql_log(ql_log_info, vha, 0xb109,
2934 "Template checksum validation error\n");
2935 goto md_failed;
2936 }
2937
2938 tmplt_hdr = (struct qla8044_minidump_template_hdr *)
2939 ha->md_tmplt_hdr;
2940 data_ptr = (uint32_t *)((uint8_t *)ha->md_dump);
2941 num_entry_hdr = tmplt_hdr->num_of_entries;
2942
2943 ql_dbg(ql_dbg_p3p, vha, 0xb11a,
2944 "Capture Mask obtained: 0x%x\n", tmplt_hdr->capture_debug_level);
2945
2946 f_capture_mask = tmplt_hdr->capture_debug_level & 0xFF;
2947
2948 /* Validate whether required debug level is set */
2949 if ((f_capture_mask & 0x3) != 0x3) {
2950 ql_log(ql_log_warn, vha, 0xb10f,
2951 "Minimum required capture mask[0x%x] level not set\n",
2952 f_capture_mask);
2953
2954 }
2955 tmplt_hdr->driver_capture_mask = ql2xmdcapmask;
2956 ql_log(ql_log_info, vha, 0xb102,
2957 "[%s]: starting data ptr: %p\n",
2958 __func__, data_ptr);
2959 ql_log(ql_log_info, vha, 0xb10b,
2960 "[%s]: no of entry headers in Template: 0x%x\n",
2961 __func__, num_entry_hdr);
2962 ql_log(ql_log_info, vha, 0xb10c,
2963 "[%s]: Total_data_size 0x%x, %d obtained\n",
2964 __func__, ha->md_dump_size, ha->md_dump_size);
2965
2966 /* Update current timestamp before taking dump */
2967 now = get_jiffies_64();
2968 timestamp = (u32)(jiffies_to_msecs(now) / 1000);
2969 tmplt_hdr->driver_timestamp = timestamp;
2970
2971 entry_hdr = (struct qla8044_minidump_entry_hdr *)
2972 (((uint8_t *)ha->md_tmplt_hdr) + tmplt_hdr->first_entry_offset);
2973 tmplt_hdr->saved_state_array[QLA8044_SS_OCM_WNDREG_INDEX] =
2974 tmplt_hdr->ocm_window_reg[ha->portnum];
2975
2976 /* Walk through the entry headers - validate/perform required action */
2977 for (i = 0; i < num_entry_hdr; i++) {
2978 if (data_collected > ha->md_dump_size) {
2979 ql_log(ql_log_info, vha, 0xb103,
2980 "Data collected: [0x%x], "
2981 "Total Dump size: [0x%x]\n",
2982 data_collected, ha->md_dump_size);
2983 return rval;
2984 }
2985
2986 if (!(entry_hdr->d_ctrl.entry_capture_mask &
2987 ql2xmdcapmask)) {
2988 entry_hdr->d_ctrl.driver_flags |=
2989 QLA82XX_DBG_SKIPPED_FLAG;
2990 goto skip_nxt_entry;
2991 }
2992
2993 ql_dbg(ql_dbg_p3p, vha, 0xb104,
2994 "Data collected: [0x%x], Dump size left:[0x%x]\n",
2995 data_collected,
2996 (ha->md_dump_size - data_collected));
2997
2998 /* Decode the entry type and take required action to capture
2999 * debug data
3000 */
3001 switch (entry_hdr->entry_type) {
3002 case QLA82XX_RDEND:
3003 qla8044_mark_entry_skipped(vha, entry_hdr, i);
3004 break;
3005 case QLA82XX_CNTRL:
3006 rval = qla8044_minidump_process_control(vha,
3007 entry_hdr);
3008 if (rval != QLA_SUCCESS) {
3009 qla8044_mark_entry_skipped(vha, entry_hdr, i);
3010 goto md_failed;
3011 }
3012 break;
3013 case QLA82XX_RDCRB:
3014 qla8044_minidump_process_rdcrb(vha,
3015 entry_hdr, &data_ptr);
3016 break;
3017 case QLA82XX_RDMEM:
3018 rval = qla8044_minidump_pex_dma_read(vha,
3019 entry_hdr, &data_ptr);
3020 if (rval != QLA_SUCCESS) {
3021 rval = qla8044_minidump_process_rdmem(vha,
3022 entry_hdr, &data_ptr);
3023 if (rval != QLA_SUCCESS) {
3024 qla8044_mark_entry_skipped(vha,
3025 entry_hdr, i);
3026 goto md_failed;
3027 }
3028 }
3029 break;
3030 case QLA82XX_BOARD:
3031 case QLA82XX_RDROM:
3032 rval = qla8044_minidump_process_rdrom(vha,
3033 entry_hdr, &data_ptr);
3034 if (rval != QLA_SUCCESS) {
3035 qla8044_mark_entry_skipped(vha,
3036 entry_hdr, i);
3037 }
3038 break;
3039 case QLA82XX_L2DTG:
3040 case QLA82XX_L2ITG:
3041 case QLA82XX_L2DAT:
3042 case QLA82XX_L2INS:
3043 rval = qla8044_minidump_process_l2tag(vha,
3044 entry_hdr, &data_ptr);
3045 if (rval != QLA_SUCCESS) {
3046 qla8044_mark_entry_skipped(vha, entry_hdr, i);
3047 goto md_failed;
3048 }
3049 break;
3050 case QLA8044_L1DTG:
3051 case QLA8044_L1ITG:
3052 case QLA82XX_L1DAT:
3053 case QLA82XX_L1INS:
3054 qla8044_minidump_process_l1cache(vha,
3055 entry_hdr, &data_ptr);
3056 break;
3057 case QLA82XX_RDOCM:
3058 qla8044_minidump_process_rdocm(vha,
3059 entry_hdr, &data_ptr);
3060 break;
3061 case QLA82XX_RDMUX:
3062 qla8044_minidump_process_rdmux(vha,
3063 entry_hdr, &data_ptr);
3064 break;
3065 case QLA82XX_QUEUE:
3066 qla8044_minidump_process_queue(vha,
3067 entry_hdr, &data_ptr);
3068 break;
3069 case QLA8044_POLLRD:
3070 rval = qla8044_minidump_process_pollrd(vha,
3071 entry_hdr, &data_ptr);
3072 if (rval != QLA_SUCCESS)
3073 qla8044_mark_entry_skipped(vha, entry_hdr, i);
3074 break;
3075 case QLA8044_RDMUX2:
3076 qla8044_minidump_process_rdmux2(vha,
3077 entry_hdr, &data_ptr);
3078 break;
3079 case QLA8044_POLLRDMWR:
3080 rval = qla8044_minidump_process_pollrdmwr(vha,
3081 entry_hdr, &data_ptr);
3082 if (rval != QLA_SUCCESS)
3083 qla8044_mark_entry_skipped(vha, entry_hdr, i);
3084 break;
3085 case QLA82XX_RDNOP:
3086 default:
3087 qla8044_mark_entry_skipped(vha, entry_hdr, i);
3088 break;
3089 }
3090
3091 data_collected = (uint8_t *)data_ptr -
3092 (uint8_t *)((uint8_t *)ha->md_dump);
3093skip_nxt_entry:
3094 /*
3095 * next entry in the template
3096 */
3097 entry_hdr = (struct qla8044_minidump_entry_hdr *)
3098 (((uint8_t *)entry_hdr) + entry_hdr->entry_size);
3099 }
3100
3101 if (data_collected != ha->md_dump_size) {
3102 ql_log(ql_log_info, vha, 0xb105,
3103 "Dump data mismatch: Data collected: "
3104 "[0x%x], total_data_size:[0x%x]\n",
3105 data_collected, ha->md_dump_size);
3106 goto md_failed;
3107 }
3108
3109 ql_log(ql_log_info, vha, 0xb110,
3110 "Firmware dump saved to temp buffer (%ld/%p %ld/%p).\n",
3111 vha->host_no, ha->md_tmplt_hdr, vha->host_no, ha->md_dump);
3112 ha->fw_dumped = 1;
3113 qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
3114
3115
3116 ql_log(ql_log_info, vha, 0xb106,
3117 "Leaving fn: %s Last entry: 0x%x\n",
3118 __func__, i);
3119md_failed:
3120 return rval;
3121}
3122
3123void
3124qla8044_get_minidump(struct scsi_qla_host *vha)
3125{
3126 struct qla_hw_data *ha = vha->hw;
3127
3128 if (!qla8044_collect_md_data(vha)) {
3129 ha->fw_dumped = 1;
3130 } else {
3131 ql_log(ql_log_fatal, vha, 0xb0db,
3132 "%s: Unable to collect minidump\n",
3133 __func__);
3134 }
3135}
3136
3137static int
3138qla8044_poll_flash_status_reg(struct scsi_qla_host *vha)
3139{
3140 uint32_t flash_status;
3141 int retries = QLA8044_FLASH_READ_RETRY_COUNT;
3142 int ret_val = QLA_SUCCESS;
3143
3144 while (retries--) {
3145 ret_val = qla8044_rd_reg_indirect(vha, QLA8044_FLASH_STATUS,
3146 &flash_status);
3147 if (ret_val) {
3148 ql_log(ql_log_warn, vha, 0xb120,
3149 "%s: Failed to read FLASH_STATUS reg.\n",
3150 __func__);
3151 break;
3152 }
3153 if ((flash_status & QLA8044_FLASH_STATUS_READY) ==
3154 QLA8044_FLASH_STATUS_READY)
3155 break;
3156 msleep(QLA8044_FLASH_STATUS_REG_POLL_DELAY);
3157 }
3158
3159 if (!retries)
3160 ret_val = QLA_FUNCTION_FAILED;
3161
3162 return ret_val;
3163}
3164
3165static int
3166qla8044_write_flash_status_reg(struct scsi_qla_host *vha,
3167 uint32_t data)
3168{
3169 int ret_val = QLA_SUCCESS;
3170 uint32_t cmd;
3171
3172 cmd = vha->hw->fdt_wrt_sts_reg_cmd;
3173
3174 ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3175 QLA8044_FLASH_STATUS_WRITE_DEF_SIG | cmd);
3176 if (ret_val) {
3177 ql_log(ql_log_warn, vha, 0xb125,
3178 "%s: Failed to write to FLASH_ADDR.\n", __func__);
3179 goto exit_func;
3180 }
3181
3182 ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, data);
3183 if (ret_val) {
3184 ql_log(ql_log_warn, vha, 0xb126,
3185 "%s: Failed to write to FLASH_WRDATA.\n", __func__);
3186 goto exit_func;
3187 }
3188
3189 ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
3190 QLA8044_FLASH_SECOND_ERASE_MS_VAL);
3191 if (ret_val) {
3192 ql_log(ql_log_warn, vha, 0xb127,
3193 "%s: Failed to write to FLASH_CONTROL.\n", __func__);
3194 goto exit_func;
3195 }
3196
3197 ret_val = qla8044_poll_flash_status_reg(vha);
3198 if (ret_val)
3199 ql_log(ql_log_warn, vha, 0xb128,
3200 "%s: Error polling flash status reg.\n", __func__);
3201
3202exit_func:
3203 return ret_val;
3204}
3205
3206/*
3207 * This function assumes that the flash lock is held.
3208 */
3209static int
3210qla8044_unprotect_flash(scsi_qla_host_t *vha)
3211{
3212 int ret_val;
3213 struct qla_hw_data *ha = vha->hw;
3214
3215 ret_val = qla8044_write_flash_status_reg(vha, ha->fdt_wrt_enable);
3216 if (ret_val)
3217 ql_log(ql_log_warn, vha, 0xb139,
3218 "%s: Write flash status failed.\n", __func__);
3219
3220 return ret_val;
3221}
3222
3223/*
3224 * This function assumes that the flash lock is held.
3225 */
3226static int
3227qla8044_protect_flash(scsi_qla_host_t *vha)
3228{
3229 int ret_val;
3230 struct qla_hw_data *ha = vha->hw;
3231
3232 ret_val = qla8044_write_flash_status_reg(vha, ha->fdt_wrt_disable);
3233 if (ret_val)
3234 ql_log(ql_log_warn, vha, 0xb13b,
3235 "%s: Write flash status failed.\n", __func__);
3236
3237 return ret_val;
3238}
3239
3240
3241static int
3242qla8044_erase_flash_sector(struct scsi_qla_host *vha,
3243 uint32_t sector_start_addr)
3244{
3245 uint32_t reversed_addr;
3246 int ret_val = QLA_SUCCESS;
3247
3248 ret_val = qla8044_poll_flash_status_reg(vha);
3249 if (ret_val) {
3250 ql_log(ql_log_warn, vha, 0xb12e,
3251 "%s: Poll flash status after erase failed..\n", __func__);
3252 }
3253
3254 reversed_addr = (((sector_start_addr & 0xFF) << 16) |
3255 (sector_start_addr & 0xFF00) |
3256 ((sector_start_addr & 0xFF0000) >> 16));
3257
3258 ret_val = qla8044_wr_reg_indirect(vha,
3259 QLA8044_FLASH_WRDATA, reversed_addr);
3260 if (ret_val) {
3261 ql_log(ql_log_warn, vha, 0xb12f,
3262 "%s: Failed to write to FLASH_WRDATA.\n", __func__);
3263 }
3264 ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3265 QLA8044_FLASH_ERASE_SIG | vha->hw->fdt_erase_cmd);
3266 if (ret_val) {
3267 ql_log(ql_log_warn, vha, 0xb130,
3268 "%s: Failed to write to FLASH_ADDR.\n", __func__);
3269 }
3270 ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
3271 QLA8044_FLASH_LAST_ERASE_MS_VAL);
3272 if (ret_val) {
3273 ql_log(ql_log_warn, vha, 0xb131,
3274 "%s: Failed write to FLASH_CONTROL.\n", __func__);
3275 }
3276 ret_val = qla8044_poll_flash_status_reg(vha);
3277 if (ret_val) {
3278 ql_log(ql_log_warn, vha, 0xb132,
3279 "%s: Poll flash status failed.\n", __func__);
3280 }
3281
3282
3283 return ret_val;
3284}
3285
3286/*
3287 * qla8044_flash_write_u32 - Write data to flash
3288 *
3289 * @ha : Pointer to adapter structure
3290 * addr : Flash address to write to
3291 * p_data : Data to be written
3292 *
3293 * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
3294 *
3295 * NOTE: Lock should be held on entry
3296 */
3297static int
3298qla8044_flash_write_u32(struct scsi_qla_host *vha, uint32_t addr,
3299 uint32_t *p_data)
3300{
3301 int ret_val = QLA_SUCCESS;
3302
3303 ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3304 0x00800000 | (addr >> 2));
3305 if (ret_val) {
3306 ql_log(ql_log_warn, vha, 0xb134,
3307 "%s: Failed write to FLASH_ADDR.\n", __func__);
3308 goto exit_func;
3309 }
3310 ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, *p_data);
3311 if (ret_val) {
3312 ql_log(ql_log_warn, vha, 0xb135,
3313 "%s: Failed write to FLASH_WRDATA.\n", __func__);
3314 goto exit_func;
3315 }
3316 ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL, 0x3D);
3317 if (ret_val) {
3318 ql_log(ql_log_warn, vha, 0xb136,
3319 "%s: Failed write to FLASH_CONTROL.\n", __func__);
3320 goto exit_func;
3321 }
3322 ret_val = qla8044_poll_flash_status_reg(vha);
3323 if (ret_val) {
3324 ql_log(ql_log_warn, vha, 0xb137,
3325 "%s: Poll flash status failed.\n", __func__);
3326 }
3327
3328exit_func:
3329 return ret_val;
3330}
3331
3332static int
3333qla8044_write_flash_buffer_mode(scsi_qla_host_t *vha, uint32_t *dwptr,
3334 uint32_t faddr, uint32_t dwords)
3335{
3336 int ret = QLA_FUNCTION_FAILED;
3337 uint32_t spi_val;
3338
3339 if (dwords < QLA8044_MIN_OPTROM_BURST_DWORDS ||
3340 dwords > QLA8044_MAX_OPTROM_BURST_DWORDS) {
3341 ql_dbg(ql_dbg_user, vha, 0xb123,
3342 "Got unsupported dwords = 0x%x.\n",
3343 dwords);
3344 return QLA_FUNCTION_FAILED;
3345 }
3346
3347 qla8044_rd_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL, &spi_val);
3348 qla8044_wr_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL,
3349 spi_val | QLA8044_FLASH_SPI_CTL);
3350 qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3351 QLA8044_FLASH_FIRST_TEMP_VAL);
3352
3353 /* First DWORD write to FLASH_WRDATA */
3354 ret = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA,
3355 *dwptr++);
3356 qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
3357 QLA8044_FLASH_FIRST_MS_PATTERN);
3358
3359 ret = qla8044_poll_flash_status_reg(vha);
3360 if (ret) {
3361 ql_log(ql_log_warn, vha, 0xb124,
3362 "%s: Failed.\n", __func__);
3363 goto exit_func;
3364 }
3365
3366 dwords--;
3367
3368 qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3369 QLA8044_FLASH_SECOND_TEMP_VAL);
3370
3371
3372 /* Second to N-1 DWORDS writes */
3373 while (dwords != 1) {
3374 qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, *dwptr++);
3375 qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
3376 QLA8044_FLASH_SECOND_MS_PATTERN);
3377 ret = qla8044_poll_flash_status_reg(vha);
3378 if (ret) {
3379 ql_log(ql_log_warn, vha, 0xb129,
3380 "%s: Failed.\n", __func__);
3381 goto exit_func;
3382 }
3383 dwords--;
3384 }
3385
3386 qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3387 QLA8044_FLASH_FIRST_TEMP_VAL | (faddr >> 2));
3388
3389 /* Last DWORD write */
3390 qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, *dwptr++);
3391 qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
3392 QLA8044_FLASH_LAST_MS_PATTERN);
3393 ret = qla8044_poll_flash_status_reg(vha);
3394 if (ret) {
3395 ql_log(ql_log_warn, vha, 0xb12a,
3396 "%s: Failed.\n", __func__);
3397 goto exit_func;
3398 }
3399 qla8044_rd_reg_indirect(vha, QLA8044_FLASH_SPI_STATUS, &spi_val);
3400
3401 if ((spi_val & QLA8044_FLASH_SPI_CTL) == QLA8044_FLASH_SPI_CTL) {
3402 ql_log(ql_log_warn, vha, 0xb12b,
3403 "%s: Failed.\n", __func__);
3404 spi_val = 0;
3405 /* Operation failed, clear error bit. */
3406 qla8044_rd_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL,
3407 &spi_val);
3408 qla8044_wr_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL,
3409 spi_val | QLA8044_FLASH_SPI_CTL);
3410 }
3411exit_func:
3412 return ret;
3413}
3414
3415static int
3416qla8044_write_flash_dword_mode(scsi_qla_host_t *vha, uint32_t *dwptr,
3417 uint32_t faddr, uint32_t dwords)
3418{
3419 int ret = QLA_FUNCTION_FAILED;
3420 uint32_t liter;
3421
3422 for (liter = 0; liter < dwords; liter++, faddr += 4, dwptr++) {
3423 ret = qla8044_flash_write_u32(vha, faddr, dwptr);
3424 if (ret) {
3425 ql_dbg(ql_dbg_p3p, vha, 0xb141,
3426 "%s: flash address=%x data=%x.\n", __func__,
3427 faddr, *dwptr);
3428 break;
3429 }
3430 }
3431
3432 return ret;
3433}
3434
3435int
3436qla8044_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
3437 uint32_t offset, uint32_t length)
3438{
3439 int rval = QLA_FUNCTION_FAILED, i, burst_iter_count;
3440 int dword_count, erase_sec_count;
3441 uint32_t erase_offset;
3442 uint8_t *p_cache, *p_src;
3443
3444 erase_offset = offset;
3445
3446 p_cache = kcalloc(length, sizeof(uint8_t), GFP_KERNEL);
3447 if (!p_cache)
3448 return QLA_FUNCTION_FAILED;
3449
3450 memcpy(p_cache, buf, length);
3451 p_src = p_cache;
3452 dword_count = length / sizeof(uint32_t);
3453 /* Since the offset and legth are sector aligned, it will be always
3454 * multiple of burst_iter_count (64)
3455 */
3456 burst_iter_count = dword_count / QLA8044_MAX_OPTROM_BURST_DWORDS;
3457 erase_sec_count = length / QLA8044_SECTOR_SIZE;
3458
3459 /* Suspend HBA. */
3460 scsi_block_requests(vha->host);
3461 /* Lock and enable write for whole operation. */
3462 qla8044_flash_lock(vha);
3463 qla8044_unprotect_flash(vha);
3464
3465 /* Erasing the sectors */
3466 for (i = 0; i < erase_sec_count; i++) {
3467 rval = qla8044_erase_flash_sector(vha, erase_offset);
3468 ql_dbg(ql_dbg_user, vha, 0xb138,
3469 "Done erase of sector=0x%x.\n",
3470 erase_offset);
3471 if (rval) {
3472 ql_log(ql_log_warn, vha, 0xb121,
3473 "Failed to erase the sector having address: "
3474 "0x%x.\n", erase_offset);
3475 goto out;
3476 }
3477 erase_offset += QLA8044_SECTOR_SIZE;
3478 }
3479 ql_dbg(ql_dbg_user, vha, 0xb139,
3480 "Got write for addr = 0x%x length=0x%x.\n",
3481 offset, length);
3482
3483 for (i = 0; i < burst_iter_count; i++) {
3484
3485 /* Go with write. */
3486 rval = qla8044_write_flash_buffer_mode(vha, (uint32_t *)p_src,
3487 offset, QLA8044_MAX_OPTROM_BURST_DWORDS);
3488 if (rval) {
3489 /* Buffer Mode failed skip to dword mode */
3490 ql_log(ql_log_warn, vha, 0xb122,
3491 "Failed to write flash in buffer mode, "
3492 "Reverting to slow-write.\n");
3493 rval = qla8044_write_flash_dword_mode(vha,
3494 (uint32_t *)p_src, offset,
3495 QLA8044_MAX_OPTROM_BURST_DWORDS);
3496 }
3497 p_src += sizeof(uint32_t) * QLA8044_MAX_OPTROM_BURST_DWORDS;
3498 offset += sizeof(uint32_t) * QLA8044_MAX_OPTROM_BURST_DWORDS;
3499 }
3500 ql_dbg(ql_dbg_user, vha, 0xb133,
3501 "Done writing.\n");
3502
3503out:
3504 qla8044_protect_flash(vha);
3505 qla8044_flash_unlock(vha);
3506 scsi_unblock_requests(vha->host);
3507 kfree(p_cache);
3508
3509 return rval;
3510}
3511
3512#define LEG_INT_PTR_B31 (1 << 31)
3513#define LEG_INT_PTR_B30 (1 << 30)
3514#define PF_BITS_MASK (0xF << 16)
3515/**
3516 * qla8044_intr_handler() - Process interrupts for the ISP8044
3517 * @irq:
3518 * @dev_id: SCSI driver HA context
3519 *
3520 * Called by system whenever the host adapter generates an interrupt.
3521 *
3522 * Returns handled flag.
3523 */
3524irqreturn_t
3525qla8044_intr_handler(int irq, void *dev_id)
3526{
3527 scsi_qla_host_t *vha;
3528 struct qla_hw_data *ha;
3529 struct rsp_que *rsp;
3530 struct device_reg_82xx __iomem *reg;
3531 int status = 0;
3532 unsigned long flags;
3533 unsigned long iter;
3534 uint32_t stat;
3535 uint16_t mb[4];
3536 uint32_t leg_int_ptr = 0, pf_bit;
3537
3538 rsp = (struct rsp_que *) dev_id;
3539 if (!rsp) {
3540 ql_log(ql_log_info, NULL, 0xb143,
3541 "%s(): NULL response queue pointer\n", __func__);
3542 return IRQ_NONE;
3543 }
3544 ha = rsp->hw;
3545 vha = pci_get_drvdata(ha->pdev);
3546
3547 if (unlikely(pci_channel_offline(ha->pdev)))
3548 return IRQ_HANDLED;
3549
3550 leg_int_ptr = qla8044_rd_reg(ha, LEG_INTR_PTR_OFFSET);
3551
3552 /* Legacy interrupt is valid if bit31 of leg_int_ptr is set */
3553 if (!(leg_int_ptr & (LEG_INT_PTR_B31))) {
3554 ql_dbg(ql_dbg_p3p, vha, 0xb144,
3555 "%s: Legacy Interrupt Bit 31 not set, "
3556 "spurious interrupt!\n", __func__);
3557 return IRQ_NONE;
3558 }
3559
3560 pf_bit = ha->portnum << 16;
3561 /* Validate the PCIE function ID set in leg_int_ptr bits [19..16] */
3562 if ((leg_int_ptr & (PF_BITS_MASK)) != pf_bit) {
3563 ql_dbg(ql_dbg_p3p, vha, 0xb145,
3564 "%s: Incorrect function ID 0x%x in "
3565 "legacy interrupt register, "
3566 "ha->pf_bit = 0x%x\n", __func__,
3567 (leg_int_ptr & (PF_BITS_MASK)), pf_bit);
3568 return IRQ_NONE;
3569 }
3570
3571 /* To de-assert legacy interrupt, write 0 to Legacy Interrupt Trigger
3572 * Control register and poll till Legacy Interrupt Pointer register
3573 * bit32 is 0.
3574 */
3575 qla8044_wr_reg(ha, LEG_INTR_TRIG_OFFSET, 0);
3576 do {
3577 leg_int_ptr = qla8044_rd_reg(ha, LEG_INTR_PTR_OFFSET);
3578 if ((leg_int_ptr & (PF_BITS_MASK)) != pf_bit)
3579 break;
3580 } while (leg_int_ptr & (LEG_INT_PTR_B30));
3581
3582 reg = &ha->iobase->isp82;
3583 spin_lock_irqsave(&ha->hardware_lock, flags);
3584 for (iter = 1; iter--; ) {
3585
3586 if (RD_REG_DWORD(&reg->host_int)) {
3587 stat = RD_REG_DWORD(&reg->host_status);
3588 if ((stat & HSRX_RISC_INT) == 0)
3589 break;
3590
3591 switch (stat & 0xff) {
3592 case 0x1:
3593 case 0x2:
3594 case 0x10:
3595 case 0x11:
3596 qla82xx_mbx_completion(vha, MSW(stat));
3597 status |= MBX_INTERRUPT;
3598 break;
3599 case 0x12:
3600 mb[0] = MSW(stat);
3601 mb[1] = RD_REG_WORD(&reg->mailbox_out[1]);
3602 mb[2] = RD_REG_WORD(&reg->mailbox_out[2]);
3603 mb[3] = RD_REG_WORD(&reg->mailbox_out[3]);
3604 qla2x00_async_event(vha, rsp, mb);
3605 break;
3606 case 0x13:
3607 qla24xx_process_response_queue(vha, rsp);
3608 break;
3609 default:
3610 ql_dbg(ql_dbg_p3p, vha, 0xb146,
3611 "Unrecognized interrupt type "
3612 "(%d).\n", stat & 0xff);
3613 break;
3614 }
3615 }
3616 WRT_REG_DWORD(&reg->host_int, 0);
3617 }
3618
3619 qla2x00_handle_mbx_completion(ha, status);
3620 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3621
3622 return IRQ_HANDLED;
3623}
3624
3625static int
3626qla8044_idc_dontreset(struct qla_hw_data *ha)
3627{
3628 uint32_t idc_ctrl;
3629
3630 idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
3631 return idc_ctrl & DONTRESET_BIT0;
3632}
3633
3634static void
3635qla8044_clear_rst_ready(scsi_qla_host_t *vha)
3636{
3637 uint32_t drv_state;
3638
3639 drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
3640
3641 /*
3642 * For ISP8044, drv_active register has 1 bit per function,
3643 * shift 1 by func_num to set a bit for the function.
3644 * For ISP82xx, drv_active has 4 bits per function
3645 */
3646 drv_state &= ~(1 << vha->hw->portnum);
3647
3648 ql_dbg(ql_dbg_p3p, vha, 0xb143,
3649 "drv_state: 0x%08x\n", drv_state);
3650 qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, drv_state);
3651}
3652
3653int
3654qla8044_abort_isp(scsi_qla_host_t *vha)
3655{
3656 int rval;
3657 uint32_t dev_state;
3658 struct qla_hw_data *ha = vha->hw;
3659
3660 qla8044_idc_lock(ha);
3661 dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
3662
3663 if (ql2xdontresethba)
3664 qla8044_set_idc_dontreset(vha);
3665
3666 /* If device_state is NEED_RESET, go ahead with
3667 * Reset,irrespective of ql2xdontresethba. This is to allow a
3668 * non-reset-owner to force a reset. Non-reset-owner sets
3669 * the IDC_CTRL BIT0 to prevent Reset-owner from doing a Reset
3670 * and then forces a Reset by setting device_state to
3671 * NEED_RESET. */
3672 if (dev_state == QLA8XXX_DEV_READY) {
3673 /* If IDC_CTRL DONTRESETHBA_BIT0 is set don't do reset
3674 * recovery */
3675 if (qla8044_idc_dontreset(ha) == DONTRESET_BIT0) {
3676 ql_dbg(ql_dbg_p3p, vha, 0xb144,
3677 "Reset recovery disabled\n");
3678 rval = QLA_FUNCTION_FAILED;
3679 goto exit_isp_reset;
3680 }
3681
3682 ql_dbg(ql_dbg_p3p, vha, 0xb145,
3683 "HW State: NEED RESET\n");
3684 qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
3685 QLA8XXX_DEV_NEED_RESET);
3686 }
3687
3688 /* For ISP8044, Reset owner is NIC, iSCSI or FCOE based on priority
3689 * and which drivers are present. Unlike ISP82XX, the function setting
3690 * NEED_RESET, may not be the Reset owner. */
3691 qla83xx_reset_ownership(vha);
3692
3693 qla8044_idc_unlock(ha);
3694 rval = qla8044_device_state_handler(vha);
3695 qla8044_idc_lock(ha);
3696 qla8044_clear_rst_ready(vha);
3697
3698exit_isp_reset:
3699 qla8044_idc_unlock(ha);
3700 if (rval == QLA_SUCCESS) {
3701 ha->flags.isp82xx_fw_hung = 0;
3702 ha->flags.nic_core_reset_hdlr_active = 0;
3703 rval = qla82xx_restart_isp(vha);
3704 }
3705
3706 return rval;
3707}
3708
diff --git a/drivers/scsi/qla2xxx/qla_nx2.h b/drivers/scsi/qla2xxx/qla_nx2.h
new file mode 100644
index 000000000000..2ab2eabab908
--- /dev/null
+++ b/drivers/scsi/qla2xxx/qla_nx2.h
@@ -0,0 +1,551 @@
1/*
2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2013 QLogic Corporation
4 *
5 * See LICENSE.qla2xxx for copyright and licensing details.
6 */
7
8#ifndef __QLA_NX2_H
9#define __QLA_NX2_H
10
11#define QSNT_ACK_TOV 30
12#define INTENT_TO_RECOVER 0x01
13#define PROCEED_TO_RECOVER 0x02
14#define IDC_LOCK_RECOVERY_OWNER_MASK 0x3C
15#define IDC_LOCK_RECOVERY_STATE_MASK 0x3
16#define IDC_LOCK_RECOVERY_STATE_SHIFT_BITS 2
17
18#define QLA8044_DRV_LOCK_MSLEEP 200
19#define QLA8044_ADDR_DDR_NET (0x0000000000000000ULL)
20#define QLA8044_ADDR_DDR_NET_MAX (0x000000000fffffffULL)
21
22#define MD_MIU_TEST_AGT_WRDATA_LO 0x410000A0
23#define MD_MIU_TEST_AGT_WRDATA_HI 0x410000A4
24#define MD_MIU_TEST_AGT_WRDATA_ULO 0x410000B0
25#define MD_MIU_TEST_AGT_WRDATA_UHI 0x410000B4
26#define MD_MIU_TEST_AGT_RDDATA_LO 0x410000A8
27#define MD_MIU_TEST_AGT_RDDATA_HI 0x410000AC
28#define MD_MIU_TEST_AGT_RDDATA_ULO 0x410000B8
29#define MD_MIU_TEST_AGT_RDDATA_UHI 0x410000BC
30
31/* MIU_TEST_AGT_CTRL flags. work for SIU as well */
32#define MIU_TA_CTL_WRITE_ENABLE (MIU_TA_CTL_WRITE | MIU_TA_CTL_ENABLE)
33#define MIU_TA_CTL_WRITE_START (MIU_TA_CTL_WRITE | MIU_TA_CTL_ENABLE | \
34 MIU_TA_CTL_START)
35#define MIU_TA_CTL_START_ENABLE (MIU_TA_CTL_START | MIU_TA_CTL_ENABLE)
36
37/* Imbus address bit used to indicate a host address. This bit is
38 * eliminated by the pcie bar and bar select before presentation
39 * over pcie. */
40/* host memory via IMBUS */
41#define QLA8044_P2_ADDR_PCIE (0x0000000800000000ULL)
42#define QLA8044_P3_ADDR_PCIE (0x0000008000000000ULL)
43#define QLA8044_ADDR_PCIE_MAX (0x0000000FFFFFFFFFULL)
44#define QLA8044_ADDR_OCM0 (0x0000000200000000ULL)
45#define QLA8044_ADDR_OCM0_MAX (0x00000002000fffffULL)
46#define QLA8044_ADDR_OCM1 (0x0000000200400000ULL)
47#define QLA8044_ADDR_OCM1_MAX (0x00000002004fffffULL)
48#define QLA8044_ADDR_QDR_NET (0x0000000300000000ULL)
49#define QLA8044_P2_ADDR_QDR_NET_MAX (0x00000003001fffffULL)
50#define QLA8044_P3_ADDR_QDR_NET_MAX (0x0000000303ffffffULL)
51#define QLA8044_ADDR_QDR_NET_MAX (0x0000000307ffffffULL)
52#define QLA8044_PCI_CRBSPACE ((unsigned long)0x06000000)
53#define QLA8044_PCI_DIRECT_CRB ((unsigned long)0x04400000)
54#define QLA8044_PCI_CAMQM ((unsigned long)0x04800000)
55#define QLA8044_PCI_CAMQM_MAX ((unsigned long)0x04ffffff)
56#define QLA8044_PCI_DDR_NET ((unsigned long)0x00000000)
57#define QLA8044_PCI_QDR_NET ((unsigned long)0x04000000)
58#define QLA8044_PCI_QDR_NET_MAX ((unsigned long)0x043fffff)
59
60/* PCI Windowing for DDR regions. */
61#define QLA8044_ADDR_IN_RANGE(addr, low, high) \
62 (((addr) <= (high)) && ((addr) >= (low)))
63
64/* Indirectly Mapped Registers */
65#define QLA8044_FLASH_SPI_STATUS 0x2808E010
66#define QLA8044_FLASH_SPI_CONTROL 0x2808E014
67#define QLA8044_FLASH_STATUS 0x42100004
68#define QLA8044_FLASH_CONTROL 0x42110004
69#define QLA8044_FLASH_ADDR 0x42110008
70#define QLA8044_FLASH_WRDATA 0x4211000C
71#define QLA8044_FLASH_RDDATA 0x42110018
72#define QLA8044_FLASH_DIRECT_WINDOW 0x42110030
73#define QLA8044_FLASH_DIRECT_DATA(DATA) (0x42150000 | (0x0000FFFF&DATA))
74
75/* Flash access regs */
76#define QLA8044_FLASH_LOCK 0x3850
77#define QLA8044_FLASH_UNLOCK 0x3854
78#define QLA8044_FLASH_LOCK_ID 0x3500
79
80/* Driver Lock regs */
81#define QLA8044_DRV_LOCK 0x3868
82#define QLA8044_DRV_UNLOCK 0x386C
83#define QLA8044_DRV_LOCK_ID 0x3504
84#define QLA8044_DRV_LOCKRECOVERY 0x379C
85
86/* IDC version */
87#define QLA8044_IDC_VER_MAJ_VALUE 0x1
88#define QLA8044_IDC_VER_MIN_VALUE 0x0
89
90/* IDC Registers : Driver Coexistence Defines */
91#define QLA8044_CRB_IDC_VER_MAJOR 0x3780
92#define QLA8044_CRB_IDC_VER_MINOR 0x3798
93#define QLA8044_IDC_DRV_AUDIT 0x3794
94#define QLA8044_SRE_SHIM_CONTROL 0x0D200284
95#define QLA8044_PORT0_RXB_PAUSE_THRS 0x0B2003A4
96#define QLA8044_PORT1_RXB_PAUSE_THRS 0x0B2013A4
97#define QLA8044_PORT0_RXB_TC_MAX_CELL 0x0B200388
98#define QLA8044_PORT1_RXB_TC_MAX_CELL 0x0B201388
99#define QLA8044_PORT0_RXB_TC_STATS 0x0B20039C
100#define QLA8044_PORT1_RXB_TC_STATS 0x0B20139C
101#define QLA8044_PORT2_IFB_PAUSE_THRS 0x0B200704
102#define QLA8044_PORT3_IFB_PAUSE_THRS 0x0B201704
103
104/* set value to pause threshold value */
105#define QLA8044_SET_PAUSE_VAL 0x0
106#define QLA8044_SET_TC_MAX_CELL_VAL 0x03FF03FF
107#define QLA8044_PEG_HALT_STATUS1 0x34A8
108#define QLA8044_PEG_HALT_STATUS2 0x34AC
109#define QLA8044_PEG_ALIVE_COUNTER 0x34B0 /* FW_HEARTBEAT */
110#define QLA8044_FW_CAPABILITIES 0x3528
111#define QLA8044_CRB_DRV_ACTIVE 0x3788 /* IDC_DRV_PRESENCE */
112#define QLA8044_CRB_DEV_STATE 0x3784 /* IDC_DEV_STATE */
113#define QLA8044_CRB_DRV_STATE 0x378C /* IDC_DRV_ACK */
114#define QLA8044_CRB_DRV_SCRATCH 0x3548
115#define QLA8044_CRB_DEV_PART_INFO1 0x37E0
116#define QLA8044_CRB_DEV_PART_INFO2 0x37E4
117#define QLA8044_FW_VER_MAJOR 0x3550
118#define QLA8044_FW_VER_MINOR 0x3554
119#define QLA8044_FW_VER_SUB 0x3558
120#define QLA8044_NPAR_STATE 0x359C
121#define QLA8044_FW_IMAGE_VALID 0x35FC
122#define QLA8044_CMDPEG_STATE 0x3650
123#define QLA8044_ASIC_TEMP 0x37B4
124#define QLA8044_FW_API 0x356C
125#define QLA8044_DRV_OP_MODE 0x3570
126#define QLA8044_CRB_WIN_BASE 0x3800
127#define QLA8044_CRB_WIN_FUNC(f) (QLA8044_CRB_WIN_BASE+((f)*4))
128#define QLA8044_SEM_LOCK_BASE 0x3840
129#define QLA8044_SEM_UNLOCK_BASE 0x3844
130#define QLA8044_SEM_LOCK_FUNC(f) (QLA8044_SEM_LOCK_BASE+((f)*8))
131#define QLA8044_SEM_UNLOCK_FUNC(f) (QLA8044_SEM_UNLOCK_BASE+((f)*8))
132#define QLA8044_LINK_STATE(f) (0x3698+((f) > 7 ? 4 : 0))
133#define QLA8044_LINK_SPEED(f) (0x36E0+(((f) >> 2) * 4))
134#define QLA8044_MAX_LINK_SPEED(f) (0x36F0+(((f) / 4) * 4))
135#define QLA8044_LINK_SPEED_FACTOR 10
136
137/* FLASH API Defines */
138#define QLA8044_FLASH_MAX_WAIT_USEC 100
139#define QLA8044_FLASH_LOCK_TIMEOUT 10000
140#define QLA8044_FLASH_SECTOR_SIZE 65536
141#define QLA8044_DRV_LOCK_TIMEOUT 2000
142#define QLA8044_FLASH_SECTOR_ERASE_CMD 0xdeadbeef
143#define QLA8044_FLASH_WRITE_CMD 0xdacdacda
144#define QLA8044_FLASH_BUFFER_WRITE_CMD 0xcadcadca
145#define QLA8044_FLASH_READ_RETRY_COUNT 2000
146#define QLA8044_FLASH_STATUS_READY 0x6
147#define QLA8044_FLASH_BUFFER_WRITE_MIN 2
148#define QLA8044_FLASH_BUFFER_WRITE_MAX 64
149#define QLA8044_FLASH_STATUS_REG_POLL_DELAY 1
150#define QLA8044_ERASE_MODE 1
151#define QLA8044_WRITE_MODE 2
152#define QLA8044_DWORD_WRITE_MODE 3
153#define QLA8044_GLOBAL_RESET 0x38CC
154#define QLA8044_WILDCARD 0x38F0
155#define QLA8044_INFORMANT 0x38FC
156#define QLA8044_HOST_MBX_CTRL 0x3038
157#define QLA8044_FW_MBX_CTRL 0x303C
158#define QLA8044_BOOTLOADER_ADDR 0x355C
159#define QLA8044_BOOTLOADER_SIZE 0x3560
160#define QLA8044_FW_IMAGE_ADDR 0x3564
161#define QLA8044_MBX_INTR_ENABLE 0x1000
162#define QLA8044_MBX_INTR_MASK 0x1200
163
164/* IDC Control Register bit defines */
165#define DONTRESET_BIT0 0x1
166#define GRACEFUL_RESET_BIT1 0x2
167
168/* ISP8044 PEG_HALT_STATUS1 bits */
169#define QLA8044_HALT_STATUS_INFORMATIONAL (0x1 << 29)
170#define QLA8044_HALT_STATUS_FW_RESET (0x2 << 29)
171#define QLA8044_HALT_STATUS_UNRECOVERABLE (0x4 << 29)
172
173/* Firmware image definitions */
174#define QLA8044_BOOTLOADER_FLASH_ADDR 0x10000
175#define QLA8044_BOOT_FROM_FLASH 0
176#define QLA8044_IDC_PARAM_ADDR 0x3e8020
177
178/* FLASH related definitions */
179#define QLA8044_OPTROM_BURST_SIZE 0x100
180#define QLA8044_MAX_OPTROM_BURST_DWORDS (QLA8044_OPTROM_BURST_SIZE / 4)
181#define QLA8044_MIN_OPTROM_BURST_DWORDS 2
182#define QLA8044_SECTOR_SIZE (64 * 1024)
183
184#define QLA8044_FLASH_SPI_CTL 0x4
185#define QLA8044_FLASH_FIRST_TEMP_VAL 0x00800000
186#define QLA8044_FLASH_SECOND_TEMP_VAL 0x00800001
187#define QLA8044_FLASH_FIRST_MS_PATTERN 0x43
188#define QLA8044_FLASH_SECOND_MS_PATTERN 0x7F
189#define QLA8044_FLASH_LAST_MS_PATTERN 0x7D
190#define QLA8044_FLASH_STATUS_WRITE_DEF_SIG 0xFD0100
191#define QLA8044_FLASH_SECOND_ERASE_MS_VAL 0x5
192#define QLA8044_FLASH_ERASE_SIG 0xFD0300
193#define QLA8044_FLASH_LAST_ERASE_MS_VAL 0x3D
194
195/* Reset template definitions */
196#define QLA8044_MAX_RESET_SEQ_ENTRIES 16
197#define QLA8044_RESTART_TEMPLATE_SIZE 0x2000
198#define QLA8044_RESET_TEMPLATE_ADDR 0x4F0000
199#define QLA8044_RESET_SEQ_VERSION 0x0101
200
201/* Reset template entry opcodes */
202#define OPCODE_NOP 0x0000
203#define OPCODE_WRITE_LIST 0x0001
204#define OPCODE_READ_WRITE_LIST 0x0002
205#define OPCODE_POLL_LIST 0x0004
206#define OPCODE_POLL_WRITE_LIST 0x0008
207#define OPCODE_READ_MODIFY_WRITE 0x0010
208#define OPCODE_SEQ_PAUSE 0x0020
209#define OPCODE_SEQ_END 0x0040
210#define OPCODE_TMPL_END 0x0080
211#define OPCODE_POLL_READ_LIST 0x0100
212
213/* Template Header */
214#define RESET_TMPLT_HDR_SIGNATURE 0xCAFE
215#define QLA8044_IDC_DRV_CTRL 0x3790
216#define AF_8044_NO_FW_DUMP 27 /* 0x08000000 */
217
218#define MINIDUMP_SIZE_36K 36864
219
220struct qla8044_reset_template_hdr {
221 uint16_t version;
222 uint16_t signature;
223 uint16_t size;
224 uint16_t entries;
225 uint16_t hdr_size;
226 uint16_t checksum;
227 uint16_t init_seq_offset;
228 uint16_t start_seq_offset;
229} __packed;
230
231/* Common Entry Header. */
232struct qla8044_reset_entry_hdr {
233 uint16_t cmd;
234 uint16_t size;
235 uint16_t count;
236 uint16_t delay;
237} __packed;
238
239/* Generic poll entry type. */
240struct qla8044_poll {
241 uint32_t test_mask;
242 uint32_t test_value;
243} __packed;
244
245/* Read modify write entry type. */
246struct qla8044_rmw {
247 uint32_t test_mask;
248 uint32_t xor_value;
249 uint32_t or_value;
250 uint8_t shl;
251 uint8_t shr;
252 uint8_t index_a;
253 uint8_t rsvd;
254} __packed;
255
256/* Generic Entry Item with 2 DWords. */
257struct qla8044_entry {
258 uint32_t arg1;
259 uint32_t arg2;
260} __packed;
261
262/* Generic Entry Item with 4 DWords.*/
263struct qla8044_quad_entry {
264 uint32_t dr_addr;
265 uint32_t dr_value;
266 uint32_t ar_addr;
267 uint32_t ar_value;
268} __packed;
269
270struct qla8044_reset_template {
271 int seq_index;
272 int seq_error;
273 int array_index;
274 uint32_t array[QLA8044_MAX_RESET_SEQ_ENTRIES];
275 uint8_t *buff;
276 uint8_t *stop_offset;
277 uint8_t *start_offset;
278 uint8_t *init_offset;
279 struct qla8044_reset_template_hdr *hdr;
280 uint8_t seq_end;
281 uint8_t template_end;
282};
283
284/* Driver_code is for driver to write some info about the entry
285 * currently not used.
286 */
287struct qla8044_minidump_entry_hdr {
288 uint32_t entry_type;
289 uint32_t entry_size;
290 uint32_t entry_capture_size;
291 struct {
292 uint8_t entry_capture_mask;
293 uint8_t entry_code;
294 uint8_t driver_code;
295 uint8_t driver_flags;
296 } d_ctrl;
297} __packed;
298
299/* Read CRB entry header */
300struct qla8044_minidump_entry_crb {
301 struct qla8044_minidump_entry_hdr h;
302 uint32_t addr;
303 struct {
304 uint8_t addr_stride;
305 uint8_t state_index_a;
306 uint16_t poll_timeout;
307 } crb_strd;
308 uint32_t data_size;
309 uint32_t op_count;
310
311 struct {
312 uint8_t opcode;
313 uint8_t state_index_v;
314 uint8_t shl;
315 uint8_t shr;
316 } crb_ctrl;
317
318 uint32_t value_1;
319 uint32_t value_2;
320 uint32_t value_3;
321} __packed;
322
323struct qla8044_minidump_entry_cache {
324 struct qla8044_minidump_entry_hdr h;
325 uint32_t tag_reg_addr;
326 struct {
327 uint16_t tag_value_stride;
328 uint16_t init_tag_value;
329 } addr_ctrl;
330 uint32_t data_size;
331 uint32_t op_count;
332 uint32_t control_addr;
333 struct {
334 uint16_t write_value;
335 uint8_t poll_mask;
336 uint8_t poll_wait;
337 } cache_ctrl;
338 uint32_t read_addr;
339 struct {
340 uint8_t read_addr_stride;
341 uint8_t read_addr_cnt;
342 uint16_t rsvd_1;
343 } read_ctrl;
344} __packed;
345
346/* Read OCM */
347struct qla8044_minidump_entry_rdocm {
348 struct qla8044_minidump_entry_hdr h;
349 uint32_t rsvd_0;
350 uint32_t rsvd_1;
351 uint32_t data_size;
352 uint32_t op_count;
353 uint32_t rsvd_2;
354 uint32_t rsvd_3;
355 uint32_t read_addr;
356 uint32_t read_addr_stride;
357} __packed;
358
359/* Read Memory */
360struct qla8044_minidump_entry_rdmem {
361 struct qla8044_minidump_entry_hdr h;
362 uint32_t rsvd[6];
363 uint32_t read_addr;
364 uint32_t read_data_size;
365};
366
367/* Read Memory: For Pex-DMA */
368struct qla8044_minidump_entry_rdmem_pex_dma {
369 struct qla8044_minidump_entry_hdr h;
370 uint32_t desc_card_addr;
371 uint16_t dma_desc_cmd;
372 uint8_t rsvd[2];
373 uint32_t start_dma_cmd;
374 uint8_t rsvd2[12];
375 uint32_t read_addr;
376 uint32_t read_data_size;
377} __packed;
378
379/* Read ROM */
380struct qla8044_minidump_entry_rdrom {
381 struct qla8044_minidump_entry_hdr h;
382 uint32_t rsvd[6];
383 uint32_t read_addr;
384 uint32_t read_data_size;
385} __packed;
386
387/* Mux entry */
388struct qla8044_minidump_entry_mux {
389 struct qla8044_minidump_entry_hdr h;
390 uint32_t select_addr;
391 uint32_t rsvd_0;
392 uint32_t data_size;
393 uint32_t op_count;
394 uint32_t select_value;
395 uint32_t select_value_stride;
396 uint32_t read_addr;
397 uint32_t rsvd_1;
398} __packed;
399
400/* Queue entry */
401struct qla8044_minidump_entry_queue {
402 struct qla8044_minidump_entry_hdr h;
403 uint32_t select_addr;
404 struct {
405 uint16_t queue_id_stride;
406 uint16_t rsvd_0;
407 } q_strd;
408 uint32_t data_size;
409 uint32_t op_count;
410 uint32_t rsvd_1;
411 uint32_t rsvd_2;
412 uint32_t read_addr;
413 struct {
414 uint8_t read_addr_stride;
415 uint8_t read_addr_cnt;
416 uint16_t rsvd_3;
417 } rd_strd;
418} __packed;
419
420/* POLLRD Entry */
421struct qla8044_minidump_entry_pollrd {
422 struct qla8044_minidump_entry_hdr h;
423 uint32_t select_addr;
424 uint32_t read_addr;
425 uint32_t select_value;
426 uint16_t select_value_stride;
427 uint16_t op_count;
428 uint32_t poll_wait;
429 uint32_t poll_mask;
430 uint32_t data_size;
431 uint32_t rsvd_1;
432} __packed;
433
434/* RDMUX2 Entry */
435struct qla8044_minidump_entry_rdmux2 {
436 struct qla8044_minidump_entry_hdr h;
437 uint32_t select_addr_1;
438 uint32_t select_addr_2;
439 uint32_t select_value_1;
440 uint32_t select_value_2;
441 uint32_t op_count;
442 uint32_t select_value_mask;
443 uint32_t read_addr;
444 uint8_t select_value_stride;
445 uint8_t data_size;
446 uint8_t rsvd[2];
447} __packed;
448
449/* POLLRDMWR Entry */
450struct qla8044_minidump_entry_pollrdmwr {
451 struct qla8044_minidump_entry_hdr h;
452 uint32_t addr_1;
453 uint32_t addr_2;
454 uint32_t value_1;
455 uint32_t value_2;
456 uint32_t poll_wait;
457 uint32_t poll_mask;
458 uint32_t modify_mask;
459 uint32_t data_size;
460} __packed;
461
462/* IDC additional information */
463struct qla8044_idc_information {
464 uint32_t request_desc; /* IDC request descriptor */
465 uint32_t info1; /* IDC additional info */
466 uint32_t info2; /* IDC additional info */
467 uint32_t info3; /* IDC additional info */
468} __packed;
469
470enum qla_regs {
471 QLA8044_PEG_HALT_STATUS1_INDEX = 0,
472 QLA8044_PEG_HALT_STATUS2_INDEX,
473 QLA8044_PEG_ALIVE_COUNTER_INDEX,
474 QLA8044_CRB_DRV_ACTIVE_INDEX,
475 QLA8044_CRB_DEV_STATE_INDEX,
476 QLA8044_CRB_DRV_STATE_INDEX,
477 QLA8044_CRB_DRV_SCRATCH_INDEX,
478 QLA8044_CRB_DEV_PART_INFO_INDEX,
479 QLA8044_CRB_DRV_IDC_VERSION_INDEX,
480 QLA8044_FW_VERSION_MAJOR_INDEX,
481 QLA8044_FW_VERSION_MINOR_INDEX,
482 QLA8044_FW_VERSION_SUB_INDEX,
483 QLA8044_CRB_CMDPEG_STATE_INDEX,
484 QLA8044_CRB_TEMP_STATE_INDEX,
485} __packed;
486
487#define CRB_REG_INDEX_MAX 14
488#define CRB_CMDPEG_CHECK_RETRY_COUNT 60
489#define CRB_CMDPEG_CHECK_DELAY 500
490
491static const uint32_t qla8044_reg_tbl[] = {
492 QLA8044_PEG_HALT_STATUS1,
493 QLA8044_PEG_HALT_STATUS2,
494 QLA8044_PEG_ALIVE_COUNTER,
495 QLA8044_CRB_DRV_ACTIVE,
496 QLA8044_CRB_DEV_STATE,
497 QLA8044_CRB_DRV_STATE,
498 QLA8044_CRB_DRV_SCRATCH,
499 QLA8044_CRB_DEV_PART_INFO1,
500 QLA8044_CRB_IDC_VER_MAJOR,
501 QLA8044_FW_VER_MAJOR,
502 QLA8044_FW_VER_MINOR,
503 QLA8044_FW_VER_SUB,
504 QLA8044_CMDPEG_STATE,
505 QLA8044_ASIC_TEMP,
506};
507
508/* MiniDump Structures */
509
510/* Driver_code is for driver to write some info about the entry
511 * currently not used.
512 */
513#define QLA8044_SS_OCM_WNDREG_INDEX 3
514#define QLA8044_DBG_STATE_ARRAY_LEN 16
515#define QLA8044_DBG_CAP_SIZE_ARRAY_LEN 8
516#define QLA8044_DBG_RSVD_ARRAY_LEN 8
517#define QLA8044_DBG_OCM_WNDREG_ARRAY_LEN 16
518#define QLA8044_SS_PCI_INDEX 0
519
520struct qla8044_minidump_template_hdr {
521 uint32_t entry_type;
522 uint32_t first_entry_offset;
523 uint32_t size_of_template;
524 uint32_t capture_debug_level;
525 uint32_t num_of_entries;
526 uint32_t version;
527 uint32_t driver_timestamp;
528 uint32_t checksum;
529
530 uint32_t driver_capture_mask;
531 uint32_t driver_info_word2;
532 uint32_t driver_info_word3;
533 uint32_t driver_info_word4;
534
535 uint32_t saved_state_array[QLA8044_DBG_STATE_ARRAY_LEN];
536 uint32_t capture_size_array[QLA8044_DBG_CAP_SIZE_ARRAY_LEN];
537 uint32_t ocm_window_reg[QLA8044_DBG_OCM_WNDREG_ARRAY_LEN];
538};
539
540struct qla8044_pex_dma_descriptor {
541 struct {
542 uint32_t read_data_size; /* 0-23: size, 24-31: rsvd */
543 uint8_t rsvd[2];
544 uint16_t dma_desc_cmd;
545 } cmd;
546 uint64_t src_addr;
547 uint64_t dma_bus_addr; /*0-3: desc-cmd, 4-7: pci-func, 8-15: desc-cmd*/
548 uint8_t rsvd[24];
549} __packed;
550
551#endif
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 9207aeb3cdbe..f92b22bca7ea 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1247,7 +1247,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
1247 if (qla2x00_vp_abort_isp(vha)) 1247 if (qla2x00_vp_abort_isp(vha))
1248 goto eh_host_reset_lock; 1248 goto eh_host_reset_lock;
1249 } else { 1249 } else {
1250 if (IS_QLA82XX(vha->hw)) { 1250 if (IS_P3P_TYPE(vha->hw)) {
1251 if (!qla82xx_fcoe_ctx_reset(vha)) { 1251 if (!qla82xx_fcoe_ctx_reset(vha)) {
1252 /* Ctx reset success */ 1252 /* Ctx reset success */
1253 ret = SUCCESS; 1253 ret = SUCCESS;
@@ -1911,7 +1911,7 @@ static struct isp_operations qla2300_isp_ops = {
1911 .get_flash_version = qla2x00_get_flash_version, 1911 .get_flash_version = qla2x00_get_flash_version,
1912 .start_scsi = qla2x00_start_scsi, 1912 .start_scsi = qla2x00_start_scsi,
1913 .abort_isp = qla2x00_abort_isp, 1913 .abort_isp = qla2x00_abort_isp,
1914 .iospace_config = qla2x00_iospace_config, 1914 .iospace_config = qla2x00_iospace_config,
1915 .initialize_adapter = qla2x00_initialize_adapter, 1915 .initialize_adapter = qla2x00_initialize_adapter,
1916}; 1916};
1917 1917
@@ -1949,7 +1949,7 @@ static struct isp_operations qla24xx_isp_ops = {
1949 .get_flash_version = qla24xx_get_flash_version, 1949 .get_flash_version = qla24xx_get_flash_version,
1950 .start_scsi = qla24xx_start_scsi, 1950 .start_scsi = qla24xx_start_scsi,
1951 .abort_isp = qla2x00_abort_isp, 1951 .abort_isp = qla2x00_abort_isp,
1952 .iospace_config = qla2x00_iospace_config, 1952 .iospace_config = qla2x00_iospace_config,
1953 .initialize_adapter = qla2x00_initialize_adapter, 1953 .initialize_adapter = qla2x00_initialize_adapter,
1954}; 1954};
1955 1955
@@ -1987,7 +1987,7 @@ static struct isp_operations qla25xx_isp_ops = {
1987 .get_flash_version = qla24xx_get_flash_version, 1987 .get_flash_version = qla24xx_get_flash_version,
1988 .start_scsi = qla24xx_dif_start_scsi, 1988 .start_scsi = qla24xx_dif_start_scsi,
1989 .abort_isp = qla2x00_abort_isp, 1989 .abort_isp = qla2x00_abort_isp,
1990 .iospace_config = qla2x00_iospace_config, 1990 .iospace_config = qla2x00_iospace_config,
1991 .initialize_adapter = qla2x00_initialize_adapter, 1991 .initialize_adapter = qla2x00_initialize_adapter,
1992}; 1992};
1993 1993
@@ -2025,7 +2025,7 @@ static struct isp_operations qla81xx_isp_ops = {
2025 .get_flash_version = qla24xx_get_flash_version, 2025 .get_flash_version = qla24xx_get_flash_version,
2026 .start_scsi = qla24xx_dif_start_scsi, 2026 .start_scsi = qla24xx_dif_start_scsi,
2027 .abort_isp = qla2x00_abort_isp, 2027 .abort_isp = qla2x00_abort_isp,
2028 .iospace_config = qla2x00_iospace_config, 2028 .iospace_config = qla2x00_iospace_config,
2029 .initialize_adapter = qla2x00_initialize_adapter, 2029 .initialize_adapter = qla2x00_initialize_adapter,
2030}; 2030};
2031 2031
@@ -2060,13 +2060,51 @@ static struct isp_operations qla82xx_isp_ops = {
2060 .beacon_blink = NULL, 2060 .beacon_blink = NULL,
2061 .read_optrom = qla82xx_read_optrom_data, 2061 .read_optrom = qla82xx_read_optrom_data,
2062 .write_optrom = qla82xx_write_optrom_data, 2062 .write_optrom = qla82xx_write_optrom_data,
2063 .get_flash_version = qla24xx_get_flash_version, 2063 .get_flash_version = qla82xx_get_flash_version,
2064 .start_scsi = qla82xx_start_scsi, 2064 .start_scsi = qla82xx_start_scsi,
2065 .abort_isp = qla82xx_abort_isp, 2065 .abort_isp = qla82xx_abort_isp,
2066 .iospace_config = qla82xx_iospace_config, 2066 .iospace_config = qla82xx_iospace_config,
2067 .initialize_adapter = qla2x00_initialize_adapter, 2067 .initialize_adapter = qla2x00_initialize_adapter,
2068}; 2068};
2069 2069
2070static struct isp_operations qla8044_isp_ops = {
2071 .pci_config = qla82xx_pci_config,
2072 .reset_chip = qla82xx_reset_chip,
2073 .chip_diag = qla24xx_chip_diag,
2074 .config_rings = qla82xx_config_rings,
2075 .reset_adapter = qla24xx_reset_adapter,
2076 .nvram_config = qla81xx_nvram_config,
2077 .update_fw_options = qla24xx_update_fw_options,
2078 .load_risc = qla82xx_load_risc,
2079 .pci_info_str = qla24xx_pci_info_str,
2080 .fw_version_str = qla24xx_fw_version_str,
2081 .intr_handler = qla8044_intr_handler,
2082 .enable_intrs = qla82xx_enable_intrs,
2083 .disable_intrs = qla82xx_disable_intrs,
2084 .abort_command = qla24xx_abort_command,
2085 .target_reset = qla24xx_abort_target,
2086 .lun_reset = qla24xx_lun_reset,
2087 .fabric_login = qla24xx_login_fabric,
2088 .fabric_logout = qla24xx_fabric_logout,
2089 .calc_req_entries = NULL,
2090 .build_iocbs = NULL,
2091 .prep_ms_iocb = qla24xx_prep_ms_iocb,
2092 .prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb,
2093 .read_nvram = NULL,
2094 .write_nvram = NULL,
2095 .fw_dump = qla24xx_fw_dump,
2096 .beacon_on = qla82xx_beacon_on,
2097 .beacon_off = qla82xx_beacon_off,
2098 .beacon_blink = NULL,
2099 .read_optrom = qla82xx_read_optrom_data,
2100 .write_optrom = qla8044_write_optrom_data,
2101 .get_flash_version = qla82xx_get_flash_version,
2102 .start_scsi = qla82xx_start_scsi,
2103 .abort_isp = qla8044_abort_isp,
2104 .iospace_config = qla82xx_iospace_config,
2105 .initialize_adapter = qla2x00_initialize_adapter,
2106};
2107
2070static struct isp_operations qla83xx_isp_ops = { 2108static struct isp_operations qla83xx_isp_ops = {
2071 .pci_config = qla25xx_pci_config, 2109 .pci_config = qla25xx_pci_config,
2072 .reset_chip = qla24xx_reset_chip, 2110 .reset_chip = qla24xx_reset_chip,
@@ -2237,6 +2275,14 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha)
2237 /* Initialize 82XX ISP flags */ 2275 /* Initialize 82XX ISP flags */
2238 qla82xx_init_flags(ha); 2276 qla82xx_init_flags(ha);
2239 break; 2277 break;
2278 case PCI_DEVICE_ID_QLOGIC_ISP8044:
2279 ha->device_type |= DT_ISP8044;
2280 ha->device_type |= DT_ZIO_SUPPORTED;
2281 ha->device_type |= DT_FWI2;
2282 ha->fw_srisc_address = RISC_START_ADDRESS_2400;
2283 /* Initialize 82XX ISP flags */
2284 qla82xx_init_flags(ha);
2285 break;
2240 case PCI_DEVICE_ID_QLOGIC_ISP2031: 2286 case PCI_DEVICE_ID_QLOGIC_ISP2031:
2241 ha->device_type |= DT_ISP2031; 2287 ha->device_type |= DT_ISP2031;
2242 ha->device_type |= DT_ZIO_SUPPORTED; 2288 ha->device_type |= DT_ZIO_SUPPORTED;
@@ -2317,7 +2363,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2317 uint16_t req_length = 0, rsp_length = 0; 2363 uint16_t req_length = 0, rsp_length = 0;
2318 struct req_que *req = NULL; 2364 struct req_que *req = NULL;
2319 struct rsp_que *rsp = NULL; 2365 struct rsp_que *rsp = NULL;
2320
2321 bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); 2366 bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
2322 sht = &qla2xxx_driver_template; 2367 sht = &qla2xxx_driver_template;
2323 if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || 2368 if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
@@ -2330,7 +2375,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2330 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8021 || 2375 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8021 ||
2331 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2031 || 2376 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2031 ||
2332 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 || 2377 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 ||
2333 pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001) { 2378 pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001 ||
2379 pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044) {
2334 bars = pci_select_bars(pdev, IORESOURCE_MEM); 2380 bars = pci_select_bars(pdev, IORESOURCE_MEM);
2335 mem_only = 1; 2381 mem_only = 1;
2336 ql_dbg_pci(ql_dbg_init, pdev, 0x0007, 2382 ql_dbg_pci(ql_dbg_init, pdev, 0x0007,
@@ -2484,6 +2530,21 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2484 ha->flash_data_off = FARX_ACCESS_FLASH_DATA; 2530 ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
2485 ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF; 2531 ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
2486 ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA; 2532 ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
2533 } else if (IS_QLA8044(ha)) {
2534 ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
2535 ha->mbx_count = MAILBOX_REGISTER_COUNT;
2536 req_length = REQUEST_ENTRY_CNT_82XX;
2537 rsp_length = RESPONSE_ENTRY_CNT_82XX;
2538 ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
2539 ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
2540 ha->gid_list_info_size = 8;
2541 ha->optrom_size = OPTROM_SIZE_83XX;
2542 ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
2543 ha->isp_ops = &qla8044_isp_ops;
2544 ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
2545 ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
2546 ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
2547 ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
2487 } else if (IS_QLA83XX(ha)) { 2548 } else if (IS_QLA83XX(ha)) {
2488 ha->portnum = PCI_FUNC(ha->pdev->devfn); 2549 ha->portnum = PCI_FUNC(ha->pdev->devfn);
2489 ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400; 2550 ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
@@ -2676,7 +2737,7 @@ que_init:
2676 rsp->rsp_q_out = &ha->iobase->ispfx00.rsp_q_out; 2737 rsp->rsp_q_out = &ha->iobase->ispfx00.rsp_q_out;
2677 } 2738 }
2678 2739
2679 if (IS_QLA82XX(ha)) { 2740 if (IS_P3P_TYPE(ha)) {
2680 req->req_q_out = &ha->iobase->isp82.req_q_out[0]; 2741 req->req_q_out = &ha->iobase->isp82.req_q_out[0];
2681 rsp->rsp_q_in = &ha->iobase->isp82.rsp_q_in[0]; 2742 rsp->rsp_q_in = &ha->iobase->isp82.rsp_q_in[0];
2682 rsp->rsp_q_out = &ha->iobase->isp82.rsp_q_out[0]; 2743 rsp->rsp_q_out = &ha->iobase->isp82.rsp_q_out[0];
@@ -2709,6 +2770,14 @@ que_init:
2709 qla82xx_idc_unlock(ha); 2770 qla82xx_idc_unlock(ha);
2710 ql_log(ql_log_fatal, base_vha, 0x00d7, 2771 ql_log(ql_log_fatal, base_vha, 0x00d7,
2711 "HW State: FAILED.\n"); 2772 "HW State: FAILED.\n");
2773 } else if (IS_QLA8044(ha)) {
2774 qla8044_idc_lock(ha);
2775 qla8044_wr_direct(base_vha,
2776 QLA8044_CRB_DEV_STATE_INDEX,
2777 QLA8XXX_DEV_FAILED);
2778 qla8044_idc_unlock(ha);
2779 ql_log(ql_log_fatal, base_vha, 0x0150,
2780 "HW State: FAILED.\n");
2712 } 2781 }
2713 2782
2714 ret = -ENODEV; 2783 ret = -ENODEV;
@@ -2881,8 +2950,13 @@ probe_hw_failed:
2881 qla82xx_clear_drv_active(ha); 2950 qla82xx_clear_drv_active(ha);
2882 qla82xx_idc_unlock(ha); 2951 qla82xx_idc_unlock(ha);
2883 } 2952 }
2953 if (IS_QLA8044(ha)) {
2954 qla8044_idc_lock(ha);
2955 qla8044_clear_drv_active(base_vha);
2956 qla8044_idc_unlock(ha);
2957 }
2884iospace_config_failed: 2958iospace_config_failed:
2885 if (IS_QLA82XX(ha)) { 2959 if (IS_P3P_TYPE(ha)) {
2886 if (!ha->nx_pcibase) 2960 if (!ha->nx_pcibase)
2887 iounmap((device_reg_t __iomem *)ha->nx_pcibase); 2961 iounmap((device_reg_t __iomem *)ha->nx_pcibase);
2888 if (!ql2xdbwr) 2962 if (!ql2xdbwr)
@@ -3061,6 +3135,11 @@ qla2x00_remove_one(struct pci_dev *pdev)
3061 3135
3062 scsi_host_put(base_vha->host); 3136 scsi_host_put(base_vha->host);
3063 3137
3138 if (IS_QLA8044(ha)) {
3139 qla8044_idc_lock(ha);
3140 qla8044_clear_drv_active(base_vha);
3141 qla8044_idc_unlock(ha);
3142 }
3064 if (IS_QLA82XX(ha)) { 3143 if (IS_QLA82XX(ha)) {
3065 qla82xx_idc_lock(ha); 3144 qla82xx_idc_lock(ha);
3066 qla82xx_clear_drv_active(ha); 3145 qla82xx_clear_drv_active(ha);
@@ -3284,7 +3363,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
3284 if (!ha->srb_mempool) 3363 if (!ha->srb_mempool)
3285 goto fail_free_gid_list; 3364 goto fail_free_gid_list;
3286 3365
3287 if (IS_QLA82XX(ha)) { 3366 if (IS_P3P_TYPE(ha)) {
3288 /* Allocate cache for CT6 Ctx. */ 3367 /* Allocate cache for CT6 Ctx. */
3289 if (!ctx_cachep) { 3368 if (!ctx_cachep) {
3290 ctx_cachep = kmem_cache_create("qla2xxx_ctx", 3369 ctx_cachep = kmem_cache_create("qla2xxx_ctx",
@@ -3318,7 +3397,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
3318 "init_cb=%p gid_list=%p, srb_mempool=%p s_dma_pool=%p.\n", 3397 "init_cb=%p gid_list=%p, srb_mempool=%p s_dma_pool=%p.\n",
3319 ha->init_cb, ha->gid_list, ha->srb_mempool, ha->s_dma_pool); 3398 ha->init_cb, ha->gid_list, ha->srb_mempool, ha->s_dma_pool);
3320 3399
3321 if (IS_QLA82XX(ha) || ql2xenabledif) { 3400 if (IS_P3P_TYPE(ha) || ql2xenabledif) {
3322 ha->dl_dma_pool = dma_pool_create(name, &ha->pdev->dev, 3401 ha->dl_dma_pool = dma_pool_create(name, &ha->pdev->dev,
3323 DSD_LIST_DMA_POOL_SIZE, 8, 0); 3402 DSD_LIST_DMA_POOL_SIZE, 8, 0);
3324 if (!ha->dl_dma_pool) { 3403 if (!ha->dl_dma_pool) {
@@ -3526,7 +3605,7 @@ fail:
3526* Frees fw dump stuff. 3605* Frees fw dump stuff.
3527* 3606*
3528* Input: 3607* Input:
3529* ha = adapter block pointer. 3608* ha = adapter block pointer
3530*/ 3609*/
3531static void 3610static void
3532qla2x00_free_fw_dump(struct qla_hw_data *ha) 3611qla2x00_free_fw_dump(struct qla_hw_data *ha)
@@ -4693,17 +4772,33 @@ qla2x00_do_dpc(void *data)
4693 4772
4694 qla2x00_do_work(base_vha); 4773 qla2x00_do_work(base_vha);
4695 4774
4696 if (IS_QLA82XX(ha)) { 4775 if (IS_P3P_TYPE(ha)) {
4697 if (test_and_clear_bit(ISP_UNRECOVERABLE, 4776 if (IS_QLA8044(ha)) {
4698 &base_vha->dpc_flags)) { 4777 if (test_and_clear_bit(ISP_UNRECOVERABLE,
4699 qla82xx_idc_lock(ha); 4778 &base_vha->dpc_flags)) {
4700 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 4779 qla8044_idc_lock(ha);
4701 QLA8XXX_DEV_FAILED); 4780 qla8044_wr_direct(base_vha,
4702 qla82xx_idc_unlock(ha); 4781 QLA8044_CRB_DEV_STATE_INDEX,
4703 ql_log(ql_log_info, base_vha, 0x4004, 4782 QLA8XXX_DEV_FAILED);
4704 "HW State: FAILED.\n"); 4783 qla8044_idc_unlock(ha);
4705 qla82xx_device_state_handler(base_vha); 4784 ql_log(ql_log_info, base_vha, 0x4004,
4706 continue; 4785 "HW State: FAILED.\n");
4786 qla8044_device_state_handler(base_vha);
4787 continue;
4788 }
4789
4790 } else {
4791 if (test_and_clear_bit(ISP_UNRECOVERABLE,
4792 &base_vha->dpc_flags)) {
4793 qla82xx_idc_lock(ha);
4794 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
4795 QLA8XXX_DEV_FAILED);
4796 qla82xx_idc_unlock(ha);
4797 ql_log(ql_log_info, base_vha, 0x0151,
4798 "HW State: FAILED.\n");
4799 qla82xx_device_state_handler(base_vha);
4800 continue;
4801 }
4707 } 4802 }
4708 4803
4709 if (test_and_clear_bit(FCOE_CTX_RESET_NEEDED, 4804 if (test_and_clear_bit(FCOE_CTX_RESET_NEEDED,
@@ -4803,16 +4898,26 @@ qla2x00_do_dpc(void *data)
4803 if (test_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags)) { 4898 if (test_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags)) {
4804 ql_dbg(ql_dbg_dpc, base_vha, 0x4009, 4899 ql_dbg(ql_dbg_dpc, base_vha, 0x4009,
4805 "Quiescence mode scheduled.\n"); 4900 "Quiescence mode scheduled.\n");
4806 if (IS_QLA82XX(ha)) { 4901 if (IS_P3P_TYPE(ha)) {
4807 qla82xx_device_state_handler(base_vha); 4902 if (IS_QLA82XX(ha))
4903 qla82xx_device_state_handler(base_vha);
4904 if (IS_QLA8044(ha))
4905 qla8044_device_state_handler(base_vha);
4808 clear_bit(ISP_QUIESCE_NEEDED, 4906 clear_bit(ISP_QUIESCE_NEEDED,
4809 &base_vha->dpc_flags); 4907 &base_vha->dpc_flags);
4810 if (!ha->flags.quiesce_owner) { 4908 if (!ha->flags.quiesce_owner) {
4811 qla2x00_perform_loop_resync(base_vha); 4909 qla2x00_perform_loop_resync(base_vha);
4812 4910 if (IS_QLA82XX(ha)) {
4813 qla82xx_idc_lock(ha); 4911 qla82xx_idc_lock(ha);
4814 qla82xx_clear_qsnt_ready(base_vha); 4912 qla82xx_clear_qsnt_ready(
4815 qla82xx_idc_unlock(ha); 4913 base_vha);
4914 qla82xx_idc_unlock(ha);
4915 } else if (IS_QLA8044(ha)) {
4916 qla8044_idc_lock(ha);
4917 qla8044_clear_qsnt_ready(
4918 base_vha);
4919 qla8044_idc_unlock(ha);
4920 }
4816 } 4921 }
4817 } else { 4922 } else {
4818 clear_bit(ISP_QUIESCE_NEEDED, 4923 clear_bit(ISP_QUIESCE_NEEDED,
@@ -4986,10 +5091,13 @@ qla2x00_timer(scsi_qla_host_t *vha)
4986 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); 5091 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
4987 5092
4988 /* Make sure qla82xx_watchdog is run only for physical port */ 5093 /* Make sure qla82xx_watchdog is run only for physical port */
4989 if (!vha->vp_idx && IS_QLA82XX(ha)) { 5094 if (!vha->vp_idx && IS_P3P_TYPE(ha)) {
4990 if (test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) 5095 if (test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags))
4991 start_dpc++; 5096 start_dpc++;
4992 qla82xx_watchdog(vha); 5097 if (IS_QLA82XX(ha))
5098 qla82xx_watchdog(vha);
5099 else if (IS_QLA8044(ha))
5100 qla8044_watchdog(vha);
4993 } 5101 }
4994 5102
4995 if (!vha->vp_idx && IS_QLAFX00(ha)) 5103 if (!vha->vp_idx && IS_QLAFX00(ha))
@@ -5069,7 +5177,7 @@ qla2x00_timer(scsi_qla_host_t *vha)
5069 /* Check if beacon LED needs to be blinked for physical host only */ 5177 /* Check if beacon LED needs to be blinked for physical host only */
5070 if (!vha->vp_idx && (ha->beacon_blink_led == 1)) { 5178 if (!vha->vp_idx && (ha->beacon_blink_led == 1)) {
5071 /* There is no beacon_blink function for ISP82xx */ 5179 /* There is no beacon_blink function for ISP82xx */
5072 if (!IS_QLA82XX(ha)) { 5180 if (!IS_P3P_TYPE(ha)) {
5073 set_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags); 5181 set_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags);
5074 start_dpc++; 5182 start_dpc++;
5075 } 5183 }
@@ -5513,6 +5621,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
5513 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8021) }, 5621 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8021) },
5514 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8031) }, 5622 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8031) },
5515 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) }, 5623 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) },
5624 { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8044) },
5516 { 0 }, 5625 { 0 },
5517}; 5626};
5518MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); 5627MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 3bef6736d885..2f2e029d41ea 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -565,7 +565,7 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
565 *start = FA_FLASH_LAYOUT_ADDR; 565 *start = FA_FLASH_LAYOUT_ADDR;
566 else if (IS_QLA81XX(ha)) 566 else if (IS_QLA81XX(ha))
567 *start = FA_FLASH_LAYOUT_ADDR_81; 567 *start = FA_FLASH_LAYOUT_ADDR_81;
568 else if (IS_QLA82XX(ha)) { 568 else if (IS_P3P_TYPE(ha)) {
569 *start = FA_FLASH_LAYOUT_ADDR_82; 569 *start = FA_FLASH_LAYOUT_ADDR_82;
570 goto end; 570 goto end;
571 } else if (IS_QLA83XX(ha)) { 571 } else if (IS_QLA83XX(ha)) {
@@ -719,7 +719,7 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
719 start = le32_to_cpu(region->start) >> 2; 719 start = le32_to_cpu(region->start) >> 2;
720 ql_dbg(ql_dbg_init, vha, 0x0049, 720 ql_dbg(ql_dbg_init, vha, 0x0049,
721 "FLT[%02x]: start=0x%x " 721 "FLT[%02x]: start=0x%x "
722 "end=0x%x size=0x%x.\n", le32_to_cpu(region->code), 722 "end=0x%x size=0x%x.\n", le32_to_cpu(region->code) & 0xff,
723 start, le32_to_cpu(region->end) >> 2, 723 start, le32_to_cpu(region->end) >> 2,
724 le32_to_cpu(region->size)); 724 le32_to_cpu(region->size));
725 725
@@ -741,13 +741,13 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
741 if (IS_QLA8031(ha)) 741 if (IS_QLA8031(ha))
742 break; 742 break;
743 ha->flt_region_vpd_nvram = start; 743 ha->flt_region_vpd_nvram = start;
744 if (IS_QLA82XX(ha)) 744 if (IS_P3P_TYPE(ha))
745 break; 745 break;
746 if (ha->flags.port0) 746 if (ha->flags.port0)
747 ha->flt_region_vpd = start; 747 ha->flt_region_vpd = start;
748 break; 748 break;
749 case FLT_REG_VPD_1: 749 case FLT_REG_VPD_1:
750 if (IS_QLA82XX(ha) || IS_QLA8031(ha)) 750 if (IS_P3P_TYPE(ha) || IS_QLA8031(ha))
751 break; 751 break;
752 if (!ha->flags.port0) 752 if (!ha->flags.port0)
753 ha->flt_region_vpd = start; 753 ha->flt_region_vpd = start;
@@ -789,9 +789,17 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
789 case FLT_REG_BOOT_CODE_82XX: 789 case FLT_REG_BOOT_CODE_82XX:
790 ha->flt_region_boot = start; 790 ha->flt_region_boot = start;
791 break; 791 break;
792 case FLT_REG_BOOT_CODE_8044:
793 if (IS_QLA8044(ha))
794 ha->flt_region_boot = start;
795 break;
792 case FLT_REG_FW_82XX: 796 case FLT_REG_FW_82XX:
793 ha->flt_region_fw = start; 797 ha->flt_region_fw = start;
794 break; 798 break;
799 case FLT_REG_CNA_FW:
800 if (IS_CNA_CAPABLE(ha))
801 ha->flt_region_fw = start;
802 break;
795 case FLT_REG_GOLD_FW_82XX: 803 case FLT_REG_GOLD_FW_82XX:
796 ha->flt_region_gold_fw = start; 804 ha->flt_region_gold_fw = start;
797 break; 805 break;
@@ -803,13 +811,13 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
803 ha->flt_region_vpd = start; 811 ha->flt_region_vpd = start;
804 break; 812 break;
805 case FLT_REG_FCOE_NVRAM_0: 813 case FLT_REG_FCOE_NVRAM_0:
806 if (!IS_QLA8031(ha)) 814 if (!(IS_QLA8031(ha) || IS_QLA8044(ha)))
807 break; 815 break;
808 if (ha->flags.port0) 816 if (ha->flags.port0)
809 ha->flt_region_nvram = start; 817 ha->flt_region_nvram = start;
810 break; 818 break;
811 case FLT_REG_FCOE_NVRAM_1: 819 case FLT_REG_FCOE_NVRAM_1:
812 if (!IS_QLA8031(ha)) 820 if (!(IS_QLA8031(ha) || IS_QLA8044(ha)))
813 break; 821 break;
814 if (!ha->flags.port0) 822 if (!ha->flags.port0)
815 ha->flt_region_nvram = start; 823 ha->flt_region_nvram = start;
@@ -883,7 +891,13 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vha)
883 mid = le16_to_cpu(fdt->man_id); 891 mid = le16_to_cpu(fdt->man_id);
884 fid = le16_to_cpu(fdt->id); 892 fid = le16_to_cpu(fdt->id);
885 ha->fdt_wrt_disable = fdt->wrt_disable_bits; 893 ha->fdt_wrt_disable = fdt->wrt_disable_bits;
886 ha->fdt_erase_cmd = flash_conf_addr(ha, 0x0300 | fdt->erase_cmd); 894 ha->fdt_wrt_enable = fdt->wrt_enable_bits;
895 ha->fdt_wrt_sts_reg_cmd = fdt->wrt_sts_reg_cmd;
896 if (IS_QLA8044(ha))
897 ha->fdt_erase_cmd = fdt->erase_cmd;
898 else
899 ha->fdt_erase_cmd =
900 flash_conf_addr(ha, 0x0300 | fdt->erase_cmd);
887 ha->fdt_block_size = le32_to_cpu(fdt->block_size); 901 ha->fdt_block_size = le32_to_cpu(fdt->block_size);
888 if (fdt->unprotect_sec_cmd) { 902 if (fdt->unprotect_sec_cmd) {
889 ha->fdt_unprotect_sec_cmd = flash_conf_addr(ha, 0x0300 | 903 ha->fdt_unprotect_sec_cmd = flash_conf_addr(ha, 0x0300 |
@@ -895,7 +909,7 @@ qla2xxx_get_fdt_info(scsi_qla_host_t *vha)
895 goto done; 909 goto done;
896no_flash_data: 910no_flash_data:
897 loc = locations[0]; 911 loc = locations[0];
898 if (IS_QLA82XX(ha)) { 912 if (IS_P3P_TYPE(ha)) {
899 ha->fdt_block_size = FLASH_BLK_SIZE_64K; 913 ha->fdt_block_size = FLASH_BLK_SIZE_64K;
900 goto done; 914 goto done;
901 } 915 }
@@ -946,7 +960,7 @@ qla2xxx_get_idc_param(scsi_qla_host_t *vha)
946 struct qla_hw_data *ha = vha->hw; 960 struct qla_hw_data *ha = vha->hw;
947 struct req_que *req = ha->req_q_map[0]; 961 struct req_que *req = ha->req_q_map[0];
948 962
949 if (!IS_QLA82XX(ha)) 963 if (!(IS_P3P_TYPE(ha)))
950 return; 964 return;
951 965
952 wptr = (uint32_t *)req->ring; 966 wptr = (uint32_t *)req->ring;
@@ -1008,6 +1022,9 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha)
1008 if (ha->flags.nic_core_reset_hdlr_active) 1022 if (ha->flags.nic_core_reset_hdlr_active)
1009 return; 1023 return;
1010 1024
1025 if (IS_QLA8044(ha))
1026 return;
1027
1011 ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr, 1028 ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr,
1012 ha->flt_region_npiv_conf << 2, sizeof(struct qla_npiv_header)); 1029 ha->flt_region_npiv_conf << 2, sizeof(struct qla_npiv_header));
1013 if (hdr.version == __constant_cpu_to_le16(0xffff)) 1030 if (hdr.version == __constant_cpu_to_le16(0xffff))
@@ -1302,7 +1319,7 @@ qla24xx_read_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr,
1302 uint32_t *dwptr; 1319 uint32_t *dwptr;
1303 struct qla_hw_data *ha = vha->hw; 1320 struct qla_hw_data *ha = vha->hw;
1304 1321
1305 if (IS_QLA82XX(ha)) 1322 if (IS_P3P_TYPE(ha))
1306 return buf; 1323 return buf;
1307 1324
1308 /* Dword reads to flash. */ 1325 /* Dword reads to flash. */
@@ -1360,7 +1377,7 @@ qla24xx_write_nvram_data(scsi_qla_host_t *vha, uint8_t *buf, uint32_t naddr,
1360 1377
1361 ret = QLA_SUCCESS; 1378 ret = QLA_SUCCESS;
1362 1379
1363 if (IS_QLA82XX(ha)) 1380 if (IS_P3P_TYPE(ha))
1364 return ret; 1381 return ret;
1365 1382
1366 /* Enable flash write. */ 1383 /* Enable flash write. */
@@ -1474,7 +1491,7 @@ qla2x00_beacon_blink(struct scsi_qla_host *vha)
1474 struct qla_hw_data *ha = vha->hw; 1491 struct qla_hw_data *ha = vha->hw;
1475 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; 1492 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
1476 1493
1477 if (IS_QLA82XX(ha)) 1494 if (IS_P3P_TYPE(ha))
1478 return; 1495 return;
1479 1496
1480 spin_lock_irqsave(&ha->hardware_lock, flags); 1497 spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -1752,7 +1769,7 @@ qla24xx_beacon_on(struct scsi_qla_host *vha)
1752 struct qla_hw_data *ha = vha->hw; 1769 struct qla_hw_data *ha = vha->hw;
1753 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 1770 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1754 1771
1755 if (IS_QLA82XX(ha)) 1772 if (IS_P3P_TYPE(ha))
1756 return QLA_SUCCESS; 1773 return QLA_SUCCESS;
1757 1774
1758 if (IS_QLA8031(ha) || IS_QLA81XX(ha)) 1775 if (IS_QLA8031(ha) || IS_QLA81XX(ha))
@@ -1804,7 +1821,7 @@ qla24xx_beacon_off(struct scsi_qla_host *vha)
1804 struct qla_hw_data *ha = vha->hw; 1821 struct qla_hw_data *ha = vha->hw;
1805 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 1822 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1806 1823
1807 if (IS_QLA82XX(ha)) 1824 if (IS_P3P_TYPE(ha))
1808 return QLA_SUCCESS; 1825 return QLA_SUCCESS;
1809 1826
1810 ha->beacon_blink_led = 0; 1827 ha->beacon_blink_led = 0;
@@ -2822,6 +2839,121 @@ qla2x00_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
2822} 2839}
2823 2840
2824int 2841int
2842qla82xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
2843{
2844 int ret = QLA_SUCCESS;
2845 uint32_t pcihdr, pcids;
2846 uint32_t *dcode;
2847 uint8_t *bcode;
2848 uint8_t code_type, last_image;
2849 struct qla_hw_data *ha = vha->hw;
2850
2851 if (!mbuf)
2852 return QLA_FUNCTION_FAILED;
2853
2854 memset(ha->bios_revision, 0, sizeof(ha->bios_revision));
2855 memset(ha->efi_revision, 0, sizeof(ha->efi_revision));
2856 memset(ha->fcode_revision, 0, sizeof(ha->fcode_revision));
2857 memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
2858
2859 dcode = mbuf;
2860
2861 /* Begin with first PCI expansion ROM header. */
2862 pcihdr = ha->flt_region_boot << 2;
2863 last_image = 1;
2864 do {
2865 /* Verify PCI expansion ROM header. */
2866 ha->isp_ops->read_optrom(vha, (uint8_t *)dcode, pcihdr,
2867 0x20 * 4);
2868 bcode = mbuf + (pcihdr % 4);
2869 if (bcode[0x0] != 0x55 || bcode[0x1] != 0xaa) {
2870 /* No signature */
2871 ql_log(ql_log_fatal, vha, 0x0154,
2872 "No matching ROM signature.\n");
2873 ret = QLA_FUNCTION_FAILED;
2874 break;
2875 }
2876
2877 /* Locate PCI data structure. */
2878 pcids = pcihdr + ((bcode[0x19] << 8) | bcode[0x18]);
2879
2880 ha->isp_ops->read_optrom(vha, (uint8_t *)dcode, pcids,
2881 0x20 * 4);
2882 bcode = mbuf + (pcihdr % 4);
2883
2884 /* Validate signature of PCI data structure. */
2885 if (bcode[0x0] != 'P' || bcode[0x1] != 'C' ||
2886 bcode[0x2] != 'I' || bcode[0x3] != 'R') {
2887 /* Incorrect header. */
2888 ql_log(ql_log_fatal, vha, 0x0155,
2889 "PCI data struct not found pcir_adr=%x.\n", pcids);
2890 ret = QLA_FUNCTION_FAILED;
2891 break;
2892 }
2893
2894 /* Read version */
2895 code_type = bcode[0x14];
2896 switch (code_type) {
2897 case ROM_CODE_TYPE_BIOS:
2898 /* Intel x86, PC-AT compatible. */
2899 ha->bios_revision[0] = bcode[0x12];
2900 ha->bios_revision[1] = bcode[0x13];
2901 ql_dbg(ql_dbg_init, vha, 0x0156,
2902 "Read BIOS %d.%d.\n",
2903 ha->bios_revision[1], ha->bios_revision[0]);
2904 break;
2905 case ROM_CODE_TYPE_FCODE:
2906 /* Open Firmware standard for PCI (FCode). */
2907 ha->fcode_revision[0] = bcode[0x12];
2908 ha->fcode_revision[1] = bcode[0x13];
2909 ql_dbg(ql_dbg_init, vha, 0x0157,
2910 "Read FCODE %d.%d.\n",
2911 ha->fcode_revision[1], ha->fcode_revision[0]);
2912 break;
2913 case ROM_CODE_TYPE_EFI:
2914 /* Extensible Firmware Interface (EFI). */
2915 ha->efi_revision[0] = bcode[0x12];
2916 ha->efi_revision[1] = bcode[0x13];
2917 ql_dbg(ql_dbg_init, vha, 0x0158,
2918 "Read EFI %d.%d.\n",
2919 ha->efi_revision[1], ha->efi_revision[0]);
2920 break;
2921 default:
2922 ql_log(ql_log_warn, vha, 0x0159,
2923 "Unrecognized code type %x at pcids %x.\n",
2924 code_type, pcids);
2925 break;
2926 }
2927
2928 last_image = bcode[0x15] & BIT_7;
2929
2930 /* Locate next PCI expansion ROM. */
2931 pcihdr += ((bcode[0x11] << 8) | bcode[0x10]) * 512;
2932 } while (!last_image);
2933
2934 /* Read firmware image information. */
2935 memset(ha->fw_revision, 0, sizeof(ha->fw_revision));
2936 dcode = mbuf;
2937 ha->isp_ops->read_optrom(vha, (uint8_t *)dcode, ha->flt_region_fw << 2,
2938 0x20);
2939 bcode = mbuf + (pcihdr % 4);
2940
2941 /* Validate signature of PCI data structure. */
2942 if (bcode[0x0] == 0x3 && bcode[0x1] == 0x0 &&
2943 bcode[0x2] == 0x40 && bcode[0x3] == 0x40) {
2944 ha->fw_revision[0] = bcode[0x4];
2945 ha->fw_revision[1] = bcode[0x5];
2946 ha->fw_revision[2] = bcode[0x6];
2947 ql_dbg(ql_dbg_init, vha, 0x015a,
2948 "Firmware revision %d.%d.%d\n",
2949 ha->fw_revision[0], ha->fw_revision[1],
2950 ha->fw_revision[2]);
2951 }
2952
2953 return ret;
2954}
2955
2956int
2825qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf) 2957qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
2826{ 2958{
2827 int ret = QLA_SUCCESS; 2959 int ret = QLA_SUCCESS;
@@ -2832,7 +2964,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
2832 int i; 2964 int i;
2833 struct qla_hw_data *ha = vha->hw; 2965 struct qla_hw_data *ha = vha->hw;
2834 2966
2835 if (IS_QLA82XX(ha)) 2967 if (IS_P3P_TYPE(ha))
2836 return ret; 2968 return ret;
2837 2969
2838 if (!mbuf) 2970 if (!mbuf)