aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSantosh Vernekar <santosh.vernekar@qlogic.com>2012-08-22 14:21:03 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-09-24 04:10:47 -0400
commit7d613ac6acec8c29e7aa3f80e28e8e982977a151 (patch)
treeeec782c42537c4658850ffb8982973f122e388a2
parent40129a4c6edc1753b9a537877b6a2eac9fc6c659 (diff)
[SCSI] qla2xxx: IDC implementation for ISP83xx.
Signed-off-by: Santosh Vernekar <santosh.vernekar@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c60
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c2
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h101
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h5
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h28
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c389
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c176
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c142
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c78
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.h15
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c684
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c28
13 files changed, 1621 insertions, 97 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index da804f487f21..f76424ef05b0 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -564,6 +564,7 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
564 struct qla_hw_data *ha = vha->hw; 564 struct qla_hw_data *ha = vha->hw;
565 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 565 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
566 int type; 566 int type;
567 uint32_t idc_control;
567 568
568 if (off != 0) 569 if (off != 0)
569 return -EINVAL; 570 return -EINVAL;
@@ -587,22 +588,36 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
587 scsi_unblock_requests(vha->host); 588 scsi_unblock_requests(vha->host);
588 break; 589 break;
589 case 0x2025d: 590 case 0x2025d:
590 if (!IS_QLA81XX(ha) || !IS_QLA8031(ha)) 591 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
591 return -EPERM; 592 return -EPERM;
592 593
593 ql_log(ql_log_info, vha, 0x706f, 594 ql_log(ql_log_info, vha, 0x706f,
594 "Issuing MPI reset.\n"); 595 "Issuing MPI reset.\n");
595 596
596 /* Make sure FC side is not in reset */ 597 if (IS_QLA83XX(ha)) {
597 qla2x00_wait_for_hba_online(vha); 598 uint32_t idc_control;
598 599
599 /* Issue MPI reset */ 600 qla83xx_idc_lock(vha, 0);
600 scsi_block_requests(vha->host); 601 __qla83xx_get_idc_control(vha, &idc_control);
601 if (qla81xx_restart_mpi_firmware(vha) != QLA_SUCCESS) 602 idc_control |= QLA83XX_IDC_GRACEFUL_RESET;
602 ql_log(ql_log_warn, vha, 0x7070, 603 __qla83xx_set_idc_control(vha, idc_control);
603 "MPI reset failed.\n"); 604 qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE,
604 scsi_unblock_requests(vha->host); 605 QLA8XXX_DEV_NEED_RESET);
605 break; 606 qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP);
607 qla83xx_idc_unlock(vha, 0);
608 break;
609 } else {
610 /* Make sure FC side is not in reset */
611 qla2x00_wait_for_hba_online(vha);
612
613 /* Issue MPI reset */
614 scsi_block_requests(vha->host);
615 if (qla81xx_restart_mpi_firmware(vha) != QLA_SUCCESS)
616 ql_log(ql_log_warn, vha, 0x7070,
617 "MPI reset failed.\n");
618 scsi_unblock_requests(vha->host);
619 break;
620 }
606 case 0x2025e: 621 case 0x2025e:
607 if (!IS_QLA82XX(ha) || vha != base_vha) { 622 if (!IS_QLA82XX(ha) || vha != base_vha) {
608 ql_log(ql_log_info, vha, 0x7071, 623 ql_log(ql_log_info, vha, 0x7071,
@@ -616,6 +631,29 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
616 qla2xxx_wake_dpc(vha); 631 qla2xxx_wake_dpc(vha);
617 qla2x00_wait_for_fcoe_ctx_reset(vha); 632 qla2x00_wait_for_fcoe_ctx_reset(vha);
618 break; 633 break;
634 case 0x2025f:
635 if (!IS_QLA8031(ha))
636 return -EPERM;
637 ql_log(ql_log_info, vha, 0x70bc,
638 "Disabling Reset by IDC control\n");
639 qla83xx_idc_lock(vha, 0);
640 __qla83xx_get_idc_control(vha, &idc_control);
641 idc_control |= QLA83XX_IDC_RESET_DISABLED;
642 __qla83xx_set_idc_control(vha, idc_control);
643 qla83xx_idc_unlock(vha, 0);
644 break;
645 case 0x20260:
646 if (!IS_QLA8031(ha))
647 return -EPERM;
648 ql_log(ql_log_info, vha, 0x70bd,
649 "Enabling Reset by IDC control\n");
650 qla83xx_idc_lock(vha, 0);
651 __qla83xx_get_idc_control(vha, &idc_control);
652 idc_control &= ~QLA83XX_IDC_RESET_DISABLED;
653 __qla83xx_set_idc_control(vha, idc_control);
654 qla83xx_idc_unlock(vha, 0);
655 break;
656
619 } 657 }
620 return count; 658 return count;
621} 659}
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index dac3427ebf24..6da13e26ccac 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -1364,7 +1364,7 @@ qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
1364 struct qla_hw_data *ha = vha->hw; 1364 struct qla_hw_data *ha = vha->hw;
1365 int rval = 0; 1365 int rval = 0;
1366 1366
1367 if (ha->flags.isp82xx_reset_hdlr_active) 1367 if (ha->flags.nic_core_reset_hdlr_active)
1368 return -EBUSY; 1368 return -EBUSY;
1369 1369
1370 rval = qla2x00_optrom_setup(bsg_job, vha, 0); 1370 rval = qla2x00_optrom_setup(bsg_job, vha, 0);
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 156f5341a7a3..55998f4fb3ae 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -11,18 +11,18 @@
11 * ---------------------------------------------------------------------- 11 * ----------------------------------------------------------------------
12 * | Level | Last Value Used | Holes | 12 * | Level | Last Value Used | Holes |
13 * ---------------------------------------------------------------------- 13 * ----------------------------------------------------------------------
14 * | Module Init and Probe | 0x0123 | 0x4b,0xba,0xfa | 14 * | Module Init and Probe | 0x0124 | 0x4b,0xba,0xfa |
15 * | Mailbox commands | 0x1140 | 0x111a-0x111b | 15 * | Mailbox commands | 0x114c | 0x111a-0x111b |
16 * | | | 0x112c-0x112e | 16 * | | | 0x112c-0x112e |
17 * | | | 0x113a | 17 * | | | 0x113a |
18 * | Device Discovery | 0x2087 | 0x2020-0x2022 | 18 * | Device Discovery | 0x2087 | 0x2020-0x2022 |
19 * | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 | 19 * | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 |
20 * | | | 0x302d-0x302e | 20 * | | | 0x302d-0x302e |
21 * | DPC Thread | 0x401c | 0x4002,0x4013 | 21 * | DPC Thread | 0x401c | 0x4002,0x4013 |
22 * | Async Events | 0x505f | 0x502b-0x502f | 22 * | Async Events | 0x506c | 0x502b-0x502f |
23 * | | | 0x5047,0x5052 | 23 * | | | 0x5047,0x5052 |
24 * | Timer Routines | 0x6011 | | 24 * | Timer Routines | 0x6011 | |
25 * | User Space Interactions | 0x70bb | 0x7018,0x702e, | 25 * | User Space Interactions | 0x70bd | 0x7018,0x702e, |
26 * | | | 0x7039,0x7045, | 26 * | | | 0x7039,0x7045, |
27 * | | | 0x7073-0x7075, | 27 * | | | 0x7073-0x7075, |
28 * | | | 0x708c, | 28 * | | | 0x708c, |
@@ -33,7 +33,7 @@
33 * | | | 0x800b,0x8039 | 33 * | | | 0x800b,0x8039 |
34 * | AER/EEH | 0x9011 | | 34 * | AER/EEH | 0x9011 | |
35 * | Virtual Port | 0xa007 | | 35 * | Virtual Port | 0xa007 | |
36 * | ISP82XX Specific | 0xb055 | 0xb024 | 36 * | ISP82XX Specific | 0xb080 | 0xb024 |
37 * | MultiQ | 0xc00c | | 37 * | MultiQ | 0xc00c | |
38 * | Misc | 0xd010 | | 38 * | Misc | 0xd010 | |
39 * | Target Mode | 0xe06f | | 39 * | Target Mode | 0xe06f | |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 7ff92ce42821..3d72beedf92f 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -115,6 +115,82 @@
115#define WRT_REG_DWORD(addr, data) writel(data,addr) 115#define WRT_REG_DWORD(addr, data) writel(data,addr)
116 116
117/* 117/*
118 * ISP83XX specific remote register addresses
119 */
120#define QLA83XX_LED_PORT0 0x00201320
121#define QLA83XX_LED_PORT1 0x00201328
122#define QLA83XX_IDC_DEV_STATE 0x22102384
123#define QLA83XX_IDC_MAJOR_VERSION 0x22102380
124#define QLA83XX_IDC_MINOR_VERSION 0x22102398
125#define QLA83XX_IDC_DRV_PRESENCE 0x22102388
126#define QLA83XX_IDC_DRIVER_ACK 0x2210238c
127#define QLA83XX_IDC_CONTROL 0x22102390
128#define QLA83XX_IDC_AUDIT 0x22102394
129#define QLA83XX_IDC_LOCK_RECOVERY 0x2210239c
130#define QLA83XX_DRIVER_LOCKID 0x22102104
131#define QLA83XX_DRIVER_LOCK 0x8111c028
132#define QLA83XX_DRIVER_UNLOCK 0x8111c02c
133#define QLA83XX_FLASH_LOCKID 0x22102100
134#define QLA83XX_FLASH_LOCK 0x8111c010
135#define QLA83XX_FLASH_UNLOCK 0x8111c014
136#define QLA83XX_DEV_PARTINFO1 0x221023e0
137#define QLA83XX_DEV_PARTINFO2 0x221023e4
138#define QLA83XX_FW_HEARTBEAT 0x221020b0
139#define QLA83XX_PEG_HALT_STATUS1 0x221020a8
140#define QLA83XX_PEG_HALT_STATUS2 0x221020ac
141
142/* 83XX: Macros defining 8200 AEN Reason codes */
143#define IDC_DEVICE_STATE_CHANGE BIT_0
144#define IDC_PEG_HALT_STATUS_CHANGE BIT_1
145#define IDC_NIC_FW_REPORTED_FAILURE BIT_2
146#define IDC_HEARTBEAT_FAILURE BIT_3
147
148/* 83XX: Macros defining 8200 AEN Error-levels */
149#define ERR_LEVEL_NON_FATAL 0x1
150#define ERR_LEVEL_RECOVERABLE_FATAL 0x2
151#define ERR_LEVEL_UNRECOVERABLE_FATAL 0x4
152
153/* 83XX: Macros for IDC Version */
154#define QLA83XX_SUPP_IDC_MAJOR_VERSION 0x01
155#define QLA83XX_SUPP_IDC_MINOR_VERSION 0x0
156
157/* 83XX: Macros for scheduling dpc tasks */
158#define QLA83XX_NIC_CORE_RESET 0x1
159#define QLA83XX_IDC_STATE_HANDLER 0x2
160#define QLA83XX_NIC_CORE_UNRECOVERABLE 0x3
161
162/* 83XX: Macros for defining IDC-Control bits */
163#define QLA83XX_IDC_RESET_DISABLED BIT_0
164#define QLA83XX_IDC_GRACEFUL_RESET BIT_1
165
166/* 83XX: Macros for different timeouts */
167#define QLA83XX_IDC_INITIALIZATION_TIMEOUT 30
168#define QLA83XX_IDC_RESET_ACK_TIMEOUT 10
169#define QLA83XX_MAX_LOCK_RECOVERY_WAIT (2 * HZ)
170
171/* 83XX: Macros for defining class in DEV-Partition Info register */
172#define QLA83XX_CLASS_TYPE_NONE 0x0
173#define QLA83XX_CLASS_TYPE_NIC 0x1
174#define QLA83XX_CLASS_TYPE_FCOE 0x2
175#define QLA83XX_CLASS_TYPE_ISCSI 0x3
176
177/* 83XX: Macros for IDC Lock-Recovery stages */
178#define IDC_LOCK_RECOVERY_STAGE1 0x1 /* Stage1: Intent for
179 * lock-recovery
180 */
181#define IDC_LOCK_RECOVERY_STAGE2 0x2 /* Stage2: Perform lock-recovery */
182
183/* 83XX: Macros for IDC Audit type */
184#define IDC_AUDIT_TIMESTAMP 0x0 /* IDC-AUDIT: Record timestamp of
185 * dev-state change to NEED-RESET
186 * or NEED-QUIESCENT
187 */
188#define IDC_AUDIT_COMPLETION 0x1 /* IDC-AUDIT: Record duration of
189 * reset-recovery completion is
190 * second
191 */
192
193/*
118 * The ISP2312 v2 chip cannot access the FLASH/GPIO registers via MMIO in an 194 * The ISP2312 v2 chip cannot access the FLASH/GPIO registers via MMIO in an
119 * 133Mhz slot. 195 * 133Mhz slot.
120 */ 196 */
@@ -596,6 +672,9 @@ typedef struct {
596#define MBA_DISCARD_RND_FRAME 0x8048 /* discard RND frame due to error. */ 672#define MBA_DISCARD_RND_FRAME 0x8048 /* discard RND frame due to error. */
597#define MBA_REJECTED_FCP_CMD 0x8049 /* rejected FCP_CMD. */ 673#define MBA_REJECTED_FCP_CMD 0x8049 /* rejected FCP_CMD. */
598 674
675/* 83XX FCoE specific */
676#define MBA_IDC_AEN 0x8200 /* FCoE: NIC Core state change AEN */
677
599/* ISP mailbox loopback echo diagnostic error code */ 678/* ISP mailbox loopback echo diagnostic error code */
600#define MBS_LB_RESET 0x17 679#define MBS_LB_RESET 0x17
601/* 680/*
@@ -2523,11 +2602,12 @@ struct qla_hw_data {
2523 uint32_t disable_msix_handshake :1; 2602 uint32_t disable_msix_handshake :1;
2524 uint32_t fcp_prio_enabled :1; 2603 uint32_t fcp_prio_enabled :1;
2525 uint32_t isp82xx_fw_hung:1; 2604 uint32_t isp82xx_fw_hung:1;
2605 uint32_t nic_core_hung:1;
2526 2606
2527 uint32_t quiesce_owner:1; 2607 uint32_t quiesce_owner:1;
2528 uint32_t thermal_supported:1; 2608 uint32_t thermal_supported:1;
2529 uint32_t isp82xx_reset_hdlr_active:1; 2609 uint32_t nic_core_reset_hdlr_active:1;
2530 uint32_t isp82xx_reset_owner:1; 2610 uint32_t nic_core_reset_owner:1;
2531 uint32_t isp82xx_no_md_cap:1; 2611 uint32_t isp82xx_no_md_cap:1;
2532 uint32_t host_shutting_down:1; 2612 uint32_t host_shutting_down:1;
2533 /* 30 bits */ 2613 /* 30 bits */
@@ -2912,8 +2992,8 @@ struct qla_hw_data {
2912 unsigned long mn_win_crb; 2992 unsigned long mn_win_crb;
2913 unsigned long ms_win_crb; 2993 unsigned long ms_win_crb;
2914 int qdr_sn_window; 2994 int qdr_sn_window;
2915 uint32_t nx_dev_init_timeout; 2995 uint32_t fcoe_dev_init_timeout;
2916 uint32_t nx_reset_timeout; 2996 uint32_t fcoe_reset_timeout;
2917 rwlock_t hw_lock; 2997 rwlock_t hw_lock;
2918 uint16_t portnum; /* port number */ 2998 uint16_t portnum; /* port number */
2919 int link_width; 2999 int link_width;
@@ -2935,6 +3015,19 @@ struct qla_hw_data {
2935 uint32_t md_dump_size; 3015 uint32_t md_dump_size;
2936 3016
2937 void *loop_id_map; 3017 void *loop_id_map;
3018
3019 /* QLA83XX IDC specific fields */
3020 uint32_t idc_audit_ts;
3021
3022 /* DPC low-priority workqueue */
3023 struct workqueue_struct *dpc_lp_wq;
3024 struct work_struct idc_aen;
3025 /* DPC high-priority workqueue */
3026 struct workqueue_struct *dpc_hp_wq;
3027 struct work_struct nic_core_reset;
3028 struct work_struct idc_state_handler;
3029 struct work_struct nic_core_unrecoverable;
3030
2938 struct qlt_hw_data tgt; 3031 struct qlt_hw_data tgt;
2939}; 3032};
2940 3033
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index a678ed5d6884..84543fe487cd 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1540,7 +1540,10 @@ struct access_chip_rsp_84xx {
1540/* 1540/*
1541 * ISP83xx mailbox commands 1541 * ISP83xx mailbox commands
1542 */ 1542 */
1543#define MBC_WRITE_REMOTE_REG 0x0001 /* Write remote register */ 1543#define MBC_WRITE_REMOTE_REG 0x0001 /* Write remote register */
1544#define MBC_READ_REMOTE_REG 0x0009 /* Read remote register */
1545#define MBC_RESTART_NIC_FIRMWARE 0x003d /* Restart NIC firmware */
1546#define MBC_SET_ACCESS_CONTROL 0x003e /* Access control command */
1544 1547
1545/* Flash access control option field bit definitions */ 1548/* Flash access control option field bit definitions */
1546#define FAC_OPT_FORCE_SEMAPHORE BIT_15 1549#define FAC_OPT_FORCE_SEMAPHORE BIT_15
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index d7588adc768b..98c187da2c91 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -76,6 +76,13 @@ extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);
76 76
77extern fc_port_t * 77extern fc_port_t *
78qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t ); 78qla2x00_alloc_fcport(scsi_qla_host_t *, gfp_t );
79
80extern int __qla83xx_set_idc_control(scsi_qla_host_t *, uint32_t);
81extern int __qla83xx_get_idc_control(scsi_qla_host_t *, uint32_t *);
82extern void qla83xx_idc_audit(scsi_qla_host_t *, int);
83extern int qla83xx_nic_core_reset(scsi_qla_host_t *);
84extern void qla83xx_reset_ownership(scsi_qla_host_t *);
85
79/* 86/*
80 * Global Data in qla_os.c source file. 87 * Global Data in qla_os.c source file.
81 */ 88 */
@@ -133,6 +140,20 @@ extern void qla2x00_relogin(struct scsi_qla_host *);
133extern void qla2x00_do_work(struct scsi_qla_host *); 140extern void qla2x00_do_work(struct scsi_qla_host *);
134extern void qla2x00_free_fcports(struct scsi_qla_host *); 141extern void qla2x00_free_fcports(struct scsi_qla_host *);
135 142
143extern void qla83xx_schedule_work(scsi_qla_host_t *, int);
144extern void qla83xx_service_idc_aen(struct work_struct *);
145extern void qla83xx_nic_core_unrecoverable_work(struct work_struct *);
146extern void qla83xx_idc_state_handler_work(struct work_struct *);
147extern void qla83xx_nic_core_reset_work(struct work_struct *);
148
149extern void qla83xx_idc_lock(scsi_qla_host_t *, uint16_t);
150extern void qla83xx_idc_unlock(scsi_qla_host_t *, uint16_t);
151extern int qla83xx_idc_state_handler(scsi_qla_host_t *);
152extern int qla83xx_set_drv_presence(scsi_qla_host_t *vha);
153extern int __qla83xx_set_drv_presence(scsi_qla_host_t *vha);
154extern int qla83xx_clear_drv_presence(scsi_qla_host_t *vha);
155extern int __qla83xx_clear_drv_presence(scsi_qla_host_t *vha);
156
136/* 157/*
137 * Global Functions in qla_mid.c source file. 158 * Global Functions in qla_mid.c source file.
138 */ 159 */
@@ -421,7 +442,11 @@ extern void qla24xx_beacon_blink(struct scsi_qla_host *);
421extern void qla83xx_beacon_blink(struct scsi_qla_host *); 442extern void qla83xx_beacon_blink(struct scsi_qla_host *);
422extern int qla82xx_beacon_on(struct scsi_qla_host *); 443extern int qla82xx_beacon_on(struct scsi_qla_host *);
423extern int qla82xx_beacon_off(struct scsi_qla_host *); 444extern int qla82xx_beacon_off(struct scsi_qla_host *);
424extern int qla83xx_write_remote_reg(struct scsi_qla_host *, uint32_t, uint32_t); 445extern int qla83xx_wr_reg(scsi_qla_host_t *, uint32_t, uint32_t);
446extern int qla83xx_rd_reg(scsi_qla_host_t *, uint32_t, uint32_t *);
447extern int qla83xx_restart_nic_firmware(scsi_qla_host_t *);
448extern int qla83xx_access_control(scsi_qla_host_t *, uint16_t, uint32_t,
449 uint32_t, uint16_t *);
425 450
426extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *, 451extern uint8_t *qla2x00_read_optrom_data(struct scsi_qla_host *, uint8_t *,
427 uint32_t, uint32_t); 452 uint32_t, uint32_t);
@@ -582,6 +607,7 @@ extern uint32_t qla82xx_wait_for_state_change(scsi_qla_host_t *, uint32_t);
582extern int qla82xx_idc_lock(struct qla_hw_data *); 607extern int qla82xx_idc_lock(struct qla_hw_data *);
583extern void qla82xx_idc_unlock(struct qla_hw_data *); 608extern void qla82xx_idc_unlock(struct qla_hw_data *);
584extern int qla82xx_device_state_handler(scsi_qla_host_t *); 609extern int qla82xx_device_state_handler(scsi_qla_host_t *);
610extern void qla8xxx_dev_failed_handler(scsi_qla_host_t *);
585extern void qla82xx_clear_qsnt_ready(scsi_qla_host_t *); 611extern void qla82xx_clear_qsnt_ready(scsi_qla_host_t *);
586 612
587extern void qla2x00_set_model_info(scsi_qla_host_t *, uint8_t *, 613extern void qla2x00_set_model_info(scsi_qla_host_t *, uint8_t *,
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index fa39411597f9..590238d878f6 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -429,6 +429,71 @@ qla2x00_async_adisc_done(struct scsi_qla_host *vha, fc_port_t *fcport,
429/* QLogic ISP2x00 Hardware Support Functions. */ 429/* QLogic ISP2x00 Hardware Support Functions. */
430/****************************************************************************/ 430/****************************************************************************/
431 431
432int
433qla83xx_nic_core_fw_load(scsi_qla_host_t *vha)
434{
435 int rval = QLA_SUCCESS;
436 struct qla_hw_data *ha = vha->hw;
437 uint32_t idc_major_ver, idc_minor_ver;
438
439 qla83xx_idc_lock(vha, 0);
440
441 /* SV: TODO: Assign initialization timeout from
442 * flash-info / other param
443 */
444 ha->fcoe_dev_init_timeout = QLA83XX_IDC_INITIALIZATION_TIMEOUT;
445 ha->fcoe_reset_timeout = QLA83XX_IDC_RESET_ACK_TIMEOUT;
446
447 /* Set our fcoe function presence */
448 if (__qla83xx_set_drv_presence(vha) != QLA_SUCCESS) {
449 ql_dbg(ql_dbg_p3p, vha, 0xb077,
450 "Error while setting DRV-Presence.\n");
451 rval = QLA_FUNCTION_FAILED;
452 goto exit;
453 }
454
455 /* Decide the reset ownership */
456 qla83xx_reset_ownership(vha);
457
458 /*
459 * On first protocol driver load:
460 * Init-Owner: Set IDC-Major-Version and Clear IDC-Lock-Recovery
461 * register.
462 * Others: Check compatibility with current IDC Major version.
463 */
464 qla83xx_rd_reg(vha, QLA83XX_IDC_MAJOR_VERSION, &idc_major_ver);
465 if (ha->flags.nic_core_reset_owner) {
466 /* Set IDC Major version */
467 idc_major_ver = QLA83XX_SUPP_IDC_MAJOR_VERSION;
468 qla83xx_wr_reg(vha, QLA83XX_IDC_MAJOR_VERSION, idc_major_ver);
469
470 /* Clearing IDC-Lock-Recovery register */
471 qla83xx_wr_reg(vha, QLA83XX_IDC_LOCK_RECOVERY, 0);
472 } else if (idc_major_ver != QLA83XX_SUPP_IDC_MAJOR_VERSION) {
473 /*
474 * Clear further IDC participation if we are not compatible with
475 * the current IDC Major Version.
476 */
477 ql_log(ql_log_warn, vha, 0xb07d,
478 "Failing load, idc_major_ver=%d, expected_major_ver=%d.\n",
479 idc_major_ver, QLA83XX_SUPP_IDC_MAJOR_VERSION);
480 __qla83xx_clear_drv_presence(vha);
481 rval = QLA_FUNCTION_FAILED;
482 goto exit;
483 }
484 /* Each function sets its supported Minor version. */
485 qla83xx_rd_reg(vha, QLA83XX_IDC_MINOR_VERSION, &idc_minor_ver);
486 idc_minor_ver |= (QLA83XX_SUPP_IDC_MINOR_VERSION << (ha->portnum * 2));
487 qla83xx_wr_reg(vha, QLA83XX_IDC_MINOR_VERSION, idc_minor_ver);
488
489 rval = qla83xx_idc_state_handler(vha);
490
491exit:
492 qla83xx_idc_unlock(vha, 0);
493
494 return rval;
495}
496
432/* 497/*
433* qla2x00_initialize_adapter 498* qla2x00_initialize_adapter
434* Initialize board. 499* Initialize board.
@@ -537,6 +602,14 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
537 } 602 }
538 } 603 }
539 604
605 /* Load the NIC Core f/w if we are the first protocol driver. */
606 if (IS_QLA8031(ha)) {
607 rval = qla83xx_nic_core_fw_load(vha);
608 if (rval)
609 ql_log(ql_log_warn, vha, 0x0124,
610 "Error in initializing NIC Core f/w.\n");
611 }
612
540 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha)) 613 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha))
541 qla24xx_read_fcp_prio_cfg(vha); 614 qla24xx_read_fcp_prio_cfg(vha);
542 615
@@ -3736,6 +3809,307 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha)
3736 spin_unlock_irqrestore(&ha->vport_slock, flags); 3809 spin_unlock_irqrestore(&ha->vport_slock, flags);
3737} 3810}
3738 3811
3812/* Assumes idc_lock always held on entry */
3813void
3814qla83xx_reset_ownership(scsi_qla_host_t *vha)
3815{
3816 struct qla_hw_data *ha = vha->hw;
3817 uint32_t drv_presence, drv_presence_mask;
3818 uint32_t dev_part_info1, dev_part_info2, class_type;
3819 uint32_t class_type_mask = 0x3;
3820 uint16_t fcoe_other_function = 0xffff, i;
3821
3822 qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
3823
3824 qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO1, &dev_part_info1);
3825 qla83xx_rd_reg(vha, QLA83XX_DEV_PARTINFO2, &dev_part_info2);
3826 for (i = 0; i < 8; i++) {
3827 class_type = ((dev_part_info1 >> (i * 4)) & class_type_mask);
3828 if ((class_type == QLA83XX_CLASS_TYPE_FCOE) &&
3829 (i != ha->portnum)) {
3830 fcoe_other_function = i;
3831 break;
3832 }
3833 }
3834 if (fcoe_other_function == 0xffff) {
3835 for (i = 0; i < 8; i++) {
3836 class_type = ((dev_part_info2 >> (i * 4)) &
3837 class_type_mask);
3838 if ((class_type == QLA83XX_CLASS_TYPE_FCOE) &&
3839 ((i + 8) != ha->portnum)) {
3840 fcoe_other_function = i + 8;
3841 break;
3842 }
3843 }
3844 }
3845 /*
3846 * Prepare drv-presence mask based on fcoe functions present.
3847 * However consider only valid physical fcoe function numbers (0-15).
3848 */
3849 drv_presence_mask = ~((1 << (ha->portnum)) |
3850 ((fcoe_other_function == 0xffff) ?
3851 0 : (1 << (fcoe_other_function))));
3852
3853 /* We are the reset owner iff:
3854 * - No other protocol drivers present.
3855 * - This is the lowest among fcoe functions. */
3856 if (!(drv_presence & drv_presence_mask) &&
3857 (ha->portnum < fcoe_other_function)) {
3858 ql_dbg(ql_dbg_p3p, vha, 0xb07f,
3859 "This host is Reset owner.\n");
3860 ha->flags.nic_core_reset_owner = 1;
3861 }
3862}
3863
3864int
3865__qla83xx_set_drv_ack(scsi_qla_host_t *vha)
3866{
3867 int rval = QLA_SUCCESS;
3868 struct qla_hw_data *ha = vha->hw;
3869 uint32_t drv_ack;
3870
3871 rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRIVER_ACK, &drv_ack);
3872 if (rval == QLA_SUCCESS) {
3873 drv_ack |= (1 << ha->portnum);
3874 rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRIVER_ACK, drv_ack);
3875 }
3876
3877 return rval;
3878}
3879
3880int
3881qla83xx_set_drv_ack(scsi_qla_host_t *vha)
3882{
3883 int rval = QLA_SUCCESS;
3884
3885 qla83xx_idc_lock(vha, 0);
3886 rval = __qla83xx_set_drv_ack(vha);
3887 qla83xx_idc_unlock(vha, 0);
3888
3889 return rval;
3890}
3891
3892int
3893__qla83xx_clear_drv_ack(scsi_qla_host_t *vha)
3894{
3895 int rval = QLA_SUCCESS;
3896 struct qla_hw_data *ha = vha->hw;
3897 uint32_t drv_ack;
3898
3899 rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRIVER_ACK, &drv_ack);
3900 if (rval == QLA_SUCCESS) {
3901 drv_ack &= ~(1 << ha->portnum);
3902 rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRIVER_ACK, drv_ack);
3903 }
3904
3905 return rval;
3906}
3907
3908int
3909qla83xx_clear_drv_ack(scsi_qla_host_t *vha)
3910{
3911 int rval = QLA_SUCCESS;
3912
3913 qla83xx_idc_lock(vha, 0);
3914 rval = __qla83xx_clear_drv_ack(vha);
3915 qla83xx_idc_unlock(vha, 0);
3916
3917 return rval;
3918}
3919
3920const char *
3921qla83xx_dev_state_to_string(uint32_t dev_state)
3922{
3923 switch (dev_state) {
3924 case QLA8XXX_DEV_COLD:
3925 return "COLD/RE-INIT";
3926 case QLA8XXX_DEV_INITIALIZING:
3927 return "INITIALIZING";
3928 case QLA8XXX_DEV_READY:
3929 return "READY";
3930 case QLA8XXX_DEV_NEED_RESET:
3931 return "NEED RESET";
3932 case QLA8XXX_DEV_NEED_QUIESCENT:
3933 return "NEED QUIESCENT";
3934 case QLA8XXX_DEV_FAILED:
3935 return "FAILED";
3936 case QLA8XXX_DEV_QUIESCENT:
3937 return "QUIESCENT";
3938 default:
3939 return "Unknown";
3940 }
3941}
3942
3943/* Assumes idc-lock always held on entry */
3944void
3945qla83xx_idc_audit(scsi_qla_host_t *vha, int audit_type)
3946{
3947 struct qla_hw_data *ha = vha->hw;
3948 uint32_t idc_audit_reg = 0, duration_secs = 0;
3949
3950 switch (audit_type) {
3951 case IDC_AUDIT_TIMESTAMP:
3952 ha->idc_audit_ts = (jiffies_to_msecs(jiffies) / 1000);
3953 idc_audit_reg = (ha->portnum) |
3954 (IDC_AUDIT_TIMESTAMP << 7) | (ha->idc_audit_ts << 8);
3955 qla83xx_wr_reg(vha, QLA83XX_IDC_AUDIT, idc_audit_reg);
3956 break;
3957
3958 case IDC_AUDIT_COMPLETION:
3959 duration_secs = ((jiffies_to_msecs(jiffies) -
3960 jiffies_to_msecs(ha->idc_audit_ts)) / 1000);
3961 idc_audit_reg = (ha->portnum) |
3962 (IDC_AUDIT_COMPLETION << 7) | (duration_secs << 8);
3963 qla83xx_wr_reg(vha, QLA83XX_IDC_AUDIT, idc_audit_reg);
3964 break;
3965
3966 default:
3967 ql_log(ql_log_warn, vha, 0xb078,
3968 "Invalid audit type specified.\n");
3969 break;
3970 }
3971}
3972
3973/* Assumes idc_lock always held on entry */
3974int
3975qla83xx_initiating_reset(scsi_qla_host_t *vha)
3976{
3977 struct qla_hw_data *ha = vha->hw;
3978 uint32_t idc_control, dev_state;
3979
3980 __qla83xx_get_idc_control(vha, &idc_control);
3981 if ((idc_control & QLA83XX_IDC_RESET_DISABLED)) {
3982 ql_log(ql_log_info, vha, 0xb080,
3983 "NIC Core reset has been disabled. idc-control=0x%x\n",
3984 idc_control);
3985 return QLA_FUNCTION_FAILED;
3986 }
3987
3988 /* Set NEED-RESET iff in READY state and we are the reset-owner */
3989 qla83xx_rd_reg(vha, QLA83XX_IDC_DEV_STATE, &dev_state);
3990 if (ha->flags.nic_core_reset_owner && dev_state == QLA8XXX_DEV_READY) {
3991 qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE,
3992 QLA8XXX_DEV_NEED_RESET);
3993 ql_log(ql_log_info, vha, 0xb056, "HW State: NEED RESET.\n");
3994 qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP);
3995 } else {
3996 const char *state = qla83xx_dev_state_to_string(dev_state);
3997 ql_log(ql_log_info, vha, 0xb057, "HW State: %s.\n", state);
3998
3999 /* SV: XXX: Is timeout required here? */
4000 /* Wait for IDC state change READY -> NEED_RESET */
4001 while (dev_state == QLA8XXX_DEV_READY) {
4002 qla83xx_idc_unlock(vha, 0);
4003 msleep(200);
4004 qla83xx_idc_lock(vha, 0);
4005 qla83xx_rd_reg(vha, QLA83XX_IDC_DEV_STATE, &dev_state);
4006 }
4007 }
4008
4009 /* Send IDC ack by writing to drv-ack register */
4010 __qla83xx_set_drv_ack(vha);
4011
4012 return QLA_SUCCESS;
4013}
4014
4015int
4016__qla83xx_set_idc_control(scsi_qla_host_t *vha, uint32_t idc_control)
4017{
4018 return qla83xx_wr_reg(vha, QLA83XX_IDC_CONTROL, idc_control);
4019}
4020
4021int
4022qla83xx_set_idc_control(scsi_qla_host_t *vha, uint32_t idc_control)
4023{
4024 int rval = QLA_SUCCESS;
4025
4026 qla83xx_idc_lock(vha, 0);
4027 rval = __qla83xx_set_idc_control(vha, idc_control);
4028 qla83xx_idc_unlock(vha, 0);
4029
4030 return rval;
4031}
4032
4033int
4034__qla83xx_get_idc_control(scsi_qla_host_t *vha, uint32_t *idc_control)
4035{
4036 return qla83xx_rd_reg(vha, QLA83XX_IDC_CONTROL, idc_control);
4037}
4038
4039int
4040qla83xx_get_idc_control(scsi_qla_host_t *vha, uint32_t *idc_control)
4041{
4042 int rval = QLA_SUCCESS;
4043
4044 qla83xx_idc_lock(vha, 0);
4045 rval = __qla83xx_get_idc_control(vha, idc_control);
4046 qla83xx_idc_unlock(vha, 0);
4047
4048 return rval;
4049}
4050
4051int
4052qla83xx_check_driver_presence(scsi_qla_host_t *vha)
4053{
4054 uint32_t drv_presence = 0;
4055 struct qla_hw_data *ha = vha->hw;
4056
4057 qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
4058 if (drv_presence & (1 << ha->portnum))
4059 return QLA_SUCCESS;
4060 else
4061 return QLA_TEST_FAILED;
4062}
4063
4064int
4065qla83xx_nic_core_reset(scsi_qla_host_t *vha)
4066{
4067 int rval = QLA_SUCCESS;
4068 struct qla_hw_data *ha = vha->hw;
4069
4070 ql_dbg(ql_dbg_p3p, vha, 0xb058,
4071 "Entered %s().\n", __func__);
4072
4073 if (vha->device_flags & DFLG_DEV_FAILED) {
4074 ql_log(ql_log_warn, vha, 0xb059,
4075 "Device in unrecoverable FAILED state.\n");
4076 return QLA_FUNCTION_FAILED;
4077 }
4078
4079 qla83xx_idc_lock(vha, 0);
4080
4081 if (qla83xx_check_driver_presence(vha) != QLA_SUCCESS) {
4082 ql_log(ql_log_warn, vha, 0xb05a,
4083 "Function=0x%x has been removed from IDC participation.\n",
4084 ha->portnum);
4085 rval = QLA_FUNCTION_FAILED;
4086 goto exit;
4087 }
4088
4089 qla83xx_reset_ownership(vha);
4090
4091 rval = qla83xx_initiating_reset(vha);
4092
4093 /*
4094 * Perform reset if we are the reset-owner,
4095 * else wait till IDC state changes to READY/FAILED.
4096 */
4097 if (rval == QLA_SUCCESS) {
4098 rval = qla83xx_idc_state_handler(vha);
4099
4100 if (rval == QLA_SUCCESS)
4101 ha->flags.nic_core_hung = 0;
4102 __qla83xx_clear_drv_ack(vha);
4103 }
4104
4105exit:
4106 qla83xx_idc_unlock(vha, 0);
4107
4108 ql_dbg(ql_dbg_p3p, vha, 0xb05b, "Exiting %s.\n", __func__);
4109
4110 return rval;
4111}
4112
3739/* 4113/*
3740* qla82xx_quiescent_state_cleanup 4114* qla82xx_quiescent_state_cleanup
3741* Description: This function will block the new I/Os 4115* Description: This function will block the new I/Os
@@ -3871,6 +4245,14 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
3871 struct req_que *req = ha->req_q_map[0]; 4245 struct req_que *req = ha->req_q_map[0];
3872 unsigned long flags; 4246 unsigned long flags;
3873 4247
4248 if (IS_QLA8031(ha)) {
4249 ql_dbg(ql_dbg_p3p, vha, 0xb05c,
4250 "Clearing fcoe driver presence.\n");
4251 if (qla83xx_clear_drv_presence(vha) != QLA_SUCCESS)
4252 ql_dbg(ql_dbg_p3p, vha, 0xb073,
4253 "Erro while clearing DRV-Presence.\n");
4254 }
4255
3874 if (vha->flags.online) { 4256 if (vha->flags.online) {
3875 qla2x00_abort_isp_cleanup(vha); 4257 qla2x00_abort_isp_cleanup(vha);
3876 4258
@@ -3982,6 +4364,13 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
3982 } 4364 }
3983 spin_unlock_irqrestore(&ha->vport_slock, flags); 4365 spin_unlock_irqrestore(&ha->vport_slock, flags);
3984 4366
4367 if (IS_QLA8031(ha)) {
4368 ql_dbg(ql_dbg_p3p, vha, 0xb05d,
4369 "Setting back fcoe driver presence.\n");
4370 if (qla83xx_set_drv_presence(vha) != QLA_SUCCESS)
4371 ql_dbg(ql_dbg_p3p, vha, 0xb074,
4372 "Error while setting DRV-Presence.\n");
4373 }
3985 } else { 4374 } else {
3986 ql_log(ql_log_warn, vha, 0x8023, "%s **** FAILED ****.\n", 4375 ql_log(ql_log_warn, vha, 0x8023, "%s **** FAILED ****.\n",
3987 __func__); 4376 __func__);
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 31ef8e25a61d..1222e937a5fe 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -332,6 +332,166 @@ qla2x00_get_link_speed_str(struct qla_hw_data *ha)
332 return link_speed; 332 return link_speed;
333} 333}
334 334
335void
336qla83xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
337{
338 struct qla_hw_data *ha = vha->hw;
339
340 /*
341 * 8200 AEN Interpretation:
342 * mb[0] = AEN code
343 * mb[1] = AEN Reason code
344 * mb[2] = LSW of Peg-Halt Status-1 Register
345 * mb[6] = MSW of Peg-Halt Status-1 Register
346 * mb[3] = LSW of Peg-Halt Status-2 register
347 * mb[7] = MSW of Peg-Halt Status-2 register
348 * mb[4] = IDC Device-State Register value
349 * mb[5] = IDC Driver-Presence Register value
350 */
351 ql_dbg(ql_dbg_async, vha, 0x506b, "AEN Code: mb[0] = 0x%x AEN reason: "
352 "mb[1] = 0x%x PH-status1: mb[2] = 0x%x PH-status1: mb[6] = 0x%x.\n",
353 mb[0], mb[1], mb[2], mb[6]);
354 ql_dbg(ql_dbg_async, vha, 0x506c, "PH-status2: mb[3] = 0x%x "
355 "PH-status2: mb[7] = 0x%x Device-State: mb[4] = 0x%x "
356 "Drv-Presence: mb[5] = 0x%x.\n", mb[3], mb[7], mb[4], mb[5]);
357
358 if (mb[1] & (IDC_PEG_HALT_STATUS_CHANGE | IDC_NIC_FW_REPORTED_FAILURE |
359 IDC_HEARTBEAT_FAILURE)) {
360 ha->flags.nic_core_hung = 1;
361 ql_log(ql_log_warn, vha, 0x5060,
362 "83XX: F/W Error Reported: Check if reset required.\n");
363
364 if (mb[1] & IDC_PEG_HALT_STATUS_CHANGE) {
365 uint32_t protocol_engine_id, fw_err_code, err_level;
366
367 /*
368 * IDC_PEG_HALT_STATUS_CHANGE interpretation:
369 * - PEG-Halt Status-1 Register:
370 * (LSW = mb[2], MSW = mb[6])
371 * Bits 0-7 = protocol-engine ID
372 * Bits 8-28 = f/w error code
373 * Bits 29-31 = Error-level
374 * Error-level 0x1 = Non-Fatal error
375 * Error-level 0x2 = Recoverable Fatal error
376 * Error-level 0x4 = UnRecoverable Fatal error
377 * - PEG-Halt Status-2 Register:
378 * (LSW = mb[3], MSW = mb[7])
379 */
380 protocol_engine_id = (mb[2] & 0xff);
381 fw_err_code = (((mb[2] & 0xff00) >> 8) |
382 ((mb[6] & 0x1fff) << 8));
383 err_level = ((mb[6] & 0xe000) >> 13);
384 ql_log(ql_log_warn, vha, 0x5061, "PegHalt Status-1 "
385 "Register: protocol_engine_id=0x%x "
386 "fw_err_code=0x%x err_level=0x%x.\n",
387 protocol_engine_id, fw_err_code, err_level);
388 ql_log(ql_log_warn, vha, 0x5062, "PegHalt Status-2 "
389 "Register: 0x%x%x.\n", mb[7], mb[3]);
390 if (err_level == ERR_LEVEL_NON_FATAL) {
391 ql_log(ql_log_warn, vha, 0x5063,
392 "Not a fatal error, f/w has recovered "
393 "iteself.\n");
394 } else if (err_level == ERR_LEVEL_RECOVERABLE_FATAL) {
395 ql_log(ql_log_fatal, vha, 0x5064,
396 "Recoverable Fatal error: Chip reset "
397 "required.\n");
398 qla83xx_schedule_work(vha,
399 QLA83XX_NIC_CORE_RESET);
400 } else if (err_level == ERR_LEVEL_UNRECOVERABLE_FATAL) {
401 ql_log(ql_log_fatal, vha, 0x5065,
402 "Unrecoverable Fatal error: Set FAILED "
403 "state, reboot required.\n");
404 qla83xx_schedule_work(vha,
405 QLA83XX_NIC_CORE_UNRECOVERABLE);
406 }
407 }
408
409 if (mb[1] & IDC_NIC_FW_REPORTED_FAILURE) {
410 uint16_t peg_fw_state, nw_interface_link_up;
411 uint16_t nw_interface_signal_detect, sfp_status;
412 uint16_t htbt_counter, htbt_monitor_enable;
413 uint16_t sfp_additonal_info, sfp_multirate;
414 uint16_t sfp_tx_fault, link_speed, dcbx_status;
415
416 /*
417 * IDC_NIC_FW_REPORTED_FAILURE interpretation:
418 * - PEG-to-FC Status Register:
419 * (LSW = mb[2], MSW = mb[6])
420 * Bits 0-7 = Peg-Firmware state
421 * Bit 8 = N/W Interface Link-up
422 * Bit 9 = N/W Interface signal detected
423 * Bits 10-11 = SFP Status
424 * SFP Status 0x0 = SFP+ transceiver not expected
425 * SFP Status 0x1 = SFP+ transceiver not present
426 * SFP Status 0x2 = SFP+ transceiver invalid
427 * SFP Status 0x3 = SFP+ transceiver present and
428 * valid
429 * Bits 12-14 = Heartbeat Counter
430 * Bit 15 = Heartbeat Monitor Enable
431 * Bits 16-17 = SFP Additional Info
432 * SFP info 0x0 = Unregocnized transceiver for
433 * Ethernet
434 * SFP info 0x1 = SFP+ brand validation failed
435 * SFP info 0x2 = SFP+ speed validation failed
436 * SFP info 0x3 = SFP+ access error
437 * Bit 18 = SFP Multirate
438 * Bit 19 = SFP Tx Fault
439 * Bits 20-22 = Link Speed
440 * Bits 23-27 = Reserved
441 * Bits 28-30 = DCBX Status
442 * DCBX Status 0x0 = DCBX Disabled
443 * DCBX Status 0x1 = DCBX Enabled
444 * DCBX Status 0x2 = DCBX Exchange error
445 * Bit 31 = Reserved
446 */
447 peg_fw_state = (mb[2] & 0x00ff);
448 nw_interface_link_up = ((mb[2] & 0x0100) >> 8);
449 nw_interface_signal_detect = ((mb[2] & 0x0200) >> 9);
450 sfp_status = ((mb[2] & 0x0c00) >> 10);
451 htbt_counter = ((mb[2] & 0x7000) >> 12);
452 htbt_monitor_enable = ((mb[2] & 0x8000) >> 15);
453 sfp_additonal_info = (mb[6] & 0x0003);
454 sfp_multirate = ((mb[6] & 0x0004) >> 2);
455 sfp_tx_fault = ((mb[6] & 0x0008) >> 3);
456 link_speed = ((mb[6] & 0x0070) >> 4);
457 dcbx_status = ((mb[6] & 0x7000) >> 12);
458
459 ql_log(ql_log_warn, vha, 0x5066,
460 "Peg-to-Fc Status Register:\n"
461 "peg_fw_state=0x%x, nw_interface_link_up=0x%x, "
462 "nw_interface_signal_detect=0x%x"
463 "\nsfp_statis=0x%x.\n ", peg_fw_state,
464 nw_interface_link_up, nw_interface_signal_detect,
465 sfp_status);
466 ql_log(ql_log_warn, vha, 0x5067,
467 "htbt_counter=0x%x, htbt_monitor_enable=0x%x, "
468 "sfp_additonal_info=0x%x, sfp_multirate=0x%x.\n ",
469 htbt_counter, htbt_monitor_enable,
470 sfp_additonal_info, sfp_multirate);
471 ql_log(ql_log_warn, vha, 0x5068,
472 "sfp_tx_fault=0x%x, link_state=0x%x, "
473 "dcbx_status=0x%x.\n", sfp_tx_fault, link_speed,
474 dcbx_status);
475
476 qla83xx_schedule_work(vha, QLA83XX_NIC_CORE_RESET);
477 }
478
479 if (mb[1] & IDC_HEARTBEAT_FAILURE) {
480 ql_log(ql_log_warn, vha, 0x5069,
481 "Heartbeat Failure encountered, chip reset "
482 "required.\n");
483
484 qla83xx_schedule_work(vha, QLA83XX_NIC_CORE_RESET);
485 }
486 }
487
488 if (mb[1] & IDC_DEVICE_STATE_CHANGE) {
489 ql_log(ql_log_info, vha, 0x506a,
490 "IDC Device-State changed = 0x%x.\n", mb[4]);
491 qla83xx_schedule_work(vha, MBA_IDC_AEN);
492 }
493}
494
335/** 495/**
336 * qla2x00_async_event() - Process aynchronous events. 496 * qla2x00_async_event() - Process aynchronous events.
337 * @ha: SCSI driver HA context 497 * @ha: SCSI driver HA context
@@ -825,8 +985,18 @@ skip_rio:
825 case MBA_IDC_COMPLETE: 985 case MBA_IDC_COMPLETE:
826 case MBA_IDC_NOTIFY: 986 case MBA_IDC_NOTIFY:
827 case MBA_IDC_TIME_EXT: 987 case MBA_IDC_TIME_EXT:
828 qla81xx_idc_event(vha, mb[0], mb[1]); 988 if (IS_QLA81XX(vha->hw))
989 qla81xx_idc_event(vha, mb[0], mb[1]);
990 break;
991
992 case MBA_IDC_AEN:
993 mb[4] = RD_REG_WORD(&reg24->mailbox4);
994 mb[5] = RD_REG_WORD(&reg24->mailbox5);
995 mb[6] = RD_REG_WORD(&reg24->mailbox6);
996 mb[7] = RD_REG_WORD(&reg24->mailbox7);
997 qla83xx_handle_8200_aen(vha, mb);
829 break; 998 break;
999
830 default: 1000 default:
831 ql_dbg(ql_dbg_async, vha, 0x5057, 1001 ql_dbg(ql_dbg_async, vha, 0x5057,
832 "Unknown AEN:%04x %04x %04x %04x\n", 1002 "Unknown AEN:%04x %04x %04x %04x\n",
@@ -2301,7 +2471,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
2301 unsigned long iter; 2471 unsigned long iter;
2302 uint32_t stat; 2472 uint32_t stat;
2303 uint32_t hccr; 2473 uint32_t hccr;
2304 uint16_t mb[4]; 2474 uint16_t mb[8];
2305 struct rsp_que *rsp; 2475 struct rsp_que *rsp;
2306 unsigned long flags; 2476 unsigned long flags;
2307 2477
@@ -2457,7 +2627,7 @@ qla24xx_msix_default(int irq, void *dev_id)
2457 int status; 2627 int status;
2458 uint32_t stat; 2628 uint32_t stat;
2459 uint32_t hccr; 2629 uint32_t hccr;
2460 uint16_t mb[4]; 2630 uint16_t mb[8];
2461 unsigned long flags; 2631 unsigned long flags;
2462 2632
2463 rsp = (struct rsp_que *) dev_id; 2633 rsp = (struct rsp_que *) dev_id;
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index f8a1a64c0ca7..1587b64b4bc3 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 (ha->flags.isp82xx_fw_hung) { 78 if (IS_QLA82XX(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,
@@ -232,7 +232,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
232 ha->flags.mbox_int = 0; 232 ha->flags.mbox_int = 0;
233 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 233 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
234 234
235 if (ha->flags.isp82xx_fw_hung) { 235 if ((IS_QLA82XX(ha) && ha->flags.isp82xx_fw_hung)) {
236 ha->flags.mbox_busy = 0; 236 ha->flags.mbox_busy = 0;
237 /* Setting Link-Down error */ 237 /* Setting Link-Down error */
238 mcp->mb[0] = MBS_LINK_DOWN_ERROR; 238 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
@@ -4741,7 +4741,7 @@ qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
4741} 4741}
4742 4742
4743int 4743int
4744qla83xx_write_remote_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data) 4744qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
4745{ 4745{
4746 int rval; 4746 int rval;
4747 struct qla_hw_data *ha = vha->hw; 4747 struct qla_hw_data *ha = vha->hw;
@@ -4814,3 +4814,139 @@ qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
4814 return rval; 4814 return rval;
4815} 4815}
4816 4816
4817int
4818qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
4819{
4820 int rval;
4821 mbx_cmd_t mc;
4822 mbx_cmd_t *mcp = &mc;
4823 struct qla_hw_data *ha = vha->hw;
4824 unsigned long retry_max_time = jiffies + (2 * HZ);
4825
4826 if (!IS_QLA83XX(ha))
4827 return QLA_FUNCTION_FAILED;
4828
4829 ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
4830
4831retry_rd_reg:
4832 mcp->mb[0] = MBC_READ_REMOTE_REG;
4833 mcp->mb[1] = LSW(reg);
4834 mcp->mb[2] = MSW(reg);
4835 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4836 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4837 mcp->tov = MBX_TOV_SECONDS;
4838 mcp->flags = 0;
4839 rval = qla2x00_mailbox_command(vha, mcp);
4840
4841 if (rval != QLA_SUCCESS) {
4842 ql_dbg(ql_dbg_mbx, vha, 0x114c,
4843 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4844 rval, mcp->mb[0], mcp->mb[1]);
4845 } else {
4846 *data = (mcp->mb[3] | (mcp->mb[4] << 16));
4847 if (*data == QLA8XXX_BAD_VALUE) {
4848 /*
4849 * During soft-reset CAMRAM register reads might
4850 * return 0xbad0bad0. So retry for MAX of 2 sec
4851 * while reading camram registers.
4852 */
4853 if (time_after(jiffies, retry_max_time)) {
4854 ql_dbg(ql_dbg_mbx, vha, 0x1141,
4855 "Failure to read CAMRAM register. "
4856 "data=0x%x.\n", *data);
4857 return QLA_FUNCTION_FAILED;
4858 }
4859 msleep(100);
4860 goto retry_rd_reg;
4861 }
4862 ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
4863 }
4864
4865 return rval;
4866}
4867
4868int
4869qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
4870{
4871 int rval;
4872 mbx_cmd_t mc;
4873 mbx_cmd_t *mcp = &mc;
4874 struct qla_hw_data *ha = vha->hw;
4875
4876 if (!IS_QLA83XX(ha))
4877 return QLA_FUNCTION_FAILED;
4878
4879 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
4880
4881 mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
4882 mcp->out_mb = MBX_0;
4883 mcp->in_mb = MBX_1|MBX_0;
4884 mcp->tov = MBX_TOV_SECONDS;
4885 mcp->flags = 0;
4886 rval = qla2x00_mailbox_command(vha, mcp);
4887
4888 if (rval != QLA_SUCCESS) {
4889 ql_dbg(ql_dbg_mbx, vha, 0x1144,
4890 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4891 rval, mcp->mb[0], mcp->mb[1]);
4892 ha->isp_ops->fw_dump(vha, 0);
4893 } else {
4894 ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
4895 }
4896
4897 return rval;
4898}
4899
4900int
4901qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
4902 uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
4903{
4904 int rval;
4905 mbx_cmd_t mc;
4906 mbx_cmd_t *mcp = &mc;
4907 uint8_t subcode = (uint8_t)options;
4908 struct qla_hw_data *ha = vha->hw;
4909
4910 if (!IS_QLA8031(ha))
4911 return QLA_FUNCTION_FAILED;
4912
4913 ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
4914
4915 mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
4916 mcp->mb[1] = options;
4917 mcp->out_mb = MBX_1|MBX_0;
4918 if (subcode & BIT_2) {
4919 mcp->mb[2] = LSW(start_addr);
4920 mcp->mb[3] = MSW(start_addr);
4921 mcp->mb[4] = LSW(end_addr);
4922 mcp->mb[5] = MSW(end_addr);
4923 mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
4924 }
4925 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4926 if (!(subcode & (BIT_2 | BIT_5)))
4927 mcp->in_mb |= MBX_4|MBX_3;
4928 mcp->tov = MBX_TOV_SECONDS;
4929 mcp->flags = 0;
4930 rval = qla2x00_mailbox_command(vha, mcp);
4931
4932 if (rval != QLA_SUCCESS) {
4933 ql_dbg(ql_dbg_mbx, vha, 0x1147,
4934 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
4935 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
4936 mcp->mb[4]);
4937 ha->isp_ops->fw_dump(vha, 0);
4938 } else {
4939 if (subcode & BIT_5)
4940 *sector_size = mcp->mb[1];
4941 else if (subcode & (BIT_6 | BIT_7)) {
4942 ql_dbg(ql_dbg_mbx, vha, 0x1148,
4943 "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
4944 } else if (subcode & (BIT_3 | BIT_4)) {
4945 ql_dbg(ql_dbg_mbx, vha, 0x1149,
4946 "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
4947 }
4948 ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
4949 }
4950
4951 return rval;
4952}
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 642aea04faa7..75cdf200f453 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -2355,7 +2355,7 @@ qla82xx_need_reset(struct qla_hw_data *ha)
2355 uint32_t drv_state; 2355 uint32_t drv_state;
2356 int rval; 2356 int rval;
2357 2357
2358 if (ha->flags.isp82xx_reset_owner) 2358 if (ha->flags.nic_core_reset_owner)
2359 return 1; 2359 return 1;
2360 else { 2360 else {
2361 drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE); 2361 drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
@@ -2864,7 +2864,7 @@ qla82xx_device_bootstrap(scsi_qla_host_t *vha)
2864 timeout = msleep_interruptible(200); 2864 timeout = msleep_interruptible(200);
2865 if (timeout) { 2865 if (timeout) {
2866 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 2866 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
2867 QLA82XX_DEV_FAILED); 2867 QLA8XXX_DEV_FAILED);
2868 return QLA_FUNCTION_FAILED; 2868 return QLA_FUNCTION_FAILED;
2869 } 2869 }
2870 2870
@@ -2895,7 +2895,7 @@ dev_initialize:
2895 /* set to DEV_INITIALIZING */ 2895 /* set to DEV_INITIALIZING */
2896 ql_log(ql_log_info, vha, 0x009e, 2896 ql_log(ql_log_info, vha, 0x009e,
2897 "HW State: INITIALIZING.\n"); 2897 "HW State: INITIALIZING.\n");
2898 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_INITIALIZING); 2898 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_INITIALIZING);
2899 2899
2900 /* Driver that sets device state to initializating sets IDC version */ 2900 /* Driver that sets device state to initializating sets IDC version */
2901 qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, QLA82XX_IDC_VERSION); 2901 qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, QLA82XX_IDC_VERSION);
@@ -2908,14 +2908,14 @@ dev_initialize:
2908 ql_log(ql_log_fatal, vha, 0x00ad, 2908 ql_log(ql_log_fatal, vha, 0x00ad,
2909 "HW State: FAILED.\n"); 2909 "HW State: FAILED.\n");
2910 qla82xx_clear_drv_active(ha); 2910 qla82xx_clear_drv_active(ha);
2911 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_FAILED); 2911 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_FAILED);
2912 return rval; 2912 return rval;
2913 } 2913 }
2914 2914
2915dev_ready: 2915dev_ready:
2916 ql_log(ql_log_info, vha, 0x00ae, 2916 ql_log(ql_log_info, vha, 0x00ae,
2917 "HW State: READY.\n"); 2917 "HW State: READY.\n");
2918 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_READY); 2918 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_READY);
2919 2919
2920 return QLA_SUCCESS; 2920 return QLA_SUCCESS;
2921} 2921}
@@ -2964,7 +2964,7 @@ qla82xx_need_qsnt_handler(scsi_qla_host_t *vha)
2964 "DRV_STATE:%d.\n", QLA2XXX_DRIVER_NAME, 2964 "DRV_STATE:%d.\n", QLA2XXX_DRIVER_NAME,
2965 drv_active, drv_state); 2965 drv_active, drv_state);
2966 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 2966 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
2967 QLA82XX_DEV_READY); 2967 QLA8XXX_DEV_READY);
2968 ql_log(ql_log_info, vha, 0xb025, 2968 ql_log(ql_log_info, vha, 0xb025,
2969 "HW State: DEV_READY.\n"); 2969 "HW State: DEV_READY.\n");
2970 qla82xx_idc_unlock(ha); 2970 qla82xx_idc_unlock(ha);
@@ -2985,10 +2985,10 @@ qla82xx_need_qsnt_handler(scsi_qla_host_t *vha)
2985 } 2985 }
2986 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 2986 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
2987 /* everyone acked so set the state to DEV_QUIESCENCE */ 2987 /* everyone acked so set the state to DEV_QUIESCENCE */
2988 if (dev_state == QLA82XX_DEV_NEED_QUIESCENT) { 2988 if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT) {
2989 ql_log(ql_log_info, vha, 0xb026, 2989 ql_log(ql_log_info, vha, 0xb026,
2990 "HW State: DEV_QUIESCENT.\n"); 2990 "HW State: DEV_QUIESCENT.\n");
2991 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_QUIESCENT); 2991 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_QUIESCENT);
2992 } 2992 }
2993} 2993}
2994 2994
@@ -3018,8 +3018,8 @@ qla82xx_wait_for_state_change(scsi_qla_host_t *vha, uint32_t curr_state)
3018 return dev_state; 3018 return dev_state;
3019} 3019}
3020 3020
3021static void 3021void
3022qla82xx_dev_failed_handler(scsi_qla_host_t *vha) 3022qla8xxx_dev_failed_handler(scsi_qla_host_t *vha)
3023{ 3023{
3024 struct qla_hw_data *ha = vha->hw; 3024 struct qla_hw_data *ha = vha->hw;
3025 3025
@@ -3067,7 +3067,7 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha)
3067 } 3067 }
3068 3068
3069 drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); 3069 drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
3070 if (!ha->flags.isp82xx_reset_owner) { 3070 if (!ha->flags.nic_core_reset_owner) {
3071 ql_dbg(ql_dbg_p3p, vha, 0xb028, 3071 ql_dbg(ql_dbg_p3p, vha, 0xb028,
3072 "reset_acknowledged by 0x%x\n", ha->portnum); 3072 "reset_acknowledged by 0x%x\n", ha->portnum);
3073 qla82xx_set_rst_ready(ha); 3073 qla82xx_set_rst_ready(ha);
@@ -3079,7 +3079,7 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha)
3079 } 3079 }
3080 3080
3081 /* wait for 10 seconds for reset ack from all functions */ 3081 /* wait for 10 seconds for reset ack from all functions */
3082 reset_timeout = jiffies + (ha->nx_reset_timeout * HZ); 3082 reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
3083 3083
3084 drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE); 3084 drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
3085 drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); 3085 drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
@@ -3091,7 +3091,7 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha)
3091 drv_state, drv_active, dev_state, active_mask); 3091 drv_state, drv_active, dev_state, active_mask);
3092 3092
3093 while (drv_state != drv_active && 3093 while (drv_state != drv_active &&
3094 dev_state != QLA82XX_DEV_INITIALIZING) { 3094 dev_state != QLA8XXX_DEV_INITIALIZING) {
3095 if (time_after_eq(jiffies, reset_timeout)) { 3095 if (time_after_eq(jiffies, reset_timeout)) {
3096 ql_log(ql_log_warn, vha, 0x00b5, 3096 ql_log(ql_log_warn, vha, 0x00b5,
3097 "Reset timeout.\n"); 3097 "Reset timeout.\n");
@@ -3102,7 +3102,7 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha)
3102 qla82xx_idc_lock(ha); 3102 qla82xx_idc_lock(ha);
3103 drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE); 3103 drv_state = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
3104 drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); 3104 drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
3105 if (ha->flags.isp82xx_reset_owner) 3105 if (ha->flags.nic_core_reset_owner)
3106 drv_active &= active_mask; 3106 drv_active &= active_mask;
3107 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 3107 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
3108 } 3108 }
@@ -3118,11 +3118,11 @@ qla82xx_need_reset_handler(scsi_qla_host_t *vha)
3118 dev_state < MAX_STATES ? qdev_state(dev_state) : "Unknown"); 3118 dev_state < MAX_STATES ? qdev_state(dev_state) : "Unknown");
3119 3119
3120 /* Force to DEV_COLD unless someone else is starting a reset */ 3120 /* Force to DEV_COLD unless someone else is starting a reset */
3121 if (dev_state != QLA82XX_DEV_INITIALIZING && 3121 if (dev_state != QLA8XXX_DEV_INITIALIZING &&
3122 dev_state != QLA82XX_DEV_COLD) { 3122 dev_state != QLA8XXX_DEV_COLD) {
3123 ql_log(ql_log_info, vha, 0x00b7, 3123 ql_log(ql_log_info, vha, 0x00b7,
3124 "HW State: COLD/RE-INIT.\n"); 3124 "HW State: COLD/RE-INIT.\n");
3125 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_COLD); 3125 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_COLD);
3126 qla82xx_set_rst_ready(ha); 3126 qla82xx_set_rst_ready(ha);
3127 if (ql2xmdenable) { 3127 if (ql2xmdenable) {
3128 if (qla82xx_md_collect(vha)) 3128 if (qla82xx_md_collect(vha))
@@ -3240,7 +3240,7 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha)
3240 dev_state < MAX_STATES ? qdev_state(dev_state) : "Unknown"); 3240 dev_state < MAX_STATES ? qdev_state(dev_state) : "Unknown");
3241 3241
3242 /* wait for 30 seconds for device to go ready */ 3242 /* wait for 30 seconds for device to go ready */
3243 dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ); 3243 dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout * HZ);
3244 3244
3245 while (1) { 3245 while (1) {
3246 3246
@@ -3264,18 +3264,18 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha)
3264 } 3264 }
3265 3265
3266 switch (dev_state) { 3266 switch (dev_state) {
3267 case QLA82XX_DEV_READY: 3267 case QLA8XXX_DEV_READY:
3268 ha->flags.isp82xx_reset_owner = 0; 3268 ha->flags.nic_core_reset_owner = 0;
3269 goto rel_lock; 3269 goto rel_lock;
3270 case QLA82XX_DEV_COLD: 3270 case QLA8XXX_DEV_COLD:
3271 rval = qla82xx_device_bootstrap(vha); 3271 rval = qla82xx_device_bootstrap(vha);
3272 break; 3272 break;
3273 case QLA82XX_DEV_INITIALIZING: 3273 case QLA8XXX_DEV_INITIALIZING:
3274 qla82xx_idc_unlock(ha); 3274 qla82xx_idc_unlock(ha);
3275 msleep(1000); 3275 msleep(1000);
3276 qla82xx_idc_lock(ha); 3276 qla82xx_idc_lock(ha);
3277 break; 3277 break;
3278 case QLA82XX_DEV_NEED_RESET: 3278 case QLA8XXX_DEV_NEED_RESET:
3279 if (!ql2xdontresethba) 3279 if (!ql2xdontresethba)
3280 qla82xx_need_reset_handler(vha); 3280 qla82xx_need_reset_handler(vha);
3281 else { 3281 else {
@@ -3284,15 +3284,15 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha)
3284 qla82xx_idc_lock(ha); 3284 qla82xx_idc_lock(ha);
3285 } 3285 }
3286 dev_init_timeout = jiffies + 3286 dev_init_timeout = jiffies +
3287 (ha->nx_dev_init_timeout * HZ); 3287 (ha->fcoe_dev_init_timeout * HZ);
3288 break; 3288 break;
3289 case QLA82XX_DEV_NEED_QUIESCENT: 3289 case QLA8XXX_DEV_NEED_QUIESCENT:
3290 qla82xx_need_qsnt_handler(vha); 3290 qla82xx_need_qsnt_handler(vha);
3291 /* Reset timeout value after quiescence handler */ 3291 /* Reset timeout value after quiescence handler */
3292 dev_init_timeout = jiffies + (ha->nx_dev_init_timeout\ 3292 dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout\
3293 * HZ); 3293 * HZ);
3294 break; 3294 break;
3295 case QLA82XX_DEV_QUIESCENT: 3295 case QLA8XXX_DEV_QUIESCENT:
3296 /* Owner will exit and other will wait for the state 3296 /* Owner will exit and other will wait for the state
3297 * to get changed 3297 * to get changed
3298 */ 3298 */
@@ -3304,11 +3304,11 @@ qla82xx_device_state_handler(scsi_qla_host_t *vha)
3304 qla82xx_idc_lock(ha); 3304 qla82xx_idc_lock(ha);
3305 3305
3306 /* Reset timeout value after quiescence handler */ 3306 /* Reset timeout value after quiescence handler */
3307 dev_init_timeout = jiffies + (ha->nx_dev_init_timeout\ 3307 dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout\
3308 * HZ); 3308 * HZ);
3309 break; 3309 break;
3310 case QLA82XX_DEV_FAILED: 3310 case QLA8XXX_DEV_FAILED:
3311 qla82xx_dev_failed_handler(vha); 3311 qla8xxx_dev_failed_handler(vha);
3312 rval = QLA_FUNCTION_FAILED; 3312 rval = QLA_FUNCTION_FAILED;
3313 goto exit; 3313 goto exit;
3314 default: 3314 default:
@@ -3368,23 +3368,23 @@ void qla82xx_watchdog(scsi_qla_host_t *vha)
3368 struct qla_hw_data *ha = vha->hw; 3368 struct qla_hw_data *ha = vha->hw;
3369 3369
3370 /* don't poll if reset is going on */ 3370 /* don't poll if reset is going on */
3371 if (!ha->flags.isp82xx_reset_hdlr_active) { 3371 if (!ha->flags.nic_core_reset_hdlr_active) {
3372 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 3372 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
3373 if (qla82xx_check_temp(vha)) { 3373 if (qla82xx_check_temp(vha)) {
3374 set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags); 3374 set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);
3375 ha->flags.isp82xx_fw_hung = 1; 3375 ha->flags.isp82xx_fw_hung = 1;
3376 qla82xx_clear_pending_mbx(vha); 3376 qla82xx_clear_pending_mbx(vha);
3377 } else if (dev_state == QLA82XX_DEV_NEED_RESET && 3377 } else if (dev_state == QLA8XXX_DEV_NEED_RESET &&
3378 !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) { 3378 !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) {
3379 ql_log(ql_log_warn, vha, 0x6001, 3379 ql_log(ql_log_warn, vha, 0x6001,
3380 "Adapter reset needed.\n"); 3380 "Adapter reset needed.\n");
3381 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 3381 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
3382 } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT && 3382 } else if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT &&
3383 !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) { 3383 !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) {
3384 ql_log(ql_log_warn, vha, 0x6002, 3384 ql_log(ql_log_warn, vha, 0x6002,
3385 "Quiescent needed.\n"); 3385 "Quiescent needed.\n");
3386 set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags); 3386 set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
3387 } else if (dev_state == QLA82XX_DEV_FAILED && 3387 } else if (dev_state == QLA8XXX_DEV_FAILED &&
3388 !test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags) && 3388 !test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags) &&
3389 vha->flags.online == 1) { 3389 vha->flags.online == 1) {
3390 ql_log(ql_log_warn, vha, 0xb055, 3390 ql_log(ql_log_warn, vha, 0xb055,
@@ -3453,12 +3453,12 @@ qla82xx_set_reset_owner(scsi_qla_host_t *vha)
3453 uint32_t dev_state; 3453 uint32_t dev_state;
3454 3454
3455 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 3455 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
3456 if (dev_state == QLA82XX_DEV_READY) { 3456 if (dev_state == QLA8XXX_DEV_READY) {
3457 ql_log(ql_log_info, vha, 0xb02f, 3457 ql_log(ql_log_info, vha, 0xb02f,
3458 "HW State: NEED RESET\n"); 3458 "HW State: NEED RESET\n");
3459 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 3459 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
3460 QLA82XX_DEV_NEED_RESET); 3460 QLA8XXX_DEV_NEED_RESET);
3461 ha->flags.isp82xx_reset_owner = 1; 3461 ha->flags.nic_core_reset_owner = 1;
3462 ql_dbg(ql_dbg_p3p, vha, 0xb030, 3462 ql_dbg(ql_dbg_p3p, vha, 0xb030,
3463 "reset_owner is 0x%x\n", ha->portnum); 3463 "reset_owner is 0x%x\n", ha->portnum);
3464 } else 3464 } else
@@ -3489,7 +3489,7 @@ qla82xx_abort_isp(scsi_qla_host_t *vha)
3489 "Device in failed state, exiting.\n"); 3489 "Device in failed state, exiting.\n");
3490 return QLA_SUCCESS; 3490 return QLA_SUCCESS;
3491 } 3491 }
3492 ha->flags.isp82xx_reset_hdlr_active = 1; 3492 ha->flags.nic_core_reset_hdlr_active = 1;
3493 3493
3494 qla82xx_idc_lock(ha); 3494 qla82xx_idc_lock(ha);
3495 qla82xx_set_reset_owner(vha); 3495 qla82xx_set_reset_owner(vha);
@@ -3503,7 +3503,7 @@ qla82xx_abort_isp(scsi_qla_host_t *vha)
3503 3503
3504 if (rval == QLA_SUCCESS) { 3504 if (rval == QLA_SUCCESS) {
3505 ha->flags.isp82xx_fw_hung = 0; 3505 ha->flags.isp82xx_fw_hung = 0;
3506 ha->flags.isp82xx_reset_hdlr_active = 0; 3506 ha->flags.nic_core_reset_hdlr_active = 0;
3507 qla82xx_restart_isp(vha); 3507 qla82xx_restart_isp(vha);
3508 } 3508 }
3509 3509
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h
index 6eb210e3cc63..d0aa16ccf49a 100644
--- a/drivers/scsi/qla2xxx/qla_nx.h
+++ b/drivers/scsi/qla2xxx/qla_nx.h
@@ -542,14 +542,15 @@
542#define QLA82XX_CRB_DRV_IDC_VERSION (QLA82XX_CAM_RAM(0x174)) 542#define QLA82XX_CRB_DRV_IDC_VERSION (QLA82XX_CAM_RAM(0x174))
543 543
544/* Every driver should use these Device State */ 544/* Every driver should use these Device State */
545#define QLA82XX_DEV_COLD 1 545#define QLA8XXX_DEV_COLD 1
546#define QLA82XX_DEV_INITIALIZING 2 546#define QLA8XXX_DEV_INITIALIZING 2
547#define QLA82XX_DEV_READY 3 547#define QLA8XXX_DEV_READY 3
548#define QLA82XX_DEV_NEED_RESET 4 548#define QLA8XXX_DEV_NEED_RESET 4
549#define QLA82XX_DEV_NEED_QUIESCENT 5 549#define QLA8XXX_DEV_NEED_QUIESCENT 5
550#define QLA82XX_DEV_FAILED 6 550#define QLA8XXX_DEV_FAILED 6
551#define QLA82XX_DEV_QUIESCENT 7 551#define QLA8XXX_DEV_QUIESCENT 7
552#define MAX_STATES 8 /* Increment if new state added */ 552#define MAX_STATES 8 /* Increment if new state added */
553#define QLA8XXX_BAD_VALUE 0xbad0bad0
553 554
554#define QLA82XX_IDC_VERSION 1 555#define QLA82XX_IDC_VERSION 1
555#define QLA82XX_ROM_DEV_INIT_TIMEOUT 30 556#define QLA82XX_ROM_DEV_INIT_TIMEOUT 30
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3e775650c20c..c705a51ee333 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2149,7 +2149,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2149 scsi_qla_host_t *base_vha = NULL; 2149 scsi_qla_host_t *base_vha = NULL;
2150 struct qla_hw_data *ha; 2150 struct qla_hw_data *ha;
2151 char pci_info[30]; 2151 char pci_info[30];
2152 char fw_str[30]; 2152 char fw_str[30], wq_name[30];
2153 struct scsi_host_template *sht; 2153 struct scsi_host_template *sht;
2154 int bars, mem_only = 0; 2154 int bars, mem_only = 0;
2155 uint16_t req_length = 0, rsp_length = 0; 2155 uint16_t req_length = 0, rsp_length = 0;
@@ -2319,6 +2319,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2319 ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF; 2319 ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
2320 ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA; 2320 ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
2321 } else if (IS_QLA83XX(ha)) { 2321 } else if (IS_QLA83XX(ha)) {
2322 ha->portnum = PCI_FUNC(ha->pdev->devfn);
2322 ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400; 2323 ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
2323 ha->mbx_count = MAILBOX_REGISTER_COUNT; 2324 ha->mbx_count = MAILBOX_REGISTER_COUNT;
2324 req_length = REQUEST_ENTRY_CNT_24XX; 2325 req_length = REQUEST_ENTRY_CNT_24XX;
@@ -2403,6 +2404,20 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2403 base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER + 2404 base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER +
2404 base_vha->vp_idx; 2405 base_vha->vp_idx;
2405 2406
2407 if (IS_QLA8031(ha)) {
2408 sprintf(wq_name, "qla2xxx_%lu_dpc_lp_wq", base_vha->host_no);
2409 ha->dpc_lp_wq = create_singlethread_workqueue(wq_name);
2410 INIT_WORK(&ha->idc_aen, qla83xx_service_idc_aen);
2411
2412 sprintf(wq_name, "qla2xxx_%lu_dpc_hp_wq", base_vha->host_no);
2413 ha->dpc_hp_wq = create_singlethread_workqueue(wq_name);
2414 INIT_WORK(&ha->nic_core_reset, qla83xx_nic_core_reset_work);
2415 INIT_WORK(&ha->idc_state_handler,
2416 qla83xx_idc_state_handler_work);
2417 INIT_WORK(&ha->nic_core_unrecoverable,
2418 qla83xx_nic_core_unrecoverable_work);
2419 }
2420
2406 /* Set the SG table size based on ISP type */ 2421 /* Set the SG table size based on ISP type */
2407 if (!IS_FWI2_CAPABLE(ha)) { 2422 if (!IS_FWI2_CAPABLE(ha)) {
2408 if (IS_QLA2100(ha)) 2423 if (IS_QLA2100(ha))
@@ -2500,7 +2515,7 @@ que_init:
2500 if (IS_QLA82XX(ha)) { 2515 if (IS_QLA82XX(ha)) {
2501 qla82xx_idc_lock(ha); 2516 qla82xx_idc_lock(ha);
2502 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 2517 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
2503 QLA82XX_DEV_FAILED); 2518 QLA8XXX_DEV_FAILED);
2504 qla82xx_idc_unlock(ha); 2519 qla82xx_idc_unlock(ha);
2505 ql_log(ql_log_fatal, base_vha, 0x00d7, 2520 ql_log(ql_log_fatal, base_vha, 0x00d7,
2506 "HW State: FAILED.\n"); 2521 "HW State: FAILED.\n");
@@ -2751,6 +2766,14 @@ qla2x00_remove_one(struct pci_dev *pdev)
2751 } 2766 }
2752 mutex_unlock(&ha->vport_lock); 2767 mutex_unlock(&ha->vport_lock);
2753 2768
2769 if (IS_QLA8031(ha)) {
2770 ql_dbg(ql_dbg_p3p, base_vha, 0xb07e,
2771 "Clearing fcoe driver presence.\n");
2772 if (qla83xx_clear_drv_presence(base_vha) != QLA_SUCCESS)
2773 ql_dbg(ql_dbg_p3p, base_vha, 0xb079,
2774 "Error while clearing DRV-Presence.\n");
2775 }
2776
2754 set_bit(UNLOADING, &base_vha->dpc_flags); 2777 set_bit(UNLOADING, &base_vha->dpc_flags);
2755 2778
2756 qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); 2779 qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
@@ -2772,6 +2795,21 @@ qla2x00_remove_one(struct pci_dev *pdev)
2772 ha->wq = NULL; 2795 ha->wq = NULL;
2773 } 2796 }
2774 2797
2798 /* Cancel all work and destroy DPC workqueues */
2799 if (ha->dpc_lp_wq) {
2800 cancel_work_sync(&ha->idc_aen);
2801 destroy_workqueue(ha->dpc_lp_wq);
2802 ha->dpc_lp_wq = NULL;
2803 }
2804
2805 if (ha->dpc_hp_wq) {
2806 cancel_work_sync(&ha->nic_core_reset);
2807 cancel_work_sync(&ha->idc_state_handler);
2808 cancel_work_sync(&ha->nic_core_unrecoverable);
2809 destroy_workqueue(ha->dpc_hp_wq);
2810 ha->dpc_hp_wq = NULL;
2811 }
2812
2775 /* Kill the kernel thread for this host */ 2813 /* Kill the kernel thread for this host */
2776 if (ha->dpc_thread) { 2814 if (ha->dpc_thread) {
2777 struct task_struct *t = ha->dpc_thread; 2815 struct task_struct *t = ha->dpc_thread;
@@ -2838,7 +2876,6 @@ qla2x00_free_device(scsi_qla_host_t *vha)
2838 qla2x00_stop_dpc_thread(vha); 2876 qla2x00_stop_dpc_thread(vha);
2839 2877
2840 qla25xx_delete_queues(vha); 2878 qla25xx_delete_queues(vha);
2841
2842 if (ha->flags.fce_enabled) 2879 if (ha->flags.fce_enabled)
2843 qla2x00_disable_fce_trace(vha, NULL, NULL); 2880 qla2x00_disable_fce_trace(vha, NULL, NULL);
2844 2881
@@ -3709,6 +3746,637 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
3709 } 3746 }
3710} 3747}
3711 3748
3749/* Schedule work on any of the dpc-workqueues */
3750void
3751qla83xx_schedule_work(scsi_qla_host_t *base_vha, int work_code)
3752{
3753 struct qla_hw_data *ha = base_vha->hw;
3754
3755 switch (work_code) {
3756 case MBA_IDC_AEN: /* 0x8200 */
3757 if (ha->dpc_lp_wq)
3758 queue_work(ha->dpc_lp_wq, &ha->idc_aen);
3759 break;
3760
3761 case QLA83XX_NIC_CORE_RESET: /* 0x1 */
3762 if (!ha->flags.nic_core_reset_hdlr_active) {
3763 if (ha->dpc_hp_wq)
3764 queue_work(ha->dpc_hp_wq, &ha->nic_core_reset);
3765 } else
3766 ql_dbg(ql_dbg_p3p, base_vha, 0xb05e,
3767 "NIC Core reset is already active. Skip "
3768 "scheduling it again.\n");
3769 break;
3770 case QLA83XX_IDC_STATE_HANDLER: /* 0x2 */
3771 if (ha->dpc_hp_wq)
3772 queue_work(ha->dpc_hp_wq, &ha->idc_state_handler);
3773 break;
3774 case QLA83XX_NIC_CORE_UNRECOVERABLE: /* 0x3 */
3775 if (ha->dpc_hp_wq)
3776 queue_work(ha->dpc_hp_wq, &ha->nic_core_unrecoverable);
3777 break;
3778 default:
3779 ql_log(ql_log_warn, base_vha, 0xb05f,
3780 "Unknow work-code=0x%x.\n", work_code);
3781 }
3782
3783 return;
3784}
3785
3786/* Work: Perform NIC Core Unrecoverable state handling */
3787void
3788qla83xx_nic_core_unrecoverable_work(struct work_struct *work)
3789{
3790 struct qla_hw_data *ha =
3791 container_of(work, struct qla_hw_data, nic_core_reset);
3792 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
3793 uint32_t dev_state = 0;
3794
3795 qla83xx_idc_lock(base_vha, 0);
3796 qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
3797 qla83xx_reset_ownership(base_vha);
3798 if (ha->flags.nic_core_reset_owner) {
3799 ha->flags.nic_core_reset_owner = 0;
3800 qla83xx_wr_reg(base_vha, QLA83XX_IDC_DEV_STATE,
3801 QLA8XXX_DEV_FAILED);
3802 ql_log(ql_log_info, base_vha, 0xb060, "HW State: FAILED.\n");
3803 qla83xx_schedule_work(base_vha, QLA83XX_IDC_STATE_HANDLER);
3804 }
3805 qla83xx_idc_unlock(base_vha, 0);
3806}
3807
3808/* Work: Execute IDC state handler */
3809void
3810qla83xx_idc_state_handler_work(struct work_struct *work)
3811{
3812 struct qla_hw_data *ha =
3813 container_of(work, struct qla_hw_data, nic_core_reset);
3814 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
3815 uint32_t dev_state = 0;
3816
3817 qla83xx_idc_lock(base_vha, 0);
3818 qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
3819 if (dev_state == QLA8XXX_DEV_FAILED ||
3820 dev_state == QLA8XXX_DEV_NEED_QUIESCENT)
3821 qla83xx_idc_state_handler(base_vha);
3822 qla83xx_idc_unlock(base_vha, 0);
3823}
3824
3825int
3826qla83xx_check_nic_core_fw_alive(scsi_qla_host_t *base_vha)
3827{
3828 int rval = QLA_SUCCESS;
3829 unsigned long heart_beat_wait = jiffies + (1 * HZ);
3830 uint32_t heart_beat_counter1, heart_beat_counter2;
3831
3832 do {
3833 if (time_after(jiffies, heart_beat_wait)) {
3834 ql_dbg(ql_dbg_p3p, base_vha, 0xb07c,
3835 "Nic Core f/w is not alive.\n");
3836 rval = QLA_FUNCTION_FAILED;
3837 break;
3838 }
3839
3840 qla83xx_idc_lock(base_vha, 0);
3841 qla83xx_rd_reg(base_vha, QLA83XX_FW_HEARTBEAT,
3842 &heart_beat_counter1);
3843 qla83xx_idc_unlock(base_vha, 0);
3844 msleep(100);
3845 qla83xx_idc_lock(base_vha, 0);
3846 qla83xx_rd_reg(base_vha, QLA83XX_FW_HEARTBEAT,
3847 &heart_beat_counter2);
3848 qla83xx_idc_unlock(base_vha, 0);
3849 } while (heart_beat_counter1 == heart_beat_counter2);
3850
3851 return rval;
3852}
3853
3854/* Work: Perform NIC Core Reset handling */
3855void
3856qla83xx_nic_core_reset_work(struct work_struct *work)
3857{
3858 struct qla_hw_data *ha =
3859 container_of(work, struct qla_hw_data, nic_core_reset);
3860 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
3861 uint32_t dev_state = 0;
3862
3863 if (!ha->flags.nic_core_reset_hdlr_active) {
3864 if (qla83xx_check_nic_core_fw_alive(base_vha) == QLA_SUCCESS) {
3865 qla83xx_idc_lock(base_vha, 0);
3866 qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE,
3867 &dev_state);
3868 qla83xx_idc_unlock(base_vha, 0);
3869 if (dev_state != QLA8XXX_DEV_NEED_RESET) {
3870 ql_dbg(ql_dbg_p3p, base_vha, 0xb07a,
3871 "Nic Core f/w is alive.\n");
3872 return;
3873 }
3874 }
3875
3876 ha->flags.nic_core_reset_hdlr_active = 1;
3877 if (qla83xx_nic_core_reset(base_vha)) {
3878 /* NIC Core reset failed. */
3879 ql_dbg(ql_dbg_p3p, base_vha, 0xb061,
3880 "NIC Core reset failed.\n");
3881 }
3882 ha->flags.nic_core_reset_hdlr_active = 0;
3883 }
3884}
3885
3886/* Work: Handle 8200 IDC aens */
3887void
3888qla83xx_service_idc_aen(struct work_struct *work)
3889{
3890 struct qla_hw_data *ha =
3891 container_of(work, struct qla_hw_data, idc_aen);
3892 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
3893 uint32_t dev_state, idc_control;
3894
3895 qla83xx_idc_lock(base_vha, 0);
3896 qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
3897 qla83xx_rd_reg(base_vha, QLA83XX_IDC_CONTROL, &idc_control);
3898 qla83xx_idc_unlock(base_vha, 0);
3899 if (dev_state == QLA8XXX_DEV_NEED_RESET) {
3900 if (idc_control & QLA83XX_IDC_GRACEFUL_RESET) {
3901 ql_dbg(ql_dbg_p3p, base_vha, 0xb062,
3902 "Application requested NIC Core Reset.\n");
3903 qla83xx_schedule_work(base_vha, QLA83XX_NIC_CORE_RESET);
3904 } else if (qla83xx_check_nic_core_fw_alive(base_vha) ==
3905 QLA_SUCCESS) {
3906 ql_dbg(ql_dbg_p3p, base_vha, 0xb07b,
3907 "Other protocol driver requested NIC Core Reset.\n");
3908 qla83xx_schedule_work(base_vha, QLA83XX_NIC_CORE_RESET);
3909 }
3910 } else if (dev_state == QLA8XXX_DEV_FAILED ||
3911 dev_state == QLA8XXX_DEV_NEED_QUIESCENT) {
3912 qla83xx_schedule_work(base_vha, QLA83XX_IDC_STATE_HANDLER);
3913 }
3914}
3915
3916static void
3917qla83xx_wait_logic(void)
3918{
3919 int i;
3920
3921 /* Yield CPU */
3922 if (!in_interrupt()) {
3923 /*
3924 * Wait about 200ms before retrying again.
3925 * This controls the number of retries for single
3926 * lock operation.
3927 */
3928 msleep(100);
3929 schedule();
3930 } else {
3931 for (i = 0; i < 20; i++)
3932 cpu_relax(); /* This a nop instr on i386 */
3933 }
3934}
3935
3936int
3937qla83xx_force_lock_recovery(scsi_qla_host_t *base_vha)
3938{
3939 int rval;
3940 uint32_t data;
3941 uint32_t idc_lck_rcvry_stage_mask = 0x3;
3942 uint32_t idc_lck_rcvry_owner_mask = 0x3c;
3943 struct qla_hw_data *ha = base_vha->hw;
3944
3945 rval = qla83xx_rd_reg(base_vha, QLA83XX_IDC_LOCK_RECOVERY, &data);
3946 if (rval)
3947 return rval;
3948
3949 if ((data & idc_lck_rcvry_stage_mask) > 0) {
3950 return QLA_SUCCESS;
3951 } else {
3952 data = (IDC_LOCK_RECOVERY_STAGE1) | (ha->portnum << 2);
3953 rval = qla83xx_wr_reg(base_vha, QLA83XX_IDC_LOCK_RECOVERY,
3954 data);
3955 if (rval)
3956 return rval;
3957
3958 msleep(200);
3959
3960 rval = qla83xx_rd_reg(base_vha, QLA83XX_IDC_LOCK_RECOVERY,
3961 &data);
3962 if (rval)
3963 return rval;
3964
3965 if (((data & idc_lck_rcvry_owner_mask) >> 2) == ha->portnum) {
3966 data &= (IDC_LOCK_RECOVERY_STAGE2 |
3967 ~(idc_lck_rcvry_stage_mask));
3968 rval = qla83xx_wr_reg(base_vha,
3969 QLA83XX_IDC_LOCK_RECOVERY, data);
3970 if (rval)
3971 return rval;
3972
3973 /* Forcefully perform IDC UnLock */
3974 rval = qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_UNLOCK,
3975 &data);
3976 if (rval)
3977 return rval;
3978 /* Clear lock-id by setting 0xff */
3979 rval = qla83xx_wr_reg(base_vha, QLA83XX_DRIVER_LOCKID,
3980 0xff);
3981 if (rval)
3982 return rval;
3983 /* Clear lock-recovery by setting 0x0 */
3984 rval = qla83xx_wr_reg(base_vha,
3985 QLA83XX_IDC_LOCK_RECOVERY, 0x0);
3986 if (rval)
3987 return rval;
3988 } else
3989 return QLA_SUCCESS;
3990 }
3991
3992 return rval;
3993}
3994
3995int
3996qla83xx_idc_lock_recovery(scsi_qla_host_t *base_vha)
3997{
3998 int rval = QLA_SUCCESS;
3999 uint32_t o_drv_lockid, n_drv_lockid;
4000 unsigned long lock_recovery_timeout;
4001
4002 lock_recovery_timeout = jiffies + QLA83XX_MAX_LOCK_RECOVERY_WAIT;
4003retry_lockid:
4004 rval = qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCKID, &o_drv_lockid);
4005 if (rval)
4006 goto exit;
4007
4008 /* MAX wait time before forcing IDC Lock recovery = 2 secs */
4009 if (time_after_eq(jiffies, lock_recovery_timeout)) {
4010 if (qla83xx_force_lock_recovery(base_vha) == QLA_SUCCESS)
4011 return QLA_SUCCESS;
4012 else
4013 return QLA_FUNCTION_FAILED;
4014 }
4015
4016 rval = qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCKID, &n_drv_lockid);
4017 if (rval)
4018 goto exit;
4019
4020 if (o_drv_lockid == n_drv_lockid) {
4021 qla83xx_wait_logic();
4022 goto retry_lockid;
4023 } else
4024 return QLA_SUCCESS;
4025
4026exit:
4027 return rval;
4028}
4029
4030void
4031qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id)
4032{
4033 uint16_t options = (requester_id << 15) | BIT_6;
4034 uint32_t data;
4035 struct qla_hw_data *ha = base_vha->hw;
4036
4037 /* IDC-lock implementation using driver-lock/lock-id remote registers */
4038retry_lock:
4039 if (qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCK, &data)
4040 == QLA_SUCCESS) {
4041 if (data) {
4042 /* Setting lock-id to our function-number */
4043 qla83xx_wr_reg(base_vha, QLA83XX_DRIVER_LOCKID,
4044 ha->portnum);
4045 } else {
4046 ql_dbg(ql_dbg_p3p, base_vha, 0xb063,
4047 "Failed to acquire IDC lock. retrying...\n");
4048
4049 /* Retry/Perform IDC-Lock recovery */
4050 if (qla83xx_idc_lock_recovery(base_vha)
4051 == QLA_SUCCESS) {
4052 qla83xx_wait_logic();
4053 goto retry_lock;
4054 } else
4055 ql_log(ql_log_warn, base_vha, 0xb075,
4056 "IDC Lock recovery FAILED.\n");
4057 }
4058
4059 }
4060
4061 return;
4062
4063 /* XXX: IDC-lock implementation using access-control mbx */
4064retry_lock2:
4065 if (qla83xx_access_control(base_vha, options, 0, 0, NULL)) {
4066 ql_dbg(ql_dbg_p3p, base_vha, 0xb072,
4067 "Failed to acquire IDC lock. retrying...\n");
4068 /* Retry/Perform IDC-Lock recovery */
4069 if (qla83xx_idc_lock_recovery(base_vha) == QLA_SUCCESS) {
4070 qla83xx_wait_logic();
4071 goto retry_lock2;
4072 } else
4073 ql_log(ql_log_warn, base_vha, 0xb076,
4074 "IDC Lock recovery FAILED.\n");
4075 }
4076
4077 return;
4078}
4079
4080void
4081qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
4082{
4083 uint16_t options = (requester_id << 15) | BIT_7, retry;
4084 uint32_t data;
4085 struct qla_hw_data *ha = base_vha->hw;
4086
4087 /* IDC-unlock implementation using driver-unlock/lock-id
4088 * remote registers
4089 */
4090 retry = 0;
4091retry_unlock:
4092 if (qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCKID, &data)
4093 == QLA_SUCCESS) {
4094 if (data == ha->portnum) {
4095 qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_UNLOCK, &data);
4096 /* Clearing lock-id by setting 0xff */
4097 qla83xx_wr_reg(base_vha, QLA83XX_DRIVER_LOCKID, 0xff);
4098 } else if (retry < 10) {
4099 /* SV: XXX: IDC unlock retrying needed here? */
4100
4101 /* Retry for IDC-unlock */
4102 qla83xx_wait_logic();
4103 retry++;
4104 ql_dbg(ql_dbg_p3p, base_vha, 0xb064,
4105 "Failed to release IDC lock, retyring=%d\n", retry);
4106 goto retry_unlock;
4107 }
4108 } else if (retry < 10) {
4109 /* Retry for IDC-unlock */
4110 qla83xx_wait_logic();
4111 retry++;
4112 ql_dbg(ql_dbg_p3p, base_vha, 0xb065,
4113 "Failed to read drv-lockid, retyring=%d\n", retry);
4114 goto retry_unlock;
4115 }
4116
4117 return;
4118
4119 /* XXX: IDC-unlock implementation using access-control mbx */
4120 retry = 0;
4121retry_unlock2:
4122 if (qla83xx_access_control(base_vha, options, 0, 0, NULL)) {
4123 if (retry < 10) {
4124 /* Retry for IDC-unlock */
4125 qla83xx_wait_logic();
4126 retry++;
4127 ql_dbg(ql_dbg_p3p, base_vha, 0xb066,
4128 "Failed to release IDC lock, retyring=%d\n", retry);
4129 goto retry_unlock2;
4130 }
4131 }
4132
4133 return;
4134}
4135
4136int
4137__qla83xx_set_drv_presence(scsi_qla_host_t *vha)
4138{
4139 int rval = QLA_SUCCESS;
4140 struct qla_hw_data *ha = vha->hw;
4141 uint32_t drv_presence;
4142
4143 rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
4144 if (rval == QLA_SUCCESS) {
4145 drv_presence |= (1 << ha->portnum);
4146 rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRV_PRESENCE,
4147 drv_presence);
4148 }
4149
4150 return rval;
4151}
4152
4153int
4154qla83xx_set_drv_presence(scsi_qla_host_t *vha)
4155{
4156 int rval = QLA_SUCCESS;
4157
4158 qla83xx_idc_lock(vha, 0);
4159 rval = __qla83xx_set_drv_presence(vha);
4160 qla83xx_idc_unlock(vha, 0);
4161
4162 return rval;
4163}
4164
4165int
4166__qla83xx_clear_drv_presence(scsi_qla_host_t *vha)
4167{
4168 int rval = QLA_SUCCESS;
4169 struct qla_hw_data *ha = vha->hw;
4170 uint32_t drv_presence;
4171
4172 rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
4173 if (rval == QLA_SUCCESS) {
4174 drv_presence &= ~(1 << ha->portnum);
4175 rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRV_PRESENCE,
4176 drv_presence);
4177 }
4178
4179 return rval;
4180}
4181
4182int
4183qla83xx_clear_drv_presence(scsi_qla_host_t *vha)
4184{
4185 int rval = QLA_SUCCESS;
4186
4187 qla83xx_idc_lock(vha, 0);
4188 rval = __qla83xx_clear_drv_presence(vha);
4189 qla83xx_idc_unlock(vha, 0);
4190
4191 return rval;
4192}
4193
4194void
4195qla83xx_need_reset_handler(scsi_qla_host_t *vha)
4196{
4197 struct qla_hw_data *ha = vha->hw;
4198 uint32_t drv_ack, drv_presence;
4199 unsigned long ack_timeout;
4200
4201 /* Wait for IDC ACK from all functions (DRV-ACK == DRV-PRESENCE) */
4202 ack_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
4203 while (1) {
4204 qla83xx_rd_reg(vha, QLA83XX_IDC_DRIVER_ACK, &drv_ack);
4205 qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
4206 if (drv_ack == drv_presence)
4207 break;
4208
4209 if (time_after_eq(jiffies, ack_timeout)) {
4210 ql_log(ql_log_warn, vha, 0xb067,
4211 "RESET ACK TIMEOUT! drv_presence=0x%x "
4212 "drv_ack=0x%x\n", drv_presence, drv_ack);
4213 /*
4214 * The function(s) which did not ack in time are forced
4215 * to withdraw any further participation in the IDC
4216 * reset.
4217 */
4218 if (drv_ack != drv_presence)
4219 qla83xx_wr_reg(vha, QLA83XX_IDC_DRV_PRESENCE,
4220 drv_ack);
4221 break;
4222 }
4223
4224 qla83xx_idc_unlock(vha, 0);
4225 msleep(1000);
4226 qla83xx_idc_lock(vha, 0);
4227 }
4228
4229 qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_COLD);
4230 ql_log(ql_log_info, vha, 0xb068, "HW State: COLD/RE-INIT.\n");
4231}
4232
4233int
4234qla83xx_device_bootstrap(scsi_qla_host_t *vha)
4235{
4236 int rval = QLA_SUCCESS;
4237 uint32_t idc_control;
4238
4239 qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_INITIALIZING);
4240 ql_log(ql_log_info, vha, 0xb069, "HW State: INITIALIZING.\n");
4241
4242 /* Clearing IDC-Control Graceful-Reset Bit before resetting f/w */
4243 __qla83xx_get_idc_control(vha, &idc_control);
4244 idc_control &= ~QLA83XX_IDC_GRACEFUL_RESET;
4245 __qla83xx_set_idc_control(vha, 0);
4246
4247 qla83xx_idc_unlock(vha, 0);
4248 rval = qla83xx_restart_nic_firmware(vha);
4249 qla83xx_idc_lock(vha, 0);
4250
4251 if (rval != QLA_SUCCESS) {
4252 ql_log(ql_log_fatal, vha, 0xb06a,
4253 "Failed to restart NIC f/w.\n");
4254 qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_FAILED);
4255 ql_log(ql_log_info, vha, 0xb06b, "HW State: FAILED.\n");
4256 } else {
4257 ql_dbg(ql_dbg_p3p, vha, 0xb06c,
4258 "Success in restarting nic f/w.\n");
4259 qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_READY);
4260 ql_log(ql_log_info, vha, 0xb06d, "HW State: READY.\n");
4261 }
4262
4263 return rval;
4264}
4265
4266/* Assumes idc_lock always held on entry */
4267int
4268qla83xx_idc_state_handler(scsi_qla_host_t *base_vha)
4269{
4270 struct qla_hw_data *ha = base_vha->hw;
4271 int rval = QLA_SUCCESS;
4272 unsigned long dev_init_timeout;
4273 uint32_t dev_state;
4274
4275 /* Wait for MAX-INIT-TIMEOUT for the device to go ready */
4276 dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout * HZ);
4277
4278 while (1) {
4279
4280 if (time_after_eq(jiffies, dev_init_timeout)) {
4281 ql_log(ql_log_warn, base_vha, 0xb06e,
4282 "Initialization TIMEOUT!\n");
4283 /* Init timeout. Disable further NIC Core
4284 * communication.
4285 */
4286 qla83xx_wr_reg(base_vha, QLA83XX_IDC_DEV_STATE,
4287 QLA8XXX_DEV_FAILED);
4288 ql_log(ql_log_info, base_vha, 0xb06f,
4289 "HW State: FAILED.\n");
4290 }
4291
4292 qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
4293 switch (dev_state) {
4294 case QLA8XXX_DEV_READY:
4295 if (ha->flags.nic_core_reset_owner)
4296 qla83xx_idc_audit(base_vha,
4297 IDC_AUDIT_COMPLETION);
4298 ha->flags.nic_core_reset_owner = 0;
4299 ql_dbg(ql_dbg_p3p, base_vha, 0xb070,
4300 "Reset_owner reset by 0x%x.\n",
4301 ha->portnum);
4302 goto exit;
4303 case QLA8XXX_DEV_COLD:
4304 if (ha->flags.nic_core_reset_owner)
4305 rval = qla83xx_device_bootstrap(base_vha);
4306 else {
4307 /* Wait for AEN to change device-state */
4308 qla83xx_idc_unlock(base_vha, 0);
4309 msleep(1000);
4310 qla83xx_idc_lock(base_vha, 0);
4311 }
4312 break;
4313 case QLA8XXX_DEV_INITIALIZING:
4314 /* Wait for AEN to change device-state */
4315 qla83xx_idc_unlock(base_vha, 0);
4316 msleep(1000);
4317 qla83xx_idc_lock(base_vha, 0);
4318 break;
4319 case QLA8XXX_DEV_NEED_RESET:
4320 if (!ql2xdontresethba && ha->flags.nic_core_reset_owner)
4321 qla83xx_need_reset_handler(base_vha);
4322 else {
4323 /* Wait for AEN to change device-state */
4324 qla83xx_idc_unlock(base_vha, 0);
4325 msleep(1000);
4326 qla83xx_idc_lock(base_vha, 0);
4327 }
4328 /* reset timeout value after need reset handler */
4329 dev_init_timeout = jiffies +
4330 (ha->fcoe_dev_init_timeout * HZ);
4331 break;
4332 case QLA8XXX_DEV_NEED_QUIESCENT:
4333 /* XXX: DEBUG for now */
4334 qla83xx_idc_unlock(base_vha, 0);
4335 msleep(1000);
4336 qla83xx_idc_lock(base_vha, 0);
4337 break;
4338 case QLA8XXX_DEV_QUIESCENT:
4339 /* XXX: DEBUG for now */
4340 if (ha->flags.quiesce_owner)
4341 goto exit;
4342
4343 qla83xx_idc_unlock(base_vha, 0);
4344 msleep(1000);
4345 qla83xx_idc_lock(base_vha, 0);
4346 dev_init_timeout = jiffies +
4347 (ha->fcoe_dev_init_timeout * HZ);
4348 break;
4349 case QLA8XXX_DEV_FAILED:
4350 if (ha->flags.nic_core_reset_owner)
4351 qla83xx_idc_audit(base_vha,
4352 IDC_AUDIT_COMPLETION);
4353 ha->flags.nic_core_reset_owner = 0;
4354 __qla83xx_clear_drv_presence(base_vha);
4355 qla83xx_idc_unlock(base_vha, 0);
4356 qla8xxx_dev_failed_handler(base_vha);
4357 rval = QLA_FUNCTION_FAILED;
4358 qla83xx_idc_lock(base_vha, 0);
4359 goto exit;
4360 case QLA8XXX_BAD_VALUE:
4361 qla83xx_idc_unlock(base_vha, 0);
4362 msleep(1000);
4363 qla83xx_idc_lock(base_vha, 0);
4364 break;
4365 default:
4366 ql_log(ql_log_warn, base_vha, 0xb071,
4367 "Unknow Device State: %x.\n", dev_state);
4368 qla83xx_idc_unlock(base_vha, 0);
4369 qla8xxx_dev_failed_handler(base_vha);
4370 rval = QLA_FUNCTION_FAILED;
4371 qla83xx_idc_lock(base_vha, 0);
4372 goto exit;
4373 }
4374 }
4375
4376exit:
4377 return rval;
4378}
4379
3712/************************************************************************** 4380/**************************************************************************
3713* qla2x00_do_dpc 4381* qla2x00_do_dpc
3714* This kernel thread is a task that is schedule by the interrupt handler 4382* This kernel thread is a task that is schedule by the interrupt handler
@@ -3764,7 +4432,7 @@ qla2x00_do_dpc(void *data)
3764 &base_vha->dpc_flags)) { 4432 &base_vha->dpc_flags)) {
3765 qla82xx_idc_lock(ha); 4433 qla82xx_idc_lock(ha);
3766 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 4434 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
3767 QLA82XX_DEV_FAILED); 4435 QLA8XXX_DEV_FAILED);
3768 qla82xx_idc_unlock(ha); 4436 qla82xx_idc_unlock(ha);
3769 ql_log(ql_log_info, base_vha, 0x4004, 4437 ql_log(ql_log_info, base_vha, 0x4004,
3770 "HW State: FAILED.\n"); 4438 "HW State: FAILED.\n");
@@ -4341,7 +5009,7 @@ uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha)
4341 qla82xx_idc_lock(ha); 5009 qla82xx_idc_lock(ha);
4342 5010
4343 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 5011 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
4344 QLA82XX_DEV_INITIALIZING); 5012 QLA8XXX_DEV_INITIALIZING);
4345 5013
4346 qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, 5014 qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION,
4347 QLA82XX_IDC_VERSION); 5015 QLA82XX_IDC_VERSION);
@@ -4365,12 +5033,12 @@ uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha)
4365 "HW State: FAILED.\n"); 5033 "HW State: FAILED.\n");
4366 qla82xx_clear_drv_active(ha); 5034 qla82xx_clear_drv_active(ha);
4367 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 5035 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
4368 QLA82XX_DEV_FAILED); 5036 QLA8XXX_DEV_FAILED);
4369 } else { 5037 } else {
4370 ql_log(ql_log_info, base_vha, 0x900c, 5038 ql_log(ql_log_info, base_vha, 0x900c,
4371 "HW State: READY.\n"); 5039 "HW State: READY.\n");
4372 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 5040 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
4373 QLA82XX_DEV_READY); 5041 QLA8XXX_DEV_READY);
4374 qla82xx_idc_unlock(ha); 5042 qla82xx_idc_unlock(ha);
4375 ha->flags.isp82xx_fw_hung = 0; 5043 ha->flags.isp82xx_fw_hung = 0;
4376 rval = qla82xx_restart_isp(base_vha); 5044 rval = qla82xx_restart_isp(base_vha);
@@ -4385,7 +5053,7 @@ uint32_t qla82xx_error_recovery(scsi_qla_host_t *base_vha)
4385 "This devfn is not reset owner = 0x%x.\n", 5053 "This devfn is not reset owner = 0x%x.\n",
4386 ha->pdev->devfn); 5054 ha->pdev->devfn);
4387 if ((qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == 5055 if ((qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) ==
4388 QLA82XX_DEV_READY)) { 5056 QLA8XXX_DEV_READY)) {
4389 ha->flags.isp82xx_fw_hung = 0; 5057 ha->flags.isp82xx_fw_hung = 0;
4390 rval = qla82xx_restart_isp(base_vha); 5058 rval = qla82xx_restart_isp(base_vha);
4391 qla82xx_idc_lock(ha); 5059 qla82xx_idc_lock(ha);
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index a683e766d1ae..e66fa7fbd933 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -966,16 +966,16 @@ qla2xxx_get_idc_param(scsi_qla_host_t *vha)
966 QLA82XX_IDC_PARAM_ADDR , 8); 966 QLA82XX_IDC_PARAM_ADDR , 8);
967 967
968 if (*wptr == __constant_cpu_to_le32(0xffffffff)) { 968 if (*wptr == __constant_cpu_to_le32(0xffffffff)) {
969 ha->nx_dev_init_timeout = QLA82XX_ROM_DEV_INIT_TIMEOUT; 969 ha->fcoe_dev_init_timeout = QLA82XX_ROM_DEV_INIT_TIMEOUT;
970 ha->nx_reset_timeout = QLA82XX_ROM_DRV_RESET_ACK_TIMEOUT; 970 ha->fcoe_reset_timeout = QLA82XX_ROM_DRV_RESET_ACK_TIMEOUT;
971 } else { 971 } else {
972 ha->nx_dev_init_timeout = le32_to_cpu(*wptr++); 972 ha->fcoe_dev_init_timeout = le32_to_cpu(*wptr++);
973 ha->nx_reset_timeout = le32_to_cpu(*wptr); 973 ha->fcoe_reset_timeout = le32_to_cpu(*wptr);
974 } 974 }
975 ql_dbg(ql_dbg_init, vha, 0x004e, 975 ql_dbg(ql_dbg_init, vha, 0x004e,
976 "nx_dev_init_timeout=%d " 976 "fcoe_dev_init_timeout=%d "
977 "nx_reset_timeout=%d.\n", ha->nx_dev_init_timeout, 977 "fcoe_reset_timeout=%d.\n", ha->fcoe_dev_init_timeout,
978 ha->nx_reset_timeout); 978 ha->fcoe_reset_timeout);
979 return; 979 return;
980} 980}
981 981
@@ -1017,7 +1017,7 @@ qla2xxx_flash_npiv_conf(scsi_qla_host_t *vha)
1017 !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha)) 1017 !IS_CNA_CAPABLE(ha) && !IS_QLA2031(ha))
1018 return; 1018 return;
1019 1019
1020 if (ha->flags.isp82xx_reset_hdlr_active) 1020 if (ha->flags.nic_core_reset_hdlr_active)
1021 return; 1021 return;
1022 1022
1023 ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr, 1023 ha->isp_ops->read_optrom(vha, (uint8_t *)&hdr,
@@ -1675,15 +1675,15 @@ qla83xx_beacon_blink(struct scsi_qla_host *vha)
1675 1675
1676 if (IS_QLA2031(ha) && ha->beacon_blink_led) { 1676 if (IS_QLA2031(ha) && ha->beacon_blink_led) {
1677 if (ha->flags.port0) 1677 if (ha->flags.port0)
1678 led_select_value = 0x00201320; 1678 led_select_value = QLA83XX_LED_PORT0;
1679 else 1679 else
1680 led_select_value = 0x00201328; 1680 led_select_value = QLA83XX_LED_PORT1;
1681 1681
1682 qla83xx_write_remote_reg(vha, led_select_value, 0x40002000); 1682 qla83xx_wr_reg(vha, led_select_value, 0x40002000);
1683 qla83xx_write_remote_reg(vha, led_select_value + 4, 0x40002000); 1683 qla83xx_wr_reg(vha, led_select_value + 4, 0x40002000);
1684 msleep(1000); 1684 msleep(1000);
1685 qla83xx_write_remote_reg(vha, led_select_value, 0x40004000); 1685 qla83xx_wr_reg(vha, led_select_value, 0x40004000);
1686 qla83xx_write_remote_reg(vha, led_select_value + 4, 0x40004000); 1686 qla83xx_wr_reg(vha, led_select_value + 4, 0x40004000);
1687 } else if ((IS_QLA8031(ha) || IS_QLA81XX(ha)) && ha->beacon_blink_led) { 1687 } else if ((IS_QLA8031(ha) || IS_QLA81XX(ha)) && ha->beacon_blink_led) {
1688 int rval; 1688 int rval;
1689 1689