blob: 2d5610be2d70f6abe42bc5a58498f5fe3295c655 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
Armen Baloyanbd21eaf2014-04-11 16:54:24 -04003 * Copyright (c) 2003-2014 QLogic Corporation
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
Andrew Vasquezfa90c542005-10-27 11:10:08 -07005 * See LICENSE.qla2xxx for copyright and licensing details.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 */
Saurav Kashyap3ce88662011-07-14 12:00:12 -07007
8/*
9 * Table for showing the current message id in use for particular level
10 * Change this table for addition of log/debug messages.
Arun Easie02587d2011-08-16 11:29:23 -070011 * ----------------------------------------------------------------------
12 * | Level | Last Value Used | Holes |
13 * ----------------------------------------------------------------------
Chad Dupuisf73cb692014-02-26 04:15:06 -050014 * | Module Init and Probe | 0x017d | 0x004b,0x0141 |
15 * | | | 0x0144,0x0146 |
16 * | | | 0x015b-0x0160 |
17 * | | | 0x016e-0x0170 |
Joe Carnuccio7c9c4762014-09-25 05:16:47 -040018 * | Mailbox commands | 0x118d | 0x1115-0x1116 |
19 * | | | 0x111a-0x111b |
Himanshu Madhanidf57cab2014-09-25 05:16:46 -040020 * | Device Discovery | 0x2016 | 0x2020-0x2022, |
Bart Van Assche6593d5b2013-06-25 11:27:24 -040021 * | | | 0x2011-0x2012, |
Himanshu Madhanidf57cab2014-09-25 05:16:46 -040022 * | | | 0x2099-0x20a4 |
Chad Dupuis36008cf2013-10-03 03:21:13 -040023 * | Queue Command and IO tracing | 0x3059 | 0x3006-0x300b |
Arun Easi9e522cd2012-08-22 14:21:31 -040024 * | | | 0x3027-0x3028 |
Giridhar Malavali8ae6d9c2013-03-28 08:21:23 -040025 * | | | 0x303d-0x3041 |
26 * | | | 0x302d,0x3033 |
27 * | | | 0x3036,0x3038 |
28 * | | | 0x303a |
Armen Baloyane8f5e952013-10-30 03:38:17 -040029 * | DPC Thread | 0x4023 | 0x4002,0x4013 |
Santosh Vernekar454073c2013-08-27 01:37:48 -040030 * | Async Events | 0x5087 | 0x502b-0x502f |
Joe Carnucciob5a340d2014-09-25 05:16:48 -040031 * | | | 0x5047 |
Saurav Kashyap6ddcfef2013-08-27 01:37:53 -040032 * | | | 0x5084,0x5075 |
Chad Dupuisa78951b2013-08-27 01:37:34 -040033 * | | | 0x503d,0x5044 |
Chad Dupuis8e5a9482014-08-08 07:38:09 -040034 * | | | 0x507b,0x505f |
Armen Baloyan71e56002013-08-27 01:37:38 -040035 * | Timer Routines | 0x6012 | |
Chad Dupuisf73cb692014-02-26 04:15:06 -050036 * | User Space Interactions | 0x70e2 | 0x7018,0x702e |
37 * | | | 0x7020,0x7024 |
38 * | | | 0x7039,0x7045 |
39 * | | | 0x7073-0x7075 |
40 * | | | 0x70a5-0x70a6 |
41 * | | | 0x70a8,0x70ab |
42 * | | | 0x70ad-0x70ae |
43 * | | | 0x70d7-0x70db |
44 * | | | 0x70de-0x70df |
Chad Dupuis7108b762014-04-11 16:54:45 -040045 * | Task Management | 0x803d | 0x8000,0x800b |
Chad Dupuis63ee7072014-04-11 16:54:46 -040046 * | | | 0x8019 |
Chad Dupuis7108b762014-04-11 16:54:45 -040047 * | | | 0x8025,0x8026 |
48 * | | | 0x8031,0x8032 |
49 * | | | 0x8039,0x803c |
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -040050 * | AER/EEH | 0x9011 | |
Arun Easie02587d2011-08-16 11:29:23 -070051 * | Virtual Port | 0xa007 | |
Atul Deshmukh27f4b722014-04-11 16:54:26 -040052 * | ISP82XX Specific | 0xb157 | 0xb002,0xb024 |
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -040053 * | | | 0xb09e,0xb0ae |
Hiral Patela018d8f2014-04-11 16:54:34 -040054 * | | | 0xb0c3,0xb0c6 |
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -040055 * | | | 0xb0e0-0xb0ef |
56 * | | | 0xb085,0xb0dc |
57 * | | | 0xb107,0xb108 |
58 * | | | 0xb111,0xb11e |
59 * | | | 0xb12c,0xb12d |
60 * | | | 0xb13a,0xb142 |
61 * | | | 0xb13c-0xb140 |
Saurav Kashyap6ddcfef2013-08-27 01:37:53 -040062 * | | | 0xb149 |
Giridhar Malavali6246b8a2012-02-09 11:15:34 -080063 * | MultiQ | 0xc00c | |
Joe Carnuccio2ac224b2014-09-25 05:16:36 -040064 * | Misc | 0xd213 | 0xd011-0xd017 |
Joe Carnuccio349c3902014-09-25 05:16:40 -040065 * | | | 0xd021,0xd024 |
66 * | | | 0xd025,0xd029 |
67 * | | | 0xd02a,0xd02e |
Joe Carnuccio2ac224b2014-09-25 05:16:36 -040068 * | | | 0xd031-0xd0ff |
Chad Dupuisf73cb692014-02-26 04:15:06 -050069 * | | | 0xd101-0xd1fe |
Joe Carnuccio2ac224b2014-09-25 05:16:36 -040070 * | | | 0xd214-0xd2fe |
Quinn Tranf83adb62014-04-11 16:54:43 -040071 * | Target Mode | 0xe078 | |
Saurav Kashyap6ddcfef2013-08-27 01:37:53 -040072 * | Target Mode Management | 0xf072 | 0xf002-0xf003 |
73 * | | | 0xf046-0xf049 |
Nicholas Bellinger2d70c102012-05-15 14:34:28 -040074 * | Target Mode Task Management | 0x1000b | |
Arun Easie02587d2011-08-16 11:29:23 -070075 * ----------------------------------------------------------------------
Saurav Kashyap3ce88662011-07-14 12:00:12 -070076 */
77
Linus Torvalds1da177e2005-04-16 15:20:36 -070078#include "qla_def.h"
79
80#include <linux/delay.h>
81
Saurav Kashyap3ce88662011-07-14 12:00:12 -070082static uint32_t ql_dbg_offset = 0x800;
83
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070084static inline void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080085qla2xxx_prep_dump(struct qla_hw_data *ha, struct qla2xxx_fw_dump *fw_dump)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -070086{
87 fw_dump->fw_major_version = htonl(ha->fw_major_version);
88 fw_dump->fw_minor_version = htonl(ha->fw_minor_version);
89 fw_dump->fw_subminor_version = htonl(ha->fw_subminor_version);
90 fw_dump->fw_attributes = htonl(ha->fw_attributes);
91
92 fw_dump->vendor = htonl(ha->pdev->vendor);
93 fw_dump->device = htonl(ha->pdev->device);
94 fw_dump->subsystem_vendor = htonl(ha->pdev->subsystem_vendor);
95 fw_dump->subsystem_device = htonl(ha->pdev->subsystem_device);
96}
97
98static inline void *
Anirban Chakraborty73208df2008-12-09 16:45:39 -080099qla2xxx_copy_queues(struct qla_hw_data *ha, void *ptr)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700100{
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800101 struct req_que *req = ha->req_q_map[0];
102 struct rsp_que *rsp = ha->rsp_q_map[0];
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700103 /* Request queue. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800104 memcpy(ptr, req->ring, req->length *
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700105 sizeof(request_t));
106
107 /* Response queue. */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800108 ptr += req->length * sizeof(request_t);
109 memcpy(ptr, rsp->ring, rsp->length *
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700110 sizeof(response_t));
111
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800112 return ptr + (rsp->length * sizeof(response_t));
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700113}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
Chad Dupuisf73cb692014-02-26 04:15:06 -0500115int
116qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
117 uint32_t ram_dwords, void **nxt)
118{
119 int rval;
120 uint32_t cnt, stat, timer, dwords, idx;
121 uint16_t mb0, mb1;
122 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
123 dma_addr_t dump_dma = ha->gid_list_dma;
124 uint32_t *dump = (uint32_t *)ha->gid_list;
125
126 rval = QLA_SUCCESS;
127 mb0 = 0;
128
129 WRT_REG_WORD(&reg->mailbox0, MBC_LOAD_DUMP_MPI_RAM);
130 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
131
132 dwords = qla2x00_gid_list_size(ha) / 4;
133 for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS;
134 cnt += dwords, addr += dwords) {
135 if (cnt + dwords > ram_dwords)
136 dwords = ram_dwords - cnt;
137
138 WRT_REG_WORD(&reg->mailbox1, LSW(addr));
139 WRT_REG_WORD(&reg->mailbox8, MSW(addr));
140
141 WRT_REG_WORD(&reg->mailbox2, MSW(dump_dma));
142 WRT_REG_WORD(&reg->mailbox3, LSW(dump_dma));
143 WRT_REG_WORD(&reg->mailbox6, MSW(MSD(dump_dma)));
144 WRT_REG_WORD(&reg->mailbox7, LSW(MSD(dump_dma)));
145
146 WRT_REG_WORD(&reg->mailbox4, MSW(dwords));
147 WRT_REG_WORD(&reg->mailbox5, LSW(dwords));
148
149 WRT_REG_WORD(&reg->mailbox9, 0);
150 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
151
152 ha->flags.mbox_int = 0;
153 for (timer = 6000000; timer; timer--) {
154 /* Check for pending interrupts. */
155 stat = RD_REG_DWORD(&reg->host_status);
156 if (stat & HSRX_RISC_INT) {
157 stat &= 0xff;
158
159 if (stat == 0x1 || stat == 0x2 ||
160 stat == 0x10 || stat == 0x11) {
161 set_bit(MBX_INTERRUPT,
162 &ha->mbx_cmd_flags);
163
164 mb0 = RD_REG_WORD(&reg->mailbox0);
165 mb1 = RD_REG_WORD(&reg->mailbox1);
166
167 WRT_REG_DWORD(&reg->hccr,
168 HCCRX_CLR_RISC_INT);
169 RD_REG_DWORD(&reg->hccr);
170 break;
171 }
172
173 /* Clear this intr; it wasn't a mailbox intr */
174 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
175 RD_REG_DWORD(&reg->hccr);
176 }
177 udelay(5);
178 }
179 ha->flags.mbox_int = 1;
180
181 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
182 rval = mb0 & MBS_MASK;
183 for (idx = 0; idx < dwords; idx++)
184 ram[cnt + idx] = IS_QLA27XX(ha) ?
185 le32_to_cpu(dump[idx]) : swab32(dump[idx]);
186 } else {
187 rval = QLA_FUNCTION_FAILED;
188 }
189 }
190
191 *nxt = rval == QLA_SUCCESS ? &ram[cnt] : NULL;
192 return rval;
193}
194
195int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800196qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram,
Andrew Vasquezc5722702008-04-24 15:21:22 -0700197 uint32_t ram_dwords, void **nxt)
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700198{
199 int rval;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700200 uint32_t cnt, stat, timer, dwords, idx;
201 uint16_t mb0;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700202 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700203 dma_addr_t dump_dma = ha->gid_list_dma;
204 uint32_t *dump = (uint32_t *)ha->gid_list;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700205
206 rval = QLA_SUCCESS;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700207 mb0 = 0;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700208
Andrew Vasquezc5722702008-04-24 15:21:22 -0700209 WRT_REG_WORD(&reg->mailbox0, MBC_DUMP_RISC_RAM_EXTENDED);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700210 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
211
Chad Dupuis642ef982012-02-09 11:15:57 -0800212 dwords = qla2x00_gid_list_size(ha) / 4;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700213 for (cnt = 0; cnt < ram_dwords && rval == QLA_SUCCESS;
214 cnt += dwords, addr += dwords) {
215 if (cnt + dwords > ram_dwords)
216 dwords = ram_dwords - cnt;
217
218 WRT_REG_WORD(&reg->mailbox1, LSW(addr));
219 WRT_REG_WORD(&reg->mailbox8, MSW(addr));
220
221 WRT_REG_WORD(&reg->mailbox2, MSW(dump_dma));
222 WRT_REG_WORD(&reg->mailbox3, LSW(dump_dma));
223 WRT_REG_WORD(&reg->mailbox6, MSW(MSD(dump_dma)));
224 WRT_REG_WORD(&reg->mailbox7, LSW(MSD(dump_dma)));
225
226 WRT_REG_WORD(&reg->mailbox4, MSW(dwords));
227 WRT_REG_WORD(&reg->mailbox5, LSW(dwords));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700228 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
229
Chad Dupuisf73cb692014-02-26 04:15:06 -0500230 ha->flags.mbox_int = 0;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700231 for (timer = 6000000; timer; timer--) {
232 /* Check for pending interrupts. */
233 stat = RD_REG_DWORD(&reg->host_status);
234 if (stat & HSRX_RISC_INT) {
235 stat &= 0xff;
236
237 if (stat == 0x1 || stat == 0x2 ||
238 stat == 0x10 || stat == 0x11) {
239 set_bit(MBX_INTERRUPT,
240 &ha->mbx_cmd_flags);
241
Andrew Vasquezc5722702008-04-24 15:21:22 -0700242 mb0 = RD_REG_WORD(&reg->mailbox0);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700243
244 WRT_REG_DWORD(&reg->hccr,
245 HCCRX_CLR_RISC_INT);
246 RD_REG_DWORD(&reg->hccr);
247 break;
248 }
249
250 /* Clear this intr; it wasn't a mailbox intr */
251 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
252 RD_REG_DWORD(&reg->hccr);
253 }
254 udelay(5);
255 }
Chad Dupuisf73cb692014-02-26 04:15:06 -0500256 ha->flags.mbox_int = 1;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700257
258 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
Andrew Vasquezc5722702008-04-24 15:21:22 -0700259 rval = mb0 & MBS_MASK;
260 for (idx = 0; idx < dwords; idx++)
Chad Dupuisf73cb692014-02-26 04:15:06 -0500261 ram[cnt + idx] = IS_QLA27XX(ha) ?
262 le32_to_cpu(dump[idx]) : swab32(dump[idx]);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700263 } else {
264 rval = QLA_FUNCTION_FAILED;
265 }
266 }
267
Andrew Vasquezc5722702008-04-24 15:21:22 -0700268 *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -0700269 return rval;
270}
271
Andrew Vasquezc5722702008-04-24 15:21:22 -0700272static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800273qla24xx_dump_memory(struct qla_hw_data *ha, uint32_t *code_ram,
Andrew Vasquezc5722702008-04-24 15:21:22 -0700274 uint32_t cram_size, void **nxt)
275{
276 int rval;
277
278 /* Code RAM. */
279 rval = qla24xx_dump_ram(ha, 0x20000, code_ram, cram_size / 4, nxt);
280 if (rval != QLA_SUCCESS)
281 return rval;
282
Hiral Patel61f098d2014-04-11 16:54:21 -0400283 set_bit(RISC_SRAM_DUMP_CMPL, &ha->fw_dump_cap_flags);
284
Andrew Vasquezc5722702008-04-24 15:21:22 -0700285 /* External Memory. */
Hiral Patel61f098d2014-04-11 16:54:21 -0400286 rval = qla24xx_dump_ram(ha, 0x100000, *nxt,
Andrew Vasquezc5722702008-04-24 15:21:22 -0700287 ha->fw_memory_size - 0x100000 + 1, nxt);
Hiral Patel61f098d2014-04-11 16:54:21 -0400288 if (rval == QLA_SUCCESS)
289 set_bit(RISC_EXT_MEM_DUMP_CMPL, &ha->fw_dump_cap_flags);
290
291 return rval;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700292}
293
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700294static uint32_t *
295qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase,
296 uint32_t count, uint32_t *buf)
297{
298 uint32_t __iomem *dmp_reg;
299
300 WRT_REG_DWORD(&reg->iobase_addr, iobase);
301 dmp_reg = &reg->iobase_window;
302 while (count--)
303 *buf++ = htonl(RD_REG_DWORD(dmp_reg++));
304
305 return buf;
306}
307
Hiral Patel2f389fc2014-04-11 16:54:20 -0400308void
Hiral Patel61f098d2014-04-11 16:54:21 -0400309qla24xx_pause_risc(struct device_reg_24xx __iomem *reg, struct qla_hw_data *ha)
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700310{
Andrew Vasquezc3b058a2007-09-20 14:07:38 -0700311 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_PAUSE);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700312
Hiral Patel2f389fc2014-04-11 16:54:20 -0400313 /* 100 usec delay is sufficient enough for hardware to pause RISC */
314 udelay(100);
Hiral Patel61f098d2014-04-11 16:54:21 -0400315 if (RD_REG_DWORD(&reg->host_status) & HSRX_RISC_PAUSED)
316 set_bit(RISC_PAUSE_CMPL, &ha->fw_dump_cap_flags);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700317}
318
Chad Dupuisf73cb692014-02-26 04:15:06 -0500319int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800320qla24xx_soft_reset(struct qla_hw_data *ha)
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700321{
322 int rval = QLA_SUCCESS;
323 uint32_t cnt;
Hiral Patel2f389fc2014-04-11 16:54:20 -0400324 uint16_t wd;
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700325 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
326
Hiral Patel2f389fc2014-04-11 16:54:20 -0400327 /*
328 * Reset RISC. The delay is dependent on system architecture.
329 * Driver can proceed with the reset sequence after waiting
330 * for a timeout period.
331 */
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700332 WRT_REG_DWORD(&reg->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
333 for (cnt = 0; cnt < 30000; cnt++) {
334 if ((RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE) == 0)
335 break;
336
337 udelay(10);
338 }
Hiral Patel61f098d2014-04-11 16:54:21 -0400339 if (!(RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE))
340 set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700341
342 WRT_REG_DWORD(&reg->ctrl_status,
343 CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES);
344 pci_read_config_word(ha->pdev, PCI_COMMAND, &wd);
345
346 udelay(100);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700347
348 /* Wait for soft-reset to complete. */
349 for (cnt = 0; cnt < 30000; cnt++) {
350 if ((RD_REG_DWORD(&reg->ctrl_status) &
351 CSRX_ISP_SOFT_RESET) == 0)
352 break;
353
354 udelay(10);
355 }
Hiral Patel61f098d2014-04-11 16:54:21 -0400356 if (!(RD_REG_DWORD(&reg->ctrl_status) & CSRX_ISP_SOFT_RESET))
357 set_bit(ISP_RESET_CMPL, &ha->fw_dump_cap_flags);
358
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700359 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
360 RD_REG_DWORD(&reg->hccr); /* PCI Posting. */
361
Hiral Patel2f389fc2014-04-11 16:54:20 -0400362 for (cnt = 10000; RD_REG_WORD(&reg->mailbox0) != 0 &&
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700363 rval == QLA_SUCCESS; cnt--) {
364 if (cnt)
Hiral Patel2f389fc2014-04-11 16:54:20 -0400365 udelay(10);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700366 else
367 rval = QLA_FUNCTION_TIMEOUT;
368 }
Hiral Patel61f098d2014-04-11 16:54:21 -0400369 if (rval == QLA_SUCCESS)
370 set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700371
372 return rval;
373}
374
Andrew Vasquezc5722702008-04-24 15:21:22 -0700375static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800376qla2xxx_dump_ram(struct qla_hw_data *ha, uint32_t addr, uint16_t *ram,
Andrew Vasqueze18e9632009-06-17 10:30:31 -0700377 uint32_t ram_words, void **nxt)
Andrew Vasquezc5722702008-04-24 15:21:22 -0700378{
379 int rval;
380 uint32_t cnt, stat, timer, words, idx;
381 uint16_t mb0;
382 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
383 dma_addr_t dump_dma = ha->gid_list_dma;
384 uint16_t *dump = (uint16_t *)ha->gid_list;
385
386 rval = QLA_SUCCESS;
387 mb0 = 0;
388
389 WRT_MAILBOX_REG(ha, reg, 0, MBC_DUMP_RISC_RAM_EXTENDED);
390 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
391
Chad Dupuis642ef982012-02-09 11:15:57 -0800392 words = qla2x00_gid_list_size(ha) / 2;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700393 for (cnt = 0; cnt < ram_words && rval == QLA_SUCCESS;
394 cnt += words, addr += words) {
395 if (cnt + words > ram_words)
396 words = ram_words - cnt;
397
398 WRT_MAILBOX_REG(ha, reg, 1, LSW(addr));
399 WRT_MAILBOX_REG(ha, reg, 8, MSW(addr));
400
401 WRT_MAILBOX_REG(ha, reg, 2, MSW(dump_dma));
402 WRT_MAILBOX_REG(ha, reg, 3, LSW(dump_dma));
403 WRT_MAILBOX_REG(ha, reg, 6, MSW(MSD(dump_dma)));
404 WRT_MAILBOX_REG(ha, reg, 7, LSW(MSD(dump_dma)));
405
406 WRT_MAILBOX_REG(ha, reg, 4, words);
407 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
408
409 for (timer = 6000000; timer; timer--) {
410 /* Check for pending interrupts. */
411 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
412 if (stat & HSR_RISC_INT) {
413 stat &= 0xff;
414
415 if (stat == 0x1 || stat == 0x2) {
416 set_bit(MBX_INTERRUPT,
417 &ha->mbx_cmd_flags);
418
419 mb0 = RD_MAILBOX_REG(ha, reg, 0);
420
421 /* Release mailbox registers. */
422 WRT_REG_WORD(&reg->semaphore, 0);
423 WRT_REG_WORD(&reg->hccr,
424 HCCR_CLR_RISC_INT);
425 RD_REG_WORD(&reg->hccr);
426 break;
427 } else if (stat == 0x10 || stat == 0x11) {
428 set_bit(MBX_INTERRUPT,
429 &ha->mbx_cmd_flags);
430
431 mb0 = RD_MAILBOX_REG(ha, reg, 0);
432
433 WRT_REG_WORD(&reg->hccr,
434 HCCR_CLR_RISC_INT);
435 RD_REG_WORD(&reg->hccr);
436 break;
437 }
438
439 /* clear this intr; it wasn't a mailbox intr */
440 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
441 RD_REG_WORD(&reg->hccr);
442 }
443 udelay(5);
444 }
445
446 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
447 rval = mb0 & MBS_MASK;
448 for (idx = 0; idx < words; idx++)
449 ram[cnt + idx] = swab16(dump[idx]);
450 } else {
451 rval = QLA_FUNCTION_FAILED;
452 }
453 }
454
455 *nxt = rval == QLA_SUCCESS ? &ram[cnt]: NULL;
456 return rval;
457}
458
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700459static inline void
460qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count,
461 uint16_t *buf)
462{
463 uint16_t __iomem *dmp_reg = &reg->u.isp2300.fb_cmd;
464
465 while (count--)
466 *buf++ = htons(RD_REG_WORD(dmp_reg++));
467}
468
Andrew Vasquezbb99de62009-01-05 11:18:08 -0800469static inline void *
470qla24xx_copy_eft(struct qla_hw_data *ha, void *ptr)
471{
472 if (!ha->eft)
473 return ptr;
474
475 memcpy(ptr, ha->eft, ntohl(ha->fw_dump->eft_size));
476 return ptr + ntohl(ha->fw_dump->eft_size);
477}
478
479static inline void *
480qla25xx_copy_fce(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
481{
482 uint32_t cnt;
483 uint32_t *iter_reg;
484 struct qla2xxx_fce_chain *fcec = ptr;
485
486 if (!ha->fce)
487 return ptr;
488
489 *last_chain = &fcec->type;
490 fcec->type = __constant_htonl(DUMP_CHAIN_FCE);
491 fcec->chain_size = htonl(sizeof(struct qla2xxx_fce_chain) +
492 fce_calc_size(ha->fce_bufs));
493 fcec->size = htonl(fce_calc_size(ha->fce_bufs));
494 fcec->addr_l = htonl(LSD(ha->fce_dma));
495 fcec->addr_h = htonl(MSD(ha->fce_dma));
496
497 iter_reg = fcec->eregs;
498 for (cnt = 0; cnt < 8; cnt++)
499 *iter_reg++ = htonl(ha->fce_mb[cnt]);
500
501 memcpy(iter_reg, ha->fce, ntohl(fcec->size));
502
Giridhar Malavali3cb0a672011-11-18 09:03:11 -0800503 return (char *)iter_reg + ntohl(fcec->size);
Andrew Vasquezbb99de62009-01-05 11:18:08 -0800504}
505
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800506static inline void *
Nicholas Bellinger2d70c102012-05-15 14:34:28 -0400507qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr,
508 uint32_t **last_chain)
509{
510 struct qla2xxx_mqueue_chain *q;
511 struct qla2xxx_mqueue_header *qh;
512 uint32_t num_queues;
513 int que;
514 struct {
515 int length;
516 void *ring;
517 } aq, *aqp;
518
Arun Easi00876ae2013-03-25 02:21:37 -0400519 if (!ha->tgt.atio_ring)
Nicholas Bellinger2d70c102012-05-15 14:34:28 -0400520 return ptr;
521
522 num_queues = 1;
523 aqp = &aq;
524 aqp->length = ha->tgt.atio_q_length;
525 aqp->ring = ha->tgt.atio_ring;
526
527 for (que = 0; que < num_queues; que++) {
528 /* aqp = ha->atio_q_map[que]; */
529 q = ptr;
530 *last_chain = &q->type;
531 q->type = __constant_htonl(DUMP_CHAIN_QUEUE);
532 q->chain_size = htonl(
533 sizeof(struct qla2xxx_mqueue_chain) +
534 sizeof(struct qla2xxx_mqueue_header) +
535 (aqp->length * sizeof(request_t)));
536 ptr += sizeof(struct qla2xxx_mqueue_chain);
537
538 /* Add header. */
539 qh = ptr;
540 qh->queue = __constant_htonl(TYPE_ATIO_QUEUE);
541 qh->number = htonl(que);
542 qh->size = htonl(aqp->length * sizeof(request_t));
543 ptr += sizeof(struct qla2xxx_mqueue_header);
544
545 /* Add data. */
546 memcpy(ptr, aqp->ring, aqp->length * sizeof(request_t));
547
548 ptr += aqp->length * sizeof(request_t);
549 }
550
551 return ptr;
552}
553
554static inline void *
Giridhar Malavali050c9bb2012-02-09 11:15:33 -0800555qla25xx_copy_mqueues(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
556{
557 struct qla2xxx_mqueue_chain *q;
558 struct qla2xxx_mqueue_header *qh;
559 struct req_que *req;
560 struct rsp_que *rsp;
561 int que;
562
563 if (!ha->mqenable)
564 return ptr;
565
566 /* Request queues */
567 for (que = 1; que < ha->max_req_queues; que++) {
568 req = ha->req_q_map[que];
569 if (!req)
570 break;
571
572 /* Add chain. */
573 q = ptr;
574 *last_chain = &q->type;
575 q->type = __constant_htonl(DUMP_CHAIN_QUEUE);
576 q->chain_size = htonl(
577 sizeof(struct qla2xxx_mqueue_chain) +
578 sizeof(struct qla2xxx_mqueue_header) +
579 (req->length * sizeof(request_t)));
580 ptr += sizeof(struct qla2xxx_mqueue_chain);
581
582 /* Add header. */
583 qh = ptr;
584 qh->queue = __constant_htonl(TYPE_REQUEST_QUEUE);
585 qh->number = htonl(que);
586 qh->size = htonl(req->length * sizeof(request_t));
587 ptr += sizeof(struct qla2xxx_mqueue_header);
588
589 /* Add data. */
590 memcpy(ptr, req->ring, req->length * sizeof(request_t));
591 ptr += req->length * sizeof(request_t);
592 }
593
594 /* Response queues */
595 for (que = 1; que < ha->max_rsp_queues; que++) {
596 rsp = ha->rsp_q_map[que];
597 if (!rsp)
598 break;
599
600 /* Add chain. */
601 q = ptr;
602 *last_chain = &q->type;
603 q->type = __constant_htonl(DUMP_CHAIN_QUEUE);
604 q->chain_size = htonl(
605 sizeof(struct qla2xxx_mqueue_chain) +
606 sizeof(struct qla2xxx_mqueue_header) +
607 (rsp->length * sizeof(response_t)));
608 ptr += sizeof(struct qla2xxx_mqueue_chain);
609
610 /* Add header. */
611 qh = ptr;
612 qh->queue = __constant_htonl(TYPE_RESPONSE_QUEUE);
613 qh->number = htonl(que);
614 qh->size = htonl(rsp->length * sizeof(response_t));
615 ptr += sizeof(struct qla2xxx_mqueue_header);
616
617 /* Add data. */
618 memcpy(ptr, rsp->ring, rsp->length * sizeof(response_t));
619 ptr += rsp->length * sizeof(response_t);
620 }
621
622 return ptr;
623}
624
625static inline void *
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800626qla25xx_copy_mq(struct qla_hw_data *ha, void *ptr, uint32_t **last_chain)
627{
628 uint32_t cnt, que_idx;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700629 uint8_t que_cnt;
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800630 struct qla2xxx_mq_chain *mq = ptr;
Andrew Vasquezda9b1d52013-08-27 01:37:30 -0400631 device_reg_t __iomem *reg;
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800632
Chad Dupuisf73cb692014-02-26 04:15:06 -0500633 if (!ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha))
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800634 return ptr;
635
636 mq = ptr;
637 *last_chain = &mq->type;
638 mq->type = __constant_htonl(DUMP_CHAIN_MQ);
639 mq->chain_size = __constant_htonl(sizeof(struct qla2xxx_mq_chain));
640
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700641 que_cnt = ha->max_req_queues > ha->max_rsp_queues ?
642 ha->max_req_queues : ha->max_rsp_queues;
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800643 mq->count = htonl(que_cnt);
644 for (cnt = 0; cnt < que_cnt; cnt++) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -0400645 reg = ISP_QUE_REG(ha, cnt);
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800646 que_idx = cnt * 4;
Andrew Vasquezda9b1d52013-08-27 01:37:30 -0400647 mq->qregs[que_idx] =
648 htonl(RD_REG_DWORD(&reg->isp25mq.req_q_in));
649 mq->qregs[que_idx+1] =
650 htonl(RD_REG_DWORD(&reg->isp25mq.req_q_out));
651 mq->qregs[que_idx+2] =
652 htonl(RD_REG_DWORD(&reg->isp25mq.rsp_q_in));
653 mq->qregs[que_idx+3] =
654 htonl(RD_REG_DWORD(&reg->isp25mq.rsp_q_out));
Andrew Vasquezd63ab532009-01-05 11:18:09 -0800655 }
656
657 return ptr + sizeof(struct qla2xxx_mq_chain);
658}
659
Giridhar Malavali08de2842011-08-16 11:31:44 -0700660void
Andrew Vasquez3420d362009-10-13 15:16:45 -0700661qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval)
662{
663 struct qla_hw_data *ha = vha->hw;
664
665 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700666 ql_log(ql_log_warn, vha, 0xd000,
Hiral Patel61f098d2014-04-11 16:54:21 -0400667 "Failed to dump firmware (%x), dump status flags (0x%lx).\n",
668 rval, ha->fw_dump_cap_flags);
Andrew Vasquez3420d362009-10-13 15:16:45 -0700669 ha->fw_dumped = 0;
670 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700671 ql_log(ql_log_info, vha, 0xd001,
Hiral Patel61f098d2014-04-11 16:54:21 -0400672 "Firmware dump saved to temp buffer (%ld/%p), dump status flags (0x%lx).\n",
673 vha->host_no, ha->fw_dump, ha->fw_dump_cap_flags);
Andrew Vasquez3420d362009-10-13 15:16:45 -0700674 ha->fw_dumped = 1;
675 qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
676 }
677}
678
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679/**
680 * qla2300_fw_dump() - Dumps binary data from the 2300 firmware.
681 * @ha: HA context
682 * @hardware_locked: Called with the hardware_lock
683 */
684void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800685qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686{
687 int rval;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700688 uint32_t cnt;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800689 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez3d716442005-07-06 10:30:26 -0700690 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700691 uint16_t __iomem *dmp_reg;
692 unsigned long flags;
693 struct qla2300_fw_dump *fw;
Andrew Vasquezc5722702008-04-24 15:21:22 -0700694 void *nxt;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800695 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 flags = 0;
698
699 if (!hardware_locked)
700 spin_lock_irqsave(&ha->hardware_lock, flags);
701
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700702 if (!ha->fw_dump) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700703 ql_log(ql_log_warn, vha, 0xd002,
704 "No buffer available for dump.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705 goto qla2300_fw_dump_failed;
706 }
707
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700708 if (ha->fw_dumped) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700709 ql_log(ql_log_warn, vha, 0xd003,
710 "Firmware has been previously dumped (%p) "
711 "-- ignoring request.\n",
712 ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 goto qla2300_fw_dump_failed;
714 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700715 fw = &ha->fw_dump->isp.isp23;
716 qla2xxx_prep_dump(ha, ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717
718 rval = QLA_SUCCESS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700719 fw->hccr = htons(RD_REG_WORD(&reg->hccr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720
721 /* Pause RISC. */
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700722 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 if (IS_QLA2300(ha)) {
724 for (cnt = 30000;
725 (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
726 rval == QLA_SUCCESS; cnt--) {
727 if (cnt)
728 udelay(100);
729 else
730 rval = QLA_FUNCTION_TIMEOUT;
731 }
732 } else {
733 RD_REG_WORD(&reg->hccr); /* PCI Posting. */
734 udelay(10);
735 }
736
737 if (rval == QLA_SUCCESS) {
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700738 dmp_reg = &reg->flash_address;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700739 for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700740 fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700742 dmp_reg = &reg->u.isp2300.req_q_in;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700743 for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700744 fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700746 dmp_reg = &reg->u.isp2300.mailbox0;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700747 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700748 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749
750 WRT_REG_WORD(&reg->ctrl_status, 0x40);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700751 qla2xxx_read_window(reg, 32, fw->resp_dma_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752
753 WRT_REG_WORD(&reg->ctrl_status, 0x50);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700754 qla2xxx_read_window(reg, 48, fw->dma_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755
756 WRT_REG_WORD(&reg->ctrl_status, 0x00);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700757 dmp_reg = &reg->risc_hw;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700758 for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700759 fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700761 WRT_REG_WORD(&reg->pcr, 0x2000);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700762 qla2xxx_read_window(reg, 16, fw->risc_gp0_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700764 WRT_REG_WORD(&reg->pcr, 0x2200);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700765 qla2xxx_read_window(reg, 16, fw->risc_gp1_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700767 WRT_REG_WORD(&reg->pcr, 0x2400);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700768 qla2xxx_read_window(reg, 16, fw->risc_gp2_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700770 WRT_REG_WORD(&reg->pcr, 0x2600);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700771 qla2xxx_read_window(reg, 16, fw->risc_gp3_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700773 WRT_REG_WORD(&reg->pcr, 0x2800);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700774 qla2xxx_read_window(reg, 16, fw->risc_gp4_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700776 WRT_REG_WORD(&reg->pcr, 0x2A00);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700777 qla2xxx_read_window(reg, 16, fw->risc_gp5_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700779 WRT_REG_WORD(&reg->pcr, 0x2C00);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700780 qla2xxx_read_window(reg, 16, fw->risc_gp6_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700782 WRT_REG_WORD(&reg->pcr, 0x2E00);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700783 qla2xxx_read_window(reg, 16, fw->risc_gp7_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700785 WRT_REG_WORD(&reg->ctrl_status, 0x10);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700786 qla2xxx_read_window(reg, 64, fw->frame_buf_hdw_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700788 WRT_REG_WORD(&reg->ctrl_status, 0x20);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700789 qla2xxx_read_window(reg, 64, fw->fpm_b0_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700791 WRT_REG_WORD(&reg->ctrl_status, 0x30);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700792 qla2xxx_read_window(reg, 64, fw->fpm_b1_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793
794 /* Reset RISC. */
795 WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
796 for (cnt = 0; cnt < 30000; cnt++) {
797 if ((RD_REG_WORD(&reg->ctrl_status) &
798 CSR_ISP_SOFT_RESET) == 0)
799 break;
800
801 udelay(10);
802 }
803 }
804
805 if (!IS_QLA2300(ha)) {
806 for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
807 rval == QLA_SUCCESS; cnt--) {
808 if (cnt)
809 udelay(100);
810 else
811 rval = QLA_FUNCTION_TIMEOUT;
812 }
813 }
814
Andrew Vasquezc5722702008-04-24 15:21:22 -0700815 /* Get RISC SRAM. */
816 if (rval == QLA_SUCCESS)
817 rval = qla2xxx_dump_ram(ha, 0x800, fw->risc_ram,
818 sizeof(fw->risc_ram) / 2, &nxt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819
Andrew Vasquezc5722702008-04-24 15:21:22 -0700820 /* Get stack SRAM. */
821 if (rval == QLA_SUCCESS)
822 rval = qla2xxx_dump_ram(ha, 0x10000, fw->stack_ram,
823 sizeof(fw->stack_ram) / 2, &nxt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824
Andrew Vasquezc5722702008-04-24 15:21:22 -0700825 /* Get data SRAM. */
826 if (rval == QLA_SUCCESS)
827 rval = qla2xxx_dump_ram(ha, 0x11000, fw->data_ram,
828 ha->fw_memory_size - 0x11000 + 1, &nxt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700830 if (rval == QLA_SUCCESS)
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800831 qla2xxx_copy_queues(ha, nxt);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700832
Andrew Vasquez3420d362009-10-13 15:16:45 -0700833 qla2xxx_dump_post_process(base_vha, rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834
835qla2300_fw_dump_failed:
836 if (!hardware_locked)
837 spin_unlock_irqrestore(&ha->hardware_lock, flags);
838}
839
840/**
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware.
842 * @ha: HA context
843 * @hardware_locked: Called with the hardware_lock
844 */
845void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800846qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847{
848 int rval;
849 uint32_t cnt, timer;
850 uint16_t risc_address;
851 uint16_t mb0, mb2;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800852 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez3d716442005-07-06 10:30:26 -0700853 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 uint16_t __iomem *dmp_reg;
855 unsigned long flags;
856 struct qla2100_fw_dump *fw;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800857 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858
859 risc_address = 0;
860 mb0 = mb2 = 0;
861 flags = 0;
862
863 if (!hardware_locked)
864 spin_lock_irqsave(&ha->hardware_lock, flags);
865
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700866 if (!ha->fw_dump) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700867 ql_log(ql_log_warn, vha, 0xd004,
868 "No buffer available for dump.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 goto qla2100_fw_dump_failed;
870 }
871
Andrew Vasquezd4e3e042006-05-17 15:09:50 -0700872 if (ha->fw_dumped) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700873 ql_log(ql_log_warn, vha, 0xd005,
874 "Firmware has been previously dumped (%p) "
875 "-- ignoring request.\n",
876 ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 goto qla2100_fw_dump_failed;
878 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700879 fw = &ha->fw_dump->isp.isp21;
880 qla2xxx_prep_dump(ha, ha->fw_dump);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881
882 rval = QLA_SUCCESS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700883 fw->hccr = htons(RD_REG_WORD(&reg->hccr));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
885 /* Pause RISC. */
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700886 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 for (cnt = 30000; (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
888 rval == QLA_SUCCESS; cnt--) {
889 if (cnt)
890 udelay(100);
891 else
892 rval = QLA_FUNCTION_TIMEOUT;
893 }
894 if (rval == QLA_SUCCESS) {
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700895 dmp_reg = &reg->flash_address;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700896 for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700897 fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700899 dmp_reg = &reg->u.isp2100.mailbox0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700901 if (cnt == 8)
902 dmp_reg = &reg->u_end.isp2200.mailbox8;
903
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700904 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 }
906
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700907 dmp_reg = &reg->u.isp2100.unused_2[0];
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700908 for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700909 fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910
911 WRT_REG_WORD(&reg->ctrl_status, 0x00);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700912 dmp_reg = &reg->risc_hw;
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700913 for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++)
Andrew Vasqueza7a167b2006-06-23 16:10:29 -0700914 fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700916 WRT_REG_WORD(&reg->pcr, 0x2000);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700917 qla2xxx_read_window(reg, 16, fw->risc_gp0_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700919 WRT_REG_WORD(&reg->pcr, 0x2100);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700920 qla2xxx_read_window(reg, 16, fw->risc_gp1_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700922 WRT_REG_WORD(&reg->pcr, 0x2200);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700923 qla2xxx_read_window(reg, 16, fw->risc_gp2_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700925 WRT_REG_WORD(&reg->pcr, 0x2300);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700926 qla2xxx_read_window(reg, 16, fw->risc_gp3_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700928 WRT_REG_WORD(&reg->pcr, 0x2400);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700929 qla2xxx_read_window(reg, 16, fw->risc_gp4_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700931 WRT_REG_WORD(&reg->pcr, 0x2500);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700932 qla2xxx_read_window(reg, 16, fw->risc_gp5_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700934 WRT_REG_WORD(&reg->pcr, 0x2600);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700935 qla2xxx_read_window(reg, 16, fw->risc_gp6_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700937 WRT_REG_WORD(&reg->pcr, 0x2700);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700938 qla2xxx_read_window(reg, 16, fw->risc_gp7_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700940 WRT_REG_WORD(&reg->ctrl_status, 0x10);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700941 qla2xxx_read_window(reg, 16, fw->frame_buf_hdw_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700943 WRT_REG_WORD(&reg->ctrl_status, 0x20);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700944 qla2xxx_read_window(reg, 64, fw->fpm_b0_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700946 WRT_REG_WORD(&reg->ctrl_status, 0x30);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -0700947 qla2xxx_read_window(reg, 64, fw->fpm_b1_reg);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948
949 /* Reset the ISP. */
950 WRT_REG_WORD(&reg->ctrl_status, CSR_ISP_SOFT_RESET);
951 }
952
953 for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 &&
954 rval == QLA_SUCCESS; cnt--) {
955 if (cnt)
956 udelay(100);
957 else
958 rval = QLA_FUNCTION_TIMEOUT;
959 }
960
961 /* Pause RISC. */
962 if (rval == QLA_SUCCESS && (IS_QLA2200(ha) || (IS_QLA2100(ha) &&
963 (RD_REG_WORD(&reg->mctr) & (BIT_1 | BIT_0)) != 0))) {
964
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -0700965 WRT_REG_WORD(&reg->hccr, HCCR_PAUSE_RISC);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966 for (cnt = 30000;
967 (RD_REG_WORD(&reg->hccr) & HCCR_RISC_PAUSE) == 0 &&
968 rval == QLA_SUCCESS; cnt--) {
969 if (cnt)
970 udelay(100);
971 else
972 rval = QLA_FUNCTION_TIMEOUT;
973 }
974 if (rval == QLA_SUCCESS) {
975 /* Set memory configuration and timing. */
976 if (IS_QLA2100(ha))
977 WRT_REG_WORD(&reg->mctr, 0xf1);
978 else
979 WRT_REG_WORD(&reg->mctr, 0xf2);
980 RD_REG_WORD(&reg->mctr); /* PCI Posting. */
981
982 /* Release RISC. */
983 WRT_REG_WORD(&reg->hccr, HCCR_RELEASE_RISC);
984 }
985 }
986
987 if (rval == QLA_SUCCESS) {
988 /* Get RISC SRAM. */
989 risc_address = 0x1000;
990 WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
991 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
992 }
993 for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS;
994 cnt++, risc_address++) {
995 WRT_MAILBOX_REG(ha, reg, 1, risc_address);
996 WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
997
998 for (timer = 6000000; timer != 0; timer--) {
999 /* Check for pending interrupts. */
1000 if (RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) {
1001 if (RD_REG_WORD(&reg->semaphore) & BIT_0) {
1002 set_bit(MBX_INTERRUPT,
1003 &ha->mbx_cmd_flags);
1004
1005 mb0 = RD_MAILBOX_REG(ha, reg, 0);
1006 mb2 = RD_MAILBOX_REG(ha, reg, 2);
1007
1008 WRT_REG_WORD(&reg->semaphore, 0);
1009 WRT_REG_WORD(&reg->hccr,
1010 HCCR_CLR_RISC_INT);
1011 RD_REG_WORD(&reg->hccr);
1012 break;
1013 }
1014 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
1015 RD_REG_WORD(&reg->hccr);
1016 }
1017 udelay(5);
1018 }
1019
1020 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags)) {
1021 rval = mb0 & MBS_MASK;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001022 fw->risc_ram[cnt] = htons(mb2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 } else {
1024 rval = QLA_FUNCTION_FAILED;
1025 }
1026 }
1027
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001028 if (rval == QLA_SUCCESS)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001029 qla2xxx_copy_queues(ha, &fw->risc_ram[cnt]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001030
Andrew Vasquez3420d362009-10-13 15:16:45 -07001031 qla2xxx_dump_post_process(base_vha, rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032
1033qla2100_fw_dump_failed:
1034 if (!hardware_locked)
1035 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1036}
1037
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001038void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001039qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001040{
1041 int rval;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001042 uint32_t cnt;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001043 uint32_t risc_address;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001044 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001045 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1046 uint32_t __iomem *dmp_reg;
1047 uint32_t *iter_reg;
1048 uint16_t __iomem *mbx_reg;
1049 unsigned long flags;
1050 struct qla24xx_fw_dump *fw;
1051 uint32_t ext_mem_cnt;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001052 void *nxt;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001053 void *nxt_chain;
1054 uint32_t *last_chain = NULL;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001055 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001056
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001057 if (IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -07001058 return;
1059
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001060 risc_address = ext_mem_cnt = 0;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001061 flags = 0;
Hiral Patel61f098d2014-04-11 16:54:21 -04001062 ha->fw_dump_cap_flags = 0;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001063
1064 if (!hardware_locked)
1065 spin_lock_irqsave(&ha->hardware_lock, flags);
1066
Andrew Vasquezd4e3e042006-05-17 15:09:50 -07001067 if (!ha->fw_dump) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001068 ql_log(ql_log_warn, vha, 0xd006,
1069 "No buffer available for dump.\n");
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001070 goto qla24xx_fw_dump_failed;
1071 }
1072
1073 if (ha->fw_dumped) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001074 ql_log(ql_log_warn, vha, 0xd007,
1075 "Firmware has been previously dumped (%p) "
1076 "-- ignoring request.\n",
1077 ha->fw_dump);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001078 goto qla24xx_fw_dump_failed;
1079 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001080 fw = &ha->fw_dump->isp.isp24;
1081 qla2xxx_prep_dump(ha, ha->fw_dump);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001082
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07001083 fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001084
Hiral Patel2f389fc2014-04-11 16:54:20 -04001085 /*
1086 * Pause RISC. No need to track timeout, as resetting the chip
1087 * is the right approach incase of pause timeout
1088 */
Hiral Patel61f098d2014-04-11 16:54:21 -04001089 qla24xx_pause_risc(reg, ha);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001090
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001091 /* Host interface registers. */
1092 dmp_reg = &reg->flash_addr;
1093 for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
1094 fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001095
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001096 /* Disable interrupts. */
1097 WRT_REG_DWORD(&reg->ictrl, 0);
1098 RD_REG_DWORD(&reg->ictrl);
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001099
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001100 /* Shadow registers. */
1101 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1102 RD_REG_DWORD(&reg->iobase_addr);
1103 WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
1104 fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001105
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001106 WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
1107 fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001108
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001109 WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
1110 fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001111
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001112 WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
1113 fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001114
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001115 WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
1116 fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001117
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001118 WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
1119 fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001120
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001121 WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
1122 fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
andrew.vasquez@qlogic.com210d5352006-01-13 17:05:21 -08001123
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001124 /* Mailbox registers. */
1125 mbx_reg = &reg->mailbox0;
1126 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
1127 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001128
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001129 /* Transfer sequence registers. */
1130 iter_reg = fw->xseq_gp_reg;
1131 iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1132 iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1133 iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1134 iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1135 iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1136 iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1137 iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1138 qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001139
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001140 qla24xx_read_window(reg, 0xBFE0, 16, fw->xseq_0_reg);
1141 qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001142
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001143 /* Receive sequence registers. */
1144 iter_reg = fw->rseq_gp_reg;
1145 iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1146 iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1147 iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1148 iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1149 iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1150 iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1151 iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1152 qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001153
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001154 qla24xx_read_window(reg, 0xFFD0, 16, fw->rseq_0_reg);
1155 qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1156 qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001157
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001158 /* Command DMA registers. */
1159 qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001160
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001161 /* Queues. */
1162 iter_reg = fw->req0_dma_reg;
1163 iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
1164 dmp_reg = &reg->iobase_q;
1165 for (cnt = 0; cnt < 7; cnt++)
1166 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001167
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001168 iter_reg = fw->resp0_dma_reg;
1169 iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
1170 dmp_reg = &reg->iobase_q;
1171 for (cnt = 0; cnt < 7; cnt++)
1172 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001173
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001174 iter_reg = fw->req1_dma_reg;
1175 iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
1176 dmp_reg = &reg->iobase_q;
1177 for (cnt = 0; cnt < 7; cnt++)
1178 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001179
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001180 /* Transmit DMA registers. */
1181 iter_reg = fw->xmt0_dma_reg;
1182 iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
1183 qla24xx_read_window(reg, 0x7610, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001184
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001185 iter_reg = fw->xmt1_dma_reg;
1186 iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
1187 qla24xx_read_window(reg, 0x7630, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001188
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001189 iter_reg = fw->xmt2_dma_reg;
1190 iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
1191 qla24xx_read_window(reg, 0x7650, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001192
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001193 iter_reg = fw->xmt3_dma_reg;
1194 iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
1195 qla24xx_read_window(reg, 0x7670, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001196
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001197 iter_reg = fw->xmt4_dma_reg;
1198 iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
1199 qla24xx_read_window(reg, 0x7690, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001200
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001201 qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001202
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001203 /* Receive DMA registers. */
1204 iter_reg = fw->rcvt0_data_dma_reg;
1205 iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
1206 qla24xx_read_window(reg, 0x7710, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001207
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001208 iter_reg = fw->rcvt1_data_dma_reg;
1209 iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
1210 qla24xx_read_window(reg, 0x7730, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001211
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001212 /* RISC registers. */
1213 iter_reg = fw->risc_gp_reg;
1214 iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
1215 iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
1216 iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
1217 iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
1218 iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
1219 iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
1220 iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
1221 qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001222
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001223 /* Local memory controller registers. */
1224 iter_reg = fw->lmc_reg;
1225 iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
1226 iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
1227 iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
1228 iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
1229 iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
1230 iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
1231 qla24xx_read_window(reg, 0x3060, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001232
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001233 /* Fibre Protocol Module registers. */
1234 iter_reg = fw->fpm_hdw_reg;
1235 iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
1236 iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
1237 iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
1238 iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
1239 iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
1240 iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
1241 iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
1242 iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
1243 iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
1244 iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
1245 iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
1246 qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001247
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001248 /* Frame Buffer registers. */
1249 iter_reg = fw->fb_hdw_reg;
1250 iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
1251 iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
1252 iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
1253 iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
1254 iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
1255 iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
1256 iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
1257 iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
1258 iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
1259 iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
1260 qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001261
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001262 rval = qla24xx_soft_reset(ha);
1263 if (rval != QLA_SUCCESS)
1264 goto qla24xx_fw_dump_failed_0;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001265
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001266 rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
Andrew Vasquezc5722702008-04-24 15:21:22 -07001267 &nxt);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001268 if (rval != QLA_SUCCESS)
1269 goto qla24xx_fw_dump_failed_0;
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001270
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001271 nxt = qla2xxx_copy_queues(ha, nxt);
Andrew Vasquezbb99de62009-01-05 11:18:08 -08001272
1273 qla24xx_copy_eft(ha, nxt);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001274
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001275 nxt_chain = (void *)ha->fw_dump + ha->chain_offset;
1276 nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
1277 if (last_chain) {
1278 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
1279 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
1280 }
1281
1282 /* Adjust valid length. */
1283 ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
1284
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001285qla24xx_fw_dump_failed_0:
Andrew Vasquez3420d362009-10-13 15:16:45 -07001286 qla2xxx_dump_post_process(base_vha, rval);
Andrew Vasquez6d9b61e2005-07-06 10:30:36 -07001287
1288qla24xx_fw_dump_failed:
1289 if (!hardware_locked)
1290 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1291}
1292
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001293void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001294qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001295{
1296 int rval;
1297 uint32_t cnt;
1298 uint32_t risc_address;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001299 struct qla_hw_data *ha = vha->hw;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001300 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1301 uint32_t __iomem *dmp_reg;
1302 uint32_t *iter_reg;
1303 uint16_t __iomem *mbx_reg;
1304 unsigned long flags;
1305 struct qla25xx_fw_dump *fw;
1306 uint32_t ext_mem_cnt;
Andrew Vasquezd63ab532009-01-05 11:18:09 -08001307 void *nxt, *nxt_chain;
Andrew Vasquezbb99de62009-01-05 11:18:08 -08001308 uint32_t *last_chain = NULL;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001309 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001310
1311 risc_address = ext_mem_cnt = 0;
1312 flags = 0;
Hiral Patel61f098d2014-04-11 16:54:21 -04001313 ha->fw_dump_cap_flags = 0;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001314
1315 if (!hardware_locked)
1316 spin_lock_irqsave(&ha->hardware_lock, flags);
1317
1318 if (!ha->fw_dump) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001319 ql_log(ql_log_warn, vha, 0xd008,
1320 "No buffer available for dump.\n");
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001321 goto qla25xx_fw_dump_failed;
1322 }
1323
1324 if (ha->fw_dumped) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001325 ql_log(ql_log_warn, vha, 0xd009,
1326 "Firmware has been previously dumped (%p) "
1327 "-- ignoring request.\n",
1328 ha->fw_dump);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001329 goto qla25xx_fw_dump_failed;
1330 }
1331 fw = &ha->fw_dump->isp.isp25;
1332 qla2xxx_prep_dump(ha, ha->fw_dump);
Andrew Vasquezb5836922007-09-20 14:07:39 -07001333 ha->fw_dump->version = __constant_htonl(2);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001334
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001335 fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
1336
Hiral Patel2f389fc2014-04-11 16:54:20 -04001337 /*
1338 * Pause RISC. No need to track timeout, as resetting the chip
1339 * is the right approach incase of pause timeout
1340 */
Hiral Patel61f098d2014-04-11 16:54:21 -04001341 qla24xx_pause_risc(reg, ha);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001342
Andrew Vasquezb5836922007-09-20 14:07:39 -07001343 /* Host/Risc registers. */
1344 iter_reg = fw->host_risc_reg;
1345 iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
1346 qla24xx_read_window(reg, 0x7010, 16, iter_reg);
1347
1348 /* PCIe registers. */
1349 WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
1350 RD_REG_DWORD(&reg->iobase_addr);
1351 WRT_REG_DWORD(&reg->iobase_window, 0x01);
1352 dmp_reg = &reg->iobase_c4;
1353 fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++));
1354 fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++));
1355 fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
1356 fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001357
Andrew Vasquezb5836922007-09-20 14:07:39 -07001358 WRT_REG_DWORD(&reg->iobase_window, 0x00);
1359 RD_REG_DWORD(&reg->iobase_window);
1360
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001361 /* Host interface registers. */
1362 dmp_reg = &reg->flash_addr;
1363 for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
1364 fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001365
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001366 /* Disable interrupts. */
1367 WRT_REG_DWORD(&reg->ictrl, 0);
1368 RD_REG_DWORD(&reg->ictrl);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001369
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001370 /* Shadow registers. */
1371 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1372 RD_REG_DWORD(&reg->iobase_addr);
1373 WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
1374 fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001375
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001376 WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
1377 fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001378
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001379 WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
1380 fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001381
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001382 WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
1383 fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001384
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001385 WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
1386 fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001387
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001388 WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
1389 fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001390
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001391 WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
1392 fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001393
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001394 WRT_REG_DWORD(&reg->iobase_select, 0xB0700000);
1395 fw->shadow_reg[7] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001396
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001397 WRT_REG_DWORD(&reg->iobase_select, 0xB0800000);
1398 fw->shadow_reg[8] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001399
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001400 WRT_REG_DWORD(&reg->iobase_select, 0xB0900000);
1401 fw->shadow_reg[9] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001402
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001403 WRT_REG_DWORD(&reg->iobase_select, 0xB0A00000);
1404 fw->shadow_reg[10] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001405
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001406 /* RISC I/O register. */
1407 WRT_REG_DWORD(&reg->iobase_addr, 0x0010);
1408 fw->risc_io_reg = htonl(RD_REG_DWORD(&reg->iobase_window));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001409
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001410 /* Mailbox registers. */
1411 mbx_reg = &reg->mailbox0;
1412 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
1413 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001414
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001415 /* Transfer sequence registers. */
1416 iter_reg = fw->xseq_gp_reg;
1417 iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1418 iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1419 iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1420 iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1421 iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1422 iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1423 iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1424 qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001425
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001426 iter_reg = fw->xseq_0_reg;
1427 iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
1428 iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
1429 qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001430
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001431 qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001432
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001433 /* Receive sequence registers. */
1434 iter_reg = fw->rseq_gp_reg;
1435 iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1436 iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1437 iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1438 iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1439 iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1440 iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1441 iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1442 qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001443
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001444 iter_reg = fw->rseq_0_reg;
1445 iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
1446 qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001447
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001448 qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1449 qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001450
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001451 /* Auxiliary sequence registers. */
1452 iter_reg = fw->aseq_gp_reg;
1453 iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
1454 iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
1455 iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
1456 iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
1457 iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
1458 iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
1459 iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
1460 qla24xx_read_window(reg, 0xB070, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001461
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001462 iter_reg = fw->aseq_0_reg;
1463 iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
1464 qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001465
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001466 qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
1467 qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001468
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001469 /* Command DMA registers. */
1470 qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001471
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001472 /* Queues. */
1473 iter_reg = fw->req0_dma_reg;
1474 iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
1475 dmp_reg = &reg->iobase_q;
1476 for (cnt = 0; cnt < 7; cnt++)
1477 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001478
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001479 iter_reg = fw->resp0_dma_reg;
1480 iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
1481 dmp_reg = &reg->iobase_q;
1482 for (cnt = 0; cnt < 7; cnt++)
1483 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001484
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001485 iter_reg = fw->req1_dma_reg;
1486 iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
1487 dmp_reg = &reg->iobase_q;
1488 for (cnt = 0; cnt < 7; cnt++)
1489 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001490
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001491 /* Transmit DMA registers. */
1492 iter_reg = fw->xmt0_dma_reg;
1493 iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
1494 qla24xx_read_window(reg, 0x7610, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001495
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001496 iter_reg = fw->xmt1_dma_reg;
1497 iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
1498 qla24xx_read_window(reg, 0x7630, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001499
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001500 iter_reg = fw->xmt2_dma_reg;
1501 iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
1502 qla24xx_read_window(reg, 0x7650, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001503
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001504 iter_reg = fw->xmt3_dma_reg;
1505 iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
1506 qla24xx_read_window(reg, 0x7670, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001507
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001508 iter_reg = fw->xmt4_dma_reg;
1509 iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
1510 qla24xx_read_window(reg, 0x7690, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001511
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001512 qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001513
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001514 /* Receive DMA registers. */
1515 iter_reg = fw->rcvt0_data_dma_reg;
1516 iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
1517 qla24xx_read_window(reg, 0x7710, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001518
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001519 iter_reg = fw->rcvt1_data_dma_reg;
1520 iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
1521 qla24xx_read_window(reg, 0x7730, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001522
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001523 /* RISC registers. */
1524 iter_reg = fw->risc_gp_reg;
1525 iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
1526 iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
1527 iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
1528 iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
1529 iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
1530 iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
1531 iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
1532 qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001533
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001534 /* Local memory controller registers. */
1535 iter_reg = fw->lmc_reg;
1536 iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
1537 iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
1538 iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
1539 iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
1540 iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
1541 iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
1542 iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
1543 qla24xx_read_window(reg, 0x3070, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001544
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001545 /* Fibre Protocol Module registers. */
1546 iter_reg = fw->fpm_hdw_reg;
1547 iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
1548 iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
1549 iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
1550 iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
1551 iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
1552 iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
1553 iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
1554 iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
1555 iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
1556 iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
1557 iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
1558 qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001559
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001560 /* Frame Buffer registers. */
1561 iter_reg = fw->fb_hdw_reg;
1562 iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
1563 iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
1564 iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
1565 iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
1566 iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
1567 iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
1568 iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
1569 iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
1570 iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
1571 iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
1572 iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
1573 qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001574
Andrew Vasquezd63ab532009-01-05 11:18:09 -08001575 /* Multi queue registers */
1576 nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
1577 &last_chain);
1578
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001579 rval = qla24xx_soft_reset(ha);
1580 if (rval != QLA_SUCCESS)
1581 goto qla25xx_fw_dump_failed_0;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001582
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001583 rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
Andrew Vasquezc5722702008-04-24 15:21:22 -07001584 &nxt);
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001585 if (rval != QLA_SUCCESS)
1586 goto qla25xx_fw_dump_failed_0;
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001587
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001588 nxt = qla2xxx_copy_queues(ha, nxt);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001589
Bart Van Assche7f544d02013-06-25 11:27:27 -04001590 qla24xx_copy_eft(ha, nxt);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08001591
Andrew Vasquezd63ab532009-01-05 11:18:09 -08001592 /* Chain entries -- started with MQ. */
Giridhar Malavali050c9bb2012-02-09 11:15:33 -08001593 nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
1594 nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001595 nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
Andrew Vasquezbb99de62009-01-05 11:18:08 -08001596 if (last_chain) {
1597 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
1598 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
1599 }
Andrew Vasquezdf613b92008-01-17 09:02:17 -08001600
Giridhar Malavali050c9bb2012-02-09 11:15:33 -08001601 /* Adjust valid length. */
1602 ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
1603
Andrew Vasquezc81d04c2007-07-26 11:41:13 -07001604qla25xx_fw_dump_failed_0:
Andrew Vasquez3420d362009-10-13 15:16:45 -07001605 qla2xxx_dump_post_process(base_vha, rval);
Andrew Vasquezc3a2f0d2007-07-19 20:37:34 -07001606
1607qla25xx_fw_dump_failed:
1608 if (!hardware_locked)
1609 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1610}
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001611
1612void
1613qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
1614{
1615 int rval;
1616 uint32_t cnt;
1617 uint32_t risc_address;
1618 struct qla_hw_data *ha = vha->hw;
1619 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1620 uint32_t __iomem *dmp_reg;
1621 uint32_t *iter_reg;
1622 uint16_t __iomem *mbx_reg;
1623 unsigned long flags;
1624 struct qla81xx_fw_dump *fw;
1625 uint32_t ext_mem_cnt;
1626 void *nxt, *nxt_chain;
1627 uint32_t *last_chain = NULL;
1628 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
1629
1630 risc_address = ext_mem_cnt = 0;
1631 flags = 0;
Hiral Patel61f098d2014-04-11 16:54:21 -04001632 ha->fw_dump_cap_flags = 0;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001633
1634 if (!hardware_locked)
1635 spin_lock_irqsave(&ha->hardware_lock, flags);
1636
1637 if (!ha->fw_dump) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001638 ql_log(ql_log_warn, vha, 0xd00a,
1639 "No buffer available for dump.\n");
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001640 goto qla81xx_fw_dump_failed;
1641 }
1642
1643 if (ha->fw_dumped) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001644 ql_log(ql_log_warn, vha, 0xd00b,
1645 "Firmware has been previously dumped (%p) "
1646 "-- ignoring request.\n",
1647 ha->fw_dump);
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001648 goto qla81xx_fw_dump_failed;
1649 }
1650 fw = &ha->fw_dump->isp.isp81;
1651 qla2xxx_prep_dump(ha, ha->fw_dump);
1652
1653 fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
1654
Hiral Patel2f389fc2014-04-11 16:54:20 -04001655 /*
1656 * Pause RISC. No need to track timeout, as resetting the chip
1657 * is the right approach incase of pause timeout
1658 */
Hiral Patel61f098d2014-04-11 16:54:21 -04001659 qla24xx_pause_risc(reg, ha);
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001660
1661 /* Host/Risc registers. */
1662 iter_reg = fw->host_risc_reg;
1663 iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
1664 qla24xx_read_window(reg, 0x7010, 16, iter_reg);
1665
1666 /* PCIe registers. */
1667 WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
1668 RD_REG_DWORD(&reg->iobase_addr);
1669 WRT_REG_DWORD(&reg->iobase_window, 0x01);
1670 dmp_reg = &reg->iobase_c4;
1671 fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++));
1672 fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++));
1673 fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
1674 fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));
1675
1676 WRT_REG_DWORD(&reg->iobase_window, 0x00);
1677 RD_REG_DWORD(&reg->iobase_window);
1678
1679 /* Host interface registers. */
1680 dmp_reg = &reg->flash_addr;
1681 for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
1682 fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
1683
1684 /* Disable interrupts. */
1685 WRT_REG_DWORD(&reg->ictrl, 0);
1686 RD_REG_DWORD(&reg->ictrl);
1687
1688 /* Shadow registers. */
1689 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1690 RD_REG_DWORD(&reg->iobase_addr);
1691 WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
1692 fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1693
1694 WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
1695 fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1696
1697 WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
1698 fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1699
1700 WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
1701 fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1702
1703 WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
1704 fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1705
1706 WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
1707 fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1708
1709 WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
1710 fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1711
1712 WRT_REG_DWORD(&reg->iobase_select, 0xB0700000);
1713 fw->shadow_reg[7] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1714
1715 WRT_REG_DWORD(&reg->iobase_select, 0xB0800000);
1716 fw->shadow_reg[8] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1717
1718 WRT_REG_DWORD(&reg->iobase_select, 0xB0900000);
1719 fw->shadow_reg[9] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1720
1721 WRT_REG_DWORD(&reg->iobase_select, 0xB0A00000);
1722 fw->shadow_reg[10] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
1723
1724 /* RISC I/O register. */
1725 WRT_REG_DWORD(&reg->iobase_addr, 0x0010);
1726 fw->risc_io_reg = htonl(RD_REG_DWORD(&reg->iobase_window));
1727
1728 /* Mailbox registers. */
1729 mbx_reg = &reg->mailbox0;
1730 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
1731 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
1732
1733 /* Transfer sequence registers. */
1734 iter_reg = fw->xseq_gp_reg;
1735 iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
1736 iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
1737 iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
1738 iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
1739 iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
1740 iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
1741 iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
1742 qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
1743
1744 iter_reg = fw->xseq_0_reg;
1745 iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
1746 iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
1747 qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
1748
1749 qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
1750
1751 /* Receive sequence registers. */
1752 iter_reg = fw->rseq_gp_reg;
1753 iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
1754 iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
1755 iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
1756 iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
1757 iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
1758 iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
1759 iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
1760 qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
1761
1762 iter_reg = fw->rseq_0_reg;
1763 iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
1764 qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
1765
1766 qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
1767 qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
1768
1769 /* Auxiliary sequence registers. */
1770 iter_reg = fw->aseq_gp_reg;
1771 iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
1772 iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
1773 iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
1774 iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
1775 iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
1776 iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
1777 iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
1778 qla24xx_read_window(reg, 0xB070, 16, iter_reg);
1779
1780 iter_reg = fw->aseq_0_reg;
1781 iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
1782 qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
1783
1784 qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
1785 qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
1786
1787 /* Command DMA registers. */
1788 qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg);
1789
1790 /* Queues. */
1791 iter_reg = fw->req0_dma_reg;
1792 iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
1793 dmp_reg = &reg->iobase_q;
1794 for (cnt = 0; cnt < 7; cnt++)
1795 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
1796
1797 iter_reg = fw->resp0_dma_reg;
1798 iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
1799 dmp_reg = &reg->iobase_q;
1800 for (cnt = 0; cnt < 7; cnt++)
1801 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
1802
1803 iter_reg = fw->req1_dma_reg;
1804 iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
1805 dmp_reg = &reg->iobase_q;
1806 for (cnt = 0; cnt < 7; cnt++)
1807 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
1808
1809 /* Transmit DMA registers. */
1810 iter_reg = fw->xmt0_dma_reg;
1811 iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
1812 qla24xx_read_window(reg, 0x7610, 16, iter_reg);
1813
1814 iter_reg = fw->xmt1_dma_reg;
1815 iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
1816 qla24xx_read_window(reg, 0x7630, 16, iter_reg);
1817
1818 iter_reg = fw->xmt2_dma_reg;
1819 iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
1820 qla24xx_read_window(reg, 0x7650, 16, iter_reg);
1821
1822 iter_reg = fw->xmt3_dma_reg;
1823 iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
1824 qla24xx_read_window(reg, 0x7670, 16, iter_reg);
1825
1826 iter_reg = fw->xmt4_dma_reg;
1827 iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
1828 qla24xx_read_window(reg, 0x7690, 16, iter_reg);
1829
1830 qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
1831
1832 /* Receive DMA registers. */
1833 iter_reg = fw->rcvt0_data_dma_reg;
1834 iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
1835 qla24xx_read_window(reg, 0x7710, 16, iter_reg);
1836
1837 iter_reg = fw->rcvt1_data_dma_reg;
1838 iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
1839 qla24xx_read_window(reg, 0x7730, 16, iter_reg);
1840
1841 /* RISC registers. */
1842 iter_reg = fw->risc_gp_reg;
1843 iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
1844 iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
1845 iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
1846 iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
1847 iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
1848 iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
1849 iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
1850 qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
1851
1852 /* Local memory controller registers. */
1853 iter_reg = fw->lmc_reg;
1854 iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
1855 iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
1856 iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
1857 iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
1858 iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
1859 iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
1860 iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
1861 qla24xx_read_window(reg, 0x3070, 16, iter_reg);
1862
1863 /* Fibre Protocol Module registers. */
1864 iter_reg = fw->fpm_hdw_reg;
1865 iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
1866 iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
1867 iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
1868 iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
1869 iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
1870 iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
1871 iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
1872 iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
1873 iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
1874 iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
1875 iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
1876 iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
1877 iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg);
1878 qla24xx_read_window(reg, 0x40D0, 16, iter_reg);
1879
1880 /* Frame Buffer registers. */
1881 iter_reg = fw->fb_hdw_reg;
1882 iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
1883 iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
1884 iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
1885 iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
1886 iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
1887 iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
1888 iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
1889 iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
1890 iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
1891 iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
1892 iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
1893 iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg);
1894 qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
1895
1896 /* Multi queue registers */
1897 nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
1898 &last_chain);
1899
1900 rval = qla24xx_soft_reset(ha);
1901 if (rval != QLA_SUCCESS)
1902 goto qla81xx_fw_dump_failed_0;
1903
1904 rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
1905 &nxt);
1906 if (rval != QLA_SUCCESS)
1907 goto qla81xx_fw_dump_failed_0;
1908
1909 nxt = qla2xxx_copy_queues(ha, nxt);
1910
Bart Van Assche7f544d02013-06-25 11:27:27 -04001911 qla24xx_copy_eft(ha, nxt);
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001912
1913 /* Chain entries -- started with MQ. */
Giridhar Malavali050c9bb2012-02-09 11:15:33 -08001914 nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
1915 nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001916 nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001917 if (last_chain) {
1918 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
1919 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
1920 }
1921
Giridhar Malavali050c9bb2012-02-09 11:15:33 -08001922 /* Adjust valid length. */
1923 ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
1924
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001925qla81xx_fw_dump_failed_0:
Andrew Vasquez3420d362009-10-13 15:16:45 -07001926 qla2xxx_dump_post_process(base_vha, rval);
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001927
1928qla81xx_fw_dump_failed:
1929 if (!hardware_locked)
1930 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1931}
1932
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001933void
1934qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
1935{
1936 int rval;
1937 uint32_t cnt, reg_data;
1938 uint32_t risc_address;
1939 struct qla_hw_data *ha = vha->hw;
1940 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1941 uint32_t __iomem *dmp_reg;
1942 uint32_t *iter_reg;
1943 uint16_t __iomem *mbx_reg;
1944 unsigned long flags;
1945 struct qla83xx_fw_dump *fw;
1946 uint32_t ext_mem_cnt;
1947 void *nxt, *nxt_chain;
1948 uint32_t *last_chain = NULL;
1949 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
1950
1951 risc_address = ext_mem_cnt = 0;
1952 flags = 0;
Hiral Patel61f098d2014-04-11 16:54:21 -04001953 ha->fw_dump_cap_flags = 0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001954
1955 if (!hardware_locked)
1956 spin_lock_irqsave(&ha->hardware_lock, flags);
1957
1958 if (!ha->fw_dump) {
1959 ql_log(ql_log_warn, vha, 0xd00c,
1960 "No buffer available for dump!!!\n");
1961 goto qla83xx_fw_dump_failed;
1962 }
1963
1964 if (ha->fw_dumped) {
1965 ql_log(ql_log_warn, vha, 0xd00d,
1966 "Firmware has been previously dumped (%p) -- ignoring "
1967 "request...\n", ha->fw_dump);
1968 goto qla83xx_fw_dump_failed;
1969 }
1970 fw = &ha->fw_dump->isp.isp83;
1971 qla2xxx_prep_dump(ha, ha->fw_dump);
1972
1973 fw->host_status = htonl(RD_REG_DWORD(&reg->host_status));
1974
Hiral Patel2f389fc2014-04-11 16:54:20 -04001975 /*
1976 * Pause RISC. No need to track timeout, as resetting the chip
1977 * is the right approach incase of pause timeout
1978 */
Hiral Patel61f098d2014-04-11 16:54:21 -04001979 qla24xx_pause_risc(reg, ha);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001980
1981 WRT_REG_DWORD(&reg->iobase_addr, 0x6000);
1982 dmp_reg = &reg->iobase_window;
1983 reg_data = RD_REG_DWORD(dmp_reg);
1984 WRT_REG_DWORD(dmp_reg, 0);
1985
1986 dmp_reg = &reg->unused_4_1[0];
1987 reg_data = RD_REG_DWORD(dmp_reg);
1988 WRT_REG_DWORD(dmp_reg, 0);
1989
1990 WRT_REG_DWORD(&reg->iobase_addr, 0x6010);
1991 dmp_reg = &reg->unused_4_1[2];
1992 reg_data = RD_REG_DWORD(dmp_reg);
1993 WRT_REG_DWORD(dmp_reg, 0);
1994
1995 /* select PCR and disable ecc checking and correction */
1996 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
1997 RD_REG_DWORD(&reg->iobase_addr);
1998 WRT_REG_DWORD(&reg->iobase_select, 0x60000000); /* write to F0h = PCR */
1999
2000 /* Host/Risc registers. */
2001 iter_reg = fw->host_risc_reg;
2002 iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg);
2003 iter_reg = qla24xx_read_window(reg, 0x7010, 16, iter_reg);
2004 qla24xx_read_window(reg, 0x7040, 16, iter_reg);
2005
2006 /* PCIe registers. */
2007 WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
2008 RD_REG_DWORD(&reg->iobase_addr);
2009 WRT_REG_DWORD(&reg->iobase_window, 0x01);
2010 dmp_reg = &reg->iobase_c4;
2011 fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++));
2012 fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++));
2013 fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg));
2014 fw->pcie_regs[3] = htonl(RD_REG_DWORD(&reg->iobase_window));
2015
2016 WRT_REG_DWORD(&reg->iobase_window, 0x00);
2017 RD_REG_DWORD(&reg->iobase_window);
2018
2019 /* Host interface registers. */
2020 dmp_reg = &reg->flash_addr;
2021 for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++)
2022 fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++));
2023
2024 /* Disable interrupts. */
2025 WRT_REG_DWORD(&reg->ictrl, 0);
2026 RD_REG_DWORD(&reg->ictrl);
2027
2028 /* Shadow registers. */
2029 WRT_REG_DWORD(&reg->iobase_addr, 0x0F70);
2030 RD_REG_DWORD(&reg->iobase_addr);
2031 WRT_REG_DWORD(&reg->iobase_select, 0xB0000000);
2032 fw->shadow_reg[0] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
2033
2034 WRT_REG_DWORD(&reg->iobase_select, 0xB0100000);
2035 fw->shadow_reg[1] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
2036
2037 WRT_REG_DWORD(&reg->iobase_select, 0xB0200000);
2038 fw->shadow_reg[2] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
2039
2040 WRT_REG_DWORD(&reg->iobase_select, 0xB0300000);
2041 fw->shadow_reg[3] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
2042
2043 WRT_REG_DWORD(&reg->iobase_select, 0xB0400000);
2044 fw->shadow_reg[4] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
2045
2046 WRT_REG_DWORD(&reg->iobase_select, 0xB0500000);
2047 fw->shadow_reg[5] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
2048
2049 WRT_REG_DWORD(&reg->iobase_select, 0xB0600000);
2050 fw->shadow_reg[6] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
2051
2052 WRT_REG_DWORD(&reg->iobase_select, 0xB0700000);
2053 fw->shadow_reg[7] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
2054
2055 WRT_REG_DWORD(&reg->iobase_select, 0xB0800000);
2056 fw->shadow_reg[8] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
2057
2058 WRT_REG_DWORD(&reg->iobase_select, 0xB0900000);
2059 fw->shadow_reg[9] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
2060
2061 WRT_REG_DWORD(&reg->iobase_select, 0xB0A00000);
2062 fw->shadow_reg[10] = htonl(RD_REG_DWORD(&reg->iobase_sdata));
2063
2064 /* RISC I/O register. */
2065 WRT_REG_DWORD(&reg->iobase_addr, 0x0010);
2066 fw->risc_io_reg = htonl(RD_REG_DWORD(&reg->iobase_window));
2067
2068 /* Mailbox registers. */
2069 mbx_reg = &reg->mailbox0;
2070 for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++)
2071 fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++));
2072
2073 /* Transfer sequence registers. */
2074 iter_reg = fw->xseq_gp_reg;
2075 iter_reg = qla24xx_read_window(reg, 0xBE00, 16, iter_reg);
2076 iter_reg = qla24xx_read_window(reg, 0xBE10, 16, iter_reg);
2077 iter_reg = qla24xx_read_window(reg, 0xBE20, 16, iter_reg);
2078 iter_reg = qla24xx_read_window(reg, 0xBE30, 16, iter_reg);
2079 iter_reg = qla24xx_read_window(reg, 0xBE40, 16, iter_reg);
2080 iter_reg = qla24xx_read_window(reg, 0xBE50, 16, iter_reg);
2081 iter_reg = qla24xx_read_window(reg, 0xBE60, 16, iter_reg);
2082 iter_reg = qla24xx_read_window(reg, 0xBE70, 16, iter_reg);
2083 iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg);
2084 iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg);
2085 iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg);
2086 iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg);
2087 iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg);
2088 iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg);
2089 iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg);
2090 qla24xx_read_window(reg, 0xBF70, 16, iter_reg);
2091
2092 iter_reg = fw->xseq_0_reg;
2093 iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg);
2094 iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg);
2095 qla24xx_read_window(reg, 0xBFE0, 16, iter_reg);
2096
2097 qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg);
2098
2099 qla24xx_read_window(reg, 0xBEF0, 16, fw->xseq_2_reg);
2100
2101 /* Receive sequence registers. */
2102 iter_reg = fw->rseq_gp_reg;
2103 iter_reg = qla24xx_read_window(reg, 0xFE00, 16, iter_reg);
2104 iter_reg = qla24xx_read_window(reg, 0xFE10, 16, iter_reg);
2105 iter_reg = qla24xx_read_window(reg, 0xFE20, 16, iter_reg);
2106 iter_reg = qla24xx_read_window(reg, 0xFE30, 16, iter_reg);
2107 iter_reg = qla24xx_read_window(reg, 0xFE40, 16, iter_reg);
2108 iter_reg = qla24xx_read_window(reg, 0xFE50, 16, iter_reg);
2109 iter_reg = qla24xx_read_window(reg, 0xFE60, 16, iter_reg);
2110 iter_reg = qla24xx_read_window(reg, 0xFE70, 16, iter_reg);
2111 iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg);
2112 iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg);
2113 iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg);
2114 iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg);
2115 iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg);
2116 iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg);
2117 iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg);
2118 qla24xx_read_window(reg, 0xFF70, 16, iter_reg);
2119
2120 iter_reg = fw->rseq_0_reg;
2121 iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg);
2122 qla24xx_read_window(reg, 0xFFD0, 16, iter_reg);
2123
2124 qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg);
2125 qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg);
2126 qla24xx_read_window(reg, 0xFEF0, 16, fw->rseq_3_reg);
2127
2128 /* Auxiliary sequence registers. */
2129 iter_reg = fw->aseq_gp_reg;
2130 iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg);
2131 iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg);
2132 iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg);
2133 iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg);
2134 iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg);
2135 iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg);
2136 iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg);
2137 iter_reg = qla24xx_read_window(reg, 0xB070, 16, iter_reg);
2138 iter_reg = qla24xx_read_window(reg, 0xB100, 16, iter_reg);
2139 iter_reg = qla24xx_read_window(reg, 0xB110, 16, iter_reg);
2140 iter_reg = qla24xx_read_window(reg, 0xB120, 16, iter_reg);
2141 iter_reg = qla24xx_read_window(reg, 0xB130, 16, iter_reg);
2142 iter_reg = qla24xx_read_window(reg, 0xB140, 16, iter_reg);
2143 iter_reg = qla24xx_read_window(reg, 0xB150, 16, iter_reg);
2144 iter_reg = qla24xx_read_window(reg, 0xB160, 16, iter_reg);
2145 qla24xx_read_window(reg, 0xB170, 16, iter_reg);
2146
2147 iter_reg = fw->aseq_0_reg;
2148 iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg);
2149 qla24xx_read_window(reg, 0xB0D0, 16, iter_reg);
2150
2151 qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg);
2152 qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg);
2153 qla24xx_read_window(reg, 0xB1F0, 16, fw->aseq_3_reg);
2154
2155 /* Command DMA registers. */
2156 iter_reg = fw->cmd_dma_reg;
2157 iter_reg = qla24xx_read_window(reg, 0x7100, 16, iter_reg);
2158 iter_reg = qla24xx_read_window(reg, 0x7120, 16, iter_reg);
2159 iter_reg = qla24xx_read_window(reg, 0x7130, 16, iter_reg);
2160 qla24xx_read_window(reg, 0x71F0, 16, iter_reg);
2161
2162 /* Queues. */
2163 iter_reg = fw->req0_dma_reg;
2164 iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg);
2165 dmp_reg = &reg->iobase_q;
2166 for (cnt = 0; cnt < 7; cnt++)
2167 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
2168
2169 iter_reg = fw->resp0_dma_reg;
2170 iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg);
2171 dmp_reg = &reg->iobase_q;
2172 for (cnt = 0; cnt < 7; cnt++)
2173 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
2174
2175 iter_reg = fw->req1_dma_reg;
2176 iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg);
2177 dmp_reg = &reg->iobase_q;
2178 for (cnt = 0; cnt < 7; cnt++)
2179 *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++));
2180
2181 /* Transmit DMA registers. */
2182 iter_reg = fw->xmt0_dma_reg;
2183 iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg);
2184 qla24xx_read_window(reg, 0x7610, 16, iter_reg);
2185
2186 iter_reg = fw->xmt1_dma_reg;
2187 iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg);
2188 qla24xx_read_window(reg, 0x7630, 16, iter_reg);
2189
2190 iter_reg = fw->xmt2_dma_reg;
2191 iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg);
2192 qla24xx_read_window(reg, 0x7650, 16, iter_reg);
2193
2194 iter_reg = fw->xmt3_dma_reg;
2195 iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg);
2196 qla24xx_read_window(reg, 0x7670, 16, iter_reg);
2197
2198 iter_reg = fw->xmt4_dma_reg;
2199 iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg);
2200 qla24xx_read_window(reg, 0x7690, 16, iter_reg);
2201
2202 qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg);
2203
2204 /* Receive DMA registers. */
2205 iter_reg = fw->rcvt0_data_dma_reg;
2206 iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg);
2207 qla24xx_read_window(reg, 0x7710, 16, iter_reg);
2208
2209 iter_reg = fw->rcvt1_data_dma_reg;
2210 iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg);
2211 qla24xx_read_window(reg, 0x7730, 16, iter_reg);
2212
2213 /* RISC registers. */
2214 iter_reg = fw->risc_gp_reg;
2215 iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg);
2216 iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg);
2217 iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg);
2218 iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg);
2219 iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg);
2220 iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg);
2221 iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg);
2222 qla24xx_read_window(reg, 0x0F70, 16, iter_reg);
2223
2224 /* Local memory controller registers. */
2225 iter_reg = fw->lmc_reg;
2226 iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg);
2227 iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg);
2228 iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg);
2229 iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg);
2230 iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg);
2231 iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg);
2232 iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg);
2233 qla24xx_read_window(reg, 0x3070, 16, iter_reg);
2234
2235 /* Fibre Protocol Module registers. */
2236 iter_reg = fw->fpm_hdw_reg;
2237 iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg);
2238 iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg);
2239 iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg);
2240 iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg);
2241 iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg);
2242 iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg);
2243 iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg);
2244 iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg);
2245 iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg);
2246 iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg);
2247 iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg);
2248 iter_reg = qla24xx_read_window(reg, 0x40B0, 16, iter_reg);
2249 iter_reg = qla24xx_read_window(reg, 0x40C0, 16, iter_reg);
2250 iter_reg = qla24xx_read_window(reg, 0x40D0, 16, iter_reg);
2251 iter_reg = qla24xx_read_window(reg, 0x40E0, 16, iter_reg);
2252 qla24xx_read_window(reg, 0x40F0, 16, iter_reg);
2253
2254 /* RQ0 Array registers. */
2255 iter_reg = fw->rq0_array_reg;
2256 iter_reg = qla24xx_read_window(reg, 0x5C00, 16, iter_reg);
2257 iter_reg = qla24xx_read_window(reg, 0x5C10, 16, iter_reg);
2258 iter_reg = qla24xx_read_window(reg, 0x5C20, 16, iter_reg);
2259 iter_reg = qla24xx_read_window(reg, 0x5C30, 16, iter_reg);
2260 iter_reg = qla24xx_read_window(reg, 0x5C40, 16, iter_reg);
2261 iter_reg = qla24xx_read_window(reg, 0x5C50, 16, iter_reg);
2262 iter_reg = qla24xx_read_window(reg, 0x5C60, 16, iter_reg);
2263 iter_reg = qla24xx_read_window(reg, 0x5C70, 16, iter_reg);
2264 iter_reg = qla24xx_read_window(reg, 0x5C80, 16, iter_reg);
2265 iter_reg = qla24xx_read_window(reg, 0x5C90, 16, iter_reg);
2266 iter_reg = qla24xx_read_window(reg, 0x5CA0, 16, iter_reg);
2267 iter_reg = qla24xx_read_window(reg, 0x5CB0, 16, iter_reg);
2268 iter_reg = qla24xx_read_window(reg, 0x5CC0, 16, iter_reg);
2269 iter_reg = qla24xx_read_window(reg, 0x5CD0, 16, iter_reg);
2270 iter_reg = qla24xx_read_window(reg, 0x5CE0, 16, iter_reg);
2271 qla24xx_read_window(reg, 0x5CF0, 16, iter_reg);
2272
2273 /* RQ1 Array registers. */
2274 iter_reg = fw->rq1_array_reg;
2275 iter_reg = qla24xx_read_window(reg, 0x5D00, 16, iter_reg);
2276 iter_reg = qla24xx_read_window(reg, 0x5D10, 16, iter_reg);
2277 iter_reg = qla24xx_read_window(reg, 0x5D20, 16, iter_reg);
2278 iter_reg = qla24xx_read_window(reg, 0x5D30, 16, iter_reg);
2279 iter_reg = qla24xx_read_window(reg, 0x5D40, 16, iter_reg);
2280 iter_reg = qla24xx_read_window(reg, 0x5D50, 16, iter_reg);
2281 iter_reg = qla24xx_read_window(reg, 0x5D60, 16, iter_reg);
2282 iter_reg = qla24xx_read_window(reg, 0x5D70, 16, iter_reg);
2283 iter_reg = qla24xx_read_window(reg, 0x5D80, 16, iter_reg);
2284 iter_reg = qla24xx_read_window(reg, 0x5D90, 16, iter_reg);
2285 iter_reg = qla24xx_read_window(reg, 0x5DA0, 16, iter_reg);
2286 iter_reg = qla24xx_read_window(reg, 0x5DB0, 16, iter_reg);
2287 iter_reg = qla24xx_read_window(reg, 0x5DC0, 16, iter_reg);
2288 iter_reg = qla24xx_read_window(reg, 0x5DD0, 16, iter_reg);
2289 iter_reg = qla24xx_read_window(reg, 0x5DE0, 16, iter_reg);
2290 qla24xx_read_window(reg, 0x5DF0, 16, iter_reg);
2291
2292 /* RP0 Array registers. */
2293 iter_reg = fw->rp0_array_reg;
2294 iter_reg = qla24xx_read_window(reg, 0x5E00, 16, iter_reg);
2295 iter_reg = qla24xx_read_window(reg, 0x5E10, 16, iter_reg);
2296 iter_reg = qla24xx_read_window(reg, 0x5E20, 16, iter_reg);
2297 iter_reg = qla24xx_read_window(reg, 0x5E30, 16, iter_reg);
2298 iter_reg = qla24xx_read_window(reg, 0x5E40, 16, iter_reg);
2299 iter_reg = qla24xx_read_window(reg, 0x5E50, 16, iter_reg);
2300 iter_reg = qla24xx_read_window(reg, 0x5E60, 16, iter_reg);
2301 iter_reg = qla24xx_read_window(reg, 0x5E70, 16, iter_reg);
2302 iter_reg = qla24xx_read_window(reg, 0x5E80, 16, iter_reg);
2303 iter_reg = qla24xx_read_window(reg, 0x5E90, 16, iter_reg);
2304 iter_reg = qla24xx_read_window(reg, 0x5EA0, 16, iter_reg);
2305 iter_reg = qla24xx_read_window(reg, 0x5EB0, 16, iter_reg);
2306 iter_reg = qla24xx_read_window(reg, 0x5EC0, 16, iter_reg);
2307 iter_reg = qla24xx_read_window(reg, 0x5ED0, 16, iter_reg);
2308 iter_reg = qla24xx_read_window(reg, 0x5EE0, 16, iter_reg);
2309 qla24xx_read_window(reg, 0x5EF0, 16, iter_reg);
2310
2311 /* RP1 Array registers. */
2312 iter_reg = fw->rp1_array_reg;
2313 iter_reg = qla24xx_read_window(reg, 0x5F00, 16, iter_reg);
2314 iter_reg = qla24xx_read_window(reg, 0x5F10, 16, iter_reg);
2315 iter_reg = qla24xx_read_window(reg, 0x5F20, 16, iter_reg);
2316 iter_reg = qla24xx_read_window(reg, 0x5F30, 16, iter_reg);
2317 iter_reg = qla24xx_read_window(reg, 0x5F40, 16, iter_reg);
2318 iter_reg = qla24xx_read_window(reg, 0x5F50, 16, iter_reg);
2319 iter_reg = qla24xx_read_window(reg, 0x5F60, 16, iter_reg);
2320 iter_reg = qla24xx_read_window(reg, 0x5F70, 16, iter_reg);
2321 iter_reg = qla24xx_read_window(reg, 0x5F80, 16, iter_reg);
2322 iter_reg = qla24xx_read_window(reg, 0x5F90, 16, iter_reg);
2323 iter_reg = qla24xx_read_window(reg, 0x5FA0, 16, iter_reg);
2324 iter_reg = qla24xx_read_window(reg, 0x5FB0, 16, iter_reg);
2325 iter_reg = qla24xx_read_window(reg, 0x5FC0, 16, iter_reg);
2326 iter_reg = qla24xx_read_window(reg, 0x5FD0, 16, iter_reg);
2327 iter_reg = qla24xx_read_window(reg, 0x5FE0, 16, iter_reg);
2328 qla24xx_read_window(reg, 0x5FF0, 16, iter_reg);
2329
2330 iter_reg = fw->at0_array_reg;
2331 iter_reg = qla24xx_read_window(reg, 0x7080, 16, iter_reg);
2332 iter_reg = qla24xx_read_window(reg, 0x7090, 16, iter_reg);
2333 iter_reg = qla24xx_read_window(reg, 0x70A0, 16, iter_reg);
2334 iter_reg = qla24xx_read_window(reg, 0x70B0, 16, iter_reg);
2335 iter_reg = qla24xx_read_window(reg, 0x70C0, 16, iter_reg);
2336 iter_reg = qla24xx_read_window(reg, 0x70D0, 16, iter_reg);
2337 iter_reg = qla24xx_read_window(reg, 0x70E0, 16, iter_reg);
2338 qla24xx_read_window(reg, 0x70F0, 16, iter_reg);
2339
2340 /* I/O Queue Control registers. */
2341 qla24xx_read_window(reg, 0x7800, 16, fw->queue_control_reg);
2342
2343 /* Frame Buffer registers. */
2344 iter_reg = fw->fb_hdw_reg;
2345 iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg);
2346 iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg);
2347 iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg);
2348 iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg);
2349 iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg);
2350 iter_reg = qla24xx_read_window(reg, 0x6060, 16, iter_reg);
2351 iter_reg = qla24xx_read_window(reg, 0x6070, 16, iter_reg);
2352 iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg);
2353 iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg);
2354 iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg);
2355 iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg);
2356 iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg);
2357 iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg);
2358 iter_reg = qla24xx_read_window(reg, 0x61C0, 16, iter_reg);
2359 iter_reg = qla24xx_read_window(reg, 0x6530, 16, iter_reg);
2360 iter_reg = qla24xx_read_window(reg, 0x6540, 16, iter_reg);
2361 iter_reg = qla24xx_read_window(reg, 0x6550, 16, iter_reg);
2362 iter_reg = qla24xx_read_window(reg, 0x6560, 16, iter_reg);
2363 iter_reg = qla24xx_read_window(reg, 0x6570, 16, iter_reg);
2364 iter_reg = qla24xx_read_window(reg, 0x6580, 16, iter_reg);
2365 iter_reg = qla24xx_read_window(reg, 0x6590, 16, iter_reg);
2366 iter_reg = qla24xx_read_window(reg, 0x65A0, 16, iter_reg);
2367 iter_reg = qla24xx_read_window(reg, 0x65B0, 16, iter_reg);
2368 iter_reg = qla24xx_read_window(reg, 0x65C0, 16, iter_reg);
2369 iter_reg = qla24xx_read_window(reg, 0x65D0, 16, iter_reg);
2370 iter_reg = qla24xx_read_window(reg, 0x65E0, 16, iter_reg);
2371 qla24xx_read_window(reg, 0x6F00, 16, iter_reg);
2372
2373 /* Multi queue registers */
2374 nxt_chain = qla25xx_copy_mq(ha, (void *)ha->fw_dump + ha->chain_offset,
2375 &last_chain);
2376
2377 rval = qla24xx_soft_reset(ha);
2378 if (rval != QLA_SUCCESS) {
2379 ql_log(ql_log_warn, vha, 0xd00e,
2380 "SOFT RESET FAILED, forcing continuation of dump!!!\n");
2381 rval = QLA_SUCCESS;
2382
2383 ql_log(ql_log_warn, vha, 0xd00f, "try a bigger hammer!!!\n");
2384
2385 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
2386 RD_REG_DWORD(&reg->hccr);
2387
2388 WRT_REG_DWORD(&reg->hccr, HCCRX_REL_RISC_PAUSE);
2389 RD_REG_DWORD(&reg->hccr);
2390
2391 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_RESET);
2392 RD_REG_DWORD(&reg->hccr);
2393
2394 for (cnt = 30000; cnt && (RD_REG_WORD(&reg->mailbox0)); cnt--)
2395 udelay(5);
2396
2397 if (!cnt) {
2398 nxt = fw->code_ram;
Saurav Kashyap8c0bc702012-11-21 02:40:35 -05002399 nxt += sizeof(fw->code_ram);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002400 nxt += (ha->fw_memory_size - 0x100000 + 1);
2401 goto copy_queue;
Hiral Patel61f098d2014-04-11 16:54:21 -04002402 } else {
2403 set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002404 ql_log(ql_log_warn, vha, 0xd010,
2405 "bigger hammer success?\n");
Hiral Patel61f098d2014-04-11 16:54:21 -04002406 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002407 }
2408
2409 rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram),
2410 &nxt);
2411 if (rval != QLA_SUCCESS)
2412 goto qla83xx_fw_dump_failed_0;
2413
2414copy_queue:
2415 nxt = qla2xxx_copy_queues(ha, nxt);
2416
Bart Van Assche7f544d02013-06-25 11:27:27 -04002417 qla24xx_copy_eft(ha, nxt);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002418
2419 /* Chain entries -- started with MQ. */
2420 nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain);
2421 nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain);
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04002422 nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002423 if (last_chain) {
2424 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT);
2425 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
2426 }
2427
2428 /* Adjust valid length. */
2429 ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump);
2430
2431qla83xx_fw_dump_failed_0:
2432 qla2xxx_dump_post_process(base_vha, rval);
2433
2434qla83xx_fw_dump_failed:
2435 if (!hardware_locked)
2436 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2437}
2438
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439/****************************************************************************/
2440/* Driver Debug Functions. */
2441/****************************************************************************/
Chad Dupuiscfb09192011-11-18 09:03:07 -08002442
2443static inline int
2444ql_mask_match(uint32_t level)
2445{
2446 if (ql2xextended_error_logging == 1)
2447 ql2xextended_error_logging = QL_DBG_DEFAULT1_MASK;
2448 return (level & ql2xextended_error_logging) == level;
2449}
2450
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002451/*
2452 * This function is for formatting and logging debug information.
2453 * It is to be used when vha is available. It formats the message
2454 * and logs it to the messages file.
2455 * parameters:
2456 * level: The level of the debug messages to be printed.
2457 * If ql2xextended_error_logging value is correctly set,
2458 * this message will appear in the messages file.
2459 * vha: Pointer to the scsi_qla_host_t.
2460 * id: This is a unique identifier for the level. It identifies the
2461 * part of the code from where the message originated.
2462 * msg: The message to be displayed.
2463 */
2464void
Joe Perches086b3e82011-11-18 09:03:05 -08002465ql_dbg(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...)
2466{
2467 va_list va;
2468 struct va_format vaf;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002469
Chad Dupuiscfb09192011-11-18 09:03:07 -08002470 if (!ql_mask_match(level))
Joe Perches086b3e82011-11-18 09:03:05 -08002471 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002472
Joe Perches086b3e82011-11-18 09:03:05 -08002473 va_start(va, fmt);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002474
Joe Perches086b3e82011-11-18 09:03:05 -08002475 vaf.fmt = fmt;
2476 vaf.va = &va;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002477
Joe Perches086b3e82011-11-18 09:03:05 -08002478 if (vha != NULL) {
2479 const struct pci_dev *pdev = vha->hw->pdev;
2480 /* <module-name> <pci-name> <msg-id>:<host> Message */
2481 pr_warn("%s [%s]-%04x:%ld: %pV",
2482 QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset,
2483 vha->host_no, &vaf);
2484 } else {
2485 pr_warn("%s [%s]-%04x: : %pV",
2486 QL_MSGHDR, "0000:00:00.0", id + ql_dbg_offset, &vaf);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002487 }
2488
Joe Perches086b3e82011-11-18 09:03:05 -08002489 va_end(va);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002490
2491}
2492
2493/*
2494 * This function is for formatting and logging debug information.
Masanari Iidad6a03582012-08-22 14:20:58 -04002495 * It is to be used when vha is not available and pci is available,
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002496 * i.e., before host allocation. It formats the message and logs it
2497 * to the messages file.
2498 * parameters:
2499 * level: The level of the debug messages to be printed.
2500 * If ql2xextended_error_logging value is correctly set,
2501 * this message will appear in the messages file.
2502 * pdev: Pointer to the struct pci_dev.
2503 * id: This is a unique id for the level. It identifies the part
2504 * of the code from where the message originated.
2505 * msg: The message to be displayed.
2506 */
2507void
Joe Perches086b3e82011-11-18 09:03:05 -08002508ql_dbg_pci(uint32_t level, struct pci_dev *pdev, int32_t id,
2509 const char *fmt, ...)
2510{
2511 va_list va;
2512 struct va_format vaf;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002513
2514 if (pdev == NULL)
2515 return;
Chad Dupuiscfb09192011-11-18 09:03:07 -08002516 if (!ql_mask_match(level))
Joe Perches086b3e82011-11-18 09:03:05 -08002517 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002518
Joe Perches086b3e82011-11-18 09:03:05 -08002519 va_start(va, fmt);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002520
Joe Perches086b3e82011-11-18 09:03:05 -08002521 vaf.fmt = fmt;
2522 vaf.va = &va;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002523
Joe Perches086b3e82011-11-18 09:03:05 -08002524 /* <module-name> <dev-name>:<msg-id> Message */
2525 pr_warn("%s [%s]-%04x: : %pV",
2526 QL_MSGHDR, dev_name(&(pdev->dev)), id + ql_dbg_offset, &vaf);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002527
Joe Perches086b3e82011-11-18 09:03:05 -08002528 va_end(va);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002529}
2530
2531/*
2532 * This function is for formatting and logging log messages.
2533 * It is to be used when vha is available. It formats the message
2534 * and logs it to the messages file. All the messages will be logged
2535 * irrespective of value of ql2xextended_error_logging.
2536 * parameters:
2537 * level: The level of the log messages to be printed in the
2538 * messages file.
2539 * vha: Pointer to the scsi_qla_host_t
2540 * id: This is a unique id for the level. It identifies the
2541 * part of the code from where the message originated.
2542 * msg: The message to be displayed.
2543 */
2544void
Joe Perches086b3e82011-11-18 09:03:05 -08002545ql_log(uint32_t level, scsi_qla_host_t *vha, int32_t id, const char *fmt, ...)
2546{
2547 va_list va;
2548 struct va_format vaf;
2549 char pbuf[128];
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002550
Joe Perches086b3e82011-11-18 09:03:05 -08002551 if (level > ql_errlev)
2552 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002553
Joe Perches086b3e82011-11-18 09:03:05 -08002554 if (vha != NULL) {
2555 const struct pci_dev *pdev = vha->hw->pdev;
2556 /* <module-name> <msg-id>:<host> Message */
2557 snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x:%ld: ",
2558 QL_MSGHDR, dev_name(&(pdev->dev)), id, vha->host_no);
2559 } else {
2560 snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
2561 QL_MSGHDR, "0000:00:00.0", id);
2562 }
2563 pbuf[sizeof(pbuf) - 1] = 0;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002564
Joe Perches086b3e82011-11-18 09:03:05 -08002565 va_start(va, fmt);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002566
Joe Perches086b3e82011-11-18 09:03:05 -08002567 vaf.fmt = fmt;
2568 vaf.va = &va;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002569
Joe Perches086b3e82011-11-18 09:03:05 -08002570 switch (level) {
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002571 case ql_log_fatal: /* FATAL LOG */
Joe Perches086b3e82011-11-18 09:03:05 -08002572 pr_crit("%s%pV", pbuf, &vaf);
2573 break;
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002574 case ql_log_warn:
Joe Perches086b3e82011-11-18 09:03:05 -08002575 pr_err("%s%pV", pbuf, &vaf);
2576 break;
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002577 case ql_log_info:
Joe Perches086b3e82011-11-18 09:03:05 -08002578 pr_warn("%s%pV", pbuf, &vaf);
2579 break;
2580 default:
2581 pr_info("%s%pV", pbuf, &vaf);
2582 break;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002583 }
2584
Joe Perches086b3e82011-11-18 09:03:05 -08002585 va_end(va);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002586}
2587
2588/*
2589 * This function is for formatting and logging log messages.
Masanari Iidad6a03582012-08-22 14:20:58 -04002590 * It is to be used when vha is not available and pci is available,
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002591 * i.e., before host allocation. It formats the message and logs
2592 * it to the messages file. All the messages are logged irrespective
2593 * of the value of ql2xextended_error_logging.
2594 * parameters:
2595 * level: The level of the log messages to be printed in the
2596 * messages file.
2597 * pdev: Pointer to the struct pci_dev.
2598 * id: This is a unique id for the level. It identifies the
2599 * part of the code from where the message originated.
2600 * msg: The message to be displayed.
2601 */
2602void
Joe Perches086b3e82011-11-18 09:03:05 -08002603ql_log_pci(uint32_t level, struct pci_dev *pdev, int32_t id,
2604 const char *fmt, ...)
2605{
2606 va_list va;
2607 struct va_format vaf;
2608 char pbuf[128];
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002609
2610 if (pdev == NULL)
2611 return;
Joe Perches086b3e82011-11-18 09:03:05 -08002612 if (level > ql_errlev)
2613 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002614
Joe Perches086b3e82011-11-18 09:03:05 -08002615 /* <module-name> <dev-name>:<msg-id> Message */
2616 snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
2617 QL_MSGHDR, dev_name(&(pdev->dev)), id);
2618 pbuf[sizeof(pbuf) - 1] = 0;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002619
Joe Perches086b3e82011-11-18 09:03:05 -08002620 va_start(va, fmt);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002621
Joe Perches086b3e82011-11-18 09:03:05 -08002622 vaf.fmt = fmt;
2623 vaf.va = &va;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002624
Joe Perches086b3e82011-11-18 09:03:05 -08002625 switch (level) {
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002626 case ql_log_fatal: /* FATAL LOG */
Joe Perches086b3e82011-11-18 09:03:05 -08002627 pr_crit("%s%pV", pbuf, &vaf);
2628 break;
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002629 case ql_log_warn:
Joe Perches086b3e82011-11-18 09:03:05 -08002630 pr_err("%s%pV", pbuf, &vaf);
2631 break;
Chad Dupuis70a3fc72012-02-09 11:15:48 -08002632 case ql_log_info:
Joe Perches086b3e82011-11-18 09:03:05 -08002633 pr_warn("%s%pV", pbuf, &vaf);
2634 break;
2635 default:
2636 pr_info("%s%pV", pbuf, &vaf);
2637 break;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002638 }
2639
Joe Perches086b3e82011-11-18 09:03:05 -08002640 va_end(va);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002641}
2642
2643void
2644ql_dump_regs(uint32_t level, scsi_qla_host_t *vha, int32_t id)
2645{
2646 int i;
2647 struct qla_hw_data *ha = vha->hw;
2648 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
2649 struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
2650 struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
2651 uint16_t __iomem *mbx_reg;
2652
Chad Dupuiscfb09192011-11-18 09:03:07 -08002653 if (!ql_mask_match(level))
2654 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002655
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04002656 if (IS_P3P_TYPE(ha))
Chad Dupuiscfb09192011-11-18 09:03:07 -08002657 mbx_reg = &reg82->mailbox_in[0];
2658 else if (IS_FWI2_CAPABLE(ha))
2659 mbx_reg = &reg24->mailbox0;
2660 else
2661 mbx_reg = MAILBOX_REG(ha, reg, 0);
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002662
Chad Dupuiscfb09192011-11-18 09:03:07 -08002663 ql_dbg(level, vha, id, "Mailbox registers:\n");
2664 for (i = 0; i < 6; i++)
2665 ql_dbg(level, vha, id,
2666 "mbox[%d] 0x%04x\n", i, RD_REG_WORD(mbx_reg++));
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002667}
2668
2669
2670void
2671ql_dump_buffer(uint32_t level, scsi_qla_host_t *vha, int32_t id,
2672 uint8_t *b, uint32_t size)
2673{
2674 uint32_t cnt;
2675 uint8_t c;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002676
Chad Dupuiscfb09192011-11-18 09:03:07 -08002677 if (!ql_mask_match(level))
2678 return;
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002679
Chad Dupuiscfb09192011-11-18 09:03:07 -08002680 ql_dbg(level, vha, id, " 0 1 2 3 4 5 6 7 8 "
2681 "9 Ah Bh Ch Dh Eh Fh\n");
2682 ql_dbg(level, vha, id, "----------------------------------"
2683 "----------------------------\n");
2684
2685 ql_dbg(level, vha, id, " ");
2686 for (cnt = 0; cnt < size;) {
2687 c = *b++;
2688 printk("%02x", (uint32_t) c);
2689 cnt++;
2690 if (!(cnt % 16))
2691 printk("\n");
2692 else
2693 printk(" ");
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002694 }
Chad Dupuiscfb09192011-11-18 09:03:07 -08002695 if (cnt % 16)
2696 ql_dbg(level, vha, id, "\n");
Saurav Kashyap3ce88662011-07-14 12:00:12 -07002697}