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