]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/scsi/qla2xxx/qla_mbx.c
[SCSI] qla2xxx: Enable Minidump by default with default capture mask 0x1f.
[mirror_ubuntu-artful-kernel.git] / drivers / scsi / qla2xxx / qla_mbx.c
CommitLineData
1da177e4 1/*
fa90c54f 2 * QLogic Fibre Channel HBA Driver
07e264b7 3 * Copyright (c) 2003-2011 QLogic Corporation
1da177e4 4 *
fa90c54f 5 * See LICENSE.qla2xxx for copyright and licensing details.
1da177e4
LT
6 */
7#include "qla_def.h"
8
9#include <linux/delay.h>
5a0e3ad6 10#include <linux/gfp.h>
1da177e4 11
1da177e4
LT
12
13/*
14 * qla2x00_mailbox_command
15 * Issue mailbox command and waits for completion.
16 *
17 * Input:
18 * ha = adapter block pointer.
19 * mcp = driver internal mbx struct pointer.
20 *
21 * Output:
22 * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
23 *
24 * Returns:
25 * 0 : QLA_SUCCESS = cmd performed success
26 * 1 : QLA_FUNCTION_FAILED (error encountered)
27 * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
28 *
29 * Context:
30 * Kernel context.
31 */
32static int
7b867cf7 33qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
1da177e4
LT
34{
35 int rval;
36 unsigned long flags = 0;
2c3dfe3f 37 device_reg_t __iomem *reg;
1c7c6357 38 uint8_t abort_active;
2c3dfe3f 39 uint8_t io_lock_on;
cdbb0a4f 40 uint16_t command = 0;
1da177e4
LT
41 uint16_t *iptr;
42 uint16_t __iomem *optr;
43 uint32_t cnt;
44 uint32_t mboxes;
1da177e4 45 unsigned long wait_time;
7b867cf7
AC
46 struct qla_hw_data *ha = vha->hw;
47 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
2c3dfe3f 48
7c3df132
SK
49 ql_dbg(ql_dbg_mbx, base_vha, 0x1000, "Entered %s.\n", __func__);
50
51 if (ha->pdev->error_state > pci_channel_io_frozen) {
52 ql_log(ql_log_warn, base_vha, 0x1001,
53 "error_state is greater than pci_channel_io_frozen, "
54 "exiting.\n");
b9b12f73 55 return QLA_FUNCTION_TIMEOUT;
7c3df132 56 }
b9b12f73 57
a9083016 58 if (vha->device_flags & DFLG_DEV_FAILED) {
7c3df132
SK
59 ql_log(ql_log_warn, base_vha, 0x1002,
60 "Device in failed state, exiting.\n");
a9083016
GM
61 return QLA_FUNCTION_TIMEOUT;
62 }
63
2c3dfe3f 64 reg = ha->iobase;
7b867cf7 65 io_lock_on = base_vha->flags.init_done;
1da177e4
LT
66
67 rval = QLA_SUCCESS;
7b867cf7 68 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
1c7c6357 69
1da177e4 70
85880801 71 if (ha->flags.pci_channel_io_perm_failure) {
7c3df132
SK
72 ql_log(ql_log_warn, base_vha, 0x1003,
73 "Perm failure on EEH timeout MBX, exiting.\n");
85880801
AV
74 return QLA_FUNCTION_TIMEOUT;
75 }
76
862cd01e
GM
77 if (ha->flags.isp82xx_fw_hung) {
78 /* Setting Link-Down error */
79 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
7c3df132
SK
80 ql_log(ql_log_warn, base_vha, 0x1004,
81 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
862cd01e
GM
82 rval = QLA_FUNCTION_FAILED;
83 goto premature_exit;
84 }
85
1da177e4 86 /*
1c7c6357
AV
87 * Wait for active mailbox commands to finish by waiting at most tov
88 * seconds. This is to serialize actual issuing of mailbox cmds during
89 * non ISP abort time.
1da177e4 90 */
8eca3f39
AV
91 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
92 /* Timeout occurred. Return error. */
7c3df132
SK
93 ql_log(ql_log_warn, base_vha, 0x1005,
94 "Cmd access timeout, Exiting.\n");
8eca3f39 95 return QLA_FUNCTION_TIMEOUT;
1da177e4
LT
96 }
97
98 ha->flags.mbox_busy = 1;
99 /* Save mailbox command for debug */
100 ha->mcp = mcp;
101
7c3df132
SK
102 ql_dbg(ql_dbg_mbx, base_vha, 0x1006,
103 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
1da177e4
LT
104
105 spin_lock_irqsave(&ha->hardware_lock, flags);
106
107 /* Load mailbox registers. */
a9083016
GM
108 if (IS_QLA82XX(ha))
109 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
110 else if (IS_FWI2_CAPABLE(ha) && !IS_QLA82XX(ha))
1c7c6357
AV
111 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
112 else
113 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
1da177e4
LT
114
115 iptr = mcp->mb;
116 command = mcp->mb[0];
117 mboxes = mcp->out_mb;
118
119 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
120 if (IS_QLA2200(ha) && cnt == 8)
1c7c6357
AV
121 optr =
122 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
1da177e4
LT
123 if (mboxes & BIT_0)
124 WRT_REG_WORD(optr, *iptr);
125
126 mboxes >>= 1;
127 optr++;
128 iptr++;
129 }
130
7c3df132
SK
131 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1111,
132 "Loaded MBX registers (displayed in bytes) =.\n");
133 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1112,
134 (uint8_t *)mcp->mb, 16);
135 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1113,
136 ".\n");
137 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1114,
138 ((uint8_t *)mcp->mb + 0x10), 16);
139 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1115,
140 ".\n");
141 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1116,
142 ((uint8_t *)mcp->mb + 0x20), 8);
143 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1117,
144 "I/O Address = %p.\n", optr);
145 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x100e);
1da177e4
LT
146
147 /* Issue set host interrupt command to send cmd out. */
148 ha->flags.mbox_int = 0;
149 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
150
151 /* Unlock mbx registers and wait for interrupt */
7c3df132
SK
152 ql_dbg(ql_dbg_mbx, base_vha, 0x100f,
153 "Going to unlock irq & waiting for interrupts. "
154 "jiffies=%lx.\n", jiffies);
1da177e4
LT
155
156 /* Wait for mbx cmd completion until timeout */
157
124f85e6 158 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
1da177e4
LT
159 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
160
a9083016
GM
161 if (IS_QLA82XX(ha)) {
162 if (RD_REG_DWORD(&reg->isp82.hint) &
163 HINT_MBX_INT_PENDING) {
164 spin_unlock_irqrestore(&ha->hardware_lock,
165 flags);
7c3df132
SK
166 ql_dbg(ql_dbg_mbx, base_vha, 0x1010,
167 "Pending mailbox timeout, exiting.\n");
cdbb0a4f
SV
168 rval = QLA_FUNCTION_TIMEOUT;
169 goto premature_exit;
a9083016
GM
170 }
171 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
172 } else if (IS_FWI2_CAPABLE(ha))
1c7c6357
AV
173 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
174 else
175 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
1da177e4
LT
176 spin_unlock_irqrestore(&ha->hardware_lock, flags);
177
0b05a1f0 178 wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ);
1da177e4 179
1da177e4
LT
180 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
181
1da177e4 182 } else {
7c3df132
SK
183 ql_dbg(ql_dbg_mbx, base_vha, 0x1011,
184 "Cmd=%x Polling Mode.\n", command);
1da177e4 185
a9083016
GM
186 if (IS_QLA82XX(ha)) {
187 if (RD_REG_DWORD(&reg->isp82.hint) &
188 HINT_MBX_INT_PENDING) {
189 spin_unlock_irqrestore(&ha->hardware_lock,
190 flags);
7c3df132
SK
191 ql_dbg(ql_dbg_mbx, base_vha, 0x1012,
192 "Pending mailbox timeout, exiting.\n");
cdbb0a4f
SV
193 rval = QLA_FUNCTION_TIMEOUT;
194 goto premature_exit;
a9083016
GM
195 }
196 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
197 } else if (IS_FWI2_CAPABLE(ha))
1c7c6357
AV
198 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
199 else
200 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
1da177e4 201 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1da177e4
LT
202
203 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
204 while (!ha->flags.mbox_int) {
205 if (time_after(jiffies, wait_time))
206 break;
207
208 /* Check for pending interrupts. */
73208dfd 209 qla2x00_poll(ha->rsp_q_map[0]);
1da177e4 210
85880801
AV
211 if (!ha->flags.mbox_int &&
212 !(IS_QLA2200(ha) &&
213 command == MBC_LOAD_RISC_RAM_EXTENDED))
59989831 214 msleep(10);
1da177e4 215 } /* while */
7c3df132
SK
216 ql_dbg(ql_dbg_mbx, base_vha, 0x1013,
217 "Waited %d sec.\n",
218 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
1da177e4
LT
219 }
220
1da177e4
LT
221 /* Check whether we timed out */
222 if (ha->flags.mbox_int) {
223 uint16_t *iptr2;
224
7c3df132
SK
225 ql_dbg(ql_dbg_mbx, base_vha, 0x1014,
226 "Cmd=%x completed.\n", command);
1da177e4
LT
227
228 /* Got interrupt. Clear the flag. */
229 ha->flags.mbox_int = 0;
230 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
231
7190575f 232 if (ha->flags.isp82xx_fw_hung) {
cdbb0a4f
SV
233 ha->flags.mbox_busy = 0;
234 /* Setting Link-Down error */
235 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
236 ha->mcp = NULL;
237 rval = QLA_FUNCTION_FAILED;
7c3df132
SK
238 ql_log(ql_log_warn, base_vha, 0x1015,
239 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
cdbb0a4f
SV
240 goto premature_exit;
241 }
242
354d6b21 243 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
1da177e4 244 rval = QLA_FUNCTION_FAILED;
1da177e4
LT
245
246 /* Load return mailbox registers. */
247 iptr2 = mcp->mb;
248 iptr = (uint16_t *)&ha->mailbox_out[0];
249 mboxes = mcp->in_mb;
250 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
251 if (mboxes & BIT_0)
252 *iptr2 = *iptr;
253
254 mboxes >>= 1;
255 iptr2++;
256 iptr++;
257 }
258 } else {
259
1c7c6357
AV
260 uint16_t mb0;
261 uint32_t ictrl;
262
e428924c 263 if (IS_FWI2_CAPABLE(ha)) {
1c7c6357
AV
264 mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
265 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
266 } else {
cca5335c 267 mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
1c7c6357
AV
268 ictrl = RD_REG_WORD(&reg->isp.ictrl);
269 }
7c3df132
SK
270 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1119,
271 "MBX Command timeout for cmd %x.\n", command);
272 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111a,
273 "iocontrol=%x jiffies=%lx.\n", ictrl, jiffies);
274 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111b,
275 "mb[0] = 0x%x.\n", mb0);
276 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1019);
1da177e4 277
1da177e4
LT
278 rval = QLA_FUNCTION_TIMEOUT;
279 }
280
1da177e4
LT
281 ha->flags.mbox_busy = 0;
282
283 /* Clean up */
284 ha->mcp = NULL;
285
124f85e6 286 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
7c3df132
SK
287 ql_dbg(ql_dbg_mbx, base_vha, 0x101a,
288 "Checking for additional resp interrupt.\n");
1da177e4
LT
289
290 /* polling mode for non isp_abort commands. */
73208dfd 291 qla2x00_poll(ha->rsp_q_map[0]);
1da177e4
LT
292 }
293
1c7c6357
AV
294 if (rval == QLA_FUNCTION_TIMEOUT &&
295 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
85880801
AV
296 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
297 ha->flags.eeh_busy) {
1da177e4 298 /* not in dpc. schedule it for dpc to take over. */
7c3df132
SK
299 ql_dbg(ql_dbg_mbx, base_vha, 0x101b,
300 "Timeout, schedule isp_abort_needed.\n");
cdbb0a4f
SV
301
302 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
303 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
304 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
305
7c3df132
SK
306 ql_log(ql_log_info, base_vha, 0x101c,
307 "Mailbox cmd timeout occured. "
308 "Scheduling ISP abort eeh_busy=0x%x.\n",
309 ha->flags.eeh_busy);
cdbb0a4f
SV
310 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
311 qla2xxx_wake_dpc(vha);
312 }
1da177e4 313 } else if (!abort_active) {
1da177e4 314 /* call abort directly since we are in the DPC thread */
7c3df132
SK
315 ql_dbg(ql_dbg_mbx, base_vha, 0x101d,
316 "Timeout, calling abort_isp.\n");
cdbb0a4f
SV
317
318 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
319 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
320 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
321
7c3df132
SK
322 ql_log(ql_log_info, base_vha, 0x101e,
323 "Mailbox cmd timeout occured. "
324 "Scheduling ISP abort.\n");
cdbb0a4f
SV
325
326 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
327 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
328 if (ha->isp_ops->abort_isp(vha)) {
329 /* Failed. retry later. */
330 set_bit(ISP_ABORT_NEEDED,
331 &vha->dpc_flags);
332 }
333 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
7c3df132
SK
334 ql_dbg(ql_dbg_mbx, base_vha, 0x101f,
335 "Finished abort_isp.\n");
1da177e4 336 }
1da177e4
LT
337 }
338 }
339
cdbb0a4f 340premature_exit:
1da177e4 341 /* Allow next mbx cmd to come in. */
8eca3f39 342 complete(&ha->mbx_cmd_comp);
1da177e4
LT
343
344 if (rval) {
7c3df132
SK
345 ql_dbg(ql_dbg_mbx, base_vha, 0x1020,
346 "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, cmd=%x ****.\n",
347 mcp->mb[0], mcp->mb[1], mcp->mb[2], command);
1da177e4 348 } else {
7c3df132 349 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
1da177e4
LT
350 }
351
1da177e4
LT
352 return rval;
353}
354
1da177e4 355int
7b867cf7 356qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
590f98e5 357 uint32_t risc_code_size)
1da177e4
LT
358{
359 int rval;
7b867cf7 360 struct qla_hw_data *ha = vha->hw;
1da177e4
LT
361 mbx_cmd_t mc;
362 mbx_cmd_t *mcp = &mc;
1da177e4 363
7c3df132 364 ql_dbg(ql_dbg_mbx, vha, 0x1022, "Entered %s.\n", __func__);
1da177e4 365
e428924c 366 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
590f98e5
AV
367 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
368 mcp->mb[8] = MSW(risc_addr);
369 mcp->out_mb = MBX_8|MBX_0;
1da177e4 370 } else {
590f98e5
AV
371 mcp->mb[0] = MBC_LOAD_RISC_RAM;
372 mcp->out_mb = MBX_0;
1da177e4 373 }
1da177e4
LT
374 mcp->mb[1] = LSW(risc_addr);
375 mcp->mb[2] = MSW(req_dma);
376 mcp->mb[3] = LSW(req_dma);
1da177e4
LT
377 mcp->mb[6] = MSW(MSD(req_dma));
378 mcp->mb[7] = LSW(MSD(req_dma));
590f98e5 379 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
e428924c 380 if (IS_FWI2_CAPABLE(ha)) {
1c7c6357
AV
381 mcp->mb[4] = MSW(risc_code_size);
382 mcp->mb[5] = LSW(risc_code_size);
383 mcp->out_mb |= MBX_5|MBX_4;
384 } else {
385 mcp->mb[4] = LSW(risc_code_size);
386 mcp->out_mb |= MBX_4;
387 }
388
1da177e4 389 mcp->in_mb = MBX_0;
b93480e3 390 mcp->tov = MBX_TOV_SECONDS;
1da177e4 391 mcp->flags = 0;
7b867cf7 392 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4 393
1da177e4 394 if (rval != QLA_SUCCESS) {
7c3df132
SK
395 ql_dbg(ql_dbg_mbx, vha, 0x1023,
396 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
1da177e4 397 } else {
7c3df132 398 ql_dbg(ql_dbg_mbx, vha, 0x1024, "Done %s.\n", __func__);
1da177e4
LT
399 }
400
401 return rval;
402}
403
cad454b1 404#define EXTENDED_BB_CREDITS BIT_0
1da177e4
LT
405/*
406 * qla2x00_execute_fw
1c7c6357 407 * Start adapter firmware.
1da177e4
LT
408 *
409 * Input:
1c7c6357
AV
410 * ha = adapter block pointer.
411 * TARGET_QUEUE_LOCK must be released.
412 * ADAPTER_STATE_LOCK must be released.
1da177e4
LT
413 *
414 * Returns:
1c7c6357 415 * qla2x00 local function return status code.
1da177e4
LT
416 *
417 * Context:
1c7c6357 418 * Kernel context.
1da177e4
LT
419 */
420int
7b867cf7 421qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
1da177e4
LT
422{
423 int rval;
7b867cf7 424 struct qla_hw_data *ha = vha->hw;
1da177e4
LT
425 mbx_cmd_t mc;
426 mbx_cmd_t *mcp = &mc;
427
7c3df132 428 ql_dbg(ql_dbg_mbx, vha, 0x1025, "Entered %s.\n", __func__);
1da177e4
LT
429
430 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
1c7c6357
AV
431 mcp->out_mb = MBX_0;
432 mcp->in_mb = MBX_0;
e428924c 433 if (IS_FWI2_CAPABLE(ha)) {
1c7c6357
AV
434 mcp->mb[1] = MSW(risc_addr);
435 mcp->mb[2] = LSW(risc_addr);
436 mcp->mb[3] = 0;
cad454b1
SV
437 if (IS_QLA81XX(ha)) {
438 struct nvram_81xx *nv = ha->nvram;
439 mcp->mb[4] = (nv->enhanced_features &
440 EXTENDED_BB_CREDITS);
441 } else
442 mcp->mb[4] = 0;
8b3253d1 443 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
1c7c6357
AV
444 mcp->in_mb |= MBX_1;
445 } else {
446 mcp->mb[1] = LSW(risc_addr);
447 mcp->out_mb |= MBX_1;
448 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
449 mcp->mb[2] = 0;
450 mcp->out_mb |= MBX_2;
451 }
1da177e4
LT
452 }
453
b93480e3 454 mcp->tov = MBX_TOV_SECONDS;
1da177e4 455 mcp->flags = 0;
7b867cf7 456 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4 457
1c7c6357 458 if (rval != QLA_SUCCESS) {
7c3df132
SK
459 ql_dbg(ql_dbg_mbx, vha, 0x1026,
460 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
1c7c6357 461 } else {
e428924c 462 if (IS_FWI2_CAPABLE(ha)) {
7c3df132
SK
463 ql_dbg(ql_dbg_mbx, vha, 0x1027,
464 "Done exchanges=%x.\n", mcp->mb[1]);
1c7c6357 465 } else {
7c3df132 466 ql_dbg(ql_dbg_mbx, vha, 0x1028, "Done %s.\n", __func__);
1c7c6357
AV
467 }
468 }
1da177e4
LT
469
470 return rval;
471}
472
473/*
474 * qla2x00_get_fw_version
475 * Get firmware version.
476 *
477 * Input:
478 * ha: adapter state pointer.
479 * major: pointer for major number.
480 * minor: pointer for minor number.
481 * subminor: pointer for subminor number.
482 *
483 * Returns:
484 * qla2x00 local function return status code.
485 *
486 * Context:
487 * Kernel context.
488 */
ca9e9c3e 489int
7b867cf7 490qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
3a03eb79 491 uint16_t *subminor, uint16_t *attributes, uint32_t *memory, uint8_t *mpi,
55a96158 492 uint32_t *mpi_caps, uint8_t *phy)
1da177e4
LT
493{
494 int rval;
495 mbx_cmd_t mc;
496 mbx_cmd_t *mcp = &mc;
497
7c3df132 498 ql_dbg(ql_dbg_mbx, vha, 0x1029, "Entered %s.\n", __func__);
1da177e4
LT
499
500 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
501 mcp->out_mb = MBX_0;
502 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3a03eb79 503 if (IS_QLA81XX(vha->hw))
55a96158 504 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
1da177e4 505 mcp->flags = 0;
b93480e3 506 mcp->tov = MBX_TOV_SECONDS;
7b867cf7 507 rval = qla2x00_mailbox_command(vha, mcp);
ca9e9c3e
AV
508 if (rval != QLA_SUCCESS)
509 goto failed;
1da177e4
LT
510
511 /* Return mailbox data. */
512 *major = mcp->mb[1];
513 *minor = mcp->mb[2];
514 *subminor = mcp->mb[3];
515 *attributes = mcp->mb[6];
7b867cf7 516 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
1da177e4
LT
517 *memory = 0x1FFFF; /* Defaults to 128KB. */
518 else
519 *memory = (mcp->mb[5] << 16) | mcp->mb[4];
3a03eb79 520 if (IS_QLA81XX(vha->hw)) {
55a96158
AV
521 mpi[0] = mcp->mb[10] & 0xff;
522 mpi[1] = mcp->mb[11] >> 8;
523 mpi[2] = mcp->mb[11] & 0xff;
3a03eb79 524 *mpi_caps = (mcp->mb[12] << 16) | mcp->mb[13];
55a96158
AV
525 phy[0] = mcp->mb[8] & 0xff;
526 phy[1] = mcp->mb[9] >> 8;
527 phy[2] = mcp->mb[9] & 0xff;
3a03eb79 528 }
ca9e9c3e 529failed:
1da177e4
LT
530 if (rval != QLA_SUCCESS) {
531 /*EMPTY*/
7c3df132 532 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
1da177e4
LT
533 } else {
534 /*EMPTY*/
7c3df132 535 ql_dbg(ql_dbg_mbx, vha, 0x102b, "Done %s.\n", __func__);
1da177e4 536 }
ca9e9c3e 537 return rval;
1da177e4
LT
538}
539
540/*
541 * qla2x00_get_fw_options
542 * Set firmware options.
543 *
544 * Input:
545 * ha = adapter block pointer.
546 * fwopt = pointer for firmware options.
547 *
548 * Returns:
549 * qla2x00 local function return status code.
550 *
551 * Context:
552 * Kernel context.
553 */
554int
7b867cf7 555qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
1da177e4
LT
556{
557 int rval;
558 mbx_cmd_t mc;
559 mbx_cmd_t *mcp = &mc;
560
7c3df132 561 ql_dbg(ql_dbg_mbx, vha, 0x102c, "Entered %s.\n", __func__);
1da177e4
LT
562
563 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
564 mcp->out_mb = MBX_0;
565 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
b93480e3 566 mcp->tov = MBX_TOV_SECONDS;
1da177e4 567 mcp->flags = 0;
7b867cf7 568 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
569
570 if (rval != QLA_SUCCESS) {
571 /*EMPTY*/
7c3df132 572 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
1da177e4 573 } else {
1c7c6357 574 fwopts[0] = mcp->mb[0];
1da177e4
LT
575 fwopts[1] = mcp->mb[1];
576 fwopts[2] = mcp->mb[2];
577 fwopts[3] = mcp->mb[3];
578
7c3df132 579 ql_dbg(ql_dbg_mbx, vha, 0x102e, "Done %s.\n", __func__);
1da177e4
LT
580 }
581
582 return rval;
583}
584
585
586/*
587 * qla2x00_set_fw_options
588 * Set firmware options.
589 *
590 * Input:
591 * ha = adapter block pointer.
592 * fwopt = pointer for firmware options.
593 *
594 * Returns:
595 * qla2x00 local function return status code.
596 *
597 * Context:
598 * Kernel context.
599 */
600int
7b867cf7 601qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
1da177e4
LT
602{
603 int rval;
604 mbx_cmd_t mc;
605 mbx_cmd_t *mcp = &mc;
606
7c3df132 607 ql_dbg(ql_dbg_mbx, vha, 0x102f, "Entered %s.\n", __func__);
1da177e4
LT
608
609 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
610 mcp->mb[1] = fwopts[1];
611 mcp->mb[2] = fwopts[2];
612 mcp->mb[3] = fwopts[3];
1c7c6357 613 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1da177e4 614 mcp->in_mb = MBX_0;
7b867cf7 615 if (IS_FWI2_CAPABLE(vha->hw)) {
1c7c6357
AV
616 mcp->in_mb |= MBX_1;
617 } else {
618 mcp->mb[10] = fwopts[10];
619 mcp->mb[11] = fwopts[11];
620 mcp->mb[12] = 0; /* Undocumented, but used */
621 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
622 }
b93480e3 623 mcp->tov = MBX_TOV_SECONDS;
1da177e4 624 mcp->flags = 0;
7b867cf7 625 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4 626
1c7c6357
AV
627 fwopts[0] = mcp->mb[0];
628
1da177e4
LT
629 if (rval != QLA_SUCCESS) {
630 /*EMPTY*/
7c3df132
SK
631 ql_dbg(ql_dbg_mbx, vha, 0x1030,
632 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
1da177e4
LT
633 } else {
634 /*EMPTY*/
7c3df132 635 ql_dbg(ql_dbg_mbx, vha, 0x1031, "Done %s.\n", __func__);
1da177e4
LT
636 }
637
638 return rval;
639}
640
641/*
642 * qla2x00_mbx_reg_test
643 * Mailbox register wrap test.
644 *
645 * Input:
646 * ha = adapter block pointer.
647 * TARGET_QUEUE_LOCK must be released.
648 * ADAPTER_STATE_LOCK must be released.
649 *
650 * Returns:
651 * qla2x00 local function return status code.
652 *
653 * Context:
654 * Kernel context.
655 */
656int
7b867cf7 657qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
1da177e4
LT
658{
659 int rval;
660 mbx_cmd_t mc;
661 mbx_cmd_t *mcp = &mc;
662
7c3df132 663 ql_dbg(ql_dbg_mbx, vha, 0x1032, "Entered %s.\n", __func__);
1da177e4
LT
664
665 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
666 mcp->mb[1] = 0xAAAA;
667 mcp->mb[2] = 0x5555;
668 mcp->mb[3] = 0xAA55;
669 mcp->mb[4] = 0x55AA;
670 mcp->mb[5] = 0xA5A5;
671 mcp->mb[6] = 0x5A5A;
672 mcp->mb[7] = 0x2525;
673 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
674 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
b93480e3 675 mcp->tov = MBX_TOV_SECONDS;
1da177e4 676 mcp->flags = 0;
7b867cf7 677 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
678
679 if (rval == QLA_SUCCESS) {
680 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
681 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
682 rval = QLA_FUNCTION_FAILED;
683 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
684 mcp->mb[7] != 0x2525)
685 rval = QLA_FUNCTION_FAILED;
686 }
687
688 if (rval != QLA_SUCCESS) {
689 /*EMPTY*/
7c3df132 690 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
1da177e4
LT
691 } else {
692 /*EMPTY*/
7c3df132 693 ql_dbg(ql_dbg_mbx, vha, 0x1034, "Done %s.\n", __func__);
1da177e4
LT
694 }
695
696 return rval;
697}
698
699/*
700 * qla2x00_verify_checksum
701 * Verify firmware checksum.
702 *
703 * Input:
704 * ha = adapter block pointer.
705 * TARGET_QUEUE_LOCK must be released.
706 * ADAPTER_STATE_LOCK must be released.
707 *
708 * Returns:
709 * qla2x00 local function return status code.
710 *
711 * Context:
712 * Kernel context.
713 */
714int
7b867cf7 715qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
1da177e4
LT
716{
717 int rval;
718 mbx_cmd_t mc;
719 mbx_cmd_t *mcp = &mc;
720
7c3df132 721 ql_dbg(ql_dbg_mbx, vha, 0x1035, "Entered %s.\n", __func__);
1da177e4
LT
722
723 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
1c7c6357
AV
724 mcp->out_mb = MBX_0;
725 mcp->in_mb = MBX_0;
7b867cf7 726 if (IS_FWI2_CAPABLE(vha->hw)) {
1c7c6357
AV
727 mcp->mb[1] = MSW(risc_addr);
728 mcp->mb[2] = LSW(risc_addr);
729 mcp->out_mb |= MBX_2|MBX_1;
730 mcp->in_mb |= MBX_2|MBX_1;
731 } else {
732 mcp->mb[1] = LSW(risc_addr);
733 mcp->out_mb |= MBX_1;
734 mcp->in_mb |= MBX_1;
735 }
736
b93480e3 737 mcp->tov = MBX_TOV_SECONDS;
1da177e4 738 mcp->flags = 0;
7b867cf7 739 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
740
741 if (rval != QLA_SUCCESS) {
7c3df132
SK
742 ql_dbg(ql_dbg_mbx, vha, 0x1036,
743 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
744 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
1da177e4 745 } else {
7c3df132 746 ql_dbg(ql_dbg_mbx, vha, 0x1037, "Done %s.\n", __func__);
1da177e4
LT
747 }
748
749 return rval;
750}
751
752/*
753 * qla2x00_issue_iocb
754 * Issue IOCB using mailbox command
755 *
756 * Input:
757 * ha = adapter state pointer.
758 * buffer = buffer pointer.
759 * phys_addr = physical address of buffer.
760 * size = size of buffer.
761 * TARGET_QUEUE_LOCK must be released.
762 * ADAPTER_STATE_LOCK must be released.
763 *
764 * Returns:
765 * qla2x00 local function return status code.
766 *
767 * Context:
768 * Kernel context.
769 */
6e98016c 770int
7b867cf7 771qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
4d4df193 772 dma_addr_t phys_addr, size_t size, uint32_t tov)
1da177e4
LT
773{
774 int rval;
775 mbx_cmd_t mc;
776 mbx_cmd_t *mcp = &mc;
777
7c3df132
SK
778 ql_dbg(ql_dbg_mbx, vha, 0x1038, "Entered %s.\n", __func__);
779
1da177e4
LT
780 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
781 mcp->mb[1] = 0;
782 mcp->mb[2] = MSW(phys_addr);
783 mcp->mb[3] = LSW(phys_addr);
784 mcp->mb[6] = MSW(MSD(phys_addr));
785 mcp->mb[7] = LSW(MSD(phys_addr));
786 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
787 mcp->in_mb = MBX_2|MBX_0;
4d4df193 788 mcp->tov = tov;
1da177e4 789 mcp->flags = 0;
7b867cf7 790 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
791
792 if (rval != QLA_SUCCESS) {
793 /*EMPTY*/
7c3df132 794 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
1da177e4 795 } else {
8c958a99
AV
796 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
797
798 /* Mask reserved bits. */
799 sts_entry->entry_status &=
7b867cf7 800 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
7c3df132 801 ql_dbg(ql_dbg_mbx, vha, 0x103a, "Done %s.\n", __func__);
1da177e4
LT
802 }
803
804 return rval;
805}
806
4d4df193 807int
7b867cf7 808qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
4d4df193
HK
809 size_t size)
810{
7b867cf7 811 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
4d4df193
HK
812 MBX_TOV_SECONDS);
813}
814
1da177e4
LT
815/*
816 * qla2x00_abort_command
817 * Abort command aborts a specified IOCB.
818 *
819 * Input:
820 * ha = adapter block pointer.
821 * sp = SB structure pointer.
822 *
823 * Returns:
824 * qla2x00 local function return status code.
825 *
826 * Context:
827 * Kernel context.
828 */
829int
2afa19a9 830qla2x00_abort_command(srb_t *sp)
1da177e4
LT
831{
832 unsigned long flags = 0;
1da177e4 833 int rval;
73208dfd 834 uint32_t handle = 0;
1da177e4
LT
835 mbx_cmd_t mc;
836 mbx_cmd_t *mcp = &mc;
2afa19a9
AC
837 fc_port_t *fcport = sp->fcport;
838 scsi_qla_host_t *vha = fcport->vha;
7b867cf7 839 struct qla_hw_data *ha = vha->hw;
2afa19a9 840 struct req_que *req = vha->req;
1da177e4 841
7c3df132 842 ql_dbg(ql_dbg_mbx, vha, 0x103b, "Entered %s.\n", __func__);
1da177e4 843
c9c5ced9 844 spin_lock_irqsave(&ha->hardware_lock, flags);
1da177e4 845 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
7b867cf7 846 if (req->outstanding_cmds[handle] == sp)
1da177e4
LT
847 break;
848 }
c9c5ced9 849 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1da177e4
LT
850
851 if (handle == MAX_OUTSTANDING_COMMANDS) {
852 /* command not found */
853 return QLA_FUNCTION_FAILED;
854 }
855
856 mcp->mb[0] = MBC_ABORT_COMMAND;
857 if (HAS_EXTENDED_IDS(ha))
858 mcp->mb[1] = fcport->loop_id;
859 else
860 mcp->mb[1] = fcport->loop_id << 8;
861 mcp->mb[2] = (uint16_t)handle;
862 mcp->mb[3] = (uint16_t)(handle >> 16);
bdf79621 863 mcp->mb[6] = (uint16_t)sp->cmd->device->lun;
1da177e4
LT
864 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
865 mcp->in_mb = MBX_0;
b93480e3 866 mcp->tov = MBX_TOV_SECONDS;
1da177e4 867 mcp->flags = 0;
7b867cf7 868 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
869
870 if (rval != QLA_SUCCESS) {
7c3df132 871 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
1da177e4 872 } else {
7c3df132 873 ql_dbg(ql_dbg_mbx, vha, 0x103d, "Done %s.\n", __func__);
1da177e4
LT
874 }
875
876 return rval;
877}
878
1da177e4 879int
2afa19a9 880qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag)
1da177e4 881{
523ec773 882 int rval, rval2;
1da177e4
LT
883 mbx_cmd_t mc;
884 mbx_cmd_t *mcp = &mc;
7b867cf7 885 scsi_qla_host_t *vha;
73208dfd
AC
886 struct req_que *req;
887 struct rsp_que *rsp;
1da177e4 888
523ec773 889 l = l;
7b867cf7 890 vha = fcport->vha;
7c3df132
SK
891
892 ql_dbg(ql_dbg_mbx, vha, 0x103e, "Entered %s.\n", __func__);
893
7e2b895b
GM
894 req = vha->hw->req_q_map[0];
895 rsp = req->rsp;
1da177e4 896 mcp->mb[0] = MBC_ABORT_TARGET;
523ec773 897 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
7b867cf7 898 if (HAS_EXTENDED_IDS(vha->hw)) {
1da177e4
LT
899 mcp->mb[1] = fcport->loop_id;
900 mcp->mb[10] = 0;
901 mcp->out_mb |= MBX_10;
902 } else {
903 mcp->mb[1] = fcport->loop_id << 8;
904 }
7b867cf7
AC
905 mcp->mb[2] = vha->hw->loop_reset_delay;
906 mcp->mb[9] = vha->vp_idx;
1da177e4
LT
907
908 mcp->in_mb = MBX_0;
b93480e3 909 mcp->tov = MBX_TOV_SECONDS;
1da177e4 910 mcp->flags = 0;
7b867cf7 911 rval = qla2x00_mailbox_command(vha, mcp);
523ec773 912 if (rval != QLA_SUCCESS) {
7c3df132 913 ql_dbg(ql_dbg_mbx, vha, 0x103f, "Failed=%x.\n", rval);
523ec773
AV
914 }
915
916 /* Issue marker IOCB. */
73208dfd
AC
917 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
918 MK_SYNC_ID);
523ec773 919 if (rval2 != QLA_SUCCESS) {
7c3df132
SK
920 ql_dbg(ql_dbg_mbx, vha, 0x1040,
921 "Failed to issue marker IOCB (%x).\n", rval2);
523ec773 922 } else {
7c3df132 923 ql_dbg(ql_dbg_mbx, vha, 0x1041, "Done %s.\n", __func__);
523ec773
AV
924 }
925
926 return rval;
927}
928
929int
2afa19a9 930qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
523ec773
AV
931{
932 int rval, rval2;
933 mbx_cmd_t mc;
934 mbx_cmd_t *mcp = &mc;
7b867cf7 935 scsi_qla_host_t *vha;
73208dfd
AC
936 struct req_que *req;
937 struct rsp_que *rsp;
523ec773 938
7b867cf7 939 vha = fcport->vha;
7c3df132
SK
940
941 ql_dbg(ql_dbg_mbx, vha, 0x1042, "Entered %s.\n", __func__);
942
7e2b895b
GM
943 req = vha->hw->req_q_map[0];
944 rsp = req->rsp;
523ec773
AV
945 mcp->mb[0] = MBC_LUN_RESET;
946 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
7b867cf7 947 if (HAS_EXTENDED_IDS(vha->hw))
523ec773
AV
948 mcp->mb[1] = fcport->loop_id;
949 else
950 mcp->mb[1] = fcport->loop_id << 8;
951 mcp->mb[2] = l;
952 mcp->mb[3] = 0;
7b867cf7 953 mcp->mb[9] = vha->vp_idx;
1da177e4 954
523ec773 955 mcp->in_mb = MBX_0;
b93480e3 956 mcp->tov = MBX_TOV_SECONDS;
523ec773 957 mcp->flags = 0;
7b867cf7 958 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4 959 if (rval != QLA_SUCCESS) {
7c3df132 960 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
523ec773
AV
961 }
962
963 /* Issue marker IOCB. */
73208dfd
AC
964 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
965 MK_SYNC_ID_LUN);
523ec773 966 if (rval2 != QLA_SUCCESS) {
7c3df132
SK
967 ql_dbg(ql_dbg_mbx, vha, 0x1044,
968 "Failed to issue marker IOCB (%x).\n", rval2);
1da177e4 969 } else {
7c3df132 970 ql_dbg(ql_dbg_mbx, vha, 0x1045, "Done %s.\n", __func__);
1da177e4
LT
971 }
972
973 return rval;
974}
1da177e4 975
1da177e4
LT
976/*
977 * qla2x00_get_adapter_id
978 * Get adapter ID and topology.
979 *
980 * Input:
981 * ha = adapter block pointer.
982 * id = pointer for loop ID.
983 * al_pa = pointer for AL_PA.
984 * area = pointer for area.
985 * domain = pointer for domain.
986 * top = pointer for topology.
987 * TARGET_QUEUE_LOCK must be released.
988 * ADAPTER_STATE_LOCK must be released.
989 *
990 * Returns:
991 * qla2x00 local function return status code.
992 *
993 * Context:
994 * Kernel context.
995 */
996int
7b867cf7 997qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
2c3dfe3f 998 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
1da177e4
LT
999{
1000 int rval;
1001 mbx_cmd_t mc;
1002 mbx_cmd_t *mcp = &mc;
1003
7c3df132 1004 ql_dbg(ql_dbg_mbx, vha, 0x1046, "Entered %s.\n", __func__);
1da177e4
LT
1005
1006 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
7b867cf7 1007 mcp->mb[9] = vha->vp_idx;
eb66dc60 1008 mcp->out_mb = MBX_9|MBX_0;
2c3dfe3f 1009 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
a9083016 1010 if (IS_QLA8XXX_TYPE(vha->hw))
bad7001c 1011 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
b93480e3 1012 mcp->tov = MBX_TOV_SECONDS;
1da177e4 1013 mcp->flags = 0;
7b867cf7 1014 rval = qla2x00_mailbox_command(vha, mcp);
33135aa2
RA
1015 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1016 rval = QLA_COMMAND_ERROR;
42e421b1
AV
1017 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1018 rval = QLA_INVALID_COMMAND;
1da177e4
LT
1019
1020 /* Return data. */
1021 *id = mcp->mb[1];
1022 *al_pa = LSB(mcp->mb[2]);
1023 *area = MSB(mcp->mb[2]);
1024 *domain = LSB(mcp->mb[3]);
1025 *top = mcp->mb[6];
2c3dfe3f 1026 *sw_cap = mcp->mb[7];
1da177e4
LT
1027
1028 if (rval != QLA_SUCCESS) {
1029 /*EMPTY*/
7c3df132 1030 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
1da177e4 1031 } else {
7c3df132 1032 ql_dbg(ql_dbg_mbx, vha, 0x1048, "Done %s.\n", __func__);
bad7001c 1033
a9083016 1034 if (IS_QLA8XXX_TYPE(vha->hw)) {
bad7001c
AV
1035 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1036 vha->fcoe_fcf_idx = mcp->mb[10];
1037 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1038 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1039 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1040 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1041 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1042 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1043 }
1da177e4
LT
1044 }
1045
1046 return rval;
1047}
1048
1049/*
1050 * qla2x00_get_retry_cnt
1051 * Get current firmware login retry count and delay.
1052 *
1053 * Input:
1054 * ha = adapter block pointer.
1055 * retry_cnt = pointer to login retry count.
1056 * tov = pointer to login timeout value.
1057 *
1058 * Returns:
1059 * qla2x00 local function return status code.
1060 *
1061 * Context:
1062 * Kernel context.
1063 */
1064int
7b867cf7 1065qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
1da177e4
LT
1066 uint16_t *r_a_tov)
1067{
1068 int rval;
1069 uint16_t ratov;
1070 mbx_cmd_t mc;
1071 mbx_cmd_t *mcp = &mc;
1072
7c3df132 1073 ql_dbg(ql_dbg_mbx, vha, 0x1049, "Entered %s.\n", __func__);
1da177e4
LT
1074
1075 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1076 mcp->out_mb = MBX_0;
1077 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
b93480e3 1078 mcp->tov = MBX_TOV_SECONDS;
1da177e4 1079 mcp->flags = 0;
7b867cf7 1080 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
1081
1082 if (rval != QLA_SUCCESS) {
1083 /*EMPTY*/
7c3df132
SK
1084 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1085 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
1da177e4
LT
1086 } else {
1087 /* Convert returned data and check our values. */
1088 *r_a_tov = mcp->mb[3] / 2;
1089 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1090 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1091 /* Update to the larger values */
1092 *retry_cnt = (uint8_t)mcp->mb[1];
1093 *tov = ratov;
1094 }
1095
7c3df132
SK
1096 ql_dbg(ql_dbg_mbx, vha, 0x104b,
1097 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
1da177e4
LT
1098 }
1099
1100 return rval;
1101}
1102
1103/*
1104 * qla2x00_init_firmware
1105 * Initialize adapter firmware.
1106 *
1107 * Input:
1108 * ha = adapter block pointer.
1109 * dptr = Initialization control block pointer.
1110 * size = size of initialization control block.
1111 * TARGET_QUEUE_LOCK must be released.
1112 * ADAPTER_STATE_LOCK must be released.
1113 *
1114 * Returns:
1115 * qla2x00 local function return status code.
1116 *
1117 * Context:
1118 * Kernel context.
1119 */
1120int
7b867cf7 1121qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
1da177e4
LT
1122{
1123 int rval;
1124 mbx_cmd_t mc;
1125 mbx_cmd_t *mcp = &mc;
7b867cf7 1126 struct qla_hw_data *ha = vha->hw;
1da177e4 1127
7c3df132 1128 ql_dbg(ql_dbg_mbx, vha, 0x104c, "Entered %s.\n", __func__);
1da177e4 1129
a9083016
GM
1130 if (IS_QLA82XX(ha) && ql2xdbwr)
1131 qla82xx_wr_32(ha, ha->nxdb_wr_ptr,
1132 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1133
e6e074f1 1134 if (ha->flags.npiv_supported)
2c3dfe3f
SJ
1135 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1136 else
1137 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1138
b64b0e8f 1139 mcp->mb[1] = 0;
1da177e4
LT
1140 mcp->mb[2] = MSW(ha->init_cb_dma);
1141 mcp->mb[3] = LSW(ha->init_cb_dma);
1da177e4
LT
1142 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1143 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
b64b0e8f
AV
1144 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1145 if (IS_QLA81XX(ha) && ha->ex_init_cb->ex_version) {
1146 mcp->mb[1] = BIT_0;
1147 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1148 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1149 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1150 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1151 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1152 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1153 }
1154 mcp->in_mb = MBX_0;
1da177e4
LT
1155 mcp->buf_size = size;
1156 mcp->flags = MBX_DMA_OUT;
b93480e3 1157 mcp->tov = MBX_TOV_SECONDS;
7b867cf7 1158 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
1159
1160 if (rval != QLA_SUCCESS) {
1161 /*EMPTY*/
7c3df132
SK
1162 ql_dbg(ql_dbg_mbx, vha, 0x104d,
1163 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
1da177e4
LT
1164 } else {
1165 /*EMPTY*/
7c3df132 1166 ql_dbg(ql_dbg_mbx, vha, 0x104e, "Done %s.\n", __func__);
1da177e4
LT
1167 }
1168
1169 return rval;
1170}
1171
1172/*
1173 * qla2x00_get_port_database
1174 * Issue normal/enhanced get port database mailbox command
1175 * and copy device name as necessary.
1176 *
1177 * Input:
1178 * ha = adapter state pointer.
1179 * dev = structure pointer.
1180 * opt = enhanced cmd option byte.
1181 *
1182 * Returns:
1183 * qla2x00 local function return status code.
1184 *
1185 * Context:
1186 * Kernel context.
1187 */
1188int
7b867cf7 1189qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
1da177e4
LT
1190{
1191 int rval;
1192 mbx_cmd_t mc;
1193 mbx_cmd_t *mcp = &mc;
1194 port_database_t *pd;
1c7c6357 1195 struct port_database_24xx *pd24;
1da177e4 1196 dma_addr_t pd_dma;
7b867cf7 1197 struct qla_hw_data *ha = vha->hw;
1da177e4 1198
7c3df132 1199 ql_dbg(ql_dbg_mbx, vha, 0x104f, "Entered %s.\n", __func__);
1da177e4 1200
1c7c6357
AV
1201 pd24 = NULL;
1202 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
1da177e4 1203 if (pd == NULL) {
7c3df132
SK
1204 ql_log(ql_log_warn, vha, 0x1050,
1205 "Failed to allocate port database structure.\n");
1da177e4
LT
1206 return QLA_MEMORY_ALLOC_FAILED;
1207 }
1c7c6357 1208 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
1da177e4 1209
1c7c6357 1210 mcp->mb[0] = MBC_GET_PORT_DATABASE;
e428924c 1211 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
1da177e4 1212 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
1da177e4
LT
1213 mcp->mb[2] = MSW(pd_dma);
1214 mcp->mb[3] = LSW(pd_dma);
1215 mcp->mb[6] = MSW(MSD(pd_dma));
1216 mcp->mb[7] = LSW(MSD(pd_dma));
7b867cf7 1217 mcp->mb[9] = vha->vp_idx;
2c3dfe3f 1218 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
1da177e4 1219 mcp->in_mb = MBX_0;
e428924c 1220 if (IS_FWI2_CAPABLE(ha)) {
1c7c6357
AV
1221 mcp->mb[1] = fcport->loop_id;
1222 mcp->mb[10] = opt;
1223 mcp->out_mb |= MBX_10|MBX_1;
1224 mcp->in_mb |= MBX_1;
1225 } else if (HAS_EXTENDED_IDS(ha)) {
1226 mcp->mb[1] = fcport->loop_id;
1227 mcp->mb[10] = opt;
1228 mcp->out_mb |= MBX_10|MBX_1;
1229 } else {
1230 mcp->mb[1] = fcport->loop_id << 8 | opt;
1231 mcp->out_mb |= MBX_1;
1232 }
e428924c
AV
1233 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1234 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
1da177e4
LT
1235 mcp->flags = MBX_DMA_IN;
1236 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
7b867cf7 1237 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
1238 if (rval != QLA_SUCCESS)
1239 goto gpd_error_out;
1240
e428924c 1241 if (IS_FWI2_CAPABLE(ha)) {
1c7c6357
AV
1242 pd24 = (struct port_database_24xx *) pd;
1243
1244 /* Check for logged in state. */
1245 if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1246 pd24->last_login_state != PDS_PRLI_COMPLETE) {
7c3df132
SK
1247 ql_dbg(ql_dbg_mbx, vha, 0x1051,
1248 "Unable to verify login-state (%x/%x) for "
1249 "loop_id %x.\n", pd24->current_login_state,
1250 pd24->last_login_state, fcport->loop_id);
1c7c6357
AV
1251 rval = QLA_FUNCTION_FAILED;
1252 goto gpd_error_out;
1253 }
1da177e4 1254
1c7c6357
AV
1255 /* Names are little-endian. */
1256 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1257 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1258
1259 /* Get port_id of device. */
1260 fcport->d_id.b.domain = pd24->port_id[0];
1261 fcport->d_id.b.area = pd24->port_id[1];
1262 fcport->d_id.b.al_pa = pd24->port_id[2];
1263 fcport->d_id.b.rsvd_1 = 0;
1264
1265 /* If not target must be initiator or unknown type. */
1266 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1267 fcport->port_type = FCT_INITIATOR;
1268 else
1269 fcport->port_type = FCT_TARGET;
1270 } else {
1271 /* Check for logged in state. */
1272 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1273 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
7c3df132
SK
1274 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1275 "Unable to verify login-state (%x/%x) - "
1276 "portid=%02x%02x%02x.\n", pd->master_state,
1277 pd->slave_state, fcport->d_id.b.domain,
1278 fcport->d_id.b.area, fcport->d_id.b.al_pa);
1c7c6357
AV
1279 rval = QLA_FUNCTION_FAILED;
1280 goto gpd_error_out;
1281 }
1da177e4 1282
1c7c6357
AV
1283 /* Names are little-endian. */
1284 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1285 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1286
1287 /* Get port_id of device. */
1288 fcport->d_id.b.domain = pd->port_id[0];
1289 fcport->d_id.b.area = pd->port_id[3];
1290 fcport->d_id.b.al_pa = pd->port_id[2];
1291 fcport->d_id.b.rsvd_1 = 0;
1292
1c7c6357
AV
1293 /* If not target must be initiator or unknown type. */
1294 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1295 fcport->port_type = FCT_INITIATOR;
1296 else
1297 fcport->port_type = FCT_TARGET;
ad3e0eda
AV
1298
1299 /* Passback COS information. */
1300 fcport->supported_classes = (pd->options & BIT_4) ?
1301 FC_COS_CLASS2: FC_COS_CLASS3;
1c7c6357 1302 }
1da177e4
LT
1303
1304gpd_error_out:
1305 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1306
1307 if (rval != QLA_SUCCESS) {
7c3df132
SK
1308 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1309 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1310 mcp->mb[0], mcp->mb[1]);
1da177e4 1311 } else {
7c3df132 1312 ql_dbg(ql_dbg_mbx, vha, 0x1053, "Done %s.\n", __func__);
1da177e4
LT
1313 }
1314
1315 return rval;
1316}
1317
1318/*
1319 * qla2x00_get_firmware_state
1320 * Get adapter firmware state.
1321 *
1322 * Input:
1323 * ha = adapter block pointer.
1324 * dptr = pointer for firmware state.
1325 * TARGET_QUEUE_LOCK must be released.
1326 * ADAPTER_STATE_LOCK must be released.
1327 *
1328 * Returns:
1329 * qla2x00 local function return status code.
1330 *
1331 * Context:
1332 * Kernel context.
1333 */
1334int
7b867cf7 1335qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
1da177e4
LT
1336{
1337 int rval;
1338 mbx_cmd_t mc;
1339 mbx_cmd_t *mcp = &mc;
1340
7c3df132 1341 ql_dbg(ql_dbg_mbx, vha, 0x1054, "Entered %s.\n", __func__);
1da177e4
LT
1342
1343 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1344 mcp->out_mb = MBX_0;
9d2683c0
AV
1345 if (IS_FWI2_CAPABLE(vha->hw))
1346 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1347 else
1348 mcp->in_mb = MBX_1|MBX_0;
b93480e3 1349 mcp->tov = MBX_TOV_SECONDS;
1da177e4 1350 mcp->flags = 0;
7b867cf7 1351 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4 1352
4d4df193
HK
1353 /* Return firmware states. */
1354 states[0] = mcp->mb[1];
9d2683c0
AV
1355 if (IS_FWI2_CAPABLE(vha->hw)) {
1356 states[1] = mcp->mb[2];
1357 states[2] = mcp->mb[3];
1358 states[3] = mcp->mb[4];
1359 states[4] = mcp->mb[5];
1360 }
1da177e4
LT
1361
1362 if (rval != QLA_SUCCESS) {
1363 /*EMPTY*/
7c3df132 1364 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
1da177e4
LT
1365 } else {
1366 /*EMPTY*/
7c3df132 1367 ql_dbg(ql_dbg_mbx, vha, 0x1056, "Done %s.\n", __func__);
1da177e4
LT
1368 }
1369
1370 return rval;
1371}
1372
1373/*
1374 * qla2x00_get_port_name
1375 * Issue get port name mailbox command.
1376 * Returned name is in big endian format.
1377 *
1378 * Input:
1379 * ha = adapter block pointer.
1380 * loop_id = loop ID of device.
1381 * name = pointer for name.
1382 * TARGET_QUEUE_LOCK must be released.
1383 * ADAPTER_STATE_LOCK must be released.
1384 *
1385 * Returns:
1386 * qla2x00 local function return status code.
1387 *
1388 * Context:
1389 * Kernel context.
1390 */
1391int
7b867cf7 1392qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
1da177e4
LT
1393 uint8_t opt)
1394{
1395 int rval;
1396 mbx_cmd_t mc;
1397 mbx_cmd_t *mcp = &mc;
1398
7c3df132 1399 ql_dbg(ql_dbg_mbx, vha, 0x1057, "Entered %s.\n", __func__);
1da177e4
LT
1400
1401 mcp->mb[0] = MBC_GET_PORT_NAME;
7b867cf7 1402 mcp->mb[9] = vha->vp_idx;
2c3dfe3f 1403 mcp->out_mb = MBX_9|MBX_1|MBX_0;
7b867cf7 1404 if (HAS_EXTENDED_IDS(vha->hw)) {
1da177e4
LT
1405 mcp->mb[1] = loop_id;
1406 mcp->mb[10] = opt;
1407 mcp->out_mb |= MBX_10;
1408 } else {
1409 mcp->mb[1] = loop_id << 8 | opt;
1410 }
1411
1412 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
b93480e3 1413 mcp->tov = MBX_TOV_SECONDS;
1da177e4 1414 mcp->flags = 0;
7b867cf7 1415 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
1416
1417 if (rval != QLA_SUCCESS) {
1418 /*EMPTY*/
7c3df132 1419 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
1da177e4
LT
1420 } else {
1421 if (name != NULL) {
1422 /* This function returns name in big endian. */
1196ae02
RL
1423 name[0] = MSB(mcp->mb[2]);
1424 name[1] = LSB(mcp->mb[2]);
1425 name[2] = MSB(mcp->mb[3]);
1426 name[3] = LSB(mcp->mb[3]);
1427 name[4] = MSB(mcp->mb[6]);
1428 name[5] = LSB(mcp->mb[6]);
1429 name[6] = MSB(mcp->mb[7]);
1430 name[7] = LSB(mcp->mb[7]);
1da177e4
LT
1431 }
1432
7c3df132 1433 ql_dbg(ql_dbg_mbx, vha, 0x1059, "Done %s.\n", __func__);
1da177e4
LT
1434 }
1435
1436 return rval;
1437}
1438
1439/*
1440 * qla2x00_lip_reset
1441 * Issue LIP reset mailbox command.
1442 *
1443 * Input:
1444 * ha = adapter block pointer.
1445 * TARGET_QUEUE_LOCK must be released.
1446 * ADAPTER_STATE_LOCK must be released.
1447 *
1448 * Returns:
1449 * qla2x00 local function return status code.
1450 *
1451 * Context:
1452 * Kernel context.
1453 */
1454int
7b867cf7 1455qla2x00_lip_reset(scsi_qla_host_t *vha)
1da177e4
LT
1456{
1457 int rval;
1458 mbx_cmd_t mc;
1459 mbx_cmd_t *mcp = &mc;
1460
7c3df132 1461 ql_dbg(ql_dbg_mbx, vha, 0x105a, "Entered %s.\n", __func__);
1da177e4 1462
a9083016 1463 if (IS_QLA8XXX_TYPE(vha->hw)) {
3a03eb79
AV
1464 /* Logout across all FCFs. */
1465 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1466 mcp->mb[1] = BIT_1;
1467 mcp->mb[2] = 0;
1468 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1469 } else if (IS_FWI2_CAPABLE(vha->hw)) {
1c7c6357 1470 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
0c8c39af
AV
1471 mcp->mb[1] = BIT_6;
1472 mcp->mb[2] = 0;
7b867cf7 1473 mcp->mb[3] = vha->hw->loop_reset_delay;
1c7c6357 1474 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1da177e4 1475 } else {
1c7c6357
AV
1476 mcp->mb[0] = MBC_LIP_RESET;
1477 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
7b867cf7 1478 if (HAS_EXTENDED_IDS(vha->hw)) {
1c7c6357
AV
1479 mcp->mb[1] = 0x00ff;
1480 mcp->mb[10] = 0;
1481 mcp->out_mb |= MBX_10;
1482 } else {
1483 mcp->mb[1] = 0xff00;
1484 }
7b867cf7 1485 mcp->mb[2] = vha->hw->loop_reset_delay;
1c7c6357 1486 mcp->mb[3] = 0;
1da177e4 1487 }
1da177e4 1488 mcp->in_mb = MBX_0;
b93480e3 1489 mcp->tov = MBX_TOV_SECONDS;
1da177e4 1490 mcp->flags = 0;
7b867cf7 1491 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
1492
1493 if (rval != QLA_SUCCESS) {
1494 /*EMPTY*/
7c3df132 1495 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
1da177e4
LT
1496 } else {
1497 /*EMPTY*/
7c3df132 1498 ql_dbg(ql_dbg_mbx, vha, 0x105c, "Done %s.\n", __func__);
1da177e4
LT
1499 }
1500
1501 return rval;
1502}
1503
1504/*
1505 * qla2x00_send_sns
1506 * Send SNS command.
1507 *
1508 * Input:
1509 * ha = adapter block pointer.
1510 * sns = pointer for command.
1511 * cmd_size = command size.
1512 * buf_size = response/command size.
1513 * TARGET_QUEUE_LOCK must be released.
1514 * ADAPTER_STATE_LOCK must be released.
1515 *
1516 * Returns:
1517 * qla2x00 local function return status code.
1518 *
1519 * Context:
1520 * Kernel context.
1521 */
1522int
7b867cf7 1523qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
1da177e4
LT
1524 uint16_t cmd_size, size_t buf_size)
1525{
1526 int rval;
1527 mbx_cmd_t mc;
1528 mbx_cmd_t *mcp = &mc;
1529
7c3df132 1530 ql_dbg(ql_dbg_mbx, vha, 0x105d, "Entered %s.\n", __func__);
1da177e4 1531
7c3df132
SK
1532 ql_dbg(ql_dbg_mbx, vha, 0x105e,
1533 "Retry cnt=%d ratov=%d total tov=%d.\n",
1534 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
1da177e4
LT
1535
1536 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1537 mcp->mb[1] = cmd_size;
1538 mcp->mb[2] = MSW(sns_phys_address);
1539 mcp->mb[3] = LSW(sns_phys_address);
1540 mcp->mb[6] = MSW(MSD(sns_phys_address));
1541 mcp->mb[7] = LSW(MSD(sns_phys_address));
1542 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1543 mcp->in_mb = MBX_0|MBX_1;
1544 mcp->buf_size = buf_size;
1545 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
7b867cf7
AC
1546 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1547 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
1548
1549 if (rval != QLA_SUCCESS) {
1550 /*EMPTY*/
7c3df132
SK
1551 ql_dbg(ql_dbg_mbx, vha, 0x105f,
1552 "Failed=%x mb[0]=%x mb[1]=%x.\n",
1553 rval, mcp->mb[0], mcp->mb[1]);
1da177e4
LT
1554 } else {
1555 /*EMPTY*/
7c3df132 1556 ql_dbg(ql_dbg_mbx, vha, 0x1060, "Done %s.\n", __func__);
1da177e4
LT
1557 }
1558
1559 return rval;
1560}
1561
1c7c6357 1562int
7b867cf7 1563qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
1c7c6357
AV
1564 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1565{
1566 int rval;
1567
1568 struct logio_entry_24xx *lg;
1569 dma_addr_t lg_dma;
1570 uint32_t iop[2];
7b867cf7 1571 struct qla_hw_data *ha = vha->hw;
2afa19a9
AC
1572 struct req_que *req;
1573 struct rsp_que *rsp;
1c7c6357 1574
7c3df132 1575 ql_dbg(ql_dbg_mbx, vha, 0x1061, "Entered %s.\n", __func__);
1c7c6357 1576
7163ea81 1577 if (ha->flags.cpu_affinity_enabled)
68ca949c
AC
1578 req = ha->req_q_map[0];
1579 else
1580 req = vha->req;
2afa19a9
AC
1581 rsp = req->rsp;
1582
1c7c6357
AV
1583 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1584 if (lg == NULL) {
7c3df132
SK
1585 ql_log(ql_log_warn, vha, 0x1062,
1586 "Failed to allocate login IOCB.\n");
1c7c6357
AV
1587 return QLA_MEMORY_ALLOC_FAILED;
1588 }
1589 memset(lg, 0, sizeof(struct logio_entry_24xx));
1590
1591 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1592 lg->entry_count = 1;
2afa19a9 1593 lg->handle = MAKE_HANDLE(req->id, lg->handle);
1c7c6357
AV
1594 lg->nport_handle = cpu_to_le16(loop_id);
1595 lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
1596 if (opt & BIT_0)
1597 lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
8baa51a6
AV
1598 if (opt & BIT_1)
1599 lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI);
1c7c6357
AV
1600 lg->port_id[0] = al_pa;
1601 lg->port_id[1] = area;
1602 lg->port_id[2] = domain;
7b867cf7
AC
1603 lg->vp_index = vha->vp_idx;
1604 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
1c7c6357 1605 if (rval != QLA_SUCCESS) {
7c3df132
SK
1606 ql_dbg(ql_dbg_mbx, vha, 0x1063,
1607 "Failed to issue login IOCB (%x).\n", rval);
1c7c6357 1608 } else if (lg->entry_status != 0) {
7c3df132
SK
1609 ql_dbg(ql_dbg_mbx, vha, 0x1064,
1610 "Failed to complete IOCB -- error status (%x).\n",
1611 lg->entry_status);
1c7c6357
AV
1612 rval = QLA_FUNCTION_FAILED;
1613 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1614 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1615 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1616
7c3df132
SK
1617 ql_dbg(ql_dbg_mbx, vha, 0x1065,
1618 "Failed to complete IOCB -- completion status (%x) "
1619 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
1620 iop[0], iop[1]);
1c7c6357
AV
1621
1622 switch (iop[0]) {
1623 case LSC_SCODE_PORTID_USED:
1624 mb[0] = MBS_PORT_ID_USED;
1625 mb[1] = LSW(iop[1]);
1626 break;
1627 case LSC_SCODE_NPORT_USED:
1628 mb[0] = MBS_LOOP_ID_USED;
1629 break;
1630 case LSC_SCODE_NOLINK:
1631 case LSC_SCODE_NOIOCB:
1632 case LSC_SCODE_NOXCB:
1633 case LSC_SCODE_CMD_FAILED:
1634 case LSC_SCODE_NOFABRIC:
1635 case LSC_SCODE_FW_NOT_READY:
1636 case LSC_SCODE_NOT_LOGGED_IN:
1637 case LSC_SCODE_NOPCB:
1638 case LSC_SCODE_ELS_REJECT:
1639 case LSC_SCODE_CMD_PARAM_ERR:
1640 case LSC_SCODE_NONPORT:
1641 case LSC_SCODE_LOGGED_IN:
1642 case LSC_SCODE_NOFLOGI_ACC:
1643 default:
1644 mb[0] = MBS_COMMAND_ERROR;
1645 break;
1646 }
1647 } else {
7c3df132 1648 ql_dbg(ql_dbg_mbx, vha, 0x1066, "Done %s.\n", __func__);
1c7c6357
AV
1649
1650 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1651
1652 mb[0] = MBS_COMMAND_COMPLETE;
1653 mb[1] = 0;
1654 if (iop[0] & BIT_4) {
1655 if (iop[0] & BIT_8)
1656 mb[1] |= BIT_1;
1657 } else
1658 mb[1] = BIT_0;
ad3e0eda
AV
1659
1660 /* Passback COS information. */
1661 mb[10] = 0;
1662 if (lg->io_parameter[7] || lg->io_parameter[8])
1663 mb[10] |= BIT_0; /* Class 2. */
1664 if (lg->io_parameter[9] || lg->io_parameter[10])
1665 mb[10] |= BIT_1; /* Class 3. */
1c7c6357
AV
1666 }
1667
1668 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1669
1670 return rval;
1671}
1672
1da177e4
LT
1673/*
1674 * qla2x00_login_fabric
1675 * Issue login fabric port mailbox command.
1676 *
1677 * Input:
1678 * ha = adapter block pointer.
1679 * loop_id = device loop ID.
1680 * domain = device domain.
1681 * area = device area.
1682 * al_pa = device AL_PA.
1683 * status = pointer for return status.
1684 * opt = command options.
1685 * TARGET_QUEUE_LOCK must be released.
1686 * ADAPTER_STATE_LOCK must be released.
1687 *
1688 * Returns:
1689 * qla2x00 local function return status code.
1690 *
1691 * Context:
1692 * Kernel context.
1693 */
1694int
7b867cf7 1695qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
1da177e4
LT
1696 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1697{
1698 int rval;
1699 mbx_cmd_t mc;
1700 mbx_cmd_t *mcp = &mc;
7b867cf7 1701 struct qla_hw_data *ha = vha->hw;
1da177e4 1702
7c3df132 1703 ql_dbg(ql_dbg_mbx, vha, 0x1067, "Entered %s.\n", __func__);
1da177e4
LT
1704
1705 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1706 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1707 if (HAS_EXTENDED_IDS(ha)) {
1708 mcp->mb[1] = loop_id;
1709 mcp->mb[10] = opt;
1710 mcp->out_mb |= MBX_10;
1711 } else {
1712 mcp->mb[1] = (loop_id << 8) | opt;
1713 }
1714 mcp->mb[2] = domain;
1715 mcp->mb[3] = area << 8 | al_pa;
1716
1717 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1718 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1719 mcp->flags = 0;
7b867cf7 1720 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
1721
1722 /* Return mailbox statuses. */
1723 if (mb != NULL) {
1724 mb[0] = mcp->mb[0];
1725 mb[1] = mcp->mb[1];
1726 mb[2] = mcp->mb[2];
1727 mb[6] = mcp->mb[6];
1728 mb[7] = mcp->mb[7];
ad3e0eda
AV
1729 /* COS retrieved from Get-Port-Database mailbox command. */
1730 mb[10] = 0;
1da177e4
LT
1731 }
1732
1733 if (rval != QLA_SUCCESS) {
1734 /* RLU tmp code: need to change main mailbox_command function to
1735 * return ok even when the mailbox completion value is not
1736 * SUCCESS. The caller needs to be responsible to interpret
1737 * the return values of this mailbox command if we're not
1738 * to change too much of the existing code.
1739 */
1740 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
1741 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
1742 mcp->mb[0] == 0x4006)
1743 rval = QLA_SUCCESS;
1744
1745 /*EMPTY*/
7c3df132
SK
1746 ql_dbg(ql_dbg_mbx, vha, 0x1068,
1747 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
1748 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
1da177e4
LT
1749 } else {
1750 /*EMPTY*/
7c3df132 1751 ql_dbg(ql_dbg_mbx, vha, 0x1069, "Done %s.\n", __func__);
1da177e4
LT
1752 }
1753
1754 return rval;
1755}
1756
1757/*
1758 * qla2x00_login_local_device
1759 * Issue login loop port mailbox command.
fa2a1ce5 1760 *
1da177e4
LT
1761 * Input:
1762 * ha = adapter block pointer.
1763 * loop_id = device loop ID.
1764 * opt = command options.
fa2a1ce5 1765 *
1da177e4
LT
1766 * Returns:
1767 * Return status code.
fa2a1ce5 1768 *
1da177e4
LT
1769 * Context:
1770 * Kernel context.
fa2a1ce5 1771 *
1da177e4
LT
1772 */
1773int
7b867cf7 1774qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
1da177e4
LT
1775 uint16_t *mb_ret, uint8_t opt)
1776{
1777 int rval;
1778 mbx_cmd_t mc;
1779 mbx_cmd_t *mcp = &mc;
7b867cf7 1780 struct qla_hw_data *ha = vha->hw;
1da177e4 1781
7c3df132
SK
1782 ql_dbg(ql_dbg_mbx, vha, 0x106a, "Entered %s.\n", __func__);
1783
e428924c 1784 if (IS_FWI2_CAPABLE(ha))
7b867cf7 1785 return qla24xx_login_fabric(vha, fcport->loop_id,
9a52a57c
AV
1786 fcport->d_id.b.domain, fcport->d_id.b.area,
1787 fcport->d_id.b.al_pa, mb_ret, opt);
1788
1da177e4
LT
1789 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1790 if (HAS_EXTENDED_IDS(ha))
9a52a57c 1791 mcp->mb[1] = fcport->loop_id;
1da177e4 1792 else
9a52a57c 1793 mcp->mb[1] = fcport->loop_id << 8;
1da177e4
LT
1794 mcp->mb[2] = opt;
1795 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1796 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
1797 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1798 mcp->flags = 0;
7b867cf7 1799 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
1800
1801 /* Return mailbox statuses. */
1802 if (mb_ret != NULL) {
1803 mb_ret[0] = mcp->mb[0];
1804 mb_ret[1] = mcp->mb[1];
1805 mb_ret[6] = mcp->mb[6];
1806 mb_ret[7] = mcp->mb[7];
1807 }
1808
1809 if (rval != QLA_SUCCESS) {
1810 /* AV tmp code: need to change main mailbox_command function to
1811 * return ok even when the mailbox completion value is not
1812 * SUCCESS. The caller needs to be responsible to interpret
1813 * the return values of this mailbox command if we're not
1814 * to change too much of the existing code.
1815 */
1816 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
1817 rval = QLA_SUCCESS;
1818
7c3df132
SK
1819 ql_dbg(ql_dbg_mbx, vha, 0x106b,
1820 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
1821 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
1da177e4
LT
1822 } else {
1823 /*EMPTY*/
7c3df132 1824 ql_dbg(ql_dbg_mbx, vha, 0x106c, "Done %s.\n", __func__);
1da177e4
LT
1825 }
1826
1827 return (rval);
1828}
1829
1c7c6357 1830int
7b867cf7 1831qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
1c7c6357
AV
1832 uint8_t area, uint8_t al_pa)
1833{
1834 int rval;
1835 struct logio_entry_24xx *lg;
1836 dma_addr_t lg_dma;
7b867cf7 1837 struct qla_hw_data *ha = vha->hw;
2afa19a9
AC
1838 struct req_que *req;
1839 struct rsp_que *rsp;
1c7c6357 1840
7c3df132 1841 ql_dbg(ql_dbg_mbx, vha, 0x106d, "Entered %s.\n", __func__);
1c7c6357
AV
1842
1843 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1844 if (lg == NULL) {
7c3df132
SK
1845 ql_log(ql_log_warn, vha, 0x106e,
1846 "Failed to allocate logout IOCB.\n");
1c7c6357
AV
1847 return QLA_MEMORY_ALLOC_FAILED;
1848 }
1849 memset(lg, 0, sizeof(struct logio_entry_24xx));
1850
2afa19a9
AC
1851 if (ql2xmaxqueues > 1)
1852 req = ha->req_q_map[0];
1853 else
1854 req = vha->req;
1855 rsp = req->rsp;
1c7c6357
AV
1856 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1857 lg->entry_count = 1;
2afa19a9 1858 lg->handle = MAKE_HANDLE(req->id, lg->handle);
1c7c6357
AV
1859 lg->nport_handle = cpu_to_le16(loop_id);
1860 lg->control_flags =
c8d6691b
AV
1861 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
1862 LCF_FREE_NPORT);
1c7c6357
AV
1863 lg->port_id[0] = al_pa;
1864 lg->port_id[1] = area;
1865 lg->port_id[2] = domain;
7b867cf7 1866 lg->vp_index = vha->vp_idx;
73208dfd 1867
7b867cf7 1868 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
1c7c6357 1869 if (rval != QLA_SUCCESS) {
7c3df132
SK
1870 ql_dbg(ql_dbg_mbx, vha, 0x106f,
1871 "Failed to issue logout IOCB (%x).\n", rval);
1c7c6357 1872 } else if (lg->entry_status != 0) {
7c3df132
SK
1873 ql_dbg(ql_dbg_mbx, vha, 0x1070,
1874 "Failed to complete IOCB -- error status (%x).\n",
1875 lg->entry_status);
1c7c6357
AV
1876 rval = QLA_FUNCTION_FAILED;
1877 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
7c3df132
SK
1878 ql_dbg(ql_dbg_mbx, vha, 0x1071,
1879 "Failed to complete IOCB -- completion status (%x) "
1880 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
1c7c6357 1881 le32_to_cpu(lg->io_parameter[0]),
7c3df132 1882 le32_to_cpu(lg->io_parameter[1]));
1c7c6357
AV
1883 } else {
1884 /*EMPTY*/
7c3df132 1885 ql_dbg(ql_dbg_mbx, vha, 0x1072, "Done %s.\n", __func__);
1c7c6357
AV
1886 }
1887
1888 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1889
1890 return rval;
1891}
1892
1da177e4
LT
1893/*
1894 * qla2x00_fabric_logout
1895 * Issue logout fabric port mailbox command.
1896 *
1897 * Input:
1898 * ha = adapter block pointer.
1899 * loop_id = device loop ID.
1900 * TARGET_QUEUE_LOCK must be released.
1901 * ADAPTER_STATE_LOCK must be released.
1902 *
1903 * Returns:
1904 * qla2x00 local function return status code.
1905 *
1906 * Context:
1907 * Kernel context.
1908 */
1909int
7b867cf7 1910qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
1c7c6357 1911 uint8_t area, uint8_t al_pa)
1da177e4
LT
1912{
1913 int rval;
1914 mbx_cmd_t mc;
1915 mbx_cmd_t *mcp = &mc;
1916
7c3df132 1917 ql_dbg(ql_dbg_mbx, vha, 0x1073, "Entered %s.\n", __func__);
1da177e4
LT
1918
1919 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1920 mcp->out_mb = MBX_1|MBX_0;
7b867cf7 1921 if (HAS_EXTENDED_IDS(vha->hw)) {
1da177e4
LT
1922 mcp->mb[1] = loop_id;
1923 mcp->mb[10] = 0;
1924 mcp->out_mb |= MBX_10;
1925 } else {
1926 mcp->mb[1] = loop_id << 8;
1927 }
1928
1929 mcp->in_mb = MBX_1|MBX_0;
b93480e3 1930 mcp->tov = MBX_TOV_SECONDS;
1da177e4 1931 mcp->flags = 0;
7b867cf7 1932 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
1933
1934 if (rval != QLA_SUCCESS) {
1935 /*EMPTY*/
7c3df132
SK
1936 ql_dbg(ql_dbg_mbx, vha, 0x1074,
1937 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
1da177e4
LT
1938 } else {
1939 /*EMPTY*/
7c3df132 1940 ql_dbg(ql_dbg_mbx, vha, 0x1075, "Done %s.\n", __func__);
1da177e4
LT
1941 }
1942
1943 return rval;
1944}
1945
1946/*
1947 * qla2x00_full_login_lip
1948 * Issue full login LIP mailbox command.
1949 *
1950 * Input:
1951 * ha = adapter block pointer.
1952 * TARGET_QUEUE_LOCK must be released.
1953 * ADAPTER_STATE_LOCK must be released.
1954 *
1955 * Returns:
1956 * qla2x00 local function return status code.
1957 *
1958 * Context:
1959 * Kernel context.
1960 */
1961int
7b867cf7 1962qla2x00_full_login_lip(scsi_qla_host_t *vha)
1da177e4
LT
1963{
1964 int rval;
1965 mbx_cmd_t mc;
1966 mbx_cmd_t *mcp = &mc;
1967
7c3df132 1968 ql_dbg(ql_dbg_mbx, vha, 0x1076, "Entered %s.\n", __func__);
1da177e4
LT
1969
1970 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
7b867cf7 1971 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
0c8c39af 1972 mcp->mb[2] = 0;
1da177e4
LT
1973 mcp->mb[3] = 0;
1974 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1975 mcp->in_mb = MBX_0;
b93480e3 1976 mcp->tov = MBX_TOV_SECONDS;
1da177e4 1977 mcp->flags = 0;
7b867cf7 1978 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
1979
1980 if (rval != QLA_SUCCESS) {
1981 /*EMPTY*/
7c3df132 1982 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
1da177e4
LT
1983 } else {
1984 /*EMPTY*/
7c3df132 1985 ql_dbg(ql_dbg_mbx, vha, 0x1078, "Done %s.\n", __func__);
1da177e4
LT
1986 }
1987
1988 return rval;
1989}
1990
1991/*
1992 * qla2x00_get_id_list
1993 *
1994 * Input:
1995 * ha = adapter block pointer.
1996 *
1997 * Returns:
1998 * qla2x00 local function return status code.
1999 *
2000 * Context:
2001 * Kernel context.
2002 */
2003int
7b867cf7 2004qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
1da177e4
LT
2005 uint16_t *entries)
2006{
2007 int rval;
2008 mbx_cmd_t mc;
2009 mbx_cmd_t *mcp = &mc;
2010
7c3df132 2011 ql_dbg(ql_dbg_mbx, vha, 0x1079, "Entered %s.\n", __func__);
1da177e4
LT
2012
2013 if (id_list == NULL)
2014 return QLA_FUNCTION_FAILED;
2015
2016 mcp->mb[0] = MBC_GET_ID_LIST;
1c7c6357 2017 mcp->out_mb = MBX_0;
7b867cf7 2018 if (IS_FWI2_CAPABLE(vha->hw)) {
1c7c6357
AV
2019 mcp->mb[2] = MSW(id_list_dma);
2020 mcp->mb[3] = LSW(id_list_dma);
2021 mcp->mb[6] = MSW(MSD(id_list_dma));
2022 mcp->mb[7] = LSW(MSD(id_list_dma));
247ec457 2023 mcp->mb[8] = 0;
7b867cf7 2024 mcp->mb[9] = vha->vp_idx;
2c3dfe3f 2025 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
1c7c6357
AV
2026 } else {
2027 mcp->mb[1] = MSW(id_list_dma);
2028 mcp->mb[2] = LSW(id_list_dma);
2029 mcp->mb[3] = MSW(MSD(id_list_dma));
2030 mcp->mb[6] = LSW(MSD(id_list_dma));
2031 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2032 }
1da177e4 2033 mcp->in_mb = MBX_1|MBX_0;
b93480e3 2034 mcp->tov = MBX_TOV_SECONDS;
1da177e4 2035 mcp->flags = 0;
7b867cf7 2036 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
2037
2038 if (rval != QLA_SUCCESS) {
2039 /*EMPTY*/
7c3df132 2040 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
1da177e4
LT
2041 } else {
2042 *entries = mcp->mb[1];
7c3df132 2043 ql_dbg(ql_dbg_mbx, vha, 0x107b, "Done %s.\n", __func__);
1da177e4
LT
2044 }
2045
2046 return rval;
2047}
2048
2049/*
2050 * qla2x00_get_resource_cnts
2051 * Get current firmware resource counts.
2052 *
2053 * Input:
2054 * ha = adapter block pointer.
2055 *
2056 * Returns:
2057 * qla2x00 local function return status code.
2058 *
2059 * Context:
2060 * Kernel context.
2061 */
2062int
7b867cf7 2063qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
4d0ea247 2064 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
f3a0a77e 2065 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
1da177e4
LT
2066{
2067 int rval;
2068 mbx_cmd_t mc;
2069 mbx_cmd_t *mcp = &mc;
2070
7c3df132 2071 ql_dbg(ql_dbg_mbx, vha, 0x107c, "Entered %s.\n", __func__);
1da177e4
LT
2072
2073 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2074 mcp->out_mb = MBX_0;
4d0ea247 2075 mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
f3a0a77e
AV
2076 if (IS_QLA81XX(vha->hw))
2077 mcp->in_mb |= MBX_12;
b93480e3 2078 mcp->tov = MBX_TOV_SECONDS;
1da177e4 2079 mcp->flags = 0;
7b867cf7 2080 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
2081
2082 if (rval != QLA_SUCCESS) {
2083 /*EMPTY*/
7c3df132
SK
2084 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2085 "Failed mb[0]=%x.\n", mcp->mb[0]);
1da177e4 2086 } else {
7c3df132
SK
2087 ql_dbg(ql_dbg_mbx, vha, 0x107e,
2088 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2089 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2090 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2091 mcp->mb[11], mcp->mb[12]);
1da177e4
LT
2092
2093 if (cur_xchg_cnt)
2094 *cur_xchg_cnt = mcp->mb[3];
2095 if (orig_xchg_cnt)
2096 *orig_xchg_cnt = mcp->mb[6];
2097 if (cur_iocb_cnt)
2098 *cur_iocb_cnt = mcp->mb[7];
2099 if (orig_iocb_cnt)
2100 *orig_iocb_cnt = mcp->mb[10];
7b867cf7 2101 if (vha->hw->flags.npiv_supported && max_npiv_vports)
4d0ea247 2102 *max_npiv_vports = mcp->mb[11];
f3a0a77e
AV
2103 if (IS_QLA81XX(vha->hw) && max_fcfs)
2104 *max_fcfs = mcp->mb[12];
1da177e4
LT
2105 }
2106
2107 return (rval);
2108}
2109
1da177e4
LT
2110/*
2111 * qla2x00_get_fcal_position_map
2112 * Get FCAL (LILP) position map using mailbox command
2113 *
2114 * Input:
2115 * ha = adapter state pointer.
2116 * pos_map = buffer pointer (can be NULL).
2117 *
2118 * Returns:
2119 * qla2x00 local function return status code.
2120 *
2121 * Context:
2122 * Kernel context.
2123 */
2124int
7b867cf7 2125qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
1da177e4
LT
2126{
2127 int rval;
2128 mbx_cmd_t mc;
2129 mbx_cmd_t *mcp = &mc;
2130 char *pmap;
2131 dma_addr_t pmap_dma;
7b867cf7 2132 struct qla_hw_data *ha = vha->hw;
1da177e4 2133
7c3df132
SK
2134 ql_dbg(ql_dbg_mbx, vha, 0x107f, "Entered %s.\n", __func__);
2135
4b89258c 2136 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
1da177e4 2137 if (pmap == NULL) {
7c3df132
SK
2138 ql_log(ql_log_warn, vha, 0x1080,
2139 "Memory alloc failed.\n");
1da177e4
LT
2140 return QLA_MEMORY_ALLOC_FAILED;
2141 }
2142 memset(pmap, 0, FCAL_MAP_SIZE);
2143
2144 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2145 mcp->mb[2] = MSW(pmap_dma);
2146 mcp->mb[3] = LSW(pmap_dma);
2147 mcp->mb[6] = MSW(MSD(pmap_dma));
2148 mcp->mb[7] = LSW(MSD(pmap_dma));
2149 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2150 mcp->in_mb = MBX_1|MBX_0;
2151 mcp->buf_size = FCAL_MAP_SIZE;
2152 mcp->flags = MBX_DMA_IN;
2153 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
7b867cf7 2154 rval = qla2x00_mailbox_command(vha, mcp);
1da177e4
LT
2155
2156 if (rval == QLA_SUCCESS) {
7c3df132
SK
2157 ql_dbg(ql_dbg_mbx, vha, 0x1081,
2158 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2159 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2160 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2161 pmap, pmap[0] + 1);
1da177e4
LT
2162
2163 if (pos_map)
2164 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2165 }
2166 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2167
2168 if (rval != QLA_SUCCESS) {
7c3df132 2169 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
1da177e4 2170 } else {
7c3df132 2171 ql_dbg(ql_dbg_mbx, vha, 0x1083, "Done %s.\n", __func__);
1da177e4
LT
2172 }
2173
2174 return rval;
2175}
392e2f65
AV
2176
2177/*
2178 * qla2x00_get_link_status
2179 *
2180 * Input:
2181 * ha = adapter block pointer.
2182 * loop_id = device loop ID.
2183 * ret_buf = pointer to link status return buffer.
2184 *
2185 * Returns:
2186 * 0 = success.
2187 * BIT_0 = mem alloc error.
2188 * BIT_1 = mailbox error.
2189 */
2190int
7b867cf7 2191qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
43ef0580 2192 struct link_statistics *stats, dma_addr_t stats_dma)
392e2f65
AV
2193{
2194 int rval;
2195 mbx_cmd_t mc;
2196 mbx_cmd_t *mcp = &mc;
43ef0580 2197 uint32_t *siter, *diter, dwords;
7b867cf7 2198 struct qla_hw_data *ha = vha->hw;
392e2f65 2199
7c3df132 2200 ql_dbg(ql_dbg_mbx, vha, 0x1084, "Entered %s.\n", __func__);
392e2f65 2201
392e2f65 2202 mcp->mb[0] = MBC_GET_LINK_STATUS;
43ef0580
AV
2203 mcp->mb[2] = MSW(stats_dma);
2204 mcp->mb[3] = LSW(stats_dma);
2205 mcp->mb[6] = MSW(MSD(stats_dma));
2206 mcp->mb[7] = LSW(MSD(stats_dma));
392e2f65
AV
2207 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2208 mcp->in_mb = MBX_0;
e428924c 2209 if (IS_FWI2_CAPABLE(ha)) {
392e2f65
AV
2210 mcp->mb[1] = loop_id;
2211 mcp->mb[4] = 0;
2212 mcp->mb[10] = 0;
2213 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2214 mcp->in_mb |= MBX_1;
2215 } else if (HAS_EXTENDED_IDS(ha)) {
2216 mcp->mb[1] = loop_id;
2217 mcp->mb[10] = 0;
2218 mcp->out_mb |= MBX_10|MBX_1;
2219 } else {
2220 mcp->mb[1] = loop_id << 8;
2221 mcp->out_mb |= MBX_1;
2222 }
b93480e3 2223 mcp->tov = MBX_TOV_SECONDS;
392e2f65 2224 mcp->flags = IOCTL_CMD;
7b867cf7 2225 rval = qla2x00_mailbox_command(vha, mcp);
392e2f65
AV
2226
2227 if (rval == QLA_SUCCESS) {
2228 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
7c3df132
SK
2229 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2230 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
43ef0580 2231 rval = QLA_FUNCTION_FAILED;
392e2f65 2232 } else {
43ef0580 2233 /* Copy over data -- firmware data is LE. */
7c3df132 2234 ql_dbg(ql_dbg_mbx, vha, 0x1086, "Done %s.\n", __func__);
43ef0580
AV
2235 dwords = offsetof(struct link_statistics, unused1) / 4;
2236 siter = diter = &stats->link_fail_cnt;
2237 while (dwords--)
2238 *diter++ = le32_to_cpu(*siter++);
392e2f65
AV
2239 }
2240 } else {
2241 /* Failed. */
7c3df132 2242 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
392e2f65
AV
2243 }
2244
392e2f65
AV
2245 return rval;
2246}
2247
2248int
7b867cf7 2249qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
43ef0580 2250 dma_addr_t stats_dma)
1c7c6357
AV
2251{
2252 int rval;
2253 mbx_cmd_t mc;
2254 mbx_cmd_t *mcp = &mc;
43ef0580 2255 uint32_t *siter, *diter, dwords;
1c7c6357 2256
7c3df132 2257 ql_dbg(ql_dbg_mbx, vha, 0x1088, "Entered %s.\n", __func__);
1c7c6357 2258
1c7c6357 2259 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
43ef0580
AV
2260 mcp->mb[2] = MSW(stats_dma);
2261 mcp->mb[3] = LSW(stats_dma);
2262 mcp->mb[6] = MSW(MSD(stats_dma));
2263 mcp->mb[7] = LSW(MSD(stats_dma));
2264 mcp->mb[8] = sizeof(struct link_statistics) / 4;
7b867cf7 2265 mcp->mb[9] = vha->vp_idx;
1c7c6357 2266 mcp->mb[10] = 0;
43ef0580 2267 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
1c7c6357 2268 mcp->in_mb = MBX_2|MBX_1|MBX_0;
b93480e3 2269 mcp->tov = MBX_TOV_SECONDS;
1c7c6357 2270 mcp->flags = IOCTL_CMD;
7b867cf7 2271 rval = qla2x00_mailbox_command(vha, mcp);
1c7c6357
AV
2272
2273 if (rval == QLA_SUCCESS) {
2274 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
7c3df132
SK
2275 ql_dbg(ql_dbg_mbx, vha, 0x1089,
2276 "Failed mb[0]=%x.\n", mcp->mb[0]);
43ef0580 2277 rval = QLA_FUNCTION_FAILED;
1c7c6357 2278 } else {
7c3df132 2279 ql_dbg(ql_dbg_mbx, vha, 0x108a, "Done %s.\n", __func__);
1c7c6357 2280 /* Copy over data -- firmware data is LE. */
43ef0580
AV
2281 dwords = sizeof(struct link_statistics) / 4;
2282 siter = diter = &stats->link_fail_cnt;
1c7c6357 2283 while (dwords--)
43ef0580 2284 *diter++ = le32_to_cpu(*siter++);
1c7c6357
AV
2285 }
2286 } else {
2287 /* Failed. */
7c3df132 2288 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
1c7c6357
AV
2289 }
2290
1c7c6357
AV
2291 return rval;
2292}
1c7c6357
AV
2293
2294int
2afa19a9 2295qla24xx_abort_command(srb_t *sp)
1c7c6357
AV
2296{
2297 int rval;
1c7c6357
AV
2298 unsigned long flags = 0;
2299
2300 struct abort_entry_24xx *abt;
2301 dma_addr_t abt_dma;
2302 uint32_t handle;
2afa19a9
AC
2303 fc_port_t *fcport = sp->fcport;
2304 struct scsi_qla_host *vha = fcport->vha;
7b867cf7 2305 struct qla_hw_data *ha = vha->hw;
67c2e93a 2306 struct req_que *req = vha->req;
1c7c6357 2307
7c3df132 2308 ql_dbg(ql_dbg_mbx, vha, 0x108c, "Entered %s.\n", __func__);
1c7c6357 2309
7b867cf7 2310 spin_lock_irqsave(&ha->hardware_lock, flags);
1c7c6357 2311 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
7b867cf7 2312 if (req->outstanding_cmds[handle] == sp)
1c7c6357
AV
2313 break;
2314 }
7b867cf7 2315 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1c7c6357
AV
2316 if (handle == MAX_OUTSTANDING_COMMANDS) {
2317 /* Command not found. */
2318 return QLA_FUNCTION_FAILED;
2319 }
2320
2321 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2322 if (abt == NULL) {
7c3df132
SK
2323 ql_log(ql_log_warn, vha, 0x108d,
2324 "Failed to allocate abort IOCB.\n");
1c7c6357
AV
2325 return QLA_MEMORY_ALLOC_FAILED;
2326 }
2327 memset(abt, 0, sizeof(struct abort_entry_24xx));
2328
2329 abt->entry_type = ABORT_IOCB_TYPE;
2330 abt->entry_count = 1;
2afa19a9 2331 abt->handle = MAKE_HANDLE(req->id, abt->handle);
1c7c6357 2332 abt->nport_handle = cpu_to_le16(fcport->loop_id);
a74ec14f 2333 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
1c7c6357
AV
2334 abt->port_id[0] = fcport->d_id.b.al_pa;
2335 abt->port_id[1] = fcport->d_id.b.area;
2336 abt->port_id[2] = fcport->d_id.b.domain;
2c3dfe3f 2337 abt->vp_index = fcport->vp_idx;
73208dfd
AC
2338
2339 abt->req_que_no = cpu_to_le16(req->id);
2340
7b867cf7 2341 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
1c7c6357 2342 if (rval != QLA_SUCCESS) {
7c3df132
SK
2343 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2344 "Failed to issue IOCB (%x).\n", rval);
1c7c6357 2345 } else if (abt->entry_status != 0) {
7c3df132
SK
2346 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2347 "Failed to complete IOCB -- error status (%x).\n",
2348 abt->entry_status);
1c7c6357
AV
2349 rval = QLA_FUNCTION_FAILED;
2350 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
7c3df132
SK
2351 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2352 "Failed to complete IOCB -- completion status (%x).\n",
2353 le16_to_cpu(abt->nport_handle));
1c7c6357
AV
2354 rval = QLA_FUNCTION_FAILED;
2355 } else {
7c3df132 2356 ql_dbg(ql_dbg_mbx, vha, 0x1091, "Done %s.\n", __func__);
1c7c6357
AV
2357 }
2358
2359 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2360
2361 return rval;
2362}
2363
2364struct tsk_mgmt_cmd {
2365 union {
2366 struct tsk_mgmt_entry tsk;
2367 struct sts_entry_24xx sts;
2368 } p;
2369};
2370
523ec773
AV
2371static int
2372__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
2afa19a9 2373 unsigned int l, int tag)
1c7c6357 2374{
523ec773 2375 int rval, rval2;
1c7c6357 2376 struct tsk_mgmt_cmd *tsk;
9ca1d01f 2377 struct sts_entry_24xx *sts;
1c7c6357 2378 dma_addr_t tsk_dma;
7b867cf7
AC
2379 scsi_qla_host_t *vha;
2380 struct qla_hw_data *ha;
73208dfd
AC
2381 struct req_que *req;
2382 struct rsp_que *rsp;
1c7c6357 2383
7b867cf7
AC
2384 vha = fcport->vha;
2385 ha = vha->hw;
2afa19a9 2386 req = vha->req;
7c3df132
SK
2387
2388 ql_dbg(ql_dbg_mbx, vha, 0x1092, "Entered %s.\n", __func__);
2389
7163ea81 2390 if (ha->flags.cpu_affinity_enabled)
68ca949c
AC
2391 rsp = ha->rsp_q_map[tag + 1];
2392 else
2393 rsp = req->rsp;
7b867cf7 2394 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
1c7c6357 2395 if (tsk == NULL) {
7c3df132
SK
2396 ql_log(ql_log_warn, vha, 0x1093,
2397 "Failed to allocate task management IOCB.\n");
1c7c6357
AV
2398 return QLA_MEMORY_ALLOC_FAILED;
2399 }
2400 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2401
2402 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2403 tsk->p.tsk.entry_count = 1;
2afa19a9 2404 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
1c7c6357 2405 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
00a537b8 2406 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
523ec773 2407 tsk->p.tsk.control_flags = cpu_to_le32(type);
1c7c6357
AV
2408 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2409 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2410 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
2c3dfe3f 2411 tsk->p.tsk.vp_index = fcport->vp_idx;
523ec773
AV
2412 if (type == TCF_LUN_RESET) {
2413 int_to_scsilun(l, &tsk->p.tsk.lun);
2414 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2415 sizeof(tsk->p.tsk.lun));
2416 }
2c3dfe3f 2417
9ca1d01f 2418 sts = &tsk->p.sts;
7b867cf7 2419 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
1c7c6357 2420 if (rval != QLA_SUCCESS) {
7c3df132
SK
2421 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2422 "Failed to issue %s reset IOCB (%x).\n", name, rval);
9ca1d01f 2423 } else if (sts->entry_status != 0) {
7c3df132
SK
2424 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2425 "Failed to complete IOCB -- error status (%x).\n",
2426 sts->entry_status);
1c7c6357 2427 rval = QLA_FUNCTION_FAILED;
9ca1d01f 2428 } else if (sts->comp_status !=
1c7c6357 2429 __constant_cpu_to_le16(CS_COMPLETE)) {
7c3df132
SK
2430 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2431 "Failed to complete IOCB -- completion status (%x).\n",
2432 le16_to_cpu(sts->comp_status));
9ca1d01f 2433 rval = QLA_FUNCTION_FAILED;
97dec564
AV
2434 } else if (le16_to_cpu(sts->scsi_status) &
2435 SS_RESPONSE_INFO_LEN_VALID) {
2436 if (le32_to_cpu(sts->rsp_data_len) < 4) {
7c3df132
SK
2437 ql_dbg(ql_dbg_mbx, vha, 0x1097,
2438 "Ignoring inconsistent data length -- not enough "
2439 "response info (%d).\n",
2440 le32_to_cpu(sts->rsp_data_len));
97dec564 2441 } else if (sts->data[3]) {
7c3df132
SK
2442 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2443 "Failed to complete IOCB -- response (%x).\n",
2444 sts->data[3]);
97dec564
AV
2445 rval = QLA_FUNCTION_FAILED;
2446 }
1c7c6357
AV
2447 }
2448
2449 /* Issue marker IOCB. */
73208dfd 2450 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
523ec773
AV
2451 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2452 if (rval2 != QLA_SUCCESS) {
7c3df132
SK
2453 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2454 "Failed to issue marker IOCB (%x).\n", rval2);
1c7c6357 2455 } else {
7c3df132 2456 ql_dbg(ql_dbg_mbx, vha, 0x109a, "Done %s.\n", __func__);
1c7c6357
AV
2457 }
2458
7b867cf7 2459 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
1c7c6357
AV
2460
2461 return rval;
2462}
2463
523ec773 2464int
2afa19a9 2465qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
523ec773 2466{
3822263e
MI
2467 struct qla_hw_data *ha = fcport->vha->hw;
2468
2469 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2470 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2471
2afa19a9 2472 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
523ec773
AV
2473}
2474
2475int
2afa19a9 2476qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
523ec773 2477{
3822263e
MI
2478 struct qla_hw_data *ha = fcport->vha->hw;
2479
2480 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2481 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2482
2afa19a9 2483 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
523ec773
AV
2484}
2485
1c7c6357 2486int
7b867cf7 2487qla2x00_system_error(scsi_qla_host_t *vha)
1c7c6357
AV
2488{
2489 int rval;
2490 mbx_cmd_t mc;
2491 mbx_cmd_t *mcp = &mc;
7b867cf7 2492 struct qla_hw_data *ha = vha->hw;
1c7c6357 2493
68af0811 2494 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
1c7c6357
AV
2495 return QLA_FUNCTION_FAILED;
2496
7c3df132 2497 ql_dbg(ql_dbg_mbx, vha, 0x109b, "Entered %s.\n", __func__);
1c7c6357
AV
2498
2499 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2500 mcp->out_mb = MBX_0;
2501 mcp->in_mb = MBX_0;
2502 mcp->tov = 5;
2503 mcp->flags = 0;
7b867cf7 2504 rval = qla2x00_mailbox_command(vha, mcp);
1c7c6357
AV
2505
2506 if (rval != QLA_SUCCESS) {
7c3df132 2507 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
1c7c6357 2508 } else {
7c3df132 2509 ql_dbg(ql_dbg_mbx, vha, 0x109d, "Done %s.\n", __func__);
1c7c6357
AV
2510 }
2511
2512 return rval;
2513}
2514
1c7c6357
AV
2515/**
2516 * qla2x00_set_serdes_params() -
2517 * @ha: HA context
2518 *
2519 * Returns
2520 */
2521int
7b867cf7 2522qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
1c7c6357
AV
2523 uint16_t sw_em_2g, uint16_t sw_em_4g)
2524{
2525 int rval;
2526 mbx_cmd_t mc;
2527 mbx_cmd_t *mcp = &mc;
2528
7c3df132 2529 ql_dbg(ql_dbg_mbx, vha, 0x109e, "Entered %s.\n", __func__);
1c7c6357
AV
2530
2531 mcp->mb[0] = MBC_SERDES_PARAMS;
2532 mcp->mb[1] = BIT_0;
fdbc6833
AV
2533 mcp->mb[2] = sw_em_1g | BIT_15;
2534 mcp->mb[3] = sw_em_2g | BIT_15;
2535 mcp->mb[4] = sw_em_4g | BIT_15;
1c7c6357
AV
2536 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2537 mcp->in_mb = MBX_0;
b93480e3 2538 mcp->tov = MBX_TOV_SECONDS;
1c7c6357 2539 mcp->flags = 0;
7b867cf7 2540 rval = qla2x00_mailbox_command(vha, mcp);
1c7c6357
AV
2541
2542 if (rval != QLA_SUCCESS) {
2543 /*EMPTY*/
7c3df132
SK
2544 ql_dbg(ql_dbg_mbx, vha, 0x109f,
2545 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
1c7c6357
AV
2546 } else {
2547 /*EMPTY*/
7c3df132 2548 ql_dbg(ql_dbg_mbx, vha, 0x10a0, "Done %s.\n", __func__);
1c7c6357
AV
2549 }
2550
2551 return rval;
2552}
f6ef3b18
AV
2553
2554int
7b867cf7 2555qla2x00_stop_firmware(scsi_qla_host_t *vha)
f6ef3b18
AV
2556{
2557 int rval;
2558 mbx_cmd_t mc;
2559 mbx_cmd_t *mcp = &mc;
2560
7b867cf7 2561 if (!IS_FWI2_CAPABLE(vha->hw))
f6ef3b18
AV
2562 return QLA_FUNCTION_FAILED;
2563
7c3df132 2564 ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__);
f6ef3b18
AV
2565
2566 mcp->mb[0] = MBC_STOP_FIRMWARE;
2567 mcp->out_mb = MBX_0;
2568 mcp->in_mb = MBX_0;
2569 mcp->tov = 5;
2570 mcp->flags = 0;
7b867cf7 2571 rval = qla2x00_mailbox_command(vha, mcp);
f6ef3b18
AV
2572
2573 if (rval != QLA_SUCCESS) {
7c3df132 2574 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
b469a7cb
AV
2575 if (mcp->mb[0] == MBS_INVALID_COMMAND)
2576 rval = QLA_INVALID_COMMAND;
f6ef3b18 2577 } else {
7c3df132 2578 ql_dbg(ql_dbg_mbx, vha, 0x10a3, "Done %s.\n", __func__);
f6ef3b18
AV
2579 }
2580
2581 return rval;
2582}
a7a167bf
AV
2583
2584int
7b867cf7 2585qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
a7a167bf
AV
2586 uint16_t buffers)
2587{
2588 int rval;
2589 mbx_cmd_t mc;
2590 mbx_cmd_t *mcp = &mc;
2591
7c3df132
SK
2592 ql_dbg(ql_dbg_mbx, vha, 0x10a4, "Entered %s.\n", __func__);
2593
7b867cf7 2594 if (!IS_FWI2_CAPABLE(vha->hw))
a7a167bf
AV
2595 return QLA_FUNCTION_FAILED;
2596
85880801
AV
2597 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2598 return QLA_FUNCTION_FAILED;
2599
a7a167bf 2600 mcp->mb[0] = MBC_TRACE_CONTROL;
00b6bd25
AV
2601 mcp->mb[1] = TC_EFT_ENABLE;
2602 mcp->mb[2] = LSW(eft_dma);
2603 mcp->mb[3] = MSW(eft_dma);
2604 mcp->mb[4] = LSW(MSD(eft_dma));
2605 mcp->mb[5] = MSW(MSD(eft_dma));
2606 mcp->mb[6] = buffers;
2607 mcp->mb[7] = TC_AEN_DISABLE;
2608 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
a7a167bf 2609 mcp->in_mb = MBX_1|MBX_0;
b93480e3 2610 mcp->tov = MBX_TOV_SECONDS;
a7a167bf 2611 mcp->flags = 0;
7b867cf7 2612 rval = qla2x00_mailbox_command(vha, mcp);
00b6bd25 2613 if (rval != QLA_SUCCESS) {
7c3df132
SK
2614 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
2615 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2616 rval, mcp->mb[0], mcp->mb[1]);
00b6bd25 2617 } else {
7c3df132 2618 ql_dbg(ql_dbg_mbx, vha, 0x10a6, "Done %s.\n", __func__);
00b6bd25
AV
2619 }
2620
2621 return rval;
2622}
a7a167bf 2623
00b6bd25 2624int
7b867cf7 2625qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
00b6bd25
AV
2626{
2627 int rval;
2628 mbx_cmd_t mc;
2629 mbx_cmd_t *mcp = &mc;
2630
7c3df132
SK
2631 ql_dbg(ql_dbg_mbx, vha, 0x10a7, "Entered %s.\n", __func__);
2632
7b867cf7 2633 if (!IS_FWI2_CAPABLE(vha->hw))
00b6bd25
AV
2634 return QLA_FUNCTION_FAILED;
2635
85880801
AV
2636 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2637 return QLA_FUNCTION_FAILED;
2638
00b6bd25
AV
2639 mcp->mb[0] = MBC_TRACE_CONTROL;
2640 mcp->mb[1] = TC_EFT_DISABLE;
2641 mcp->out_mb = MBX_1|MBX_0;
2642 mcp->in_mb = MBX_1|MBX_0;
b93480e3 2643 mcp->tov = MBX_TOV_SECONDS;
00b6bd25 2644 mcp->flags = 0;
7b867cf7 2645 rval = qla2x00_mailbox_command(vha, mcp);
a7a167bf 2646 if (rval != QLA_SUCCESS) {
7c3df132
SK
2647 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
2648 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2649 rval, mcp->mb[0], mcp->mb[1]);
a7a167bf 2650 } else {
7c3df132 2651 ql_dbg(ql_dbg_mbx, vha, 0x10a9, "Done %s.\n", __func__);
a7a167bf
AV
2652 }
2653
2654 return rval;
2655}
2656
df613b96 2657int
7b867cf7 2658qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
df613b96
AV
2659 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
2660{
2661 int rval;
2662 mbx_cmd_t mc;
2663 mbx_cmd_t *mcp = &mc;
2664
7c3df132
SK
2665 ql_dbg(ql_dbg_mbx, vha, 0x10aa, "Entered %s.\n", __func__);
2666
3a03eb79 2667 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw))
df613b96
AV
2668 return QLA_FUNCTION_FAILED;
2669
85880801
AV
2670 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2671 return QLA_FUNCTION_FAILED;
2672
df613b96
AV
2673 mcp->mb[0] = MBC_TRACE_CONTROL;
2674 mcp->mb[1] = TC_FCE_ENABLE;
2675 mcp->mb[2] = LSW(fce_dma);
2676 mcp->mb[3] = MSW(fce_dma);
2677 mcp->mb[4] = LSW(MSD(fce_dma));
2678 mcp->mb[5] = MSW(MSD(fce_dma));
2679 mcp->mb[6] = buffers;
2680 mcp->mb[7] = TC_AEN_DISABLE;
2681 mcp->mb[8] = 0;
2682 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
2683 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
2684 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2685 MBX_1|MBX_0;
2686 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
b93480e3 2687 mcp->tov = MBX_TOV_SECONDS;
df613b96 2688 mcp->flags = 0;
7b867cf7 2689 rval = qla2x00_mailbox_command(vha, mcp);
df613b96 2690 if (rval != QLA_SUCCESS) {
7c3df132
SK
2691 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
2692 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2693 rval, mcp->mb[0], mcp->mb[1]);
df613b96 2694 } else {
7c3df132 2695 ql_dbg(ql_dbg_mbx, vha, 0x10ac, "Done %s.\n", __func__);
df613b96
AV
2696
2697 if (mb)
2698 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
2699 if (dwords)
fa0926df 2700 *dwords = buffers;
df613b96
AV
2701 }
2702
2703 return rval;
2704}
2705
2706int
7b867cf7 2707qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
df613b96
AV
2708{
2709 int rval;
2710 mbx_cmd_t mc;
2711 mbx_cmd_t *mcp = &mc;
2712
7c3df132
SK
2713 ql_dbg(ql_dbg_mbx, vha, 0x10ad, "Entered %s.\n", __func__);
2714
7b867cf7 2715 if (!IS_FWI2_CAPABLE(vha->hw))
df613b96
AV
2716 return QLA_FUNCTION_FAILED;
2717
85880801
AV
2718 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2719 return QLA_FUNCTION_FAILED;
2720
df613b96
AV
2721 mcp->mb[0] = MBC_TRACE_CONTROL;
2722 mcp->mb[1] = TC_FCE_DISABLE;
2723 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
2724 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2725 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2726 MBX_1|MBX_0;
b93480e3 2727 mcp->tov = MBX_TOV_SECONDS;
df613b96 2728 mcp->flags = 0;
7b867cf7 2729 rval = qla2x00_mailbox_command(vha, mcp);
df613b96 2730 if (rval != QLA_SUCCESS) {
7c3df132
SK
2731 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
2732 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2733 rval, mcp->mb[0], mcp->mb[1]);
df613b96 2734 } else {
7c3df132 2735 ql_dbg(ql_dbg_mbx, vha, 0x10af, "Done %s.\n", __func__);
df613b96
AV
2736
2737 if (wr)
2738 *wr = (uint64_t) mcp->mb[5] << 48 |
2739 (uint64_t) mcp->mb[4] << 32 |
2740 (uint64_t) mcp->mb[3] << 16 |
2741 (uint64_t) mcp->mb[2];
2742 if (rd)
2743 *rd = (uint64_t) mcp->mb[9] << 48 |
2744 (uint64_t) mcp->mb[8] << 32 |
2745 (uint64_t) mcp->mb[7] << 16 |
2746 (uint64_t) mcp->mb[6];
2747 }
2748
2749 return rval;
2750}
2751
6e98016c
GM
2752int
2753qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
2754 uint16_t *port_speed, uint16_t *mb)
2755{
2756 int rval;
2757 mbx_cmd_t mc;
2758 mbx_cmd_t *mcp = &mc;
2759
7c3df132
SK
2760 ql_dbg(ql_dbg_mbx, vha, 0x10b0, "Entered %s.\n", __func__);
2761
6e98016c
GM
2762 if (!IS_IIDMA_CAPABLE(vha->hw))
2763 return QLA_FUNCTION_FAILED;
2764
6e98016c
GM
2765 mcp->mb[0] = MBC_PORT_PARAMS;
2766 mcp->mb[1] = loop_id;
2767 mcp->mb[2] = mcp->mb[3] = 0;
2768 mcp->mb[9] = vha->vp_idx;
2769 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2770 mcp->in_mb = MBX_3|MBX_1|MBX_0;
2771 mcp->tov = MBX_TOV_SECONDS;
2772 mcp->flags = 0;
2773 rval = qla2x00_mailbox_command(vha, mcp);
2774
2775 /* Return mailbox statuses. */
2776 if (mb != NULL) {
2777 mb[0] = mcp->mb[0];
2778 mb[1] = mcp->mb[1];
2779 mb[3] = mcp->mb[3];
2780 }
2781
2782 if (rval != QLA_SUCCESS) {
7c3df132 2783 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
6e98016c 2784 } else {
7c3df132 2785 ql_dbg(ql_dbg_mbx, vha, 0x10b2, "Done %s.\n", __func__);
6e98016c
GM
2786 if (port_speed)
2787 *port_speed = mcp->mb[3];
2788 }
2789
2790 return rval;
2791}
2792
d8b45213 2793int
7b867cf7 2794qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
d8b45213
AV
2795 uint16_t port_speed, uint16_t *mb)
2796{
2797 int rval;
2798 mbx_cmd_t mc;
2799 mbx_cmd_t *mcp = &mc;
2800
7c3df132
SK
2801 ql_dbg(ql_dbg_mbx, vha, 0x10b3, "Entered %s.\n", __func__);
2802
7b867cf7 2803 if (!IS_IIDMA_CAPABLE(vha->hw))
d8b45213
AV
2804 return QLA_FUNCTION_FAILED;
2805
d8b45213
AV
2806 mcp->mb[0] = MBC_PORT_PARAMS;
2807 mcp->mb[1] = loop_id;
2808 mcp->mb[2] = BIT_0;
a9083016 2809 if (IS_QLA8XXX_TYPE(vha->hw))
1bb39548
HZ
2810 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
2811 else
2812 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
2813 mcp->mb[9] = vha->vp_idx;
2814 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2815 mcp->in_mb = MBX_3|MBX_1|MBX_0;
b93480e3 2816 mcp->tov = MBX_TOV_SECONDS;
d8b45213 2817 mcp->flags = 0;
7b867cf7 2818 rval = qla2x00_mailbox_command(vha, mcp);
d8b45213
AV
2819
2820 /* Return mailbox statuses. */
2821 if (mb != NULL) {
2822 mb[0] = mcp->mb[0];
2823 mb[1] = mcp->mb[1];
2824 mb[3] = mcp->mb[3];
d8b45213
AV
2825 }
2826
2827 if (rval != QLA_SUCCESS) {
7c3df132 2828 ql_dbg(ql_dbg_mbx, vha, 0x10b4, "Failed=%x.\n", rval);
d8b45213 2829 } else {
7c3df132 2830 ql_dbg(ql_dbg_mbx, vha, 0x10b5, "Done %s.\n", __func__);
d8b45213
AV
2831 }
2832
2833 return rval;
2834}
2c3dfe3f 2835
2c3dfe3f 2836void
7b867cf7 2837qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
2c3dfe3f
SJ
2838 struct vp_rpt_id_entry_24xx *rptid_entry)
2839{
2840 uint8_t vp_idx;
c6852c4c 2841 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
7b867cf7
AC
2842 struct qla_hw_data *ha = vha->hw;
2843 scsi_qla_host_t *vp;
feafb7b1 2844 unsigned long flags;
2c3dfe3f 2845
7c3df132
SK
2846 ql_dbg(ql_dbg_mbx, vha, 0x10b6, "Entered %s.\n", __func__);
2847
2c3dfe3f
SJ
2848 if (rptid_entry->entry_status != 0)
2849 return;
2c3dfe3f
SJ
2850
2851 if (rptid_entry->format == 0) {
7c3df132
SK
2852 ql_dbg(ql_dbg_mbx, vha, 0x10b7,
2853 "Format 0 : Number of VPs setup %d, number of "
2854 "VPs acquired %d.\n",
2855 MSB(le16_to_cpu(rptid_entry->vp_count)),
2856 LSB(le16_to_cpu(rptid_entry->vp_count)));
2857 ql_dbg(ql_dbg_mbx, vha, 0x10b8,
2858 "Primary port id %02x%02x%02x.\n",
2859 rptid_entry->port_id[2], rptid_entry->port_id[1],
2860 rptid_entry->port_id[0]);
2c3dfe3f 2861 } else if (rptid_entry->format == 1) {
c6852c4c 2862 vp_idx = LSB(stat);
7c3df132
SK
2863 ql_dbg(ql_dbg_mbx, vha, 0x10b9,
2864 "Format 1: VP[%d] enabled - status %d - with "
2865 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
2c3dfe3f 2866 rptid_entry->port_id[2], rptid_entry->port_id[1],
7c3df132 2867 rptid_entry->port_id[0]);
531a82d1
AV
2868
2869 vp = vha;
2870 if (vp_idx == 0 && (MSB(stat) != 1))
2871 goto reg_needed;
2c3dfe3f 2872
81eb9b49 2873 if (MSB(stat) == 1) {
7c3df132
SK
2874 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
2875 "Could not acquire ID for VP[%d].\n", vp_idx);
2c3dfe3f 2876 return;
81eb9b49 2877 }
2c3dfe3f 2878
feafb7b1
AE
2879 spin_lock_irqsave(&ha->vport_slock, flags);
2880 list_for_each_entry(vp, &ha->vp_list, list)
7b867cf7 2881 if (vp_idx == vp->vp_idx)
2c3dfe3f 2882 break;
feafb7b1
AE
2883 spin_unlock_irqrestore(&ha->vport_slock, flags);
2884
7b867cf7 2885 if (!vp)
2c3dfe3f
SJ
2886 return;
2887
7b867cf7
AC
2888 vp->d_id.b.domain = rptid_entry->port_id[2];
2889 vp->d_id.b.area = rptid_entry->port_id[1];
2890 vp->d_id.b.al_pa = rptid_entry->port_id[0];
2c3dfe3f
SJ
2891
2892 /*
2893 * Cannot configure here as we are still sitting on the
2894 * response queue. Handle it in dpc context.
2895 */
7b867cf7 2896 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
2c3dfe3f 2897
531a82d1
AV
2898reg_needed:
2899 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
2900 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
2901 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
7b867cf7 2902 qla2xxx_wake_dpc(vha);
2c3dfe3f
SJ
2903 }
2904}
2905
2906/*
2907 * qla24xx_modify_vp_config
2908 * Change VP configuration for vha
2909 *
2910 * Input:
2911 * vha = adapter block pointer.
2912 *
2913 * Returns:
2914 * qla2xxx local function return status code.
2915 *
2916 * Context:
2917 * Kernel context.
2918 */
2919int
2920qla24xx_modify_vp_config(scsi_qla_host_t *vha)
2921{
2922 int rval;
2923 struct vp_config_entry_24xx *vpmod;
2924 dma_addr_t vpmod_dma;
7b867cf7
AC
2925 struct qla_hw_data *ha = vha->hw;
2926 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
2c3dfe3f
SJ
2927
2928 /* This can be called by the parent */
2c3dfe3f 2929
7c3df132
SK
2930 ql_dbg(ql_dbg_mbx, vha, 0x10bb, "Entered %s.\n", __func__);
2931
7b867cf7 2932 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
2c3dfe3f 2933 if (!vpmod) {
7c3df132
SK
2934 ql_log(ql_log_warn, vha, 0x10bc,
2935 "Failed to allocate modify VP IOCB.\n");
2c3dfe3f
SJ
2936 return QLA_MEMORY_ALLOC_FAILED;
2937 }
2938
2939 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
2940 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
2941 vpmod->entry_count = 1;
2942 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
2943 vpmod->vp_count = 1;
2944 vpmod->vp_index1 = vha->vp_idx;
2945 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
2946 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
2947 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
2948 vpmod->entry_count = 1;
2949
7b867cf7 2950 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
2c3dfe3f 2951 if (rval != QLA_SUCCESS) {
7c3df132
SK
2952 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
2953 "Failed to issue VP config IOCB (%x).\n", rval);
2c3dfe3f 2954 } else if (vpmod->comp_status != 0) {
7c3df132
SK
2955 ql_dbg(ql_dbg_mbx, vha, 0x10be,
2956 "Failed to complete IOCB -- error status (%x).\n",
2957 vpmod->comp_status);
2c3dfe3f
SJ
2958 rval = QLA_FUNCTION_FAILED;
2959 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
7c3df132
SK
2960 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
2961 "Failed to complete IOCB -- completion status (%x).\n",
2962 le16_to_cpu(vpmod->comp_status));
2c3dfe3f
SJ
2963 rval = QLA_FUNCTION_FAILED;
2964 } else {
2965 /* EMPTY */
7c3df132 2966 ql_dbg(ql_dbg_mbx, vha, 0x10c0, "Done %s.\n", __func__);
2c3dfe3f
SJ
2967 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
2968 }
7b867cf7 2969 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
2c3dfe3f
SJ
2970
2971 return rval;
2972}
2973
2974/*
2975 * qla24xx_control_vp
2976 * Enable a virtual port for given host
2977 *
2978 * Input:
2979 * ha = adapter block pointer.
2980 * vhba = virtual adapter (unused)
2981 * index = index number for enabled VP
2982 *
2983 * Returns:
2984 * qla2xxx local function return status code.
2985 *
2986 * Context:
2987 * Kernel context.
2988 */
2989int
2990qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
2991{
2992 int rval;
2993 int map, pos;
2994 struct vp_ctrl_entry_24xx *vce;
2995 dma_addr_t vce_dma;
7b867cf7 2996 struct qla_hw_data *ha = vha->hw;
2c3dfe3f 2997 int vp_index = vha->vp_idx;
7b867cf7 2998 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
2c3dfe3f 2999
7c3df132
SK
3000 ql_dbg(ql_dbg_mbx, vha, 0x10c1,
3001 "Entered %s enabling index %d.\n", __func__, vp_index);
2c3dfe3f 3002
eb66dc60 3003 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
2c3dfe3f
SJ
3004 return QLA_PARAMETER_ERROR;
3005
3006 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3007 if (!vce) {
7c3df132
SK
3008 ql_log(ql_log_warn, vha, 0x10c2,
3009 "Failed to allocate VP control IOCB.\n");
2c3dfe3f
SJ
3010 return QLA_MEMORY_ALLOC_FAILED;
3011 }
3012 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3013
3014 vce->entry_type = VP_CTRL_IOCB_TYPE;
3015 vce->entry_count = 1;
3016 vce->command = cpu_to_le16(cmd);
3017 vce->vp_count = __constant_cpu_to_le16(1);
3018
3019 /* index map in firmware starts with 1; decrement index
3020 * this is ok as we never use index 0
3021 */
3022 map = (vp_index - 1) / 8;
3023 pos = (vp_index - 1) & 7;
6c2f527c 3024 mutex_lock(&ha->vport_lock);
2c3dfe3f 3025 vce->vp_idx_map[map] |= 1 << pos;
6c2f527c 3026 mutex_unlock(&ha->vport_lock);
2c3dfe3f 3027
7b867cf7 3028 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
2c3dfe3f 3029 if (rval != QLA_SUCCESS) {
7c3df132
SK
3030 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3031 "Failed to issue VP control IOCB (%x).\n", rval);
2c3dfe3f 3032 } else if (vce->entry_status != 0) {
7c3df132
SK
3033 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3034 "Failed to complete IOCB -- error status (%x).\n",
2c3dfe3f
SJ
3035 vce->entry_status);
3036 rval = QLA_FUNCTION_FAILED;
3037 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
7c3df132
SK
3038 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3039 "Failed to complet IOCB -- completion status (%x).\n",
2c3dfe3f
SJ
3040 le16_to_cpu(vce->comp_status));
3041 rval = QLA_FUNCTION_FAILED;
3042 } else {
7c3df132 3043 ql_dbg(ql_dbg_mbx, vha, 0x10c6, "Done %s.\n", __func__);
2c3dfe3f
SJ
3044 }
3045
3046 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3047
3048 return rval;
3049}
3050
3051/*
3052 * qla2x00_send_change_request
3053 * Receive or disable RSCN request from fabric controller
3054 *
3055 * Input:
3056 * ha = adapter block pointer
3057 * format = registration format:
3058 * 0 - Reserved
3059 * 1 - Fabric detected registration
3060 * 2 - N_port detected registration
3061 * 3 - Full registration
3062 * FF - clear registration
3063 * vp_idx = Virtual port index
3064 *
3065 * Returns:
3066 * qla2x00 local function return status code.
3067 *
3068 * Context:
3069 * Kernel Context
3070 */
3071
3072int
7b867cf7 3073qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
2c3dfe3f
SJ
3074 uint16_t vp_idx)
3075{
3076 int rval;
3077 mbx_cmd_t mc;
3078 mbx_cmd_t *mcp = &mc;
3079
7c3df132
SK
3080 ql_dbg(ql_dbg_mbx, vha, 0x10c7, "Entered %s.\n", __func__);
3081
2c3dfe3f
SJ
3082 /*
3083 * This command is implicitly executed by firmware during login for the
3084 * physical hosts
3085 */
3086 if (vp_idx == 0)
3087 return QLA_FUNCTION_FAILED;
3088
3089 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3090 mcp->mb[1] = format;
3091 mcp->mb[9] = vp_idx;
3092 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3093 mcp->in_mb = MBX_0|MBX_1;
3094 mcp->tov = MBX_TOV_SECONDS;
3095 mcp->flags = 0;
7b867cf7 3096 rval = qla2x00_mailbox_command(vha, mcp);
2c3dfe3f
SJ
3097
3098 if (rval == QLA_SUCCESS) {
3099 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3100 rval = BIT_1;
3101 }
3102 } else
3103 rval = BIT_1;
3104
3105 return rval;
3106}
338c9161
AV
3107
3108int
7b867cf7 3109qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
338c9161
AV
3110 uint32_t size)
3111{
3112 int rval;
3113 mbx_cmd_t mc;
3114 mbx_cmd_t *mcp = &mc;
3115
7c3df132 3116 ql_dbg(ql_dbg_mbx, vha, 0x1009, "Entered %s.\n", __func__);
338c9161 3117
7b867cf7 3118 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
338c9161
AV
3119 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3120 mcp->mb[8] = MSW(addr);
3121 mcp->out_mb = MBX_8|MBX_0;
3122 } else {
3123 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3124 mcp->out_mb = MBX_0;
3125 }
3126 mcp->mb[1] = LSW(addr);
3127 mcp->mb[2] = MSW(req_dma);
3128 mcp->mb[3] = LSW(req_dma);
3129 mcp->mb[6] = MSW(MSD(req_dma));
3130 mcp->mb[7] = LSW(MSD(req_dma));
3131 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
7b867cf7 3132 if (IS_FWI2_CAPABLE(vha->hw)) {
338c9161
AV
3133 mcp->mb[4] = MSW(size);
3134 mcp->mb[5] = LSW(size);
3135 mcp->out_mb |= MBX_5|MBX_4;
3136 } else {
3137 mcp->mb[4] = LSW(size);
3138 mcp->out_mb |= MBX_4;
3139 }
3140
3141 mcp->in_mb = MBX_0;
b93480e3 3142 mcp->tov = MBX_TOV_SECONDS;
338c9161 3143 mcp->flags = 0;
7b867cf7 3144 rval = qla2x00_mailbox_command(vha, mcp);
338c9161
AV
3145
3146 if (rval != QLA_SUCCESS) {
7c3df132
SK
3147 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3148 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
338c9161 3149 } else {
7c3df132 3150 ql_dbg(ql_dbg_mbx, vha, 0x1007, "Done %s.\n", __func__);
338c9161
AV
3151 }
3152
3153 return rval;
3154}
4d4df193
HK
3155
3156/* 84XX Support **************************************************************/
3157
3158struct cs84xx_mgmt_cmd {
3159 union {
3160 struct verify_chip_entry_84xx req;
3161 struct verify_chip_rsp_84xx rsp;
3162 } p;
3163};
3164
3165int
7b867cf7 3166qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
4d4df193
HK
3167{
3168 int rval, retry;
3169 struct cs84xx_mgmt_cmd *mn;
3170 dma_addr_t mn_dma;
3171 uint16_t options;
3172 unsigned long flags;
7b867cf7 3173 struct qla_hw_data *ha = vha->hw;
4d4df193 3174
7c3df132 3175 ql_dbg(ql_dbg_mbx, vha, 0x10c8, "Entered %s.\n", __func__);
4d4df193
HK
3176
3177 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3178 if (mn == NULL) {
4d4df193
HK
3179 return QLA_MEMORY_ALLOC_FAILED;
3180 }
3181
3182 /* Force Update? */
3183 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3184 /* Diagnostic firmware? */
3185 /* options |= MENLO_DIAG_FW; */
3186 /* We update the firmware with only one data sequence. */
3187 options |= VCO_END_OF_DATA;
3188
4d4df193 3189 do {
c1ec1f1b 3190 retry = 0;
4d4df193
HK
3191 memset(mn, 0, sizeof(*mn));
3192 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3193 mn->p.req.entry_count = 1;
3194 mn->p.req.options = cpu_to_le16(options);
3195
7c3df132
SK
3196 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3197 "Dump of Verify Request.\n");
3198 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3199 (uint8_t *)mn, sizeof(*mn));
4d4df193 3200
7b867cf7 3201 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
4d4df193 3202 if (rval != QLA_SUCCESS) {
7c3df132
SK
3203 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3204 "Failed to issue verify IOCB (%x).\n", rval);
4d4df193
HK
3205 goto verify_done;
3206 }
3207
7c3df132
SK
3208 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3209 "Dump of Verify Response.\n");
3210 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3211 (uint8_t *)mn, sizeof(*mn));
4d4df193
HK
3212
3213 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3214 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3215 le16_to_cpu(mn->p.rsp.failure_code) : 0;
7c3df132
SK
3216 ql_dbg(ql_dbg_mbx, vha, 0x10ce,
3217 "cs=%x fc=%x.\n", status[0], status[1]);
4d4df193
HK
3218
3219 if (status[0] != CS_COMPLETE) {
3220 rval = QLA_FUNCTION_FAILED;
3221 if (!(options & VCO_DONT_UPDATE_FW)) {
7c3df132
SK
3222 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3223 "Firmware update failed. Retrying "
3224 "without update firmware.\n");
4d4df193
HK
3225 options |= VCO_DONT_UPDATE_FW;
3226 options &= ~VCO_FORCE_UPDATE;
3227 retry = 1;
3228 }
3229 } else {
7c3df132
SK
3230 ql_dbg(ql_dbg_mbx, vha, 0x10d0,
3231 "Firmware updated to %x.\n",
3232 le32_to_cpu(mn->p.rsp.fw_ver));
4d4df193
HK
3233
3234 /* NOTE: we only update OP firmware. */
3235 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3236 ha->cs84xx->op_fw_version =
3237 le32_to_cpu(mn->p.rsp.fw_ver);
3238 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3239 flags);
3240 }
3241 } while (retry);
3242
3243verify_done:
3244 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3245
3246 if (rval != QLA_SUCCESS) {
7c3df132 3247 ql_dbg(ql_dbg_mbx, vha, 0x10d1, "Failed=%x.\n", rval);
4d4df193 3248 } else {
7c3df132 3249 ql_dbg(ql_dbg_mbx, vha, 0x10d2, "Done %s.\n", __func__);
4d4df193
HK
3250 }
3251
3252 return rval;
3253}
73208dfd
AC
3254
3255int
618a7523 3256qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
73208dfd
AC
3257{
3258 int rval;
3259 unsigned long flags;
3260 mbx_cmd_t mc;
3261 mbx_cmd_t *mcp = &mc;
3262 struct device_reg_25xxmq __iomem *reg;
3263 struct qla_hw_data *ha = vha->hw;
3264
7c3df132
SK
3265 ql_dbg(ql_dbg_mbx, vha, 0x10d3, "Entered %s.\n", __func__);
3266
73208dfd 3267 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
618a7523 3268 mcp->mb[1] = req->options;
73208dfd
AC
3269 mcp->mb[2] = MSW(LSD(req->dma));
3270 mcp->mb[3] = LSW(LSD(req->dma));
3271 mcp->mb[6] = MSW(MSD(req->dma));
3272 mcp->mb[7] = LSW(MSD(req->dma));
3273 mcp->mb[5] = req->length;
3274 if (req->rsp)
3275 mcp->mb[10] = req->rsp->id;
3276 mcp->mb[12] = req->qos;
3277 mcp->mb[11] = req->vp_idx;
3278 mcp->mb[13] = req->rid;
3279
3280 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3281 QLA_QUE_PAGE * req->id);
3282
3283 mcp->mb[4] = req->id;
3284 /* que in ptr index */
3285 mcp->mb[8] = 0;
3286 /* que out ptr index */
3287 mcp->mb[9] = 0;
3288 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3289 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3290 mcp->in_mb = MBX_0;
3291 mcp->flags = MBX_DMA_OUT;
3292 mcp->tov = 60;
3293
3294 spin_lock_irqsave(&ha->hardware_lock, flags);
618a7523 3295 if (!(req->options & BIT_0)) {
73208dfd
AC
3296 WRT_REG_DWORD(&reg->req_q_in, 0);
3297 WRT_REG_DWORD(&reg->req_q_out, 0);
3298 }
2afa19a9
AC
3299 req->req_q_in = &reg->req_q_in;
3300 req->req_q_out = &reg->req_q_out;
73208dfd
AC
3301 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3302
17d98630 3303 rval = qla2x00_mailbox_command(vha, mcp);
7c3df132
SK
3304 if (rval != QLA_SUCCESS) {
3305 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3306 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3307 } else {
3308 ql_dbg(ql_dbg_mbx, vha, 0x10d5, "Done %s.\n", __func__);
3309 }
3310
73208dfd
AC
3311 return rval;
3312}
3313
3314int
618a7523 3315qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
73208dfd
AC
3316{
3317 int rval;
3318 unsigned long flags;
3319 mbx_cmd_t mc;
3320 mbx_cmd_t *mcp = &mc;
3321 struct device_reg_25xxmq __iomem *reg;
3322 struct qla_hw_data *ha = vha->hw;
3323
7c3df132
SK
3324 ql_dbg(ql_dbg_mbx, vha, 0x10d6, "Entered %s.\n", __func__);
3325
73208dfd 3326 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
618a7523 3327 mcp->mb[1] = rsp->options;
73208dfd
AC
3328 mcp->mb[2] = MSW(LSD(rsp->dma));
3329 mcp->mb[3] = LSW(LSD(rsp->dma));
3330 mcp->mb[6] = MSW(MSD(rsp->dma));
3331 mcp->mb[7] = LSW(MSD(rsp->dma));
3332 mcp->mb[5] = rsp->length;
444786d7 3333 mcp->mb[14] = rsp->msix->entry;
73208dfd
AC
3334 mcp->mb[13] = rsp->rid;
3335
3336 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3337 QLA_QUE_PAGE * rsp->id);
3338
3339 mcp->mb[4] = rsp->id;
3340 /* que in ptr index */
3341 mcp->mb[8] = 0;
3342 /* que out ptr index */
3343 mcp->mb[9] = 0;
2afa19a9 3344 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
73208dfd
AC
3345 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3346 mcp->in_mb = MBX_0;
3347 mcp->flags = MBX_DMA_OUT;
3348 mcp->tov = 60;
3349
3350 spin_lock_irqsave(&ha->hardware_lock, flags);
618a7523 3351 if (!(rsp->options & BIT_0)) {
73208dfd
AC
3352 WRT_REG_DWORD(&reg->rsp_q_out, 0);
3353 WRT_REG_DWORD(&reg->rsp_q_in, 0);
3354 }
3355
3356 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3357
17d98630 3358 rval = qla2x00_mailbox_command(vha, mcp);
7c3df132
SK
3359 if (rval != QLA_SUCCESS) {
3360 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
3361 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3362 } else {
3363 ql_dbg(ql_dbg_mbx, vha, 0x10d8, "Done %s.\n", __func__);
3364 }
3365
73208dfd
AC
3366 return rval;
3367}
3368
8a659571
AV
3369int
3370qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3371{
3372 int rval;
3373 mbx_cmd_t mc;
3374 mbx_cmd_t *mcp = &mc;
3375
7c3df132 3376 ql_dbg(ql_dbg_mbx, vha, 0x10d9, "Entered %s.\n", __func__);
8a659571
AV
3377
3378 mcp->mb[0] = MBC_IDC_ACK;
3379 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3380 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3381 mcp->in_mb = MBX_0;
3382 mcp->tov = MBX_TOV_SECONDS;
3383 mcp->flags = 0;
3384 rval = qla2x00_mailbox_command(vha, mcp);
3385
3386 if (rval != QLA_SUCCESS) {
7c3df132
SK
3387 ql_dbg(ql_dbg_mbx, vha, 0x10da,
3388 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
8a659571 3389 } else {
7c3df132 3390 ql_dbg(ql_dbg_mbx, vha, 0x10db, "Done %s.\n", __func__);
8a659571
AV
3391 }
3392
3393 return rval;
3394}
1d2874de
JC
3395
3396int
3397qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3398{
3399 int rval;
3400 mbx_cmd_t mc;
3401 mbx_cmd_t *mcp = &mc;
3402
7c3df132
SK
3403 ql_dbg(ql_dbg_mbx, vha, 0x10dc, "Entered %s.\n", __func__);
3404
1d2874de
JC
3405 if (!IS_QLA81XX(vha->hw))
3406 return QLA_FUNCTION_FAILED;
3407
1d2874de
JC
3408 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3409 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3410 mcp->out_mb = MBX_1|MBX_0;
3411 mcp->in_mb = MBX_1|MBX_0;
3412 mcp->tov = MBX_TOV_SECONDS;
3413 mcp->flags = 0;
3414 rval = qla2x00_mailbox_command(vha, mcp);
3415
3416 if (rval != QLA_SUCCESS) {
7c3df132
SK
3417 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
3418 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3419 rval, mcp->mb[0], mcp->mb[1]);
1d2874de 3420 } else {
7c3df132 3421 ql_dbg(ql_dbg_mbx, vha, 0x10de, "Done %s.\n", __func__);
1d2874de
JC
3422 *sector_size = mcp->mb[1];
3423 }
3424
3425 return rval;
3426}
3427
3428int
3429qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3430{
3431 int rval;
3432 mbx_cmd_t mc;
3433 mbx_cmd_t *mcp = &mc;
3434
3435 if (!IS_QLA81XX(vha->hw))
3436 return QLA_FUNCTION_FAILED;
3437
7c3df132 3438 ql_dbg(ql_dbg_mbx, vha, 0x10df, "Entered %s.\n", __func__);
1d2874de
JC
3439
3440 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3441 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3442 FAC_OPT_CMD_WRITE_PROTECT;
3443 mcp->out_mb = MBX_1|MBX_0;
3444 mcp->in_mb = MBX_1|MBX_0;
3445 mcp->tov = MBX_TOV_SECONDS;
3446 mcp->flags = 0;
3447 rval = qla2x00_mailbox_command(vha, mcp);
3448
3449 if (rval != QLA_SUCCESS) {
7c3df132
SK
3450 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
3451 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3452 rval, mcp->mb[0], mcp->mb[1]);
1d2874de 3453 } else {
7c3df132 3454 ql_dbg(ql_dbg_mbx, vha, 0x10e1, "Done %s.\n", __func__);
1d2874de
JC
3455 }
3456
3457 return rval;
3458}
3459
3460int
3461qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3462{
3463 int rval;
3464 mbx_cmd_t mc;
3465 mbx_cmd_t *mcp = &mc;
3466
3467 if (!IS_QLA81XX(vha->hw))
3468 return QLA_FUNCTION_FAILED;
3469
7c3df132 3470 ql_dbg(ql_dbg_mbx, vha, 0x10e2, "Entered %s.\n", __func__);
1d2874de
JC
3471
3472 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3473 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3474 mcp->mb[2] = LSW(start);
3475 mcp->mb[3] = MSW(start);
3476 mcp->mb[4] = LSW(finish);
3477 mcp->mb[5] = MSW(finish);
3478 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3479 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3480 mcp->tov = MBX_TOV_SECONDS;
3481 mcp->flags = 0;
3482 rval = qla2x00_mailbox_command(vha, mcp);
3483
3484 if (rval != QLA_SUCCESS) {
7c3df132
SK
3485 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
3486 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3487 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
1d2874de 3488 } else {
7c3df132 3489 ql_dbg(ql_dbg_mbx, vha, 0x10e4, "Done %s.\n", __func__);
1d2874de
JC
3490 }
3491
3492 return rval;
3493}
6e181be5
LC
3494
3495int
3496qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3497{
3498 int rval = 0;
3499 mbx_cmd_t mc;
3500 mbx_cmd_t *mcp = &mc;
3501
7c3df132 3502 ql_dbg(ql_dbg_mbx, vha, 0x10e5, "Entered %s.\n", __func__);
6e181be5
LC
3503
3504 mcp->mb[0] = MBC_RESTART_MPI_FW;
3505 mcp->out_mb = MBX_0;
3506 mcp->in_mb = MBX_0|MBX_1;
3507 mcp->tov = MBX_TOV_SECONDS;
3508 mcp->flags = 0;
3509 rval = qla2x00_mailbox_command(vha, mcp);
3510
3511 if (rval != QLA_SUCCESS) {
7c3df132
SK
3512 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
3513 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3514 rval, mcp->mb[0], mcp->mb[1]);
6e181be5 3515 } else {
7c3df132 3516 ql_dbg(ql_dbg_mbx, vha, 0x10e7, "Done %s.\n", __func__);
6e181be5
LC
3517 }
3518
3519 return rval;
3520}
ad0ecd61
JC
3521
3522int
6766df9e
JC
3523qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3524 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
ad0ecd61
JC
3525{
3526 int rval;
3527 mbx_cmd_t mc;
3528 mbx_cmd_t *mcp = &mc;
6766df9e
JC
3529 struct qla_hw_data *ha = vha->hw;
3530
7c3df132
SK
3531 ql_dbg(ql_dbg_mbx, vha, 0x10e8, "Entered %s.\n", __func__);
3532
6766df9e
JC
3533 if (!IS_FWI2_CAPABLE(ha))
3534 return QLA_FUNCTION_FAILED;
ad0ecd61 3535
6766df9e
JC
3536 if (len == 1)
3537 opt |= BIT_0;
3538
ad0ecd61
JC
3539 mcp->mb[0] = MBC_READ_SFP;
3540 mcp->mb[1] = dev;
3541 mcp->mb[2] = MSW(sfp_dma);
3542 mcp->mb[3] = LSW(sfp_dma);
3543 mcp->mb[6] = MSW(MSD(sfp_dma));
3544 mcp->mb[7] = LSW(MSD(sfp_dma));
3545 mcp->mb[8] = len;
6766df9e 3546 mcp->mb[9] = off;
ad0ecd61
JC
3547 mcp->mb[10] = opt;
3548 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1bff6cc8 3549 mcp->in_mb = MBX_1|MBX_0;
ad0ecd61
JC
3550 mcp->tov = MBX_TOV_SECONDS;
3551 mcp->flags = 0;
3552 rval = qla2x00_mailbox_command(vha, mcp);
3553
3554 if (opt & BIT_0)
6766df9e 3555 *sfp = mcp->mb[1];
ad0ecd61
JC
3556
3557 if (rval != QLA_SUCCESS) {
7c3df132
SK
3558 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
3559 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
ad0ecd61 3560 } else {
7c3df132 3561 ql_dbg(ql_dbg_mbx, vha, 0x10ea, "Done %s.\n", __func__);
ad0ecd61
JC
3562 }
3563
3564 return rval;
3565}
3566
3567int
6766df9e
JC
3568qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3569 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
ad0ecd61
JC
3570{
3571 int rval;
3572 mbx_cmd_t mc;
3573 mbx_cmd_t *mcp = &mc;
6766df9e
JC
3574 struct qla_hw_data *ha = vha->hw;
3575
7c3df132
SK
3576 ql_dbg(ql_dbg_mbx, vha, 0x10eb, "Entered %s.\n", __func__);
3577
6766df9e
JC
3578 if (!IS_FWI2_CAPABLE(ha))
3579 return QLA_FUNCTION_FAILED;
ad0ecd61 3580
6766df9e
JC
3581 if (len == 1)
3582 opt |= BIT_0;
3583
ad0ecd61 3584 if (opt & BIT_0)
6766df9e 3585 len = *sfp;
ad0ecd61
JC
3586
3587 mcp->mb[0] = MBC_WRITE_SFP;
3588 mcp->mb[1] = dev;
3589 mcp->mb[2] = MSW(sfp_dma);
3590 mcp->mb[3] = LSW(sfp_dma);
3591 mcp->mb[6] = MSW(MSD(sfp_dma));
3592 mcp->mb[7] = LSW(MSD(sfp_dma));
3593 mcp->mb[8] = len;
6766df9e 3594 mcp->mb[9] = off;
ad0ecd61
JC
3595 mcp->mb[10] = opt;
3596 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
6766df9e 3597 mcp->in_mb = MBX_1|MBX_0;
ad0ecd61
JC
3598 mcp->tov = MBX_TOV_SECONDS;
3599 mcp->flags = 0;
3600 rval = qla2x00_mailbox_command(vha, mcp);
3601
3602 if (rval != QLA_SUCCESS) {
7c3df132
SK
3603 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
3604 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
ad0ecd61 3605 } else {
7c3df132 3606 ql_dbg(ql_dbg_mbx, vha, 0x10ed, "Done %s.\n", __func__);
ad0ecd61
JC
3607 }
3608
3609 return rval;
3610}
ce0423f4
AV
3611
3612int
3613qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
3614 uint16_t size_in_bytes, uint16_t *actual_size)
3615{
3616 int rval;
3617 mbx_cmd_t mc;
3618 mbx_cmd_t *mcp = &mc;
3619
7c3df132
SK
3620 ql_dbg(ql_dbg_mbx, vha, 0x10ee, "Entered %s.\n", __func__);
3621
a9083016 3622 if (!IS_QLA8XXX_TYPE(vha->hw))
ce0423f4
AV
3623 return QLA_FUNCTION_FAILED;
3624
ce0423f4
AV
3625 mcp->mb[0] = MBC_GET_XGMAC_STATS;
3626 mcp->mb[2] = MSW(stats_dma);
3627 mcp->mb[3] = LSW(stats_dma);
3628 mcp->mb[6] = MSW(MSD(stats_dma));
3629 mcp->mb[7] = LSW(MSD(stats_dma));
3630 mcp->mb[8] = size_in_bytes >> 2;
3631 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
3632 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3633 mcp->tov = MBX_TOV_SECONDS;
3634 mcp->flags = 0;
3635 rval = qla2x00_mailbox_command(vha, mcp);
3636
3637 if (rval != QLA_SUCCESS) {
7c3df132
SK
3638 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
3639 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3640 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
ce0423f4 3641 } else {
7c3df132
SK
3642 ql_dbg(ql_dbg_mbx, vha, 0x10f0, "Done %s.\n", __func__);
3643
ce0423f4
AV
3644
3645 *actual_size = mcp->mb[2] << 2;
3646 }
3647
3648 return rval;
3649}
11bbc1d8
AV
3650
3651int
3652qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
3653 uint16_t size)
3654{
3655 int rval;
3656 mbx_cmd_t mc;
3657 mbx_cmd_t *mcp = &mc;
3658
7c3df132
SK
3659 ql_dbg(ql_dbg_mbx, vha, 0x10f1, "Entered %s.\n", __func__);
3660
a9083016 3661 if (!IS_QLA8XXX_TYPE(vha->hw))
11bbc1d8
AV
3662 return QLA_FUNCTION_FAILED;
3663
11bbc1d8
AV
3664 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
3665 mcp->mb[1] = 0;
3666 mcp->mb[2] = MSW(tlv_dma);
3667 mcp->mb[3] = LSW(tlv_dma);
3668 mcp->mb[6] = MSW(MSD(tlv_dma));
3669 mcp->mb[7] = LSW(MSD(tlv_dma));
3670 mcp->mb[8] = size;
3671 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3672 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3673 mcp->tov = MBX_TOV_SECONDS;
3674 mcp->flags = 0;
3675 rval = qla2x00_mailbox_command(vha, mcp);
3676
3677 if (rval != QLA_SUCCESS) {
7c3df132
SK
3678 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
3679 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3680 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
11bbc1d8 3681 } else {
7c3df132 3682 ql_dbg(ql_dbg_mbx, vha, 0x10f3, "Done %s.\n", __func__);
11bbc1d8
AV
3683 }
3684
3685 return rval;
3686}
18e7555a
AV
3687
3688int
3689qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
3690{
3691 int rval;
3692 mbx_cmd_t mc;
3693 mbx_cmd_t *mcp = &mc;
3694
7c3df132
SK
3695 ql_dbg(ql_dbg_mbx, vha, 0x10f4, "Entered %s.\n", __func__);
3696
18e7555a
AV
3697 if (!IS_FWI2_CAPABLE(vha->hw))
3698 return QLA_FUNCTION_FAILED;
3699
18e7555a
AV
3700 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3701 mcp->mb[1] = LSW(risc_addr);
3702 mcp->mb[8] = MSW(risc_addr);
3703 mcp->out_mb = MBX_8|MBX_1|MBX_0;
3704 mcp->in_mb = MBX_3|MBX_2|MBX_0;
3705 mcp->tov = 30;
3706 mcp->flags = 0;
3707 rval = qla2x00_mailbox_command(vha, mcp);
3708 if (rval != QLA_SUCCESS) {
7c3df132
SK
3709 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
3710 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
18e7555a 3711 } else {
7c3df132 3712 ql_dbg(ql_dbg_mbx, vha, 0x10f6, "Done %s.\n", __func__);
18e7555a
AV
3713 *data = mcp->mb[3] << 16 | mcp->mb[2];
3714 }
3715
3716 return rval;
3717}
3718
9a069e19 3719int
a9083016
GM
3720qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3721 uint16_t *mresp)
9a069e19
GM
3722{
3723 int rval;
3724 mbx_cmd_t mc;
3725 mbx_cmd_t *mcp = &mc;
3726 uint32_t iter_cnt = 0x1;
3727
7c3df132 3728 ql_dbg(ql_dbg_mbx, vha, 0x10f7, "Entered %s.\n", __func__);
9a069e19
GM
3729
3730 memset(mcp->mb, 0 , sizeof(mcp->mb));
3731 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3732 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
3733
3734 /* transfer count */
3735 mcp->mb[10] = LSW(mreq->transfer_size);
3736 mcp->mb[11] = MSW(mreq->transfer_size);
3737
3738 /* send data address */
3739 mcp->mb[14] = LSW(mreq->send_dma);
3740 mcp->mb[15] = MSW(mreq->send_dma);
3741 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3742 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3743
25985edc 3744 /* receive data address */
9a069e19
GM
3745 mcp->mb[16] = LSW(mreq->rcv_dma);
3746 mcp->mb[17] = MSW(mreq->rcv_dma);
3747 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3748 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3749
3750 /* Iteration count */
3751 mcp->mb[18] = LSW(iter_cnt);
3752 mcp->mb[19] = MSW(iter_cnt);
3753
3754 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3755 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
a9083016 3756 if (IS_QLA8XXX_TYPE(vha->hw))
9a069e19
GM
3757 mcp->out_mb |= MBX_2;
3758 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3759
3760 mcp->buf_size = mreq->transfer_size;
3761 mcp->tov = MBX_TOV_SECONDS;
3762 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3763
3764 rval = qla2x00_mailbox_command(vha, mcp);
3765
3766 if (rval != QLA_SUCCESS) {
7c3df132
SK
3767 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
3768 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
3769 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
3770 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
9a069e19 3771 } else {
7c3df132 3772 ql_dbg(ql_dbg_mbx, vha, 0x10f9, "Done %s.\n", __func__);
9a069e19
GM
3773 }
3774
3775 /* Copy mailbox information */
3776 memcpy( mresp, mcp->mb, 64);
9a069e19
GM
3777 return rval;
3778}
3779
3780int
a9083016
GM
3781qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3782 uint16_t *mresp)
9a069e19
GM
3783{
3784 int rval;
3785 mbx_cmd_t mc;
3786 mbx_cmd_t *mcp = &mc;
3787 struct qla_hw_data *ha = vha->hw;
3788
7c3df132 3789 ql_dbg(ql_dbg_mbx, vha, 0x10fa, "Entered %s.\n", __func__);
9a069e19
GM
3790
3791 memset(mcp->mb, 0 , sizeof(mcp->mb));
3792 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
3793 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
a9083016 3794 if (IS_QLA8XXX_TYPE(ha)) {
9a069e19 3795 mcp->mb[1] |= BIT_15;
a9083016
GM
3796 mcp->mb[2] = vha->fcoe_fcf_idx;
3797 }
9a069e19
GM
3798 mcp->mb[16] = LSW(mreq->rcv_dma);
3799 mcp->mb[17] = MSW(mreq->rcv_dma);
3800 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3801 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3802
3803 mcp->mb[10] = LSW(mreq->transfer_size);
3804
3805 mcp->mb[14] = LSW(mreq->send_dma);
3806 mcp->mb[15] = MSW(mreq->send_dma);
3807 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3808 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3809
3810 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3811 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
a9083016 3812 if (IS_QLA8XXX_TYPE(ha))
9a069e19
GM
3813 mcp->out_mb |= MBX_2;
3814
3815 mcp->in_mb = MBX_0;
a9083016 3816 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_QLA8XXX_TYPE(ha))
9a069e19 3817 mcp->in_mb |= MBX_1;
a9083016 3818 if (IS_QLA8XXX_TYPE(ha))
9a069e19
GM
3819 mcp->in_mb |= MBX_3;
3820
3821 mcp->tov = MBX_TOV_SECONDS;
3822 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3823 mcp->buf_size = mreq->transfer_size;
3824
3825 rval = qla2x00_mailbox_command(vha, mcp);
3826
3827 if (rval != QLA_SUCCESS) {
7c3df132
SK
3828 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
3829 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3830 rval, mcp->mb[0], mcp->mb[1]);
9a069e19 3831 } else {
7c3df132 3832 ql_dbg(ql_dbg_mbx, vha, 0x10fc, "Done %s.\n", __func__);
9a069e19
GM
3833 }
3834
3835 /* Copy mailbox information */
6dbdda4d 3836 memcpy(mresp, mcp->mb, 64);
9a069e19
GM
3837 return rval;
3838}
6dbdda4d 3839
9a069e19 3840int
7c3df132 3841qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
9a069e19
GM
3842{
3843 int rval;
3844 mbx_cmd_t mc;
3845 mbx_cmd_t *mcp = &mc;
3846
7c3df132
SK
3847 ql_dbg(ql_dbg_mbx, vha, 0x10fd,
3848 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
9a069e19
GM
3849
3850 mcp->mb[0] = MBC_ISP84XX_RESET;
3851 mcp->mb[1] = enable_diagnostic;
3852 mcp->out_mb = MBX_1|MBX_0;
3853 mcp->in_mb = MBX_1|MBX_0;
3854 mcp->tov = MBX_TOV_SECONDS;
3855 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
7c3df132 3856 rval = qla2x00_mailbox_command(vha, mcp);
9a069e19 3857
9a069e19 3858 if (rval != QLA_SUCCESS)
7c3df132 3859 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
9a069e19 3860 else
7c3df132 3861 ql_dbg(ql_dbg_mbx, vha, 0x10ff, "Done %s.\n", __func__);
9a069e19
GM
3862
3863 return rval;
3864}
3865
18e7555a
AV
3866int
3867qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
3868{
3869 int rval;
3870 mbx_cmd_t mc;
3871 mbx_cmd_t *mcp = &mc;
3872
7c3df132
SK
3873 ql_dbg(ql_dbg_mbx, vha, 0x1100, "Entered %s.\n", __func__);
3874
18e7555a 3875 if (!IS_FWI2_CAPABLE(vha->hw))
6c452a45 3876 return QLA_FUNCTION_FAILED;
18e7555a 3877
18e7555a
AV
3878 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
3879 mcp->mb[1] = LSW(risc_addr);
3880 mcp->mb[2] = LSW(data);
3881 mcp->mb[3] = MSW(data);
3882 mcp->mb[8] = MSW(risc_addr);
3883 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3884 mcp->in_mb = MBX_0;
3885 mcp->tov = 30;
3886 mcp->flags = 0;
3887 rval = qla2x00_mailbox_command(vha, mcp);
3888 if (rval != QLA_SUCCESS) {
7c3df132
SK
3889 ql_dbg(ql_dbg_mbx, vha, 0x1101,
3890 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
18e7555a 3891 } else {
7c3df132 3892 ql_dbg(ql_dbg_mbx, vha, 0x1102, "Done %s.\n", __func__);
18e7555a
AV
3893 }
3894
3895 return rval;
3896}
3064ff39 3897
b1d46989
MI
3898int
3899qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
3900{
3901 int rval;
3902 uint32_t stat, timer;
3903 uint16_t mb0 = 0;
3904 struct qla_hw_data *ha = vha->hw;
3905 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
3906
3907 rval = QLA_SUCCESS;
3908
7c3df132 3909 ql_dbg(ql_dbg_mbx, vha, 0x1103, "Entered %s.\n", __func__);
b1d46989
MI
3910
3911 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
3912
3913 /* Write the MBC data to the registers */
3914 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
3915 WRT_REG_WORD(&reg->mailbox1, mb[0]);
3916 WRT_REG_WORD(&reg->mailbox2, mb[1]);
3917 WRT_REG_WORD(&reg->mailbox3, mb[2]);
3918 WRT_REG_WORD(&reg->mailbox4, mb[3]);
3919
3920 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
3921
3922 /* Poll for MBC interrupt */
3923 for (timer = 6000000; timer; timer--) {
3924 /* Check for pending interrupts. */
3925 stat = RD_REG_DWORD(&reg->host_status);
3926 if (stat & HSRX_RISC_INT) {
3927 stat &= 0xff;
3928
3929 if (stat == 0x1 || stat == 0x2 ||
3930 stat == 0x10 || stat == 0x11) {
3931 set_bit(MBX_INTERRUPT,
3932 &ha->mbx_cmd_flags);
3933 mb0 = RD_REG_WORD(&reg->mailbox0);
3934 WRT_REG_DWORD(&reg->hccr,
3935 HCCRX_CLR_RISC_INT);
3936 RD_REG_DWORD(&reg->hccr);
3937 break;
3938 }
3939 }
3940 udelay(5);
3941 }
3942
3943 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
3944 rval = mb0 & MBS_MASK;
3945 else
3946 rval = QLA_FUNCTION_FAILED;
3947
3948 if (rval != QLA_SUCCESS) {
7c3df132
SK
3949 ql_dbg(ql_dbg_mbx, vha, 0x1104,
3950 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
b1d46989 3951 } else {
7c3df132 3952 ql_dbg(ql_dbg_mbx, vha, 0x1105, "Done %s.\n", __func__);
b1d46989
MI
3953 }
3954
3955 return rval;
3956}
3064ff39
MH
3957int
3958qla2x00_get_data_rate(scsi_qla_host_t *vha)
3959{
3960 int rval;
3961 mbx_cmd_t mc;
3962 mbx_cmd_t *mcp = &mc;
3963 struct qla_hw_data *ha = vha->hw;
3964
7c3df132
SK
3965 ql_dbg(ql_dbg_mbx, vha, 0x1106, "Entered %s.\n", __func__);
3966
3064ff39
MH
3967 if (!IS_FWI2_CAPABLE(ha))
3968 return QLA_FUNCTION_FAILED;
3969
3064ff39
MH
3970 mcp->mb[0] = MBC_DATA_RATE;
3971 mcp->mb[1] = 0;
3972 mcp->out_mb = MBX_1|MBX_0;
3973 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3974 mcp->tov = MBX_TOV_SECONDS;
3975 mcp->flags = 0;
3976 rval = qla2x00_mailbox_command(vha, mcp);
3977 if (rval != QLA_SUCCESS) {
7c3df132
SK
3978 ql_dbg(ql_dbg_mbx, vha, 0x1107,
3979 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3064ff39 3980 } else {
7c3df132 3981 ql_dbg(ql_dbg_mbx, vha, 0x1108, "Done %s.\n", __func__);
3064ff39
MH
3982 if (mcp->mb[1] != 0x7)
3983 ha->link_data_rate = mcp->mb[1];
3984 }
3985
3986 return rval;
3987}
09ff701a 3988
23f2ebd1
SR
3989int
3990qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
3991{
3992 int rval;
3993 mbx_cmd_t mc;
3994 mbx_cmd_t *mcp = &mc;
3995 struct qla_hw_data *ha = vha->hw;
3996
7c3df132 3997 ql_dbg(ql_dbg_mbx, vha, 0x1109, "Entered %s.\n", __func__);
23f2ebd1
SR
3998
3999 if (!IS_QLA81XX(ha))
4000 return QLA_FUNCTION_FAILED;
4001 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4002 mcp->out_mb = MBX_0;
4003 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4004 mcp->tov = MBX_TOV_SECONDS;
4005 mcp->flags = 0;
4006
4007 rval = qla2x00_mailbox_command(vha, mcp);
4008
4009 if (rval != QLA_SUCCESS) {
7c3df132
SK
4010 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4011 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
23f2ebd1
SR
4012 } else {
4013 /* Copy all bits to preserve original value */
4014 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4015
7c3df132 4016 ql_dbg(ql_dbg_mbx, vha, 0x110b, "Done %s.\n", __func__);
23f2ebd1
SR
4017 }
4018 return rval;
4019}
4020
4021int
4022qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4023{
4024 int rval;
4025 mbx_cmd_t mc;
4026 mbx_cmd_t *mcp = &mc;
4027
7c3df132 4028 ql_dbg(ql_dbg_mbx, vha, 0x110c, "Entered %s.\n", __func__);
23f2ebd1
SR
4029
4030 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4031 /* Copy all bits to preserve original setting */
4032 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4033 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4034 mcp->in_mb = MBX_0;
4035 mcp->tov = MBX_TOV_SECONDS;
4036 mcp->flags = 0;
4037 rval = qla2x00_mailbox_command(vha, mcp);
4038
4039 if (rval != QLA_SUCCESS) {
7c3df132
SK
4040 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4041 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
23f2ebd1 4042 } else
7c3df132 4043 ql_dbg(ql_dbg_mbx, vha, 0x110e, "Done %s.\n", __func__);
23f2ebd1
SR
4044
4045 return rval;
4046}
4047
4048
09ff701a
SR
4049int
4050qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4051 uint16_t *mb)
4052{
4053 int rval;
4054 mbx_cmd_t mc;
4055 mbx_cmd_t *mcp = &mc;
4056 struct qla_hw_data *ha = vha->hw;
4057
7c3df132
SK
4058 ql_dbg(ql_dbg_mbx, vha, 0x110f, "Entered %s.\n", __func__);
4059
09ff701a
SR
4060 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4061 return QLA_FUNCTION_FAILED;
4062
09ff701a
SR
4063 mcp->mb[0] = MBC_PORT_PARAMS;
4064 mcp->mb[1] = loop_id;
4065 if (ha->flags.fcp_prio_enabled)
4066 mcp->mb[2] = BIT_1;
4067 else
4068 mcp->mb[2] = BIT_2;
4069 mcp->mb[4] = priority & 0xf;
4070 mcp->mb[9] = vha->vp_idx;
4071 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4072 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4073 mcp->tov = 30;
4074 mcp->flags = 0;
4075 rval = qla2x00_mailbox_command(vha, mcp);
4076 if (mb != NULL) {
4077 mb[0] = mcp->mb[0];
4078 mb[1] = mcp->mb[1];
4079 mb[3] = mcp->mb[3];
4080 mb[4] = mcp->mb[4];
4081 }
4082
4083 if (rval != QLA_SUCCESS) {
7c3df132 4084 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
09ff701a 4085 } else {
7c3df132 4086 ql_dbg(ql_dbg_mbx, vha, 0x10cc, "Done %s.\n", __func__);
09ff701a
SR
4087 }
4088
4089 return rval;
4090}
a9083016 4091
794a5691
AV
4092int
4093qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac)
4094{
4095 int rval;
6ad11eaa 4096 uint8_t byte;
794a5691
AV
4097 struct qla_hw_data *ha = vha->hw;
4098
7c3df132 4099 ql_dbg(ql_dbg_mbx, vha, 0x10ca, "Entered %s.\n", __func__);
794a5691 4100
6ad11eaa
JC
4101 /* Integer part */
4102 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 1, BIT_13|BIT_0);
794a5691 4103 if (rval != QLA_SUCCESS) {
7c3df132 4104 ql_dbg(ql_dbg_mbx, vha, 0x10c9, "Failed=%x.\n", rval);
794a5691
AV
4105 ha->flags.thermal_supported = 0;
4106 goto fail;
4107 }
6ad11eaa 4108 *temp = byte;
794a5691 4109
6ad11eaa
JC
4110 /* Fraction part */
4111 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x10, 1, BIT_13|BIT_0);
794a5691 4112 if (rval != QLA_SUCCESS) {
7c3df132 4113 ql_dbg(ql_dbg_mbx, vha, 0x1019, "Failed=%x.\n", rval);
794a5691
AV
4114 ha->flags.thermal_supported = 0;
4115 goto fail;
4116 }
6ad11eaa 4117 *frac = (byte >> 6) * 25;
794a5691 4118
7c3df132 4119 ql_dbg(ql_dbg_mbx, vha, 0x1018, "Done %s.\n", __func__);
794a5691
AV
4120fail:
4121 return rval;
4122}
4123
a9083016
GM
4124int
4125qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
4126{
4127 int rval;
4128 struct qla_hw_data *ha = vha->hw;
4129 mbx_cmd_t mc;
4130 mbx_cmd_t *mcp = &mc;
4131
7c3df132
SK
4132 ql_dbg(ql_dbg_mbx, vha, 0x1017, "Entered %s.\n", __func__);
4133
a9083016
GM
4134 if (!IS_FWI2_CAPABLE(ha))
4135 return QLA_FUNCTION_FAILED;
4136
a9083016 4137 memset(mcp, 0, sizeof(mbx_cmd_t));
3711333d 4138 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
a9083016
GM
4139 mcp->mb[1] = 1;
4140
4141 mcp->out_mb = MBX_1|MBX_0;
4142 mcp->in_mb = MBX_0;
4143 mcp->tov = 30;
4144 mcp->flags = 0;
4145
4146 rval = qla2x00_mailbox_command(vha, mcp);
4147 if (rval != QLA_SUCCESS) {
7c3df132
SK
4148 ql_dbg(ql_dbg_mbx, vha, 0x1016,
4149 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
a9083016 4150 } else {
7c3df132 4151 ql_dbg(ql_dbg_mbx, vha, 0x100e, "Done %s.\n", __func__);
a9083016
GM
4152 }
4153
4154 return rval;
4155}
4156
4157int
4158qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4159{
4160 int rval;
4161 struct qla_hw_data *ha = vha->hw;
4162 mbx_cmd_t mc;
4163 mbx_cmd_t *mcp = &mc;
4164
7c3df132
SK
4165 ql_dbg(ql_dbg_mbx, vha, 0x100d, "Entered %s.\n", __func__);
4166
a9083016
GM
4167 if (!IS_QLA82XX(ha))
4168 return QLA_FUNCTION_FAILED;
4169
a9083016 4170 memset(mcp, 0, sizeof(mbx_cmd_t));
3711333d 4171 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
a9083016
GM
4172 mcp->mb[1] = 0;
4173
4174 mcp->out_mb = MBX_1|MBX_0;
4175 mcp->in_mb = MBX_0;
4176 mcp->tov = 30;
4177 mcp->flags = 0;
4178
4179 rval = qla2x00_mailbox_command(vha, mcp);
4180 if (rval != QLA_SUCCESS) {
7c3df132
SK
4181 ql_dbg(ql_dbg_mbx, vha, 0x100c,
4182 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
a9083016 4183 } else {
7c3df132 4184 ql_dbg(ql_dbg_mbx, vha, 0x100b, "Done %s.\n", __func__);
a9083016
GM
4185 }
4186
4187 return rval;
4188}
08de2844
GM
4189
4190int
4191qla82xx_md_get_template_size(scsi_qla_host_t *vha)
4192{
4193 struct qla_hw_data *ha = vha->hw;
4194 mbx_cmd_t mc;
4195 mbx_cmd_t *mcp = &mc;
4196 int rval = QLA_FUNCTION_FAILED;
4197
4198 ql_dbg(ql_dbg_mbx, vha, 0x111f, "Entered %s.\n", __func__);
4199
4200 memset(mcp->mb, 0 , sizeof(mcp->mb));
4201 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4202 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4203 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
4204 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
4205
4206 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4207 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
4208 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4209
4210 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4211 mcp->tov = MBX_TOV_SECONDS;
4212 rval = qla2x00_mailbox_command(vha, mcp);
4213
4214 /* Always copy back return mailbox values. */
4215 if (rval != QLA_SUCCESS) {
4216 ql_dbg(ql_dbg_mbx, vha, 0x1120,
4217 "mailbox command FAILED=0x%x, subcode=%x.\n",
4218 (mcp->mb[1] << 16) | mcp->mb[0],
4219 (mcp->mb[3] << 16) | mcp->mb[2]);
4220 } else {
4221 ql_dbg(ql_dbg_mbx, vha, 0x1121, "Done %s.\n", __func__);
4222 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
4223 if (!ha->md_template_size) {
4224 ql_dbg(ql_dbg_mbx, vha, 0x1122,
4225 "Null template size obtained.\n");
4226 rval = QLA_FUNCTION_FAILED;
4227 }
4228 }
4229 return rval;
4230}
4231
4232int
4233qla82xx_md_get_template(scsi_qla_host_t *vha)
4234{
4235 struct qla_hw_data *ha = vha->hw;
4236 mbx_cmd_t mc;
4237 mbx_cmd_t *mcp = &mc;
4238 int rval = QLA_FUNCTION_FAILED;
4239
4240 ql_dbg(ql_dbg_mbx, vha, 0x1123, "Entered %s.\n", __func__);
4241
4242 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4243 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4244 if (!ha->md_tmplt_hdr) {
4245 ql_log(ql_log_warn, vha, 0x1124,
4246 "Unable to allocate memory for Minidump template.\n");
4247 return rval;
4248 }
4249
4250 memset(mcp->mb, 0 , sizeof(mcp->mb));
4251 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4252 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4253 mcp->mb[2] = LSW(RQST_TMPLT);
4254 mcp->mb[3] = MSW(RQST_TMPLT);
4255 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
4256 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
4257 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
4258 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
4259 mcp->mb[8] = LSW(ha->md_template_size);
4260 mcp->mb[9] = MSW(ha->md_template_size);
4261
4262 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4263 mcp->tov = MBX_TOV_SECONDS;
4264 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4265 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4266 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4267 rval = qla2x00_mailbox_command(vha, mcp);
4268
4269 if (rval != QLA_SUCCESS) {
4270 ql_dbg(ql_dbg_mbx, vha, 0x1125,
4271 "mailbox command FAILED=0x%x, subcode=%x.\n",
4272 ((mcp->mb[1] << 16) | mcp->mb[0]),
4273 ((mcp->mb[3] << 16) | mcp->mb[2]));
4274 } else
4275 ql_dbg(ql_dbg_mbx, vha, 0x1126, "Done %s.\n", __func__);
4276 return rval;
4277}
999916dc
SK
4278
4279int
4280qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
4281{
4282 int rval;
4283 struct qla_hw_data *ha = vha->hw;
4284 mbx_cmd_t mc;
4285 mbx_cmd_t *mcp = &mc;
4286
4287 if (!IS_QLA82XX(ha))
4288 return QLA_FUNCTION_FAILED;
4289
4290 ql_dbg(ql_dbg_mbx, vha, 0x1127,
4291 "Entered %s.\n", __func__);
4292
4293 memset(mcp, 0, sizeof(mbx_cmd_t));
4294 mcp->mb[0] = MBC_SET_LED_CONFIG;
4295 if (enable)
4296 mcp->mb[7] = 0xE;
4297 else
4298 mcp->mb[7] = 0xD;
4299
4300 mcp->out_mb = MBX_7|MBX_0;
4301 mcp->in_mb = MBX_0;
4302 mcp->tov = 30;
4303 mcp->flags = 0;
4304
4305 rval = qla2x00_mailbox_command(vha, mcp);
4306 if (rval != QLA_SUCCESS) {
4307 ql_dbg(ql_dbg_mbx, vha, 0x1128,
4308 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4309 } else {
4310 ql_dbg(ql_dbg_mbx, vha, 0x1129,
4311 "Done %s.\n", __func__);
4312 }
4313
4314 return rval;
4315}