blob: 5470177a1ee1a62427224d7b3f64a37149dcc895 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
Andrew Vasquez07e264b2011-03-30 11:46:23 -07003 * Copyright (c) 2003-2011 QLogic Corporation
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
Andrew Vasquezfa90c542005-10-27 11:10:08 -07005 * See LICENSE.qla2xxx for copyright and licensing details.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 */
7#include "qla_def.h"
8
9#include <linux/delay.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090010#include <linux/gfp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070011
Linus Torvalds1da177e2005-04-16 15:20:36 -070012
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
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080033qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070034{
35 int rval;
36 unsigned long flags = 0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070037 device_reg_t __iomem *reg;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070038 uint8_t abort_active;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070039 uint8_t io_lock_on;
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -070040 uint16_t command = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070041 uint16_t *iptr;
42 uint16_t __iomem *optr;
43 uint32_t cnt;
44 uint32_t mboxes;
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 unsigned long wait_time;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080046 struct qla_hw_data *ha = vha->hw;
47 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070048
Saurav Kashyap7c3df132011-07-14 12:00:13 -070049 ql_dbg(ql_dbg_mbx, base_vha, 0x1000, "Entered %s.\n", __func__);
50
51 if (ha->pdev->error_state > pci_channel_io_frozen) {
52 ql_log(ql_log_warn, base_vha, 0x1001,
53 "error_state is greater than pci_channel_io_frozen, "
54 "exiting.\n");
Seokmann Jub9b12f72009-03-24 09:08:18 -070055 return QLA_FUNCTION_TIMEOUT;
Saurav Kashyap7c3df132011-07-14 12:00:13 -070056 }
Seokmann Jub9b12f72009-03-24 09:08:18 -070057
Giridhar Malavalia9083012010-04-12 17:59:55 -070058 if (vha->device_flags & DFLG_DEV_FAILED) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -070059 ql_log(ql_log_warn, base_vha, 0x1002,
60 "Device in failed state, exiting.\n");
Giridhar Malavalia9083012010-04-12 17:59:55 -070061 return QLA_FUNCTION_TIMEOUT;
62 }
63
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070064 reg = ha->iobase;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080065 io_lock_on = base_vha->flags.init_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -070066
67 rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080068 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070070
Andrew Vasquez85880802009-12-15 21:29:46 -080071 if (ha->flags.pci_channel_io_perm_failure) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -070072 ql_log(ql_log_warn, base_vha, 0x1003,
73 "Perm failure on EEH timeout MBX, exiting.\n");
Andrew Vasquez85880802009-12-15 21:29:46 -080074 return QLA_FUNCTION_TIMEOUT;
75 }
76
Giridhar Malavali862cd012011-02-23 15:27:11 -080077 if (ha->flags.isp82xx_fw_hung) {
78 /* Setting Link-Down error */
79 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
Saurav Kashyap7c3df132011-07-14 12:00:13 -070080 ql_log(ql_log_warn, base_vha, 0x1004,
81 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Andrew Vasquez1806fcd2011-11-18 09:02:15 -080082 return QLA_FUNCTION_TIMEOUT;
Giridhar Malavali862cd012011-02-23 15:27:11 -080083 }
84
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070086 * 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.
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080090 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
91 /* Timeout occurred. Return error. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -070092 ql_log(ql_log_warn, base_vha, 0x1005,
93 "Cmd access timeout, Exiting.\n");
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080094 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 }
96
97 ha->flags.mbox_busy = 1;
98 /* Save mailbox command for debug */
99 ha->mcp = mcp;
100
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700101 ql_dbg(ql_dbg_mbx, base_vha, 0x1006,
102 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
104 spin_lock_irqsave(&ha->hardware_lock, flags);
105
106 /* Load mailbox registers. */
Giridhar Malavalia9083012010-04-12 17:59:55 -0700107 if (IS_QLA82XX(ha))
108 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
109 else if (IS_FWI2_CAPABLE(ha) && !IS_QLA82XX(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700110 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
111 else
112 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113
114 iptr = mcp->mb;
115 command = mcp->mb[0];
116 mboxes = mcp->out_mb;
117
118 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
119 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700120 optr =
121 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 if (mboxes & BIT_0)
123 WRT_REG_WORD(optr, *iptr);
124
125 mboxes >>= 1;
126 optr++;
127 iptr++;
128 }
129
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700130 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1111,
131 "Loaded MBX registers (displayed in bytes) =.\n");
132 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1112,
133 (uint8_t *)mcp->mb, 16);
134 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1113,
135 ".\n");
136 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1114,
137 ((uint8_t *)mcp->mb + 0x10), 16);
138 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1115,
139 ".\n");
140 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1116,
141 ((uint8_t *)mcp->mb + 0x20), 8);
142 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1117,
143 "I/O Address = %p.\n", optr);
144 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x100e);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
146 /* Issue set host interrupt command to send cmd out. */
147 ha->flags.mbox_int = 0;
148 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
149
150 /* Unlock mbx registers and wait for interrupt */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700151 ql_dbg(ql_dbg_mbx, base_vha, 0x100f,
152 "Going to unlock irq & waiting for interrupts. "
153 "jiffies=%lx.\n", jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154
155 /* Wait for mbx cmd completion until timeout */
156
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800157 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
159
Giridhar Malavalia9083012010-04-12 17:59:55 -0700160 if (IS_QLA82XX(ha)) {
161 if (RD_REG_DWORD(&reg->isp82.hint) &
162 HINT_MBX_INT_PENDING) {
163 spin_unlock_irqrestore(&ha->hardware_lock,
164 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800165 ha->flags.mbox_busy = 0;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700166 ql_dbg(ql_dbg_mbx, base_vha, 0x1010,
167 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700168 rval = QLA_FUNCTION_TIMEOUT;
169 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700170 }
171 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
172 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700173 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
174 else
175 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176 spin_unlock_irqrestore(&ha->hardware_lock, flags);
177
Marcus Barrow0b05a1f2008-01-17 09:02:13 -0800178 wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
181
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700183 ql_dbg(ql_dbg_mbx, base_vha, 0x1011,
184 "Cmd=%x Polling Mode.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
Giridhar Malavalia9083012010-04-12 17:59:55 -0700186 if (IS_QLA82XX(ha)) {
187 if (RD_REG_DWORD(&reg->isp82.hint) &
188 HINT_MBX_INT_PENDING) {
189 spin_unlock_irqrestore(&ha->hardware_lock,
190 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800191 ha->flags.mbox_busy = 0;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700192 ql_dbg(ql_dbg_mbx, base_vha, 0x1012,
193 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700194 rval = QLA_FUNCTION_TIMEOUT;
195 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700196 }
197 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
198 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700199 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
200 else
201 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
205 while (!ha->flags.mbox_int) {
206 if (time_after(jiffies, wait_time))
207 break;
208
209 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800210 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
Andrew Vasquez85880802009-12-15 21:29:46 -0800212 if (!ha->flags.mbox_int &&
213 !(IS_QLA2200(ha) &&
214 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800215 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 } /* while */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700217 ql_dbg(ql_dbg_mbx, base_vha, 0x1013,
218 "Waited %d sec.\n",
219 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 }
221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 /* Check whether we timed out */
223 if (ha->flags.mbox_int) {
224 uint16_t *iptr2;
225
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700226 ql_dbg(ql_dbg_mbx, base_vha, 0x1014,
227 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
229 /* Got interrupt. Clear the flag. */
230 ha->flags.mbox_int = 0;
231 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
232
Giridhar Malavali71905752011-02-23 15:27:10 -0800233 if (ha->flags.isp82xx_fw_hung) {
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700234 ha->flags.mbox_busy = 0;
235 /* Setting Link-Down error */
236 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
237 ha->mcp = NULL;
238 rval = QLA_FUNCTION_FAILED;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700239 ql_log(ql_log_warn, base_vha, 0x1015,
240 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700241 goto premature_exit;
242 }
243
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400244 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
247 /* Load return mailbox registers. */
248 iptr2 = mcp->mb;
249 iptr = (uint16_t *)&ha->mailbox_out[0];
250 mboxes = mcp->in_mb;
251 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
252 if (mboxes & BIT_0)
253 *iptr2 = *iptr;
254
255 mboxes >>= 1;
256 iptr2++;
257 iptr++;
258 }
259 } else {
260
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700261 uint16_t mb0;
262 uint32_t ictrl;
263
Andrew Vasqueze4289242007-07-19 15:05:56 -0700264 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700265 mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
266 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
267 } else {
Andrew Vasquezcca53352005-08-26 19:08:30 -0700268 mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700269 ictrl = RD_REG_WORD(&reg->isp.ictrl);
270 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700271 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1119,
272 "MBX Command timeout for cmd %x.\n", command);
273 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111a,
274 "iocontrol=%x jiffies=%lx.\n", ictrl, jiffies);
275 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x111b,
276 "mb[0] = 0x%x.\n", mb0);
277 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, base_vha, 0x1019);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 rval = QLA_FUNCTION_TIMEOUT;
280 }
281
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 ha->flags.mbox_busy = 0;
283
284 /* Clean up */
285 ha->mcp = NULL;
286
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800287 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700288 ql_dbg(ql_dbg_mbx, base_vha, 0x101a,
289 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290
291 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800292 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 }
294
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700295 if (rval == QLA_FUNCTION_TIMEOUT &&
296 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800297 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
298 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 /* not in dpc. schedule it for dpc to take over. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700300 ql_dbg(ql_dbg_mbx, base_vha, 0x101b,
301 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700302
303 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
304 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
305 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800306 if (IS_QLA82XX(ha)) {
307 ql_dbg(ql_dbg_mbx, vha, 0x112a,
308 "disabling pause transmit on port "
309 "0 & 1.\n");
310 qla82xx_wr_32(ha,
311 QLA82XX_CRB_NIU + 0x98,
312 CRB_NIU_XG_PAUSE_CTL_P0|
313 CRB_NIU_XG_PAUSE_CTL_P1);
314 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700315 ql_log(ql_log_info, base_vha, 0x101c,
316 "Mailbox cmd timeout occured. "
317 "Scheduling ISP abort eeh_busy=0x%x.\n",
318 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700319 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
320 qla2xxx_wake_dpc(vha);
321 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 /* call abort directly since we are in the DPC thread */
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700324 ql_dbg(ql_dbg_mbx, base_vha, 0x101d,
325 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700327 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
328 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
329 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800330 if (IS_QLA82XX(ha)) {
331 ql_dbg(ql_dbg_mbx, vha, 0x112b,
332 "disabling pause transmit on port "
333 "0 & 1.\n");
334 qla82xx_wr_32(ha,
335 QLA82XX_CRB_NIU + 0x98,
336 CRB_NIU_XG_PAUSE_CTL_P0|
337 CRB_NIU_XG_PAUSE_CTL_P1);
338 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700339 ql_log(ql_log_info, base_vha, 0x101e,
340 "Mailbox cmd timeout occured. "
341 "Scheduling ISP abort.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700342
343 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
344 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
Giridhar Malavalid3360962012-02-09 11:14:10 -0800345 /* Allow next mbx cmd to come in. */
346 complete(&ha->mbx_cmd_comp);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700347 if (ha->isp_ops->abort_isp(vha)) {
348 /* Failed. retry later. */
349 set_bit(ISP_ABORT_NEEDED,
350 &vha->dpc_flags);
351 }
352 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700353 ql_dbg(ql_dbg_mbx, base_vha, 0x101f,
354 "Finished abort_isp.\n");
Giridhar Malavalid3360962012-02-09 11:14:10 -0800355 goto mbx_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 }
358 }
359
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700360premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800362 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363
Giridhar Malavalid3360962012-02-09 11:14:10 -0800364mbx_done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 if (rval) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700366 ql_dbg(ql_dbg_mbx, base_vha, 0x1020,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800367 "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n",
368 mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700370 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 }
372
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 return rval;
374}
375
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800377qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800378 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379{
380 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800381 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 mbx_cmd_t mc;
383 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700385 ql_dbg(ql_dbg_mbx, vha, 0x1022, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
Andrew Vasqueze4289242007-07-19 15:05:56 -0700387 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800388 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
389 mcp->mb[8] = MSW(risc_addr);
390 mcp->out_mb = MBX_8|MBX_0;
391 } else {
392 mcp->mb[0] = MBC_LOAD_RISC_RAM;
393 mcp->out_mb = MBX_0;
394 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 mcp->mb[1] = LSW(risc_addr);
396 mcp->mb[2] = MSW(req_dma);
397 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 mcp->mb[6] = MSW(MSD(req_dma));
399 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800400 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700401 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700402 mcp->mb[4] = MSW(risc_code_size);
403 mcp->mb[5] = LSW(risc_code_size);
404 mcp->out_mb |= MBX_5|MBX_4;
405 } else {
406 mcp->mb[4] = LSW(risc_code_size);
407 mcp->out_mb |= MBX_4;
408 }
409
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700411 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800413 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414
Linus Torvalds1da177e2005-04-16 15:20:36 -0700415 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700416 ql_dbg(ql_dbg_mbx, vha, 0x1023,
417 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700419 ql_dbg(ql_dbg_mbx, vha, 0x1024, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 }
421
422 return rval;
423}
424
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700425#define EXTENDED_BB_CREDITS BIT_0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426/*
427 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700428 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 *
430 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700431 * ha = adapter block pointer.
432 * TARGET_QUEUE_LOCK must be released.
433 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434 *
435 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700436 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 *
438 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700439 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 */
441int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800442qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443{
444 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800445 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 mbx_cmd_t mc;
447 mbx_cmd_t *mcp = &mc;
448
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700449 ql_dbg(ql_dbg_mbx, vha, 0x1025, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450
451 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700452 mcp->out_mb = MBX_0;
453 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700454 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700455 mcp->mb[1] = MSW(risc_addr);
456 mcp->mb[2] = LSW(risc_addr);
457 mcp->mb[3] = 0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800458 if (IS_QLA81XX(ha) || IS_QLA83XX(ha)) {
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700459 struct nvram_81xx *nv = ha->nvram;
460 mcp->mb[4] = (nv->enhanced_features &
461 EXTENDED_BB_CREDITS);
462 } else
463 mcp->mb[4] = 0;
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700464 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700465 mcp->in_mb |= MBX_1;
466 } else {
467 mcp->mb[1] = LSW(risc_addr);
468 mcp->out_mb |= MBX_1;
469 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
470 mcp->mb[2] = 0;
471 mcp->out_mb |= MBX_2;
472 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 }
474
Ravi Anandb93480e2008-04-03 13:13:25 -0700475 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800477 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700479 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700480 ql_dbg(ql_dbg_mbx, vha, 0x1026,
481 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700482 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700483 if (IS_FWI2_CAPABLE(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700484 ql_dbg(ql_dbg_mbx, vha, 0x1027,
485 "Done exchanges=%x.\n", mcp->mb[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700486 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700487 ql_dbg(ql_dbg_mbx, vha, 0x1028, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700488 }
489 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490
491 return rval;
492}
493
494/*
495 * qla2x00_get_fw_version
496 * Get firmware version.
497 *
498 * Input:
499 * ha: adapter state pointer.
500 * major: pointer for major number.
501 * minor: pointer for minor number.
502 * subminor: pointer for subminor number.
503 *
504 * Returns:
505 * qla2x00 local function return status code.
506 *
507 * Context:
508 * Kernel context.
509 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700510int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800511qla2x00_get_fw_version(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512{
513 int rval;
514 mbx_cmd_t mc;
515 mbx_cmd_t *mcp = &mc;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800516 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700518 ql_dbg(ql_dbg_mbx, vha, 0x1029, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
520 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
521 mcp->out_mb = MBX_0;
522 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800523 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha))
Andrew Vasquez55a96152009-03-24 09:08:03 -0700524 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800525 if (IS_QLA83XX(vha->hw))
526 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700528 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800529 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700530 if (rval != QLA_SUCCESS)
531 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532
533 /* Return mailbox data. */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800534 ha->fw_major_version = mcp->mb[1];
535 ha->fw_minor_version = mcp->mb[2];
536 ha->fw_subminor_version = mcp->mb[3];
537 ha->fw_attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800538 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800539 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 else
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800541 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
542 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw)) {
543 ha->mpi_version[0] = mcp->mb[10] & 0xff;
544 ha->mpi_version[1] = mcp->mb[11] >> 8;
545 ha->mpi_version[2] = mcp->mb[11] & 0xff;
546 ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
547 ha->phy_version[0] = mcp->mb[8] & 0xff;
548 ha->phy_version[1] = mcp->mb[9] >> 8;
549 ha->phy_version[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800550 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800551 if (IS_QLA83XX(ha)) {
552 if (mcp->mb[6] & BIT_15) {
553 ha->fw_attributes_h = mcp->mb[15];
554 ha->fw_attributes_ext[0] = mcp->mb[16];
555 ha->fw_attributes_ext[1] = mcp->mb[17];
556 ql_dbg(ql_dbg_mbx, vha, 0x1139,
557 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
558 __func__, mcp->mb[15], mcp->mb[6]);
559 } else
560 ql_dbg(ql_dbg_mbx, vha, 0x112f,
561 "%s: FwAttributes [Upper] invalid, MB6:%04x\n",
562 __func__, mcp->mb[6]);
563 }
564
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700565failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 if (rval != QLA_SUCCESS) {
567 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700568 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 } else {
570 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700571 ql_dbg(ql_dbg_mbx, vha, 0x102b, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700573 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574}
575
576/*
577 * qla2x00_get_fw_options
578 * Set firmware options.
579 *
580 * Input:
581 * ha = adapter block pointer.
582 * fwopt = pointer for firmware options.
583 *
584 * Returns:
585 * qla2x00 local function return status code.
586 *
587 * Context:
588 * Kernel context.
589 */
590int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800591qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592{
593 int rval;
594 mbx_cmd_t mc;
595 mbx_cmd_t *mcp = &mc;
596
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700597 ql_dbg(ql_dbg_mbx, vha, 0x102c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598
599 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
600 mcp->out_mb = MBX_0;
601 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700602 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800604 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605
606 if (rval != QLA_SUCCESS) {
607 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700608 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700610 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611 fwopts[1] = mcp->mb[1];
612 fwopts[2] = mcp->mb[2];
613 fwopts[3] = mcp->mb[3];
614
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700615 ql_dbg(ql_dbg_mbx, vha, 0x102e, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 }
617
618 return rval;
619}
620
621
622/*
623 * qla2x00_set_fw_options
624 * Set firmware options.
625 *
626 * Input:
627 * ha = adapter block pointer.
628 * fwopt = pointer for firmware options.
629 *
630 * Returns:
631 * qla2x00 local function return status code.
632 *
633 * Context:
634 * Kernel context.
635 */
636int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800637qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638{
639 int rval;
640 mbx_cmd_t mc;
641 mbx_cmd_t *mcp = &mc;
642
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700643 ql_dbg(ql_dbg_mbx, vha, 0x102f, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644
645 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
646 mcp->mb[1] = fwopts[1];
647 mcp->mb[2] = fwopts[2];
648 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700649 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800651 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700652 mcp->in_mb |= MBX_1;
653 } else {
654 mcp->mb[10] = fwopts[10];
655 mcp->mb[11] = fwopts[11];
656 mcp->mb[12] = 0; /* Undocumented, but used */
657 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
658 }
Ravi Anandb93480e2008-04-03 13:13:25 -0700659 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800661 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700663 fwopts[0] = mcp->mb[0];
664
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 if (rval != QLA_SUCCESS) {
666 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700667 ql_dbg(ql_dbg_mbx, vha, 0x1030,
668 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 } else {
670 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700671 ql_dbg(ql_dbg_mbx, vha, 0x1031, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 }
673
674 return rval;
675}
676
677/*
678 * qla2x00_mbx_reg_test
679 * Mailbox register wrap test.
680 *
681 * Input:
682 * ha = adapter block pointer.
683 * TARGET_QUEUE_LOCK must be released.
684 * ADAPTER_STATE_LOCK must be released.
685 *
686 * Returns:
687 * qla2x00 local function return status code.
688 *
689 * Context:
690 * Kernel context.
691 */
692int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800693qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694{
695 int rval;
696 mbx_cmd_t mc;
697 mbx_cmd_t *mcp = &mc;
698
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700699 ql_dbg(ql_dbg_mbx, vha, 0x1032, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700
701 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
702 mcp->mb[1] = 0xAAAA;
703 mcp->mb[2] = 0x5555;
704 mcp->mb[3] = 0xAA55;
705 mcp->mb[4] = 0x55AA;
706 mcp->mb[5] = 0xA5A5;
707 mcp->mb[6] = 0x5A5A;
708 mcp->mb[7] = 0x2525;
709 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
710 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700711 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800713 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714
715 if (rval == QLA_SUCCESS) {
716 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
717 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
718 rval = QLA_FUNCTION_FAILED;
719 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
720 mcp->mb[7] != 0x2525)
721 rval = QLA_FUNCTION_FAILED;
722 }
723
724 if (rval != QLA_SUCCESS) {
725 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700726 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700727 } else {
728 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700729 ql_dbg(ql_dbg_mbx, vha, 0x1034, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 }
731
732 return rval;
733}
734
735/*
736 * qla2x00_verify_checksum
737 * Verify firmware checksum.
738 *
739 * Input:
740 * ha = adapter block pointer.
741 * TARGET_QUEUE_LOCK must be released.
742 * ADAPTER_STATE_LOCK must be released.
743 *
744 * Returns:
745 * qla2x00 local function return status code.
746 *
747 * Context:
748 * Kernel context.
749 */
750int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800751qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752{
753 int rval;
754 mbx_cmd_t mc;
755 mbx_cmd_t *mcp = &mc;
756
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700757 ql_dbg(ql_dbg_mbx, vha, 0x1035, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758
759 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700760 mcp->out_mb = MBX_0;
761 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800762 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700763 mcp->mb[1] = MSW(risc_addr);
764 mcp->mb[2] = LSW(risc_addr);
765 mcp->out_mb |= MBX_2|MBX_1;
766 mcp->in_mb |= MBX_2|MBX_1;
767 } else {
768 mcp->mb[1] = LSW(risc_addr);
769 mcp->out_mb |= MBX_1;
770 mcp->in_mb |= MBX_1;
771 }
772
Ravi Anandb93480e2008-04-03 13:13:25 -0700773 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700774 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800775 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776
777 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700778 ql_dbg(ql_dbg_mbx, vha, 0x1036,
779 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
780 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700782 ql_dbg(ql_dbg_mbx, vha, 0x1037, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 }
784
785 return rval;
786}
787
788/*
789 * qla2x00_issue_iocb
790 * Issue IOCB using mailbox command
791 *
792 * Input:
793 * ha = adapter state pointer.
794 * buffer = buffer pointer.
795 * phys_addr = physical address of buffer.
796 * size = size of buffer.
797 * TARGET_QUEUE_LOCK must be released.
798 * ADAPTER_STATE_LOCK must be released.
799 *
800 * Returns:
801 * qla2x00 local function return status code.
802 *
803 * Context:
804 * Kernel context.
805 */
Giridhar Malavali6e980162010-03-19 17:03:58 -0700806int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800807qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700808 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809{
810 int rval;
811 mbx_cmd_t mc;
812 mbx_cmd_t *mcp = &mc;
813
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700814 ql_dbg(ql_dbg_mbx, vha, 0x1038, "Entered %s.\n", __func__);
815
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
817 mcp->mb[1] = 0;
818 mcp->mb[2] = MSW(phys_addr);
819 mcp->mb[3] = LSW(phys_addr);
820 mcp->mb[6] = MSW(MSD(phys_addr));
821 mcp->mb[7] = LSW(MSD(phys_addr));
822 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
823 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700824 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800826 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
828 if (rval != QLA_SUCCESS) {
829 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700830 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700832 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
833
834 /* Mask reserved bits. */
835 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800836 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700837 ql_dbg(ql_dbg_mbx, vha, 0x103a, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838 }
839
840 return rval;
841}
842
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700843int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800844qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700845 size_t size)
846{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800847 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700848 MBX_TOV_SECONDS);
849}
850
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851/*
852 * qla2x00_abort_command
853 * Abort command aborts a specified IOCB.
854 *
855 * Input:
856 * ha = adapter block pointer.
857 * sp = SB structure pointer.
858 *
859 * Returns:
860 * qla2x00 local function return status code.
861 *
862 * Context:
863 * Kernel context.
864 */
865int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700866qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867{
868 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800870 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 mbx_cmd_t mc;
872 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700873 fc_port_t *fcport = sp->fcport;
874 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800875 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700876 struct req_que *req = vha->req;
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800877 struct scsi_cmnd *cmd = GET_CMD_SP(sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700879 ql_dbg(ql_dbg_mbx, vha, 0x103b, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700881 spin_lock_irqsave(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800883 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 break;
885 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700886 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887
888 if (handle == MAX_OUTSTANDING_COMMANDS) {
889 /* command not found */
890 return QLA_FUNCTION_FAILED;
891 }
892
893 mcp->mb[0] = MBC_ABORT_COMMAND;
894 if (HAS_EXTENDED_IDS(ha))
895 mcp->mb[1] = fcport->loop_id;
896 else
897 mcp->mb[1] = fcport->loop_id << 8;
898 mcp->mb[2] = (uint16_t)handle;
899 mcp->mb[3] = (uint16_t)(handle >> 16);
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800900 mcp->mb[6] = (uint16_t)cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
902 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700903 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800905 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906
907 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700908 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700910 ql_dbg(ql_dbg_mbx, vha, 0x103d, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 }
912
913 return rval;
914}
915
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700917qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918{
Andrew Vasquez523ec772008-04-03 13:13:24 -0700919 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 mbx_cmd_t mc;
921 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800922 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800923 struct req_que *req;
924 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925
Andrew Vasquez523ec772008-04-03 13:13:24 -0700926 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800927 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700928
929 ql_dbg(ql_dbg_mbx, vha, 0x103e, "Entered %s.\n", __func__);
930
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700931 req = vha->hw->req_q_map[0];
932 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700934 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800935 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 mcp->mb[1] = fcport->loop_id;
937 mcp->mb[10] = 0;
938 mcp->out_mb |= MBX_10;
939 } else {
940 mcp->mb[1] = fcport->loop_id << 8;
941 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800942 mcp->mb[2] = vha->hw->loop_reset_delay;
943 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944
945 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700946 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800948 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700950 ql_dbg(ql_dbg_mbx, vha, 0x103f, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700951 }
952
953 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800954 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
955 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700956 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700957 ql_dbg(ql_dbg_mbx, vha, 0x1040,
958 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700959 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700960 ql_dbg(ql_dbg_mbx, vha, 0x1041, "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700961 }
962
963 return rval;
964}
965
966int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700967qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -0700968{
969 int rval, rval2;
970 mbx_cmd_t mc;
971 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800972 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800973 struct req_que *req;
974 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700975
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800976 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700977
978 ql_dbg(ql_dbg_mbx, vha, 0x1042, "Entered %s.\n", __func__);
979
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700980 req = vha->hw->req_q_map[0];
981 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700982 mcp->mb[0] = MBC_LUN_RESET;
983 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800984 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -0700985 mcp->mb[1] = fcport->loop_id;
986 else
987 mcp->mb[1] = fcport->loop_id << 8;
988 mcp->mb[2] = l;
989 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800990 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700991
992 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700993 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700994 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800995 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700996 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700997 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700998 }
999
1000 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001001 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1002 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001003 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001004 ql_dbg(ql_dbg_mbx, vha, 0x1044,
1005 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001006 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001007 ql_dbg(ql_dbg_mbx, vha, 0x1045, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 }
1009
1010 return rval;
1011}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012
1013/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014 * qla2x00_get_adapter_id
1015 * Get adapter ID and topology.
1016 *
1017 * Input:
1018 * ha = adapter block pointer.
1019 * id = pointer for loop ID.
1020 * al_pa = pointer for AL_PA.
1021 * area = pointer for area.
1022 * domain = pointer for domain.
1023 * top = pointer for topology.
1024 * TARGET_QUEUE_LOCK must be released.
1025 * ADAPTER_STATE_LOCK must be released.
1026 *
1027 * Returns:
1028 * qla2x00 local function return status code.
1029 *
1030 * Context:
1031 * Kernel context.
1032 */
1033int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001034qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001035 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036{
1037 int rval;
1038 mbx_cmd_t mc;
1039 mbx_cmd_t *mcp = &mc;
1040
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001041 ql_dbg(ql_dbg_mbx, vha, 0x1046, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
1043 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001044 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001045 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001046 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001047 if (IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001048 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Ravi Anandb93480e2008-04-03 13:13:25 -07001049 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001051 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001052 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1053 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001054 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1055 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056
1057 /* Return data. */
1058 *id = mcp->mb[1];
1059 *al_pa = LSB(mcp->mb[2]);
1060 *area = MSB(mcp->mb[2]);
1061 *domain = LSB(mcp->mb[3]);
1062 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001063 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064
1065 if (rval != QLA_SUCCESS) {
1066 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001067 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001069 ql_dbg(ql_dbg_mbx, vha, 0x1048, "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001070
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001071 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001072 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1073 vha->fcoe_fcf_idx = mcp->mb[10];
1074 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1075 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1076 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1077 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1078 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1079 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1080 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 }
1082
1083 return rval;
1084}
1085
1086/*
1087 * qla2x00_get_retry_cnt
1088 * Get current firmware login retry count and delay.
1089 *
1090 * Input:
1091 * ha = adapter block pointer.
1092 * retry_cnt = pointer to login retry count.
1093 * tov = pointer to login timeout value.
1094 *
1095 * Returns:
1096 * qla2x00 local function return status code.
1097 *
1098 * Context:
1099 * Kernel context.
1100 */
1101int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001102qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 uint16_t *r_a_tov)
1104{
1105 int rval;
1106 uint16_t ratov;
1107 mbx_cmd_t mc;
1108 mbx_cmd_t *mcp = &mc;
1109
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001110 ql_dbg(ql_dbg_mbx, vha, 0x1049, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111
1112 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1113 mcp->out_mb = MBX_0;
1114 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001115 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001117 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118
1119 if (rval != QLA_SUCCESS) {
1120 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001121 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1122 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 } else {
1124 /* Convert returned data and check our values. */
1125 *r_a_tov = mcp->mb[3] / 2;
1126 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1127 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1128 /* Update to the larger values */
1129 *retry_cnt = (uint8_t)mcp->mb[1];
1130 *tov = ratov;
1131 }
1132
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001133 ql_dbg(ql_dbg_mbx, vha, 0x104b,
1134 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135 }
1136
1137 return rval;
1138}
1139
1140/*
1141 * qla2x00_init_firmware
1142 * Initialize adapter firmware.
1143 *
1144 * Input:
1145 * ha = adapter block pointer.
1146 * dptr = Initialization control block pointer.
1147 * size = size of initialization control block.
1148 * TARGET_QUEUE_LOCK must be released.
1149 * ADAPTER_STATE_LOCK must be released.
1150 *
1151 * Returns:
1152 * qla2x00 local function return status code.
1153 *
1154 * Context:
1155 * Kernel context.
1156 */
1157int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001158qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159{
1160 int rval;
1161 mbx_cmd_t mc;
1162 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001163 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001165 ql_dbg(ql_dbg_mbx, vha, 0x104c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166
Giridhar Malavalia9083012010-04-12 17:59:55 -07001167 if (IS_QLA82XX(ha) && ql2xdbwr)
1168 qla82xx_wr_32(ha, ha->nxdb_wr_ptr,
1169 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1170
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001171 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001172 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1173 else
1174 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1175
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001176 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 mcp->mb[2] = MSW(ha->init_cb_dma);
1178 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1180 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001181 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001182 if ((IS_QLA81XX(ha) || IS_QLA83XX(ha)) && ha->ex_init_cb->ex_version) {
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001183 mcp->mb[1] = BIT_0;
1184 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1185 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1186 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1187 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1188 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1189 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1190 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001191 /* 1 and 2 should normally be captured. */
1192 mcp->in_mb = MBX_2|MBX_1|MBX_0;
1193 if (IS_QLA83XX(ha))
1194 /* mb3 is additional info about the installed SFP. */
1195 mcp->in_mb |= MBX_3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 mcp->buf_size = size;
1197 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001198 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001199 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200
1201 if (rval != QLA_SUCCESS) {
1202 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001203 ql_dbg(ql_dbg_mbx, vha, 0x104d,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001204 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1205 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 } else {
1207 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001208 ql_dbg(ql_dbg_mbx, vha, 0x104e, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 }
1210
1211 return rval;
1212}
1213
1214/*
1215 * qla2x00_get_port_database
1216 * Issue normal/enhanced get port database mailbox command
1217 * and copy device name as necessary.
1218 *
1219 * Input:
1220 * ha = adapter state pointer.
1221 * dev = structure pointer.
1222 * opt = enhanced cmd option byte.
1223 *
1224 * Returns:
1225 * qla2x00 local function return status code.
1226 *
1227 * Context:
1228 * Kernel context.
1229 */
1230int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001231qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232{
1233 int rval;
1234 mbx_cmd_t mc;
1235 mbx_cmd_t *mcp = &mc;
1236 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001237 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001239 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001241 ql_dbg(ql_dbg_mbx, vha, 0x104f, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001243 pd24 = NULL;
1244 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001246 ql_log(ql_log_warn, vha, 0x1050,
1247 "Failed to allocate port database structure.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 return QLA_MEMORY_ALLOC_FAILED;
1249 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001250 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001252 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001253 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255 mcp->mb[2] = MSW(pd_dma);
1256 mcp->mb[3] = LSW(pd_dma);
1257 mcp->mb[6] = MSW(MSD(pd_dma));
1258 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001259 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001260 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001262 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001263 mcp->mb[1] = fcport->loop_id;
1264 mcp->mb[10] = opt;
1265 mcp->out_mb |= MBX_10|MBX_1;
1266 mcp->in_mb |= MBX_1;
1267 } else if (HAS_EXTENDED_IDS(ha)) {
1268 mcp->mb[1] = fcport->loop_id;
1269 mcp->mb[10] = opt;
1270 mcp->out_mb |= MBX_10|MBX_1;
1271 } else {
1272 mcp->mb[1] = fcport->loop_id << 8 | opt;
1273 mcp->out_mb |= MBX_1;
1274 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001275 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1276 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277 mcp->flags = MBX_DMA_IN;
1278 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001279 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280 if (rval != QLA_SUCCESS)
1281 goto gpd_error_out;
1282
Andrew Vasqueze4289242007-07-19 15:05:56 -07001283 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001284 pd24 = (struct port_database_24xx *) pd;
1285
1286 /* Check for logged in state. */
1287 if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1288 pd24->last_login_state != PDS_PRLI_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001289 ql_dbg(ql_dbg_mbx, vha, 0x1051,
1290 "Unable to verify login-state (%x/%x) for "
1291 "loop_id %x.\n", pd24->current_login_state,
1292 pd24->last_login_state, fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001293 rval = QLA_FUNCTION_FAILED;
1294 goto gpd_error_out;
1295 }
1296
1297 /* Names are little-endian. */
1298 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1299 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1300
1301 /* Get port_id of device. */
1302 fcport->d_id.b.domain = pd24->port_id[0];
1303 fcport->d_id.b.area = pd24->port_id[1];
1304 fcport->d_id.b.al_pa = pd24->port_id[2];
1305 fcport->d_id.b.rsvd_1 = 0;
1306
1307 /* If not target must be initiator or unknown type. */
1308 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1309 fcport->port_type = FCT_INITIATOR;
1310 else
1311 fcport->port_type = FCT_TARGET;
1312 } else {
1313 /* Check for logged in state. */
1314 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1315 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001316 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1317 "Unable to verify login-state (%x/%x) - "
1318 "portid=%02x%02x%02x.\n", pd->master_state,
1319 pd->slave_state, fcport->d_id.b.domain,
1320 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001321 rval = QLA_FUNCTION_FAILED;
1322 goto gpd_error_out;
1323 }
1324
1325 /* Names are little-endian. */
1326 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1327 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1328
1329 /* Get port_id of device. */
1330 fcport->d_id.b.domain = pd->port_id[0];
1331 fcport->d_id.b.area = pd->port_id[3];
1332 fcport->d_id.b.al_pa = pd->port_id[2];
1333 fcport->d_id.b.rsvd_1 = 0;
1334
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001335 /* If not target must be initiator or unknown type. */
1336 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1337 fcport->port_type = FCT_INITIATOR;
1338 else
1339 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001340
1341 /* Passback COS information. */
1342 fcport->supported_classes = (pd->options & BIT_4) ?
1343 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 }
1345
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346gpd_error_out:
1347 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1348
1349 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001350 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1351 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1352 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001354 ql_dbg(ql_dbg_mbx, vha, 0x1053, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 }
1356
1357 return rval;
1358}
1359
1360/*
1361 * qla2x00_get_firmware_state
1362 * Get adapter firmware state.
1363 *
1364 * Input:
1365 * ha = adapter block pointer.
1366 * dptr = pointer for firmware state.
1367 * TARGET_QUEUE_LOCK must be released.
1368 * ADAPTER_STATE_LOCK must be released.
1369 *
1370 * Returns:
1371 * qla2x00 local function return status code.
1372 *
1373 * Context:
1374 * Kernel context.
1375 */
1376int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001377qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378{
1379 int rval;
1380 mbx_cmd_t mc;
1381 mbx_cmd_t *mcp = &mc;
1382
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001383 ql_dbg(ql_dbg_mbx, vha, 0x1054, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384
1385 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1386 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001387 if (IS_FWI2_CAPABLE(vha->hw))
1388 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1389 else
1390 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001391 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001393 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001395 /* Return firmware states. */
1396 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001397 if (IS_FWI2_CAPABLE(vha->hw)) {
1398 states[1] = mcp->mb[2];
1399 states[2] = mcp->mb[3];
1400 states[3] = mcp->mb[4];
1401 states[4] = mcp->mb[5];
1402 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403
1404 if (rval != QLA_SUCCESS) {
1405 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001406 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 } else {
1408 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001409 ql_dbg(ql_dbg_mbx, vha, 0x1056, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 }
1411
1412 return rval;
1413}
1414
1415/*
1416 * qla2x00_get_port_name
1417 * Issue get port name mailbox command.
1418 * Returned name is in big endian format.
1419 *
1420 * Input:
1421 * ha = adapter block pointer.
1422 * loop_id = loop ID of device.
1423 * name = pointer for name.
1424 * TARGET_QUEUE_LOCK must be released.
1425 * ADAPTER_STATE_LOCK must be released.
1426 *
1427 * Returns:
1428 * qla2x00 local function return status code.
1429 *
1430 * Context:
1431 * Kernel context.
1432 */
1433int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001434qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 uint8_t opt)
1436{
1437 int rval;
1438 mbx_cmd_t mc;
1439 mbx_cmd_t *mcp = &mc;
1440
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001441 ql_dbg(ql_dbg_mbx, vha, 0x1057, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
1443 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001444 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001445 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001446 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447 mcp->mb[1] = loop_id;
1448 mcp->mb[10] = opt;
1449 mcp->out_mb |= MBX_10;
1450 } else {
1451 mcp->mb[1] = loop_id << 8 | opt;
1452 }
1453
1454 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001455 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001457 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458
1459 if (rval != QLA_SUCCESS) {
1460 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001461 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 } else {
1463 if (name != NULL) {
1464 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05001465 name[0] = MSB(mcp->mb[2]);
1466 name[1] = LSB(mcp->mb[2]);
1467 name[2] = MSB(mcp->mb[3]);
1468 name[3] = LSB(mcp->mb[3]);
1469 name[4] = MSB(mcp->mb[6]);
1470 name[5] = LSB(mcp->mb[6]);
1471 name[6] = MSB(mcp->mb[7]);
1472 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 }
1474
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001475 ql_dbg(ql_dbg_mbx, vha, 0x1059, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 }
1477
1478 return rval;
1479}
1480
1481/*
1482 * qla2x00_lip_reset
1483 * Issue LIP reset mailbox command.
1484 *
1485 * Input:
1486 * ha = adapter block pointer.
1487 * TARGET_QUEUE_LOCK must be released.
1488 * ADAPTER_STATE_LOCK must be released.
1489 *
1490 * Returns:
1491 * qla2x00 local function return status code.
1492 *
1493 * Context:
1494 * Kernel context.
1495 */
1496int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001497qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498{
1499 int rval;
1500 mbx_cmd_t mc;
1501 mbx_cmd_t *mcp = &mc;
1502
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001503 ql_dbg(ql_dbg_mbx, vha, 0x105a, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001505 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001506 /* Logout across all FCFs. */
1507 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1508 mcp->mb[1] = BIT_1;
1509 mcp->mb[2] = 0;
1510 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1511 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001512 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001513 mcp->mb[1] = BIT_6;
1514 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001515 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001516 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001518 mcp->mb[0] = MBC_LIP_RESET;
1519 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001520 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001521 mcp->mb[1] = 0x00ff;
1522 mcp->mb[10] = 0;
1523 mcp->out_mb |= MBX_10;
1524 } else {
1525 mcp->mb[1] = 0xff00;
1526 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001527 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001528 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001531 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001533 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534
1535 if (rval != QLA_SUCCESS) {
1536 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001537 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 } else {
1539 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001540 ql_dbg(ql_dbg_mbx, vha, 0x105c, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 }
1542
1543 return rval;
1544}
1545
1546/*
1547 * qla2x00_send_sns
1548 * Send SNS command.
1549 *
1550 * Input:
1551 * ha = adapter block pointer.
1552 * sns = pointer for command.
1553 * cmd_size = command size.
1554 * buf_size = response/command size.
1555 * TARGET_QUEUE_LOCK must be released.
1556 * ADAPTER_STATE_LOCK must be released.
1557 *
1558 * Returns:
1559 * qla2x00 local function return status code.
1560 *
1561 * Context:
1562 * Kernel context.
1563 */
1564int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001565qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 uint16_t cmd_size, size_t buf_size)
1567{
1568 int rval;
1569 mbx_cmd_t mc;
1570 mbx_cmd_t *mcp = &mc;
1571
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001572 ql_dbg(ql_dbg_mbx, vha, 0x105d, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001574 ql_dbg(ql_dbg_mbx, vha, 0x105e,
1575 "Retry cnt=%d ratov=%d total tov=%d.\n",
1576 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
1578 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1579 mcp->mb[1] = cmd_size;
1580 mcp->mb[2] = MSW(sns_phys_address);
1581 mcp->mb[3] = LSW(sns_phys_address);
1582 mcp->mb[6] = MSW(MSD(sns_phys_address));
1583 mcp->mb[7] = LSW(MSD(sns_phys_address));
1584 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1585 mcp->in_mb = MBX_0|MBX_1;
1586 mcp->buf_size = buf_size;
1587 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001588 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1589 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590
1591 if (rval != QLA_SUCCESS) {
1592 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001593 ql_dbg(ql_dbg_mbx, vha, 0x105f,
1594 "Failed=%x mb[0]=%x mb[1]=%x.\n",
1595 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 } else {
1597 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001598 ql_dbg(ql_dbg_mbx, vha, 0x1060, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599 }
1600
1601 return rval;
1602}
1603
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001604int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001605qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001606 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1607{
1608 int rval;
1609
1610 struct logio_entry_24xx *lg;
1611 dma_addr_t lg_dma;
1612 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001613 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001614 struct req_que *req;
1615 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001616
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001617 ql_dbg(ql_dbg_mbx, vha, 0x1061, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001618
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07001619 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07001620 req = ha->req_q_map[0];
1621 else
1622 req = vha->req;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001623 rsp = req->rsp;
1624
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001625 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1626 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001627 ql_log(ql_log_warn, vha, 0x1062,
1628 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001629 return QLA_MEMORY_ALLOC_FAILED;
1630 }
1631 memset(lg, 0, sizeof(struct logio_entry_24xx));
1632
1633 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1634 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001635 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001636 lg->nport_handle = cpu_to_le16(loop_id);
1637 lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
1638 if (opt & BIT_0)
1639 lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07001640 if (opt & BIT_1)
1641 lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001642 lg->port_id[0] = al_pa;
1643 lg->port_id[1] = area;
1644 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001645 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08001646 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
1647 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001648 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001649 ql_dbg(ql_dbg_mbx, vha, 0x1063,
1650 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001651 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001652 ql_dbg(ql_dbg_mbx, vha, 0x1064,
1653 "Failed to complete IOCB -- error status (%x).\n",
1654 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001655 rval = QLA_FUNCTION_FAILED;
1656 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1657 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1658 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1659
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001660 ql_dbg(ql_dbg_mbx, vha, 0x1065,
1661 "Failed to complete IOCB -- completion status (%x) "
1662 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
1663 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001664
1665 switch (iop[0]) {
1666 case LSC_SCODE_PORTID_USED:
1667 mb[0] = MBS_PORT_ID_USED;
1668 mb[1] = LSW(iop[1]);
1669 break;
1670 case LSC_SCODE_NPORT_USED:
1671 mb[0] = MBS_LOOP_ID_USED;
1672 break;
1673 case LSC_SCODE_NOLINK:
1674 case LSC_SCODE_NOIOCB:
1675 case LSC_SCODE_NOXCB:
1676 case LSC_SCODE_CMD_FAILED:
1677 case LSC_SCODE_NOFABRIC:
1678 case LSC_SCODE_FW_NOT_READY:
1679 case LSC_SCODE_NOT_LOGGED_IN:
1680 case LSC_SCODE_NOPCB:
1681 case LSC_SCODE_ELS_REJECT:
1682 case LSC_SCODE_CMD_PARAM_ERR:
1683 case LSC_SCODE_NONPORT:
1684 case LSC_SCODE_LOGGED_IN:
1685 case LSC_SCODE_NOFLOGI_ACC:
1686 default:
1687 mb[0] = MBS_COMMAND_ERROR;
1688 break;
1689 }
1690 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001691 ql_dbg(ql_dbg_mbx, vha, 0x1066, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001692
1693 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1694
1695 mb[0] = MBS_COMMAND_COMPLETE;
1696 mb[1] = 0;
1697 if (iop[0] & BIT_4) {
1698 if (iop[0] & BIT_8)
1699 mb[1] |= BIT_1;
1700 } else
1701 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001702
1703 /* Passback COS information. */
1704 mb[10] = 0;
1705 if (lg->io_parameter[7] || lg->io_parameter[8])
1706 mb[10] |= BIT_0; /* Class 2. */
1707 if (lg->io_parameter[9] || lg->io_parameter[10])
1708 mb[10] |= BIT_1; /* Class 3. */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001709 }
1710
1711 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1712
1713 return rval;
1714}
1715
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716/*
1717 * qla2x00_login_fabric
1718 * Issue login fabric port mailbox command.
1719 *
1720 * Input:
1721 * ha = adapter block pointer.
1722 * loop_id = device loop ID.
1723 * domain = device domain.
1724 * area = device area.
1725 * al_pa = device AL_PA.
1726 * status = pointer for return status.
1727 * opt = command options.
1728 * TARGET_QUEUE_LOCK must be released.
1729 * ADAPTER_STATE_LOCK must be released.
1730 *
1731 * Returns:
1732 * qla2x00 local function return status code.
1733 *
1734 * Context:
1735 * Kernel context.
1736 */
1737int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001738qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1740{
1741 int rval;
1742 mbx_cmd_t mc;
1743 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001744 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001746 ql_dbg(ql_dbg_mbx, vha, 0x1067, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747
1748 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1749 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1750 if (HAS_EXTENDED_IDS(ha)) {
1751 mcp->mb[1] = loop_id;
1752 mcp->mb[10] = opt;
1753 mcp->out_mb |= MBX_10;
1754 } else {
1755 mcp->mb[1] = (loop_id << 8) | opt;
1756 }
1757 mcp->mb[2] = domain;
1758 mcp->mb[3] = area << 8 | al_pa;
1759
1760 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1761 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1762 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001763 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764
1765 /* Return mailbox statuses. */
1766 if (mb != NULL) {
1767 mb[0] = mcp->mb[0];
1768 mb[1] = mcp->mb[1];
1769 mb[2] = mcp->mb[2];
1770 mb[6] = mcp->mb[6];
1771 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001772 /* COS retrieved from Get-Port-Database mailbox command. */
1773 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 }
1775
1776 if (rval != QLA_SUCCESS) {
1777 /* RLU tmp code: need to change main mailbox_command function to
1778 * return ok even when the mailbox completion value is not
1779 * SUCCESS. The caller needs to be responsible to interpret
1780 * the return values of this mailbox command if we're not
1781 * to change too much of the existing code.
1782 */
1783 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
1784 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
1785 mcp->mb[0] == 0x4006)
1786 rval = QLA_SUCCESS;
1787
1788 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001789 ql_dbg(ql_dbg_mbx, vha, 0x1068,
1790 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
1791 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 } else {
1793 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001794 ql_dbg(ql_dbg_mbx, vha, 0x1069, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795 }
1796
1797 return rval;
1798}
1799
1800/*
1801 * qla2x00_login_local_device
1802 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001803 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 * Input:
1805 * ha = adapter block pointer.
1806 * loop_id = device loop ID.
1807 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001808 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 * Returns:
1810 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001811 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 * Context:
1813 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001814 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 */
1816int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001817qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 uint16_t *mb_ret, uint8_t opt)
1819{
1820 int rval;
1821 mbx_cmd_t mc;
1822 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001823 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001825 ql_dbg(ql_dbg_mbx, vha, 0x106a, "Entered %s.\n", __func__);
1826
Andrew Vasqueze4289242007-07-19 15:05:56 -07001827 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001828 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001829 fcport->d_id.b.domain, fcport->d_id.b.area,
1830 fcport->d_id.b.al_pa, mb_ret, opt);
1831
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1833 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001834 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 else
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001836 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 mcp->mb[2] = opt;
1838 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1839 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
1840 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1841 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001842 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843
1844 /* Return mailbox statuses. */
1845 if (mb_ret != NULL) {
1846 mb_ret[0] = mcp->mb[0];
1847 mb_ret[1] = mcp->mb[1];
1848 mb_ret[6] = mcp->mb[6];
1849 mb_ret[7] = mcp->mb[7];
1850 }
1851
1852 if (rval != QLA_SUCCESS) {
1853 /* AV tmp code: need to change main mailbox_command function to
1854 * return ok even when the mailbox completion value is not
1855 * SUCCESS. The caller needs to be responsible to interpret
1856 * the return values of this mailbox command if we're not
1857 * to change too much of the existing code.
1858 */
1859 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
1860 rval = QLA_SUCCESS;
1861
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001862 ql_dbg(ql_dbg_mbx, vha, 0x106b,
1863 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
1864 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 } else {
1866 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001867 ql_dbg(ql_dbg_mbx, vha, 0x106c, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 }
1869
1870 return (rval);
1871}
1872
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001873int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001874qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001875 uint8_t area, uint8_t al_pa)
1876{
1877 int rval;
1878 struct logio_entry_24xx *lg;
1879 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001880 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001881 struct req_que *req;
1882 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001883
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001884 ql_dbg(ql_dbg_mbx, vha, 0x106d, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001885
1886 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1887 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001888 ql_log(ql_log_warn, vha, 0x106e,
1889 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001890 return QLA_MEMORY_ALLOC_FAILED;
1891 }
1892 memset(lg, 0, sizeof(struct logio_entry_24xx));
1893
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001894 if (ql2xmaxqueues > 1)
1895 req = ha->req_q_map[0];
1896 else
1897 req = vha->req;
1898 rsp = req->rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001899 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1900 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001901 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001902 lg->nport_handle = cpu_to_le16(loop_id);
1903 lg->control_flags =
Andrew Vasquezc8d66912011-03-30 11:46:21 -07001904 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
1905 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001906 lg->port_id[0] = al_pa;
1907 lg->port_id[1] = area;
1908 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001909 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08001910 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
1911 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001912 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001913 ql_dbg(ql_dbg_mbx, vha, 0x106f,
1914 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001915 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001916 ql_dbg(ql_dbg_mbx, vha, 0x1070,
1917 "Failed to complete IOCB -- error status (%x).\n",
1918 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001919 rval = QLA_FUNCTION_FAILED;
1920 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001921 ql_dbg(ql_dbg_mbx, vha, 0x1071,
1922 "Failed to complete IOCB -- completion status (%x) "
1923 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001924 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001925 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001926 } else {
1927 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001928 ql_dbg(ql_dbg_mbx, vha, 0x1072, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001929 }
1930
1931 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1932
1933 return rval;
1934}
1935
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936/*
1937 * qla2x00_fabric_logout
1938 * Issue logout fabric port mailbox command.
1939 *
1940 * Input:
1941 * ha = adapter block pointer.
1942 * loop_id = device loop ID.
1943 * TARGET_QUEUE_LOCK must be released.
1944 * ADAPTER_STATE_LOCK must be released.
1945 *
1946 * Returns:
1947 * qla2x00 local function return status code.
1948 *
1949 * Context:
1950 * Kernel context.
1951 */
1952int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001953qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001954 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955{
1956 int rval;
1957 mbx_cmd_t mc;
1958 mbx_cmd_t *mcp = &mc;
1959
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001960 ql_dbg(ql_dbg_mbx, vha, 0x1073, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961
1962 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1963 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001964 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 mcp->mb[1] = loop_id;
1966 mcp->mb[10] = 0;
1967 mcp->out_mb |= MBX_10;
1968 } else {
1969 mcp->mb[1] = loop_id << 8;
1970 }
1971
1972 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001973 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001975 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001976
1977 if (rval != QLA_SUCCESS) {
1978 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001979 ql_dbg(ql_dbg_mbx, vha, 0x1074,
1980 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981 } else {
1982 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001983 ql_dbg(ql_dbg_mbx, vha, 0x1075, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 }
1985
1986 return rval;
1987}
1988
1989/*
1990 * qla2x00_full_login_lip
1991 * Issue full login LIP mailbox command.
1992 *
1993 * Input:
1994 * ha = adapter block pointer.
1995 * TARGET_QUEUE_LOCK must be released.
1996 * ADAPTER_STATE_LOCK must be released.
1997 *
1998 * Returns:
1999 * qla2x00 local function return status code.
2000 *
2001 * Context:
2002 * Kernel context.
2003 */
2004int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002005qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002006{
2007 int rval;
2008 mbx_cmd_t mc;
2009 mbx_cmd_t *mcp = &mc;
2010
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002011 ql_dbg(ql_dbg_mbx, vha, 0x1076, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012
2013 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002014 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002015 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002016 mcp->mb[3] = 0;
2017 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2018 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002019 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002021 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022
2023 if (rval != QLA_SUCCESS) {
2024 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002025 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026 } else {
2027 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002028 ql_dbg(ql_dbg_mbx, vha, 0x1078, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029 }
2030
2031 return rval;
2032}
2033
2034/*
2035 * qla2x00_get_id_list
2036 *
2037 * Input:
2038 * ha = adapter block pointer.
2039 *
2040 * Returns:
2041 * qla2x00 local function return status code.
2042 *
2043 * Context:
2044 * Kernel context.
2045 */
2046int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002047qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002048 uint16_t *entries)
2049{
2050 int rval;
2051 mbx_cmd_t mc;
2052 mbx_cmd_t *mcp = &mc;
2053
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002054 ql_dbg(ql_dbg_mbx, vha, 0x1079, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002055
2056 if (id_list == NULL)
2057 return QLA_FUNCTION_FAILED;
2058
2059 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002060 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002061 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002062 mcp->mb[2] = MSW(id_list_dma);
2063 mcp->mb[3] = LSW(id_list_dma);
2064 mcp->mb[6] = MSW(MSD(id_list_dma));
2065 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002066 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002067 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002068 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002069 } else {
2070 mcp->mb[1] = MSW(id_list_dma);
2071 mcp->mb[2] = LSW(id_list_dma);
2072 mcp->mb[3] = MSW(MSD(id_list_dma));
2073 mcp->mb[6] = LSW(MSD(id_list_dma));
2074 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2075 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002076 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002077 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002079 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002080
2081 if (rval != QLA_SUCCESS) {
2082 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002083 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084 } else {
2085 *entries = mcp->mb[1];
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002086 ql_dbg(ql_dbg_mbx, vha, 0x107b, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002087 }
2088
2089 return rval;
2090}
2091
2092/*
2093 * qla2x00_get_resource_cnts
2094 * Get current firmware resource counts.
2095 *
2096 * Input:
2097 * ha = adapter block pointer.
2098 *
2099 * Returns:
2100 * qla2x00 local function return status code.
2101 *
2102 * Context:
2103 * Kernel context.
2104 */
2105int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002106qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002107 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002108 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002109{
2110 int rval;
2111 mbx_cmd_t mc;
2112 mbx_cmd_t *mcp = &mc;
2113
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002114 ql_dbg(ql_dbg_mbx, vha, 0x107c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115
2116 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2117 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002118 mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002119 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002120 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002121 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002122 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002123 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124
2125 if (rval != QLA_SUCCESS) {
2126 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002127 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2128 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002130 ql_dbg(ql_dbg_mbx, vha, 0x107e,
2131 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2132 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2133 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2134 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002135
2136 if (cur_xchg_cnt)
2137 *cur_xchg_cnt = mcp->mb[3];
2138 if (orig_xchg_cnt)
2139 *orig_xchg_cnt = mcp->mb[6];
2140 if (cur_iocb_cnt)
2141 *cur_iocb_cnt = mcp->mb[7];
2142 if (orig_iocb_cnt)
2143 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002144 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002145 *max_npiv_vports = mcp->mb[11];
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002146 if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) && max_fcfs)
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002147 *max_fcfs = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 }
2149
2150 return (rval);
2151}
2152
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153/*
2154 * qla2x00_get_fcal_position_map
2155 * Get FCAL (LILP) position map using mailbox command
2156 *
2157 * Input:
2158 * ha = adapter state pointer.
2159 * pos_map = buffer pointer (can be NULL).
2160 *
2161 * Returns:
2162 * qla2x00 local function return status code.
2163 *
2164 * Context:
2165 * Kernel context.
2166 */
2167int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002168qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002169{
2170 int rval;
2171 mbx_cmd_t mc;
2172 mbx_cmd_t *mcp = &mc;
2173 char *pmap;
2174 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002175 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002177 ql_dbg(ql_dbg_mbx, vha, 0x107f, "Entered %s.\n", __func__);
2178
Andrew Vasquez4b892582008-09-11 21:22:48 -07002179 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002180 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002181 ql_log(ql_log_warn, vha, 0x1080,
2182 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002183 return QLA_MEMORY_ALLOC_FAILED;
2184 }
2185 memset(pmap, 0, FCAL_MAP_SIZE);
2186
2187 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2188 mcp->mb[2] = MSW(pmap_dma);
2189 mcp->mb[3] = LSW(pmap_dma);
2190 mcp->mb[6] = MSW(MSD(pmap_dma));
2191 mcp->mb[7] = LSW(MSD(pmap_dma));
2192 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2193 mcp->in_mb = MBX_1|MBX_0;
2194 mcp->buf_size = FCAL_MAP_SIZE;
2195 mcp->flags = MBX_DMA_IN;
2196 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002197 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002198
2199 if (rval == QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002200 ql_dbg(ql_dbg_mbx, vha, 0x1081,
2201 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2202 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2203 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2204 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002205
2206 if (pos_map)
2207 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2208 }
2209 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2210
2211 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002212 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002213 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002214 ql_dbg(ql_dbg_mbx, vha, 0x1083, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215 }
2216
2217 return rval;
2218}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002219
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002220/*
2221 * qla2x00_get_link_status
2222 *
2223 * Input:
2224 * ha = adapter block pointer.
2225 * loop_id = device loop ID.
2226 * ret_buf = pointer to link status return buffer.
2227 *
2228 * Returns:
2229 * 0 = success.
2230 * BIT_0 = mem alloc error.
2231 * BIT_1 = mailbox error.
2232 */
2233int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002234qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002235 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002236{
2237 int rval;
2238 mbx_cmd_t mc;
2239 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002240 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002241 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002242
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002243 ql_dbg(ql_dbg_mbx, vha, 0x1084, "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002244
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002245 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002246 mcp->mb[2] = MSW(stats_dma);
2247 mcp->mb[3] = LSW(stats_dma);
2248 mcp->mb[6] = MSW(MSD(stats_dma));
2249 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002250 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2251 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002252 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002253 mcp->mb[1] = loop_id;
2254 mcp->mb[4] = 0;
2255 mcp->mb[10] = 0;
2256 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2257 mcp->in_mb |= MBX_1;
2258 } else if (HAS_EXTENDED_IDS(ha)) {
2259 mcp->mb[1] = loop_id;
2260 mcp->mb[10] = 0;
2261 mcp->out_mb |= MBX_10|MBX_1;
2262 } else {
2263 mcp->mb[1] = loop_id << 8;
2264 mcp->out_mb |= MBX_1;
2265 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002266 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002267 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002268 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002269
2270 if (rval == QLA_SUCCESS) {
2271 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002272 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2273 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002274 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002275 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002276 /* Copy over data -- firmware data is LE. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002277 ql_dbg(ql_dbg_mbx, vha, 0x1086, "Done %s.\n", __func__);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002278 dwords = offsetof(struct link_statistics, unused1) / 4;
2279 siter = diter = &stats->link_fail_cnt;
2280 while (dwords--)
2281 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002282 }
2283 } else {
2284 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002285 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002286 }
2287
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002288 return rval;
2289}
2290
2291int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002292qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002293 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002294{
2295 int rval;
2296 mbx_cmd_t mc;
2297 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002298 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002299
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002300 ql_dbg(ql_dbg_mbx, vha, 0x1088, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002301
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002302 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002303 mcp->mb[2] = MSW(stats_dma);
2304 mcp->mb[3] = LSW(stats_dma);
2305 mcp->mb[6] = MSW(MSD(stats_dma));
2306 mcp->mb[7] = LSW(MSD(stats_dma));
2307 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002308 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002309 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002310 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002311 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002312 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002313 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002314 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002315
2316 if (rval == QLA_SUCCESS) {
2317 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002318 ql_dbg(ql_dbg_mbx, vha, 0x1089,
2319 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002320 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002321 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002322 ql_dbg(ql_dbg_mbx, vha, 0x108a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002323 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002324 dwords = sizeof(struct link_statistics) / 4;
2325 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002326 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002327 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002328 }
2329 } else {
2330 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002331 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002332 }
2333
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002334 return rval;
2335}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002336
2337int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002338qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002339{
2340 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002341 unsigned long flags = 0;
2342
2343 struct abort_entry_24xx *abt;
2344 dma_addr_t abt_dma;
2345 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002346 fc_port_t *fcport = sp->fcport;
2347 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002348 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07002349 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002350
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002351 ql_dbg(ql_dbg_mbx, vha, 0x108c, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002352
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002353 spin_lock_irqsave(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002354 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002355 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002356 break;
2357 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002358 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002359 if (handle == MAX_OUTSTANDING_COMMANDS) {
2360 /* Command not found. */
2361 return QLA_FUNCTION_FAILED;
2362 }
2363
2364 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2365 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002366 ql_log(ql_log_warn, vha, 0x108d,
2367 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002368 return QLA_MEMORY_ALLOC_FAILED;
2369 }
2370 memset(abt, 0, sizeof(struct abort_entry_24xx));
2371
2372 abt->entry_type = ABORT_IOCB_TYPE;
2373 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002374 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002375 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07002376 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002377 abt->port_id[0] = fcport->d_id.b.al_pa;
2378 abt->port_id[1] = fcport->d_id.b.area;
2379 abt->port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002380 abt->vp_index = fcport->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002381
2382 abt->req_que_no = cpu_to_le16(req->id);
2383
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002384 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002385 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002386 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2387 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002388 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002389 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2390 "Failed to complete IOCB -- error status (%x).\n",
2391 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002392 rval = QLA_FUNCTION_FAILED;
2393 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002394 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2395 "Failed to complete IOCB -- completion status (%x).\n",
2396 le16_to_cpu(abt->nport_handle));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002397 rval = QLA_FUNCTION_FAILED;
2398 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002399 ql_dbg(ql_dbg_mbx, vha, 0x1091, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002400 }
2401
2402 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2403
2404 return rval;
2405}
2406
2407struct tsk_mgmt_cmd {
2408 union {
2409 struct tsk_mgmt_entry tsk;
2410 struct sts_entry_24xx sts;
2411 } p;
2412};
2413
Andrew Vasquez523ec772008-04-03 13:13:24 -07002414static int
2415__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002416 unsigned int l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002417{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002418 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002419 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002420 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002421 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002422 scsi_qla_host_t *vha;
2423 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002424 struct req_que *req;
2425 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002426
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002427 vha = fcport->vha;
2428 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002429 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002430
2431 ql_dbg(ql_dbg_mbx, vha, 0x1092, "Entered %s.\n", __func__);
2432
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002433 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002434 rsp = ha->rsp_q_map[tag + 1];
2435 else
2436 rsp = req->rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002437 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002438 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002439 ql_log(ql_log_warn, vha, 0x1093,
2440 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002441 return QLA_MEMORY_ALLOC_FAILED;
2442 }
2443 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2444
2445 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2446 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002447 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002448 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002449 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002450 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002451 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2452 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2453 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002454 tsk->p.tsk.vp_index = fcport->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002455 if (type == TCF_LUN_RESET) {
2456 int_to_scsilun(l, &tsk->p.tsk.lun);
2457 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2458 sizeof(tsk->p.tsk.lun));
2459 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002460
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002461 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002462 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002463 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002464 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2465 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002466 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002467 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2468 "Failed to complete IOCB -- error status (%x).\n",
2469 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002470 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002471 } else if (sts->comp_status !=
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002472 __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002473 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2474 "Failed to complete IOCB -- completion status (%x).\n",
2475 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002476 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08002477 } else if (le16_to_cpu(sts->scsi_status) &
2478 SS_RESPONSE_INFO_LEN_VALID) {
2479 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002480 ql_dbg(ql_dbg_mbx, vha, 0x1097,
2481 "Ignoring inconsistent data length -- not enough "
2482 "response info (%d).\n",
2483 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08002484 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002485 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2486 "Failed to complete IOCB -- response (%x).\n",
2487 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08002488 rval = QLA_FUNCTION_FAILED;
2489 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002490 }
2491
2492 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002493 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002494 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2495 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002496 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2497 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002498 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002499 ql_dbg(ql_dbg_mbx, vha, 0x109a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002500 }
2501
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002502 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002503
2504 return rval;
2505}
2506
Andrew Vasquez523ec772008-04-03 13:13:24 -07002507int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002508qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002509{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002510 struct qla_hw_data *ha = fcport->vha->hw;
2511
2512 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2513 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2514
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002515 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002516}
2517
2518int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002519qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002520{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002521 struct qla_hw_data *ha = fcport->vha->hw;
2522
2523 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2524 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2525
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002526 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002527}
2528
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002529int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002530qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002531{
2532 int rval;
2533 mbx_cmd_t mc;
2534 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002535 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002536
Andrew Vasquez68af0812008-05-12 22:21:13 -07002537 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002538 return QLA_FUNCTION_FAILED;
2539
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002540 ql_dbg(ql_dbg_mbx, vha, 0x109b, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002541
2542 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2543 mcp->out_mb = MBX_0;
2544 mcp->in_mb = MBX_0;
2545 mcp->tov = 5;
2546 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002547 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002548
2549 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002550 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002551 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002552 ql_dbg(ql_dbg_mbx, vha, 0x109d, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002553 }
2554
2555 return rval;
2556}
2557
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002558/**
2559 * qla2x00_set_serdes_params() -
2560 * @ha: HA context
2561 *
2562 * Returns
2563 */
2564int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002565qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002566 uint16_t sw_em_2g, uint16_t sw_em_4g)
2567{
2568 int rval;
2569 mbx_cmd_t mc;
2570 mbx_cmd_t *mcp = &mc;
2571
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002572 ql_dbg(ql_dbg_mbx, vha, 0x109e, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002573
2574 mcp->mb[0] = MBC_SERDES_PARAMS;
2575 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08002576 mcp->mb[2] = sw_em_1g | BIT_15;
2577 mcp->mb[3] = sw_em_2g | BIT_15;
2578 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002579 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2580 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002581 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002582 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002583 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002584
2585 if (rval != QLA_SUCCESS) {
2586 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002587 ql_dbg(ql_dbg_mbx, vha, 0x109f,
2588 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002589 } else {
2590 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002591 ql_dbg(ql_dbg_mbx, vha, 0x10a0, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002592 }
2593
2594 return rval;
2595}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002596
2597int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002598qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002599{
2600 int rval;
2601 mbx_cmd_t mc;
2602 mbx_cmd_t *mcp = &mc;
2603
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002604 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002605 return QLA_FUNCTION_FAILED;
2606
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002607 ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002608
2609 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08002610 mcp->mb[1] = 0;
2611 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002612 mcp->in_mb = MBX_0;
2613 mcp->tov = 5;
2614 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002615 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002616
2617 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002618 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07002619 if (mcp->mb[0] == MBS_INVALID_COMMAND)
2620 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002621 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002622 ql_dbg(ql_dbg_mbx, vha, 0x10a3, "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002623 }
2624
2625 return rval;
2626}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002627
2628int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002629qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002630 uint16_t buffers)
2631{
2632 int rval;
2633 mbx_cmd_t mc;
2634 mbx_cmd_t *mcp = &mc;
2635
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002636 ql_dbg(ql_dbg_mbx, vha, 0x10a4, "Entered %s.\n", __func__);
2637
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002638 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002639 return QLA_FUNCTION_FAILED;
2640
Andrew Vasquez85880802009-12-15 21:29:46 -08002641 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2642 return QLA_FUNCTION_FAILED;
2643
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002644 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002645 mcp->mb[1] = TC_EFT_ENABLE;
2646 mcp->mb[2] = LSW(eft_dma);
2647 mcp->mb[3] = MSW(eft_dma);
2648 mcp->mb[4] = LSW(MSD(eft_dma));
2649 mcp->mb[5] = MSW(MSD(eft_dma));
2650 mcp->mb[6] = buffers;
2651 mcp->mb[7] = TC_AEN_DISABLE;
2652 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002653 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002654 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002655 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002656 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002657 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002658 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
2659 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2660 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002661 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002662 ql_dbg(ql_dbg_mbx, vha, 0x10a6, "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002663 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002664
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002665 return rval;
2666}
2667
2668int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002669qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002670{
2671 int rval;
2672 mbx_cmd_t mc;
2673 mbx_cmd_t *mcp = &mc;
2674
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002675 ql_dbg(ql_dbg_mbx, vha, 0x10a7, "Entered %s.\n", __func__);
2676
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002677 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002678 return QLA_FUNCTION_FAILED;
2679
Andrew Vasquez85880802009-12-15 21:29:46 -08002680 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2681 return QLA_FUNCTION_FAILED;
2682
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002683 mcp->mb[0] = MBC_TRACE_CONTROL;
2684 mcp->mb[1] = TC_EFT_DISABLE;
2685 mcp->out_mb = MBX_1|MBX_0;
2686 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002687 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002688 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002689 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002690 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002691 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
2692 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2693 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002694 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002695 ql_dbg(ql_dbg_mbx, vha, 0x10a9, "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002696 }
2697
2698 return rval;
2699}
2700
Andrew Vasquez88729e52006-06-23 16:10:50 -07002701int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002702qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002703 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
2704{
2705 int rval;
2706 mbx_cmd_t mc;
2707 mbx_cmd_t *mcp = &mc;
2708
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002709 ql_dbg(ql_dbg_mbx, vha, 0x10aa, "Entered %s.\n", __func__);
2710
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002711 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
2712 !IS_QLA83XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002713 return QLA_FUNCTION_FAILED;
2714
Andrew Vasquez85880802009-12-15 21:29:46 -08002715 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2716 return QLA_FUNCTION_FAILED;
2717
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002718 mcp->mb[0] = MBC_TRACE_CONTROL;
2719 mcp->mb[1] = TC_FCE_ENABLE;
2720 mcp->mb[2] = LSW(fce_dma);
2721 mcp->mb[3] = MSW(fce_dma);
2722 mcp->mb[4] = LSW(MSD(fce_dma));
2723 mcp->mb[5] = MSW(MSD(fce_dma));
2724 mcp->mb[6] = buffers;
2725 mcp->mb[7] = TC_AEN_DISABLE;
2726 mcp->mb[8] = 0;
2727 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
2728 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
2729 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2730 MBX_1|MBX_0;
2731 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002732 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002733 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002734 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002735 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002736 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
2737 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2738 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002739 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002740 ql_dbg(ql_dbg_mbx, vha, 0x10ac, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002741
2742 if (mb)
2743 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
2744 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07002745 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002746 }
2747
2748 return rval;
2749}
2750
2751int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002752qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002753{
2754 int rval;
2755 mbx_cmd_t mc;
2756 mbx_cmd_t *mcp = &mc;
2757
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002758 ql_dbg(ql_dbg_mbx, vha, 0x10ad, "Entered %s.\n", __func__);
2759
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002760 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002761 return QLA_FUNCTION_FAILED;
2762
Andrew Vasquez85880802009-12-15 21:29:46 -08002763 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2764 return QLA_FUNCTION_FAILED;
2765
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002766 mcp->mb[0] = MBC_TRACE_CONTROL;
2767 mcp->mb[1] = TC_FCE_DISABLE;
2768 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
2769 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2770 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2771 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002772 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002773 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002774 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002775 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002776 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
2777 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2778 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002779 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002780 ql_dbg(ql_dbg_mbx, vha, 0x10af, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002781
2782 if (wr)
2783 *wr = (uint64_t) mcp->mb[5] << 48 |
2784 (uint64_t) mcp->mb[4] << 32 |
2785 (uint64_t) mcp->mb[3] << 16 |
2786 (uint64_t) mcp->mb[2];
2787 if (rd)
2788 *rd = (uint64_t) mcp->mb[9] << 48 |
2789 (uint64_t) mcp->mb[8] << 32 |
2790 (uint64_t) mcp->mb[7] << 16 |
2791 (uint64_t) mcp->mb[6];
2792 }
2793
2794 return rval;
2795}
2796
2797int
Giridhar Malavali6e980162010-03-19 17:03:58 -07002798qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
2799 uint16_t *port_speed, uint16_t *mb)
2800{
2801 int rval;
2802 mbx_cmd_t mc;
2803 mbx_cmd_t *mcp = &mc;
2804
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002805 ql_dbg(ql_dbg_mbx, vha, 0x10b0, "Entered %s.\n", __func__);
2806
Giridhar Malavali6e980162010-03-19 17:03:58 -07002807 if (!IS_IIDMA_CAPABLE(vha->hw))
2808 return QLA_FUNCTION_FAILED;
2809
Giridhar Malavali6e980162010-03-19 17:03:58 -07002810 mcp->mb[0] = MBC_PORT_PARAMS;
2811 mcp->mb[1] = loop_id;
2812 mcp->mb[2] = mcp->mb[3] = 0;
2813 mcp->mb[9] = vha->vp_idx;
2814 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2815 mcp->in_mb = MBX_3|MBX_1|MBX_0;
2816 mcp->tov = MBX_TOV_SECONDS;
2817 mcp->flags = 0;
2818 rval = qla2x00_mailbox_command(vha, mcp);
2819
2820 /* Return mailbox statuses. */
2821 if (mb != NULL) {
2822 mb[0] = mcp->mb[0];
2823 mb[1] = mcp->mb[1];
2824 mb[3] = mcp->mb[3];
2825 }
2826
2827 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002828 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002829 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002830 ql_dbg(ql_dbg_mbx, vha, 0x10b2, "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002831 if (port_speed)
2832 *port_speed = mcp->mb[3];
2833 }
2834
2835 return rval;
2836}
2837
2838int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002839qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002840 uint16_t port_speed, uint16_t *mb)
2841{
2842 int rval;
2843 mbx_cmd_t mc;
2844 mbx_cmd_t *mcp = &mc;
2845
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002846 ql_dbg(ql_dbg_mbx, vha, 0x10b3, "Entered %s.\n", __func__);
2847
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002848 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002849 return QLA_FUNCTION_FAILED;
2850
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002851 mcp->mb[0] = MBC_PORT_PARAMS;
2852 mcp->mb[1] = loop_id;
2853 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002854 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07002855 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
2856 else
2857 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
2858 mcp->mb[9] = vha->vp_idx;
2859 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2860 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002861 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002862 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002863 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002864
2865 /* Return mailbox statuses. */
2866 if (mb != NULL) {
2867 mb[0] = mcp->mb[0];
2868 mb[1] = mcp->mb[1];
2869 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002870 }
2871
2872 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002873 ql_dbg(ql_dbg_mbx, vha, 0x10b4, "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002874 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002875 ql_dbg(ql_dbg_mbx, vha, 0x10b5, "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002876 }
2877
2878 return rval;
2879}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002880
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002881void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002882qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002883 struct vp_rpt_id_entry_24xx *rptid_entry)
2884{
2885 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07002886 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002887 struct qla_hw_data *ha = vha->hw;
2888 scsi_qla_host_t *vp;
Arun Easifeafb7b2010-09-03 14:57:00 -07002889 unsigned long flags;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002890
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002891 ql_dbg(ql_dbg_mbx, vha, 0x10b6, "Entered %s.\n", __func__);
2892
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002893 if (rptid_entry->entry_status != 0)
2894 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002895
2896 if (rptid_entry->format == 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002897 ql_dbg(ql_dbg_mbx, vha, 0x10b7,
2898 "Format 0 : Number of VPs setup %d, number of "
2899 "VPs acquired %d.\n",
2900 MSB(le16_to_cpu(rptid_entry->vp_count)),
2901 LSB(le16_to_cpu(rptid_entry->vp_count)));
2902 ql_dbg(ql_dbg_mbx, vha, 0x10b8,
2903 "Primary port id %02x%02x%02x.\n",
2904 rptid_entry->port_id[2], rptid_entry->port_id[1],
2905 rptid_entry->port_id[0]);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002906 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07002907 vp_idx = LSB(stat);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002908 ql_dbg(ql_dbg_mbx, vha, 0x10b9,
2909 "Format 1: VP[%d] enabled - status %d - with "
2910 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002911 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002912 rptid_entry->port_id[0]);
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002913
2914 vp = vha;
2915 if (vp_idx == 0 && (MSB(stat) != 1))
2916 goto reg_needed;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002917
Giridhar Malavali882a9172011-11-18 09:03:12 -08002918 if (MSB(stat) != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002919 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
2920 "Could not acquire ID for VP[%d].\n", vp_idx);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002921 return;
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07002922 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002923
Arun Easifeafb7b2010-09-03 14:57:00 -07002924 spin_lock_irqsave(&ha->vport_slock, flags);
2925 list_for_each_entry(vp, &ha->vp_list, list)
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002926 if (vp_idx == vp->vp_idx)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002927 break;
Arun Easifeafb7b2010-09-03 14:57:00 -07002928 spin_unlock_irqrestore(&ha->vport_slock, flags);
2929
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002930 if (!vp)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002931 return;
2932
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002933 vp->d_id.b.domain = rptid_entry->port_id[2];
2934 vp->d_id.b.area = rptid_entry->port_id[1];
2935 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002936
2937 /*
2938 * Cannot configure here as we are still sitting on the
2939 * response queue. Handle it in dpc context.
2940 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002941 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002942
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002943reg_needed:
2944 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
2945 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
2946 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002947 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002948 }
2949}
2950
2951/*
2952 * qla24xx_modify_vp_config
2953 * Change VP configuration for vha
2954 *
2955 * Input:
2956 * vha = adapter block pointer.
2957 *
2958 * Returns:
2959 * qla2xxx local function return status code.
2960 *
2961 * Context:
2962 * Kernel context.
2963 */
2964int
2965qla24xx_modify_vp_config(scsi_qla_host_t *vha)
2966{
2967 int rval;
2968 struct vp_config_entry_24xx *vpmod;
2969 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002970 struct qla_hw_data *ha = vha->hw;
2971 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002972
2973 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002974
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002975 ql_dbg(ql_dbg_mbx, vha, 0x10bb, "Entered %s.\n", __func__);
2976
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002977 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002978 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002979 ql_log(ql_log_warn, vha, 0x10bc,
2980 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002981 return QLA_MEMORY_ALLOC_FAILED;
2982 }
2983
2984 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
2985 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
2986 vpmod->entry_count = 1;
2987 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
2988 vpmod->vp_count = 1;
2989 vpmod->vp_index1 = vha->vp_idx;
2990 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
2991 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
2992 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
2993 vpmod->entry_count = 1;
2994
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002995 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002996 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002997 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
2998 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002999 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003000 ql_dbg(ql_dbg_mbx, vha, 0x10be,
3001 "Failed to complete IOCB -- error status (%x).\n",
3002 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003003 rval = QLA_FUNCTION_FAILED;
3004 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003005 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3006 "Failed to complete IOCB -- completion status (%x).\n",
3007 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003008 rval = QLA_FUNCTION_FAILED;
3009 } else {
3010 /* EMPTY */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003011 ql_dbg(ql_dbg_mbx, vha, 0x10c0, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003012 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3013 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003014 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003015
3016 return rval;
3017}
3018
3019/*
3020 * qla24xx_control_vp
3021 * Enable a virtual port for given host
3022 *
3023 * Input:
3024 * ha = adapter block pointer.
3025 * vhba = virtual adapter (unused)
3026 * index = index number for enabled VP
3027 *
3028 * Returns:
3029 * qla2xxx local function return status code.
3030 *
3031 * Context:
3032 * Kernel context.
3033 */
3034int
3035qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
3036{
3037 int rval;
3038 int map, pos;
3039 struct vp_ctrl_entry_24xx *vce;
3040 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003041 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003042 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003043 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003044
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003045 ql_dbg(ql_dbg_mbx, vha, 0x10c1,
3046 "Entered %s enabling index %d.\n", __func__, vp_index);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003047
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08003048 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003049 return QLA_PARAMETER_ERROR;
3050
3051 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3052 if (!vce) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003053 ql_log(ql_log_warn, vha, 0x10c2,
3054 "Failed to allocate VP control IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003055 return QLA_MEMORY_ALLOC_FAILED;
3056 }
3057 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3058
3059 vce->entry_type = VP_CTRL_IOCB_TYPE;
3060 vce->entry_count = 1;
3061 vce->command = cpu_to_le16(cmd);
3062 vce->vp_count = __constant_cpu_to_le16(1);
3063
3064 /* index map in firmware starts with 1; decrement index
3065 * this is ok as we never use index 0
3066 */
3067 map = (vp_index - 1) / 8;
3068 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003069 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003070 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003071 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003072
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003073 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003074 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003075 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3076 "Failed to issue VP control IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003077 } else if (vce->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003078 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3079 "Failed to complete IOCB -- error status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003080 vce->entry_status);
3081 rval = QLA_FUNCTION_FAILED;
3082 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003083 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3084 "Failed to complet IOCB -- completion status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003085 le16_to_cpu(vce->comp_status));
3086 rval = QLA_FUNCTION_FAILED;
3087 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003088 ql_dbg(ql_dbg_mbx, vha, 0x10c6, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003089 }
3090
3091 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3092
3093 return rval;
3094}
3095
3096/*
3097 * qla2x00_send_change_request
3098 * Receive or disable RSCN request from fabric controller
3099 *
3100 * Input:
3101 * ha = adapter block pointer
3102 * format = registration format:
3103 * 0 - Reserved
3104 * 1 - Fabric detected registration
3105 * 2 - N_port detected registration
3106 * 3 - Full registration
3107 * FF - clear registration
3108 * vp_idx = Virtual port index
3109 *
3110 * Returns:
3111 * qla2x00 local function return status code.
3112 *
3113 * Context:
3114 * Kernel Context
3115 */
3116
3117int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003118qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003119 uint16_t vp_idx)
3120{
3121 int rval;
3122 mbx_cmd_t mc;
3123 mbx_cmd_t *mcp = &mc;
3124
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003125 ql_dbg(ql_dbg_mbx, vha, 0x10c7, "Entered %s.\n", __func__);
3126
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003127 /*
3128 * This command is implicitly executed by firmware during login for the
3129 * physical hosts
3130 */
3131 if (vp_idx == 0)
3132 return QLA_FUNCTION_FAILED;
3133
3134 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3135 mcp->mb[1] = format;
3136 mcp->mb[9] = vp_idx;
3137 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3138 mcp->in_mb = MBX_0|MBX_1;
3139 mcp->tov = MBX_TOV_SECONDS;
3140 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003141 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003142
3143 if (rval == QLA_SUCCESS) {
3144 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3145 rval = BIT_1;
3146 }
3147 } else
3148 rval = BIT_1;
3149
3150 return rval;
3151}
Andrew Vasquez338c9162007-09-20 14:07:33 -07003152
3153int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003154qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07003155 uint32_t size)
3156{
3157 int rval;
3158 mbx_cmd_t mc;
3159 mbx_cmd_t *mcp = &mc;
3160
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003161 ql_dbg(ql_dbg_mbx, vha, 0x1009, "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003162
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003163 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003164 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3165 mcp->mb[8] = MSW(addr);
3166 mcp->out_mb = MBX_8|MBX_0;
3167 } else {
3168 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3169 mcp->out_mb = MBX_0;
3170 }
3171 mcp->mb[1] = LSW(addr);
3172 mcp->mb[2] = MSW(req_dma);
3173 mcp->mb[3] = LSW(req_dma);
3174 mcp->mb[6] = MSW(MSD(req_dma));
3175 mcp->mb[7] = LSW(MSD(req_dma));
3176 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003177 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003178 mcp->mb[4] = MSW(size);
3179 mcp->mb[5] = LSW(size);
3180 mcp->out_mb |= MBX_5|MBX_4;
3181 } else {
3182 mcp->mb[4] = LSW(size);
3183 mcp->out_mb |= MBX_4;
3184 }
3185
3186 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003187 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07003188 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003189 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003190
3191 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003192 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3193 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003194 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003195 ql_dbg(ql_dbg_mbx, vha, 0x1007, "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003196 }
3197
3198 return rval;
3199}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003200
3201/* 84XX Support **************************************************************/
3202
3203struct cs84xx_mgmt_cmd {
3204 union {
3205 struct verify_chip_entry_84xx req;
3206 struct verify_chip_rsp_84xx rsp;
3207 } p;
3208};
3209
3210int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003211qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003212{
3213 int rval, retry;
3214 struct cs84xx_mgmt_cmd *mn;
3215 dma_addr_t mn_dma;
3216 uint16_t options;
3217 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003218 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003219
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003220 ql_dbg(ql_dbg_mbx, vha, 0x10c8, "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003221
3222 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3223 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003224 return QLA_MEMORY_ALLOC_FAILED;
3225 }
3226
3227 /* Force Update? */
3228 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3229 /* Diagnostic firmware? */
3230 /* options |= MENLO_DIAG_FW; */
3231 /* We update the firmware with only one data sequence. */
3232 options |= VCO_END_OF_DATA;
3233
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003234 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003235 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003236 memset(mn, 0, sizeof(*mn));
3237 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3238 mn->p.req.entry_count = 1;
3239 mn->p.req.options = cpu_to_le16(options);
3240
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003241 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3242 "Dump of Verify Request.\n");
3243 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3244 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003245
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003246 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003247 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003248 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3249 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003250 goto verify_done;
3251 }
3252
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003253 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3254 "Dump of Verify Response.\n");
3255 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3256 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003257
3258 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3259 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3260 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003261 ql_dbg(ql_dbg_mbx, vha, 0x10ce,
3262 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003263
3264 if (status[0] != CS_COMPLETE) {
3265 rval = QLA_FUNCTION_FAILED;
3266 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003267 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3268 "Firmware update failed. Retrying "
3269 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003270 options |= VCO_DONT_UPDATE_FW;
3271 options &= ~VCO_FORCE_UPDATE;
3272 retry = 1;
3273 }
3274 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003275 ql_dbg(ql_dbg_mbx, vha, 0x10d0,
3276 "Firmware updated to %x.\n",
3277 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003278
3279 /* NOTE: we only update OP firmware. */
3280 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3281 ha->cs84xx->op_fw_version =
3282 le32_to_cpu(mn->p.rsp.fw_ver);
3283 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3284 flags);
3285 }
3286 } while (retry);
3287
3288verify_done:
3289 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3290
3291 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003292 ql_dbg(ql_dbg_mbx, vha, 0x10d1, "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003293 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003294 ql_dbg(ql_dbg_mbx, vha, 0x10d2, "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003295 }
3296
3297 return rval;
3298}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003299
3300int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003301qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003302{
3303 int rval;
3304 unsigned long flags;
3305 mbx_cmd_t mc;
3306 mbx_cmd_t *mcp = &mc;
3307 struct device_reg_25xxmq __iomem *reg;
3308 struct qla_hw_data *ha = vha->hw;
3309
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003310 ql_dbg(ql_dbg_mbx, vha, 0x10d3, "Entered %s.\n", __func__);
3311
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003312 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003313 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003314 mcp->mb[2] = MSW(LSD(req->dma));
3315 mcp->mb[3] = LSW(LSD(req->dma));
3316 mcp->mb[6] = MSW(MSD(req->dma));
3317 mcp->mb[7] = LSW(MSD(req->dma));
3318 mcp->mb[5] = req->length;
3319 if (req->rsp)
3320 mcp->mb[10] = req->rsp->id;
3321 mcp->mb[12] = req->qos;
3322 mcp->mb[11] = req->vp_idx;
3323 mcp->mb[13] = req->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003324 if (IS_QLA83XX(ha))
3325 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003326
3327 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3328 QLA_QUE_PAGE * req->id);
3329
3330 mcp->mb[4] = req->id;
3331 /* que in ptr index */
3332 mcp->mb[8] = 0;
3333 /* que out ptr index */
3334 mcp->mb[9] = 0;
3335 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3336 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3337 mcp->in_mb = MBX_0;
3338 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003339 mcp->tov = MBX_TOV_SECONDS * 2;
3340
3341 if (IS_QLA81XX(ha) || IS_QLA83XX(ha))
3342 mcp->in_mb |= MBX_1;
3343 if (IS_QLA83XX(ha)) {
3344 mcp->out_mb |= MBX_15;
3345 /* debug q create issue in SR-IOV */
3346 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3347 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003348
3349 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003350 if (!(req->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003351 WRT_REG_DWORD(&reg->req_q_in, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003352 if (!IS_QLA83XX(ha))
3353 WRT_REG_DWORD(&reg->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003354 }
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003355 req->req_q_in = &reg->req_q_in;
3356 req->req_q_out = &reg->req_q_out;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003357 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3358
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003359 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003360 if (rval != QLA_SUCCESS) {
3361 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3362 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3363 } else {
3364 ql_dbg(ql_dbg_mbx, vha, 0x10d5, "Done %s.\n", __func__);
3365 }
3366
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003367 return rval;
3368}
3369
3370int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003371qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003372{
3373 int rval;
3374 unsigned long flags;
3375 mbx_cmd_t mc;
3376 mbx_cmd_t *mcp = &mc;
3377 struct device_reg_25xxmq __iomem *reg;
3378 struct qla_hw_data *ha = vha->hw;
3379
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003380 ql_dbg(ql_dbg_mbx, vha, 0x10d6, "Entered %s.\n", __func__);
3381
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003382 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003383 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003384 mcp->mb[2] = MSW(LSD(rsp->dma));
3385 mcp->mb[3] = LSW(LSD(rsp->dma));
3386 mcp->mb[6] = MSW(MSD(rsp->dma));
3387 mcp->mb[7] = LSW(MSD(rsp->dma));
3388 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003389 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003390 mcp->mb[13] = rsp->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003391 if (IS_QLA83XX(ha))
3392 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003393
3394 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3395 QLA_QUE_PAGE * rsp->id);
3396
3397 mcp->mb[4] = rsp->id;
3398 /* que in ptr index */
3399 mcp->mb[8] = 0;
3400 /* que out ptr index */
3401 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003402 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003403 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3404 mcp->in_mb = MBX_0;
3405 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003406 mcp->tov = MBX_TOV_SECONDS * 2;
3407
3408 if (IS_QLA81XX(ha)) {
3409 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
3410 mcp->in_mb |= MBX_1;
3411 } else if (IS_QLA83XX(ha)) {
3412 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
3413 mcp->in_mb |= MBX_1;
3414 /* debug q create issue in SR-IOV */
3415 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3416 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003417
3418 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003419 if (!(rsp->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003420 WRT_REG_DWORD(&reg->rsp_q_out, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003421 if (!IS_QLA83XX(ha))
3422 WRT_REG_DWORD(&reg->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003423 }
3424
3425 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3426
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003427 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003428 if (rval != QLA_SUCCESS) {
3429 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
3430 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3431 } else {
3432 ql_dbg(ql_dbg_mbx, vha, 0x10d8, "Done %s.\n", __func__);
3433 }
3434
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003435 return rval;
3436}
3437
Andrew Vasquez8a659572009-02-08 20:50:12 -08003438int
3439qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3440{
3441 int rval;
3442 mbx_cmd_t mc;
3443 mbx_cmd_t *mcp = &mc;
3444
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003445 ql_dbg(ql_dbg_mbx, vha, 0x10d9, "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003446
3447 mcp->mb[0] = MBC_IDC_ACK;
3448 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3449 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3450 mcp->in_mb = MBX_0;
3451 mcp->tov = MBX_TOV_SECONDS;
3452 mcp->flags = 0;
3453 rval = qla2x00_mailbox_command(vha, mcp);
3454
3455 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003456 ql_dbg(ql_dbg_mbx, vha, 0x10da,
3457 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003458 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003459 ql_dbg(ql_dbg_mbx, vha, 0x10db, "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003460 }
3461
3462 return rval;
3463}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003464
3465int
3466qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3467{
3468 int rval;
3469 mbx_cmd_t mc;
3470 mbx_cmd_t *mcp = &mc;
3471
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003472 ql_dbg(ql_dbg_mbx, vha, 0x10dc, "Entered %s.\n", __func__);
3473
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003474 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003475 return QLA_FUNCTION_FAILED;
3476
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003477 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3478 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3479 mcp->out_mb = MBX_1|MBX_0;
3480 mcp->in_mb = MBX_1|MBX_0;
3481 mcp->tov = MBX_TOV_SECONDS;
3482 mcp->flags = 0;
3483 rval = qla2x00_mailbox_command(vha, mcp);
3484
3485 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003486 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
3487 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3488 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003489 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003490 ql_dbg(ql_dbg_mbx, vha, 0x10de, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003491 *sector_size = mcp->mb[1];
3492 }
3493
3494 return rval;
3495}
3496
3497int
3498qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3499{
3500 int rval;
3501 mbx_cmd_t mc;
3502 mbx_cmd_t *mcp = &mc;
3503
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003504 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003505 return QLA_FUNCTION_FAILED;
3506
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003507 ql_dbg(ql_dbg_mbx, vha, 0x10df, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003508
3509 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3510 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3511 FAC_OPT_CMD_WRITE_PROTECT;
3512 mcp->out_mb = MBX_1|MBX_0;
3513 mcp->in_mb = MBX_1|MBX_0;
3514 mcp->tov = MBX_TOV_SECONDS;
3515 mcp->flags = 0;
3516 rval = qla2x00_mailbox_command(vha, mcp);
3517
3518 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003519 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
3520 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3521 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003522 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003523 ql_dbg(ql_dbg_mbx, vha, 0x10e1, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003524 }
3525
3526 return rval;
3527}
3528
3529int
3530qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3531{
3532 int rval;
3533 mbx_cmd_t mc;
3534 mbx_cmd_t *mcp = &mc;
3535
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003536 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003537 return QLA_FUNCTION_FAILED;
3538
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003539 ql_dbg(ql_dbg_mbx, vha, 0x10e2, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003540
3541 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3542 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3543 mcp->mb[2] = LSW(start);
3544 mcp->mb[3] = MSW(start);
3545 mcp->mb[4] = LSW(finish);
3546 mcp->mb[5] = MSW(finish);
3547 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3548 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3549 mcp->tov = MBX_TOV_SECONDS;
3550 mcp->flags = 0;
3551 rval = qla2x00_mailbox_command(vha, mcp);
3552
3553 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003554 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
3555 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3556 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003557 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003558 ql_dbg(ql_dbg_mbx, vha, 0x10e4, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003559 }
3560
3561 return rval;
3562}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003563
3564int
3565qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3566{
3567 int rval = 0;
3568 mbx_cmd_t mc;
3569 mbx_cmd_t *mcp = &mc;
3570
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003571 ql_dbg(ql_dbg_mbx, vha, 0x10e5, "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003572
3573 mcp->mb[0] = MBC_RESTART_MPI_FW;
3574 mcp->out_mb = MBX_0;
3575 mcp->in_mb = MBX_0|MBX_1;
3576 mcp->tov = MBX_TOV_SECONDS;
3577 mcp->flags = 0;
3578 rval = qla2x00_mailbox_command(vha, mcp);
3579
3580 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003581 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
3582 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3583 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003584 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003585 ql_dbg(ql_dbg_mbx, vha, 0x10e7, "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003586 }
3587
3588 return rval;
3589}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003590
3591int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003592qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3593 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003594{
3595 int rval;
3596 mbx_cmd_t mc;
3597 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003598 struct qla_hw_data *ha = vha->hw;
3599
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003600 ql_dbg(ql_dbg_mbx, vha, 0x10e8, "Entered %s.\n", __func__);
3601
Joe Carnuccio6766df92011-05-10 11:30:15 -07003602 if (!IS_FWI2_CAPABLE(ha))
3603 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003604
Joe Carnuccio6766df92011-05-10 11:30:15 -07003605 if (len == 1)
3606 opt |= BIT_0;
3607
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003608 mcp->mb[0] = MBC_READ_SFP;
3609 mcp->mb[1] = dev;
3610 mcp->mb[2] = MSW(sfp_dma);
3611 mcp->mb[3] = LSW(sfp_dma);
3612 mcp->mb[6] = MSW(MSD(sfp_dma));
3613 mcp->mb[7] = LSW(MSD(sfp_dma));
3614 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003615 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003616 mcp->mb[10] = opt;
3617 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Joe Carnuccio1bff6cc2011-05-10 11:30:11 -07003618 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003619 mcp->tov = MBX_TOV_SECONDS;
3620 mcp->flags = 0;
3621 rval = qla2x00_mailbox_command(vha, mcp);
3622
3623 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003624 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003625
3626 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003627 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
3628 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003629 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003630 ql_dbg(ql_dbg_mbx, vha, 0x10ea, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003631 }
3632
3633 return rval;
3634}
3635
3636int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003637qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3638 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003639{
3640 int rval;
3641 mbx_cmd_t mc;
3642 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003643 struct qla_hw_data *ha = vha->hw;
3644
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003645 ql_dbg(ql_dbg_mbx, vha, 0x10eb, "Entered %s.\n", __func__);
3646
Joe Carnuccio6766df92011-05-10 11:30:15 -07003647 if (!IS_FWI2_CAPABLE(ha))
3648 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003649
Joe Carnuccio6766df92011-05-10 11:30:15 -07003650 if (len == 1)
3651 opt |= BIT_0;
3652
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003653 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003654 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003655
3656 mcp->mb[0] = MBC_WRITE_SFP;
3657 mcp->mb[1] = dev;
3658 mcp->mb[2] = MSW(sfp_dma);
3659 mcp->mb[3] = LSW(sfp_dma);
3660 mcp->mb[6] = MSW(MSD(sfp_dma));
3661 mcp->mb[7] = LSW(MSD(sfp_dma));
3662 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003663 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003664 mcp->mb[10] = opt;
3665 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003666 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003667 mcp->tov = MBX_TOV_SECONDS;
3668 mcp->flags = 0;
3669 rval = qla2x00_mailbox_command(vha, mcp);
3670
3671 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003672 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
3673 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003674 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003675 ql_dbg(ql_dbg_mbx, vha, 0x10ed, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003676 }
3677
3678 return rval;
3679}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003680
3681int
3682qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
3683 uint16_t size_in_bytes, uint16_t *actual_size)
3684{
3685 int rval;
3686 mbx_cmd_t mc;
3687 mbx_cmd_t *mcp = &mc;
3688
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003689 ql_dbg(ql_dbg_mbx, vha, 0x10ee, "Entered %s.\n", __func__);
3690
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003691 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003692 return QLA_FUNCTION_FAILED;
3693
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003694 mcp->mb[0] = MBC_GET_XGMAC_STATS;
3695 mcp->mb[2] = MSW(stats_dma);
3696 mcp->mb[3] = LSW(stats_dma);
3697 mcp->mb[6] = MSW(MSD(stats_dma));
3698 mcp->mb[7] = LSW(MSD(stats_dma));
3699 mcp->mb[8] = size_in_bytes >> 2;
3700 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
3701 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3702 mcp->tov = MBX_TOV_SECONDS;
3703 mcp->flags = 0;
3704 rval = qla2x00_mailbox_command(vha, mcp);
3705
3706 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003707 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
3708 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3709 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003710 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003711 ql_dbg(ql_dbg_mbx, vha, 0x10f0, "Done %s.\n", __func__);
3712
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003713
3714 *actual_size = mcp->mb[2] << 2;
3715 }
3716
3717 return rval;
3718}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003719
3720int
3721qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
3722 uint16_t size)
3723{
3724 int rval;
3725 mbx_cmd_t mc;
3726 mbx_cmd_t *mcp = &mc;
3727
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003728 ql_dbg(ql_dbg_mbx, vha, 0x10f1, "Entered %s.\n", __func__);
3729
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003730 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003731 return QLA_FUNCTION_FAILED;
3732
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003733 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
3734 mcp->mb[1] = 0;
3735 mcp->mb[2] = MSW(tlv_dma);
3736 mcp->mb[3] = LSW(tlv_dma);
3737 mcp->mb[6] = MSW(MSD(tlv_dma));
3738 mcp->mb[7] = LSW(MSD(tlv_dma));
3739 mcp->mb[8] = size;
3740 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3741 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3742 mcp->tov = MBX_TOV_SECONDS;
3743 mcp->flags = 0;
3744 rval = qla2x00_mailbox_command(vha, mcp);
3745
3746 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003747 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
3748 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3749 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003750 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003751 ql_dbg(ql_dbg_mbx, vha, 0x10f3, "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003752 }
3753
3754 return rval;
3755}
Andrew Vasquez18e75552009-06-03 09:55:30 -07003756
3757int
3758qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
3759{
3760 int rval;
3761 mbx_cmd_t mc;
3762 mbx_cmd_t *mcp = &mc;
3763
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003764 ql_dbg(ql_dbg_mbx, vha, 0x10f4, "Entered %s.\n", __func__);
3765
Andrew Vasquez18e75552009-06-03 09:55:30 -07003766 if (!IS_FWI2_CAPABLE(vha->hw))
3767 return QLA_FUNCTION_FAILED;
3768
Andrew Vasquez18e75552009-06-03 09:55:30 -07003769 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3770 mcp->mb[1] = LSW(risc_addr);
3771 mcp->mb[8] = MSW(risc_addr);
3772 mcp->out_mb = MBX_8|MBX_1|MBX_0;
3773 mcp->in_mb = MBX_3|MBX_2|MBX_0;
3774 mcp->tov = 30;
3775 mcp->flags = 0;
3776 rval = qla2x00_mailbox_command(vha, mcp);
3777 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003778 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
3779 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003780 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003781 ql_dbg(ql_dbg_mbx, vha, 0x10f6, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003782 *data = mcp->mb[3] << 16 | mcp->mb[2];
3783 }
3784
3785 return rval;
3786}
3787
3788int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003789qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3790 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003791{
3792 int rval;
3793 mbx_cmd_t mc;
3794 mbx_cmd_t *mcp = &mc;
3795 uint32_t iter_cnt = 0x1;
3796
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003797 ql_dbg(ql_dbg_mbx, vha, 0x10f7, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003798
3799 memset(mcp->mb, 0 , sizeof(mcp->mb));
3800 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3801 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
3802
3803 /* transfer count */
3804 mcp->mb[10] = LSW(mreq->transfer_size);
3805 mcp->mb[11] = MSW(mreq->transfer_size);
3806
3807 /* send data address */
3808 mcp->mb[14] = LSW(mreq->send_dma);
3809 mcp->mb[15] = MSW(mreq->send_dma);
3810 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3811 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3812
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003813 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003814 mcp->mb[16] = LSW(mreq->rcv_dma);
3815 mcp->mb[17] = MSW(mreq->rcv_dma);
3816 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3817 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3818
3819 /* Iteration count */
3820 mcp->mb[18] = LSW(iter_cnt);
3821 mcp->mb[19] = MSW(iter_cnt);
3822
3823 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3824 MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003825 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003826 mcp->out_mb |= MBX_2;
3827 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3828
3829 mcp->buf_size = mreq->transfer_size;
3830 mcp->tov = MBX_TOV_SECONDS;
3831 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3832
3833 rval = qla2x00_mailbox_command(vha, mcp);
3834
3835 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003836 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
3837 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
3838 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
3839 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003840 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003841 ql_dbg(ql_dbg_mbx, vha, 0x10f9, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003842 }
3843
3844 /* Copy mailbox information */
3845 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003846 return rval;
3847}
3848
3849int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003850qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3851 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003852{
3853 int rval;
3854 mbx_cmd_t mc;
3855 mbx_cmd_t *mcp = &mc;
3856 struct qla_hw_data *ha = vha->hw;
3857
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003858 ql_dbg(ql_dbg_mbx, vha, 0x10fa, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003859
3860 memset(mcp->mb, 0 , sizeof(mcp->mb));
3861 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
3862 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003863 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003864 mcp->mb[1] |= BIT_15;
Giridhar Malavalia9083012010-04-12 17:59:55 -07003865 mcp->mb[2] = vha->fcoe_fcf_idx;
3866 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003867 mcp->mb[16] = LSW(mreq->rcv_dma);
3868 mcp->mb[17] = MSW(mreq->rcv_dma);
3869 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3870 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3871
3872 mcp->mb[10] = LSW(mreq->transfer_size);
3873
3874 mcp->mb[14] = LSW(mreq->send_dma);
3875 mcp->mb[15] = MSW(mreq->send_dma);
3876 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3877 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3878
3879 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3880 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003881 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003882 mcp->out_mb |= MBX_2;
3883
3884 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003885 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
3886 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003887 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003888 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003889 mcp->in_mb |= MBX_3;
3890
3891 mcp->tov = MBX_TOV_SECONDS;
3892 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3893 mcp->buf_size = mreq->transfer_size;
3894
3895 rval = qla2x00_mailbox_command(vha, mcp);
3896
3897 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003898 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
3899 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3900 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003901 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003902 ql_dbg(ql_dbg_mbx, vha, 0x10fc, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003903 }
3904
3905 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003906 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003907 return rval;
3908}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003909
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003910int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003911qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003912{
3913 int rval;
3914 mbx_cmd_t mc;
3915 mbx_cmd_t *mcp = &mc;
3916
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003917 ql_dbg(ql_dbg_mbx, vha, 0x10fd,
3918 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003919
3920 mcp->mb[0] = MBC_ISP84XX_RESET;
3921 mcp->mb[1] = enable_diagnostic;
3922 mcp->out_mb = MBX_1|MBX_0;
3923 mcp->in_mb = MBX_1|MBX_0;
3924 mcp->tov = MBX_TOV_SECONDS;
3925 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003926 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003927
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003928 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003929 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003930 else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003931 ql_dbg(ql_dbg_mbx, vha, 0x10ff, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003932
3933 return rval;
3934}
3935
3936int
Andrew Vasquez18e75552009-06-03 09:55:30 -07003937qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
3938{
3939 int rval;
3940 mbx_cmd_t mc;
3941 mbx_cmd_t *mcp = &mc;
3942
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003943 ql_dbg(ql_dbg_mbx, vha, 0x1100, "Entered %s.\n", __func__);
3944
Andrew Vasquez18e75552009-06-03 09:55:30 -07003945 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07003946 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07003947
Andrew Vasquez18e75552009-06-03 09:55:30 -07003948 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
3949 mcp->mb[1] = LSW(risc_addr);
3950 mcp->mb[2] = LSW(data);
3951 mcp->mb[3] = MSW(data);
3952 mcp->mb[8] = MSW(risc_addr);
3953 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3954 mcp->in_mb = MBX_0;
3955 mcp->tov = 30;
3956 mcp->flags = 0;
3957 rval = qla2x00_mailbox_command(vha, mcp);
3958 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003959 ql_dbg(ql_dbg_mbx, vha, 0x1101,
3960 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003961 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003962 ql_dbg(ql_dbg_mbx, vha, 0x1102, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003963 }
3964
3965 return rval;
3966}
Michael Hernandez3064ff32009-12-15 21:29:44 -08003967
3968int
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003969qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
3970{
3971 int rval;
3972 uint32_t stat, timer;
3973 uint16_t mb0 = 0;
3974 struct qla_hw_data *ha = vha->hw;
3975 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
3976
3977 rval = QLA_SUCCESS;
3978
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003979 ql_dbg(ql_dbg_mbx, vha, 0x1103, "Entered %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003980
3981 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
3982
3983 /* Write the MBC data to the registers */
3984 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
3985 WRT_REG_WORD(&reg->mailbox1, mb[0]);
3986 WRT_REG_WORD(&reg->mailbox2, mb[1]);
3987 WRT_REG_WORD(&reg->mailbox3, mb[2]);
3988 WRT_REG_WORD(&reg->mailbox4, mb[3]);
3989
3990 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
3991
3992 /* Poll for MBC interrupt */
3993 for (timer = 6000000; timer; timer--) {
3994 /* Check for pending interrupts. */
3995 stat = RD_REG_DWORD(&reg->host_status);
3996 if (stat & HSRX_RISC_INT) {
3997 stat &= 0xff;
3998
3999 if (stat == 0x1 || stat == 0x2 ||
4000 stat == 0x10 || stat == 0x11) {
4001 set_bit(MBX_INTERRUPT,
4002 &ha->mbx_cmd_flags);
4003 mb0 = RD_REG_WORD(&reg->mailbox0);
4004 WRT_REG_DWORD(&reg->hccr,
4005 HCCRX_CLR_RISC_INT);
4006 RD_REG_DWORD(&reg->hccr);
4007 break;
4008 }
4009 }
4010 udelay(5);
4011 }
4012
4013 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
4014 rval = mb0 & MBS_MASK;
4015 else
4016 rval = QLA_FUNCTION_FAILED;
4017
4018 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004019 ql_dbg(ql_dbg_mbx, vha, 0x1104,
4020 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004021 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004022 ql_dbg(ql_dbg_mbx, vha, 0x1105, "Done %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004023 }
4024
4025 return rval;
4026}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004027
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004028int
Michael Hernandez3064ff32009-12-15 21:29:44 -08004029qla2x00_get_data_rate(scsi_qla_host_t *vha)
4030{
4031 int rval;
4032 mbx_cmd_t mc;
4033 mbx_cmd_t *mcp = &mc;
4034 struct qla_hw_data *ha = vha->hw;
4035
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004036 ql_dbg(ql_dbg_mbx, vha, 0x1106, "Entered %s.\n", __func__);
4037
Michael Hernandez3064ff32009-12-15 21:29:44 -08004038 if (!IS_FWI2_CAPABLE(ha))
4039 return QLA_FUNCTION_FAILED;
4040
Michael Hernandez3064ff32009-12-15 21:29:44 -08004041 mcp->mb[0] = MBC_DATA_RATE;
4042 mcp->mb[1] = 0;
4043 mcp->out_mb = MBX_1|MBX_0;
4044 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004045 if (IS_QLA83XX(ha))
4046 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08004047 mcp->tov = MBX_TOV_SECONDS;
4048 mcp->flags = 0;
4049 rval = qla2x00_mailbox_command(vha, mcp);
4050 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004051 ql_dbg(ql_dbg_mbx, vha, 0x1107,
4052 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004053 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004054 ql_dbg(ql_dbg_mbx, vha, 0x1108, "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004055 if (mcp->mb[1] != 0x7)
4056 ha->link_data_rate = mcp->mb[1];
4057 }
4058
4059 return rval;
4060}
Sarang Radke09ff7012010-03-19 17:03:59 -07004061
4062int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004063qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4064{
4065 int rval;
4066 mbx_cmd_t mc;
4067 mbx_cmd_t *mcp = &mc;
4068 struct qla_hw_data *ha = vha->hw;
4069
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004070 ql_dbg(ql_dbg_mbx, vha, 0x1109, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004071
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004072 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004073 return QLA_FUNCTION_FAILED;
4074 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4075 mcp->out_mb = MBX_0;
4076 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4077 mcp->tov = MBX_TOV_SECONDS;
4078 mcp->flags = 0;
4079
4080 rval = qla2x00_mailbox_command(vha, mcp);
4081
4082 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004083 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4084 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004085 } else {
4086 /* Copy all bits to preserve original value */
4087 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4088
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004089 ql_dbg(ql_dbg_mbx, vha, 0x110b, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004090 }
4091 return rval;
4092}
4093
4094int
4095qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4096{
4097 int rval;
4098 mbx_cmd_t mc;
4099 mbx_cmd_t *mcp = &mc;
4100
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004101 ql_dbg(ql_dbg_mbx, vha, 0x110c, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004102
4103 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4104 /* Copy all bits to preserve original setting */
4105 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4106 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4107 mcp->in_mb = MBX_0;
4108 mcp->tov = MBX_TOV_SECONDS;
4109 mcp->flags = 0;
4110 rval = qla2x00_mailbox_command(vha, mcp);
4111
4112 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004113 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4114 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004115 } else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004116 ql_dbg(ql_dbg_mbx, vha, 0x110e, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004117
4118 return rval;
4119}
4120
4121
4122int
Sarang Radke09ff7012010-03-19 17:03:59 -07004123qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4124 uint16_t *mb)
4125{
4126 int rval;
4127 mbx_cmd_t mc;
4128 mbx_cmd_t *mcp = &mc;
4129 struct qla_hw_data *ha = vha->hw;
4130
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004131 ql_dbg(ql_dbg_mbx, vha, 0x110f, "Entered %s.\n", __func__);
4132
Sarang Radke09ff7012010-03-19 17:03:59 -07004133 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4134 return QLA_FUNCTION_FAILED;
4135
Sarang Radke09ff7012010-03-19 17:03:59 -07004136 mcp->mb[0] = MBC_PORT_PARAMS;
4137 mcp->mb[1] = loop_id;
4138 if (ha->flags.fcp_prio_enabled)
4139 mcp->mb[2] = BIT_1;
4140 else
4141 mcp->mb[2] = BIT_2;
4142 mcp->mb[4] = priority & 0xf;
4143 mcp->mb[9] = vha->vp_idx;
4144 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4145 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4146 mcp->tov = 30;
4147 mcp->flags = 0;
4148 rval = qla2x00_mailbox_command(vha, mcp);
4149 if (mb != NULL) {
4150 mb[0] = mcp->mb[0];
4151 mb[1] = mcp->mb[1];
4152 mb[3] = mcp->mb[3];
4153 mb[4] = mcp->mb[4];
4154 }
4155
4156 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004157 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07004158 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004159 ql_dbg(ql_dbg_mbx, vha, 0x10cc, "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07004160 }
4161
4162 return rval;
4163}
Giridhar Malavalia9083012010-04-12 17:59:55 -07004164
4165int
Andrew Vasquez794a5692010-12-21 16:00:21 -08004166qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac)
4167{
4168 int rval;
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004169 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004170 struct qla_hw_data *ha = vha->hw;
4171
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004172 ql_dbg(ql_dbg_mbx, vha, 0x10ca, "Entered %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004173
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004174 /* Integer part */
4175 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 1, BIT_13|BIT_0);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004176 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004177 ql_dbg(ql_dbg_mbx, vha, 0x10c9, "Failed=%x.\n", rval);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004178 ha->flags.thermal_supported = 0;
4179 goto fail;
4180 }
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004181 *temp = byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004182
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004183 /* Fraction part */
4184 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x10, 1, BIT_13|BIT_0);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004185 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004186 ql_dbg(ql_dbg_mbx, vha, 0x1019, "Failed=%x.\n", rval);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004187 ha->flags.thermal_supported = 0;
4188 goto fail;
4189 }
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004190 *frac = (byte >> 6) * 25;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004191
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004192 ql_dbg(ql_dbg_mbx, vha, 0x1018, "Done %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004193fail:
4194 return rval;
4195}
4196
4197int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004198qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
4199{
4200 int rval;
4201 struct qla_hw_data *ha = vha->hw;
4202 mbx_cmd_t mc;
4203 mbx_cmd_t *mcp = &mc;
4204
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004205 ql_dbg(ql_dbg_mbx, vha, 0x1017, "Entered %s.\n", __func__);
4206
Giridhar Malavalia9083012010-04-12 17:59:55 -07004207 if (!IS_FWI2_CAPABLE(ha))
4208 return QLA_FUNCTION_FAILED;
4209
Giridhar Malavalia9083012010-04-12 17:59:55 -07004210 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004211 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004212 mcp->mb[1] = 1;
4213
4214 mcp->out_mb = MBX_1|MBX_0;
4215 mcp->in_mb = MBX_0;
4216 mcp->tov = 30;
4217 mcp->flags = 0;
4218
4219 rval = qla2x00_mailbox_command(vha, mcp);
4220 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004221 ql_dbg(ql_dbg_mbx, vha, 0x1016,
4222 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004223 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004224 ql_dbg(ql_dbg_mbx, vha, 0x100e, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004225 }
4226
4227 return rval;
4228}
4229
4230int
4231qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4232{
4233 int rval;
4234 struct qla_hw_data *ha = vha->hw;
4235 mbx_cmd_t mc;
4236 mbx_cmd_t *mcp = &mc;
4237
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004238 ql_dbg(ql_dbg_mbx, vha, 0x100d, "Entered %s.\n", __func__);
4239
Giridhar Malavalia9083012010-04-12 17:59:55 -07004240 if (!IS_QLA82XX(ha))
4241 return QLA_FUNCTION_FAILED;
4242
Giridhar Malavalia9083012010-04-12 17:59:55 -07004243 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004244 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004245 mcp->mb[1] = 0;
4246
4247 mcp->out_mb = MBX_1|MBX_0;
4248 mcp->in_mb = MBX_0;
4249 mcp->tov = 30;
4250 mcp->flags = 0;
4251
4252 rval = qla2x00_mailbox_command(vha, mcp);
4253 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004254 ql_dbg(ql_dbg_mbx, vha, 0x100c,
4255 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004256 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004257 ql_dbg(ql_dbg_mbx, vha, 0x100b, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004258 }
4259
4260 return rval;
4261}
Giridhar Malavali08de2842011-08-16 11:31:44 -07004262
4263int
4264qla82xx_md_get_template_size(scsi_qla_host_t *vha)
4265{
4266 struct qla_hw_data *ha = vha->hw;
4267 mbx_cmd_t mc;
4268 mbx_cmd_t *mcp = &mc;
4269 int rval = QLA_FUNCTION_FAILED;
4270
4271 ql_dbg(ql_dbg_mbx, vha, 0x111f, "Entered %s.\n", __func__);
4272
4273 memset(mcp->mb, 0 , sizeof(mcp->mb));
4274 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4275 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4276 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
4277 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
4278
4279 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4280 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
4281 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4282
4283 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4284 mcp->tov = MBX_TOV_SECONDS;
4285 rval = qla2x00_mailbox_command(vha, mcp);
4286
4287 /* Always copy back return mailbox values. */
4288 if (rval != QLA_SUCCESS) {
4289 ql_dbg(ql_dbg_mbx, vha, 0x1120,
4290 "mailbox command FAILED=0x%x, subcode=%x.\n",
4291 (mcp->mb[1] << 16) | mcp->mb[0],
4292 (mcp->mb[3] << 16) | mcp->mb[2]);
4293 } else {
4294 ql_dbg(ql_dbg_mbx, vha, 0x1121, "Done %s.\n", __func__);
4295 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
4296 if (!ha->md_template_size) {
4297 ql_dbg(ql_dbg_mbx, vha, 0x1122,
4298 "Null template size obtained.\n");
4299 rval = QLA_FUNCTION_FAILED;
4300 }
4301 }
4302 return rval;
4303}
4304
4305int
4306qla82xx_md_get_template(scsi_qla_host_t *vha)
4307{
4308 struct qla_hw_data *ha = vha->hw;
4309 mbx_cmd_t mc;
4310 mbx_cmd_t *mcp = &mc;
4311 int rval = QLA_FUNCTION_FAILED;
4312
4313 ql_dbg(ql_dbg_mbx, vha, 0x1123, "Entered %s.\n", __func__);
4314
4315 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4316 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4317 if (!ha->md_tmplt_hdr) {
4318 ql_log(ql_log_warn, vha, 0x1124,
4319 "Unable to allocate memory for Minidump template.\n");
4320 return rval;
4321 }
4322
4323 memset(mcp->mb, 0 , sizeof(mcp->mb));
4324 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4325 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4326 mcp->mb[2] = LSW(RQST_TMPLT);
4327 mcp->mb[3] = MSW(RQST_TMPLT);
4328 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
4329 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
4330 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
4331 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
4332 mcp->mb[8] = LSW(ha->md_template_size);
4333 mcp->mb[9] = MSW(ha->md_template_size);
4334
4335 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4336 mcp->tov = MBX_TOV_SECONDS;
4337 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4338 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4339 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4340 rval = qla2x00_mailbox_command(vha, mcp);
4341
4342 if (rval != QLA_SUCCESS) {
4343 ql_dbg(ql_dbg_mbx, vha, 0x1125,
4344 "mailbox command FAILED=0x%x, subcode=%x.\n",
4345 ((mcp->mb[1] << 16) | mcp->mb[0]),
4346 ((mcp->mb[3] << 16) | mcp->mb[2]));
4347 } else
4348 ql_dbg(ql_dbg_mbx, vha, 0x1126, "Done %s.\n", __func__);
4349 return rval;
4350}
Saurav Kashyap999916d2011-08-16 11:31:45 -07004351
4352int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004353qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4354{
4355 int rval;
4356 struct qla_hw_data *ha = vha->hw;
4357 mbx_cmd_t mc;
4358 mbx_cmd_t *mcp = &mc;
4359
4360 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4361 return QLA_FUNCTION_FAILED;
4362
4363 ql_dbg(ql_dbg_mbx, vha, 0x1133, "Entered %s.\n", __func__);
4364
4365 memset(mcp, 0, sizeof(mbx_cmd_t));
4366 mcp->mb[0] = MBC_SET_LED_CONFIG;
4367 mcp->mb[1] = led_cfg[0];
4368 mcp->mb[2] = led_cfg[1];
4369 if (IS_QLA8031(ha)) {
4370 mcp->mb[3] = led_cfg[2];
4371 mcp->mb[4] = led_cfg[3];
4372 mcp->mb[5] = led_cfg[4];
4373 mcp->mb[6] = led_cfg[5];
4374 }
4375
4376 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4377 if (IS_QLA8031(ha))
4378 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4379 mcp->in_mb = MBX_0;
4380 mcp->tov = 30;
4381 mcp->flags = 0;
4382
4383 rval = qla2x00_mailbox_command(vha, mcp);
4384 if (rval != QLA_SUCCESS) {
4385 ql_dbg(ql_dbg_mbx, vha, 0x1134,
4386 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4387 } else {
4388 ql_dbg(ql_dbg_mbx, vha, 0x1135, "Done %s.\n", __func__);
4389 }
4390
4391 return rval;
4392}
4393
4394int
4395qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4396{
4397 int rval;
4398 struct qla_hw_data *ha = vha->hw;
4399 mbx_cmd_t mc;
4400 mbx_cmd_t *mcp = &mc;
4401
4402 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4403 return QLA_FUNCTION_FAILED;
4404
4405 ql_dbg(ql_dbg_mbx, vha, 0x1136, "Entered %s.\n", __func__);
4406
4407 memset(mcp, 0, sizeof(mbx_cmd_t));
4408 mcp->mb[0] = MBC_GET_LED_CONFIG;
4409
4410 mcp->out_mb = MBX_0;
4411 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4412 if (IS_QLA8031(ha))
4413 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4414 mcp->tov = 30;
4415 mcp->flags = 0;
4416
4417 rval = qla2x00_mailbox_command(vha, mcp);
4418 if (rval != QLA_SUCCESS) {
4419 ql_dbg(ql_dbg_mbx, vha, 0x1137,
4420 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4421 } else {
4422 led_cfg[0] = mcp->mb[1];
4423 led_cfg[1] = mcp->mb[2];
4424 if (IS_QLA8031(ha)) {
4425 led_cfg[2] = mcp->mb[3];
4426 led_cfg[3] = mcp->mb[4];
4427 led_cfg[4] = mcp->mb[5];
4428 led_cfg[5] = mcp->mb[6];
4429 }
4430 ql_dbg(ql_dbg_mbx, vha, 0x1138, "Done %s.\n", __func__);
4431 }
4432
4433 return rval;
4434}
4435
4436int
Saurav Kashyap999916d2011-08-16 11:31:45 -07004437qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
4438{
4439 int rval;
4440 struct qla_hw_data *ha = vha->hw;
4441 mbx_cmd_t mc;
4442 mbx_cmd_t *mcp = &mc;
4443
4444 if (!IS_QLA82XX(ha))
4445 return QLA_FUNCTION_FAILED;
4446
4447 ql_dbg(ql_dbg_mbx, vha, 0x1127,
4448 "Entered %s.\n", __func__);
4449
4450 memset(mcp, 0, sizeof(mbx_cmd_t));
4451 mcp->mb[0] = MBC_SET_LED_CONFIG;
4452 if (enable)
4453 mcp->mb[7] = 0xE;
4454 else
4455 mcp->mb[7] = 0xD;
4456
4457 mcp->out_mb = MBX_7|MBX_0;
4458 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004459 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07004460 mcp->flags = 0;
4461
4462 rval = qla2x00_mailbox_command(vha, mcp);
4463 if (rval != QLA_SUCCESS) {
4464 ql_dbg(ql_dbg_mbx, vha, 0x1128,
4465 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4466 } else {
4467 ql_dbg(ql_dbg_mbx, vha, 0x1129,
4468 "Done %s.\n", __func__);
4469 }
4470
4471 return rval;
4472}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004473
4474int
4475qla83xx_write_remote_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
4476{
4477 int rval;
4478 struct qla_hw_data *ha = vha->hw;
4479 mbx_cmd_t mc;
4480 mbx_cmd_t *mcp = &mc;
4481
4482 if (!IS_QLA83XX(ha))
4483 return QLA_FUNCTION_FAILED;
4484
4485 ql_dbg(ql_dbg_mbx, vha, 0x1130, "Entered %s.\n", __func__);
4486
4487 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
4488 mcp->mb[1] = LSW(reg);
4489 mcp->mb[2] = MSW(reg);
4490 mcp->mb[3] = LSW(data);
4491 mcp->mb[4] = MSW(data);
4492 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4493
4494 mcp->in_mb = MBX_1|MBX_0;
4495 mcp->tov = MBX_TOV_SECONDS;
4496 mcp->flags = 0;
4497 rval = qla2x00_mailbox_command(vha, mcp);
4498
4499 if (rval != QLA_SUCCESS) {
4500 ql_dbg(ql_dbg_mbx, vha, 0x1131,
4501 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4502 } else {
4503 ql_dbg(ql_dbg_mbx, vha, 0x1132,
4504 "Done %s.\n", __func__);
4505 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004506
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004507 return rval;
4508}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004509
4510int
4511qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
4512{
4513 int rval;
4514 struct qla_hw_data *ha = vha->hw;
4515 mbx_cmd_t mc;
4516 mbx_cmd_t *mcp = &mc;
4517
4518 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
4519 ql_dbg(ql_dbg_mbx, vha, 0x113b,
4520 "Implicit LOGO Unsupported.\n");
4521 return QLA_FUNCTION_FAILED;
4522 }
4523
4524
4525 ql_dbg(ql_dbg_mbx, vha, 0x113c, "Done %s.\n", __func__);
4526
4527 /* Perform Implicit LOGO. */
4528 mcp->mb[0] = MBC_PORT_LOGOUT;
4529 mcp->mb[1] = fcport->loop_id;
4530 mcp->mb[10] = BIT_15;
4531 mcp->out_mb = MBX_10|MBX_1|MBX_0;
4532 mcp->in_mb = MBX_0;
4533 mcp->tov = MBX_TOV_SECONDS;
4534 mcp->flags = 0;
4535 rval = qla2x00_mailbox_command(vha, mcp);
4536 if (rval != QLA_SUCCESS)
4537 ql_dbg(ql_dbg_mbx, vha, 0x113d,
4538 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4539 else
4540 ql_dbg(ql_dbg_mbx, vha, 0x113e, "Done %s.\n", __func__);
4541
4542 return rval;
4543}
4544