blob: 61e2fb75fbf0cab10d1f976abe37f31372d08bff [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;
1646 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001647 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001648 ql_dbg(ql_dbg_mbx, vha, 0x1063,
1649 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001650 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001651 ql_dbg(ql_dbg_mbx, vha, 0x1064,
1652 "Failed to complete IOCB -- error status (%x).\n",
1653 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001654 rval = QLA_FUNCTION_FAILED;
1655 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1656 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1657 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1658
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001659 ql_dbg(ql_dbg_mbx, vha, 0x1065,
1660 "Failed to complete IOCB -- completion status (%x) "
1661 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
1662 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001663
1664 switch (iop[0]) {
1665 case LSC_SCODE_PORTID_USED:
1666 mb[0] = MBS_PORT_ID_USED;
1667 mb[1] = LSW(iop[1]);
1668 break;
1669 case LSC_SCODE_NPORT_USED:
1670 mb[0] = MBS_LOOP_ID_USED;
1671 break;
1672 case LSC_SCODE_NOLINK:
1673 case LSC_SCODE_NOIOCB:
1674 case LSC_SCODE_NOXCB:
1675 case LSC_SCODE_CMD_FAILED:
1676 case LSC_SCODE_NOFABRIC:
1677 case LSC_SCODE_FW_NOT_READY:
1678 case LSC_SCODE_NOT_LOGGED_IN:
1679 case LSC_SCODE_NOPCB:
1680 case LSC_SCODE_ELS_REJECT:
1681 case LSC_SCODE_CMD_PARAM_ERR:
1682 case LSC_SCODE_NONPORT:
1683 case LSC_SCODE_LOGGED_IN:
1684 case LSC_SCODE_NOFLOGI_ACC:
1685 default:
1686 mb[0] = MBS_COMMAND_ERROR;
1687 break;
1688 }
1689 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001690 ql_dbg(ql_dbg_mbx, vha, 0x1066, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001691
1692 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1693
1694 mb[0] = MBS_COMMAND_COMPLETE;
1695 mb[1] = 0;
1696 if (iop[0] & BIT_4) {
1697 if (iop[0] & BIT_8)
1698 mb[1] |= BIT_1;
1699 } else
1700 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001701
1702 /* Passback COS information. */
1703 mb[10] = 0;
1704 if (lg->io_parameter[7] || lg->io_parameter[8])
1705 mb[10] |= BIT_0; /* Class 2. */
1706 if (lg->io_parameter[9] || lg->io_parameter[10])
1707 mb[10] |= BIT_1; /* Class 3. */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001708 }
1709
1710 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1711
1712 return rval;
1713}
1714
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715/*
1716 * qla2x00_login_fabric
1717 * Issue login fabric port mailbox command.
1718 *
1719 * Input:
1720 * ha = adapter block pointer.
1721 * loop_id = device loop ID.
1722 * domain = device domain.
1723 * area = device area.
1724 * al_pa = device AL_PA.
1725 * status = pointer for return status.
1726 * opt = command options.
1727 * TARGET_QUEUE_LOCK must be released.
1728 * ADAPTER_STATE_LOCK must be released.
1729 *
1730 * Returns:
1731 * qla2x00 local function return status code.
1732 *
1733 * Context:
1734 * Kernel context.
1735 */
1736int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001737qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1739{
1740 int rval;
1741 mbx_cmd_t mc;
1742 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001743 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001745 ql_dbg(ql_dbg_mbx, vha, 0x1067, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746
1747 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1748 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1749 if (HAS_EXTENDED_IDS(ha)) {
1750 mcp->mb[1] = loop_id;
1751 mcp->mb[10] = opt;
1752 mcp->out_mb |= MBX_10;
1753 } else {
1754 mcp->mb[1] = (loop_id << 8) | opt;
1755 }
1756 mcp->mb[2] = domain;
1757 mcp->mb[3] = area << 8 | al_pa;
1758
1759 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1760 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1761 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001762 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763
1764 /* Return mailbox statuses. */
1765 if (mb != NULL) {
1766 mb[0] = mcp->mb[0];
1767 mb[1] = mcp->mb[1];
1768 mb[2] = mcp->mb[2];
1769 mb[6] = mcp->mb[6];
1770 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001771 /* COS retrieved from Get-Port-Database mailbox command. */
1772 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 }
1774
1775 if (rval != QLA_SUCCESS) {
1776 /* RLU tmp code: need to change main mailbox_command function to
1777 * return ok even when the mailbox completion value is not
1778 * SUCCESS. The caller needs to be responsible to interpret
1779 * the return values of this mailbox command if we're not
1780 * to change too much of the existing code.
1781 */
1782 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
1783 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
1784 mcp->mb[0] == 0x4006)
1785 rval = QLA_SUCCESS;
1786
1787 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001788 ql_dbg(ql_dbg_mbx, vha, 0x1068,
1789 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
1790 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 } else {
1792 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001793 ql_dbg(ql_dbg_mbx, vha, 0x1069, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 }
1795
1796 return rval;
1797}
1798
1799/*
1800 * qla2x00_login_local_device
1801 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001802 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 * Input:
1804 * ha = adapter block pointer.
1805 * loop_id = device loop ID.
1806 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001807 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808 * Returns:
1809 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001810 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 * Context:
1812 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001813 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 */
1815int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001816qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 uint16_t *mb_ret, uint8_t opt)
1818{
1819 int rval;
1820 mbx_cmd_t mc;
1821 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001822 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001824 ql_dbg(ql_dbg_mbx, vha, 0x106a, "Entered %s.\n", __func__);
1825
Andrew Vasqueze4289242007-07-19 15:05:56 -07001826 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001827 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001828 fcport->d_id.b.domain, fcport->d_id.b.area,
1829 fcport->d_id.b.al_pa, mb_ret, opt);
1830
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1832 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001833 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834 else
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001835 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 mcp->mb[2] = opt;
1837 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1838 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
1839 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1840 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001841 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842
1843 /* Return mailbox statuses. */
1844 if (mb_ret != NULL) {
1845 mb_ret[0] = mcp->mb[0];
1846 mb_ret[1] = mcp->mb[1];
1847 mb_ret[6] = mcp->mb[6];
1848 mb_ret[7] = mcp->mb[7];
1849 }
1850
1851 if (rval != QLA_SUCCESS) {
1852 /* AV tmp code: need to change main mailbox_command function to
1853 * return ok even when the mailbox completion value is not
1854 * SUCCESS. The caller needs to be responsible to interpret
1855 * the return values of this mailbox command if we're not
1856 * to change too much of the existing code.
1857 */
1858 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
1859 rval = QLA_SUCCESS;
1860
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001861 ql_dbg(ql_dbg_mbx, vha, 0x106b,
1862 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
1863 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 } else {
1865 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001866 ql_dbg(ql_dbg_mbx, vha, 0x106c, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 }
1868
1869 return (rval);
1870}
1871
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001872int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001873qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001874 uint8_t area, uint8_t al_pa)
1875{
1876 int rval;
1877 struct logio_entry_24xx *lg;
1878 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001879 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001880 struct req_que *req;
1881 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001882
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001883 ql_dbg(ql_dbg_mbx, vha, 0x106d, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001884
1885 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1886 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001887 ql_log(ql_log_warn, vha, 0x106e,
1888 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001889 return QLA_MEMORY_ALLOC_FAILED;
1890 }
1891 memset(lg, 0, sizeof(struct logio_entry_24xx));
1892
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001893 if (ql2xmaxqueues > 1)
1894 req = ha->req_q_map[0];
1895 else
1896 req = vha->req;
1897 rsp = req->rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001898 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1899 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001900 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001901 lg->nport_handle = cpu_to_le16(loop_id);
1902 lg->control_flags =
Andrew Vasquezc8d66912011-03-30 11:46:21 -07001903 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
1904 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001905 lg->port_id[0] = al_pa;
1906 lg->port_id[1] = area;
1907 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001908 lg->vp_index = vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001909
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001910 rval = qla2x00_issue_iocb(vha, lg, lg_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001911 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001912 ql_dbg(ql_dbg_mbx, vha, 0x106f,
1913 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001914 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001915 ql_dbg(ql_dbg_mbx, vha, 0x1070,
1916 "Failed to complete IOCB -- error status (%x).\n",
1917 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001918 rval = QLA_FUNCTION_FAILED;
1919 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001920 ql_dbg(ql_dbg_mbx, vha, 0x1071,
1921 "Failed to complete IOCB -- completion status (%x) "
1922 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001923 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001924 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001925 } else {
1926 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001927 ql_dbg(ql_dbg_mbx, vha, 0x1072, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001928 }
1929
1930 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1931
1932 return rval;
1933}
1934
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935/*
1936 * qla2x00_fabric_logout
1937 * Issue logout fabric port mailbox command.
1938 *
1939 * Input:
1940 * ha = adapter block pointer.
1941 * loop_id = device loop ID.
1942 * TARGET_QUEUE_LOCK must be released.
1943 * ADAPTER_STATE_LOCK must be released.
1944 *
1945 * Returns:
1946 * qla2x00 local function return status code.
1947 *
1948 * Context:
1949 * Kernel context.
1950 */
1951int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001952qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001953 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954{
1955 int rval;
1956 mbx_cmd_t mc;
1957 mbx_cmd_t *mcp = &mc;
1958
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001959 ql_dbg(ql_dbg_mbx, vha, 0x1073, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960
1961 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1962 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001963 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964 mcp->mb[1] = loop_id;
1965 mcp->mb[10] = 0;
1966 mcp->out_mb |= MBX_10;
1967 } else {
1968 mcp->mb[1] = loop_id << 8;
1969 }
1970
1971 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001972 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001974 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975
1976 if (rval != QLA_SUCCESS) {
1977 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001978 ql_dbg(ql_dbg_mbx, vha, 0x1074,
1979 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980 } else {
1981 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001982 ql_dbg(ql_dbg_mbx, vha, 0x1075, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983 }
1984
1985 return rval;
1986}
1987
1988/*
1989 * qla2x00_full_login_lip
1990 * Issue full login LIP mailbox command.
1991 *
1992 * Input:
1993 * ha = adapter block pointer.
1994 * TARGET_QUEUE_LOCK must be released.
1995 * ADAPTER_STATE_LOCK must be released.
1996 *
1997 * Returns:
1998 * qla2x00 local function return status code.
1999 *
2000 * Context:
2001 * Kernel context.
2002 */
2003int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002004qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005{
2006 int rval;
2007 mbx_cmd_t mc;
2008 mbx_cmd_t *mcp = &mc;
2009
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002010 ql_dbg(ql_dbg_mbx, vha, 0x1076, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002011
2012 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002013 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002014 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002015 mcp->mb[3] = 0;
2016 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2017 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002018 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002020 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002021
2022 if (rval != QLA_SUCCESS) {
2023 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002024 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025 } else {
2026 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002027 ql_dbg(ql_dbg_mbx, vha, 0x1078, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028 }
2029
2030 return rval;
2031}
2032
2033/*
2034 * qla2x00_get_id_list
2035 *
2036 * Input:
2037 * ha = adapter block pointer.
2038 *
2039 * Returns:
2040 * qla2x00 local function return status code.
2041 *
2042 * Context:
2043 * Kernel context.
2044 */
2045int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002046qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 uint16_t *entries)
2048{
2049 int rval;
2050 mbx_cmd_t mc;
2051 mbx_cmd_t *mcp = &mc;
2052
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002053 ql_dbg(ql_dbg_mbx, vha, 0x1079, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054
2055 if (id_list == NULL)
2056 return QLA_FUNCTION_FAILED;
2057
2058 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002059 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002060 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002061 mcp->mb[2] = MSW(id_list_dma);
2062 mcp->mb[3] = LSW(id_list_dma);
2063 mcp->mb[6] = MSW(MSD(id_list_dma));
2064 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002065 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002066 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002067 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002068 } else {
2069 mcp->mb[1] = MSW(id_list_dma);
2070 mcp->mb[2] = LSW(id_list_dma);
2071 mcp->mb[3] = MSW(MSD(id_list_dma));
2072 mcp->mb[6] = LSW(MSD(id_list_dma));
2073 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2074 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002076 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002078 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079
2080 if (rval != QLA_SUCCESS) {
2081 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002082 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083 } else {
2084 *entries = mcp->mb[1];
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002085 ql_dbg(ql_dbg_mbx, vha, 0x107b, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 }
2087
2088 return rval;
2089}
2090
2091/*
2092 * qla2x00_get_resource_cnts
2093 * Get current firmware resource counts.
2094 *
2095 * Input:
2096 * ha = adapter block pointer.
2097 *
2098 * Returns:
2099 * qla2x00 local function return status code.
2100 *
2101 * Context:
2102 * Kernel context.
2103 */
2104int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002105qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002106 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002107 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002108{
2109 int rval;
2110 mbx_cmd_t mc;
2111 mbx_cmd_t *mcp = &mc;
2112
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002113 ql_dbg(ql_dbg_mbx, vha, 0x107c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114
2115 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2116 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002117 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 -08002118 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002119 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002120 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002121 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002122 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123
2124 if (rval != QLA_SUCCESS) {
2125 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002126 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2127 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002129 ql_dbg(ql_dbg_mbx, vha, 0x107e,
2130 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2131 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2132 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2133 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134
2135 if (cur_xchg_cnt)
2136 *cur_xchg_cnt = mcp->mb[3];
2137 if (orig_xchg_cnt)
2138 *orig_xchg_cnt = mcp->mb[6];
2139 if (cur_iocb_cnt)
2140 *cur_iocb_cnt = mcp->mb[7];
2141 if (orig_iocb_cnt)
2142 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002143 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002144 *max_npiv_vports = mcp->mb[11];
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002145 if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) && max_fcfs)
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002146 *max_fcfs = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002147 }
2148
2149 return (rval);
2150}
2151
Linus Torvalds1da177e2005-04-16 15:20:36 -07002152/*
2153 * qla2x00_get_fcal_position_map
2154 * Get FCAL (LILP) position map using mailbox command
2155 *
2156 * Input:
2157 * ha = adapter state pointer.
2158 * pos_map = buffer pointer (can be NULL).
2159 *
2160 * Returns:
2161 * qla2x00 local function return status code.
2162 *
2163 * Context:
2164 * Kernel context.
2165 */
2166int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002167qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002168{
2169 int rval;
2170 mbx_cmd_t mc;
2171 mbx_cmd_t *mcp = &mc;
2172 char *pmap;
2173 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002174 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002175
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002176 ql_dbg(ql_dbg_mbx, vha, 0x107f, "Entered %s.\n", __func__);
2177
Andrew Vasquez4b892582008-09-11 21:22:48 -07002178 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002179 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002180 ql_log(ql_log_warn, vha, 0x1080,
2181 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182 return QLA_MEMORY_ALLOC_FAILED;
2183 }
2184 memset(pmap, 0, FCAL_MAP_SIZE);
2185
2186 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2187 mcp->mb[2] = MSW(pmap_dma);
2188 mcp->mb[3] = LSW(pmap_dma);
2189 mcp->mb[6] = MSW(MSD(pmap_dma));
2190 mcp->mb[7] = LSW(MSD(pmap_dma));
2191 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2192 mcp->in_mb = MBX_1|MBX_0;
2193 mcp->buf_size = FCAL_MAP_SIZE;
2194 mcp->flags = MBX_DMA_IN;
2195 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002196 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197
2198 if (rval == QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002199 ql_dbg(ql_dbg_mbx, vha, 0x1081,
2200 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2201 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2202 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2203 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002204
2205 if (pos_map)
2206 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2207 }
2208 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2209
2210 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002211 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002213 ql_dbg(ql_dbg_mbx, vha, 0x1083, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214 }
2215
2216 return rval;
2217}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002218
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002219/*
2220 * qla2x00_get_link_status
2221 *
2222 * Input:
2223 * ha = adapter block pointer.
2224 * loop_id = device loop ID.
2225 * ret_buf = pointer to link status return buffer.
2226 *
2227 * Returns:
2228 * 0 = success.
2229 * BIT_0 = mem alloc error.
2230 * BIT_1 = mailbox error.
2231 */
2232int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002233qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002234 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002235{
2236 int rval;
2237 mbx_cmd_t mc;
2238 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002239 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002240 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002241
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002242 ql_dbg(ql_dbg_mbx, vha, 0x1084, "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002243
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002244 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002245 mcp->mb[2] = MSW(stats_dma);
2246 mcp->mb[3] = LSW(stats_dma);
2247 mcp->mb[6] = MSW(MSD(stats_dma));
2248 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002249 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2250 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002251 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002252 mcp->mb[1] = loop_id;
2253 mcp->mb[4] = 0;
2254 mcp->mb[10] = 0;
2255 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2256 mcp->in_mb |= MBX_1;
2257 } else if (HAS_EXTENDED_IDS(ha)) {
2258 mcp->mb[1] = loop_id;
2259 mcp->mb[10] = 0;
2260 mcp->out_mb |= MBX_10|MBX_1;
2261 } else {
2262 mcp->mb[1] = loop_id << 8;
2263 mcp->out_mb |= MBX_1;
2264 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002265 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002266 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002267 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002268
2269 if (rval == QLA_SUCCESS) {
2270 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002271 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2272 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002273 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002274 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002275 /* Copy over data -- firmware data is LE. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002276 ql_dbg(ql_dbg_mbx, vha, 0x1086, "Done %s.\n", __func__);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002277 dwords = offsetof(struct link_statistics, unused1) / 4;
2278 siter = diter = &stats->link_fail_cnt;
2279 while (dwords--)
2280 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002281 }
2282 } else {
2283 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002284 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002285 }
2286
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002287 return rval;
2288}
2289
2290int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002291qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002292 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002293{
2294 int rval;
2295 mbx_cmd_t mc;
2296 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002297 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002298
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002299 ql_dbg(ql_dbg_mbx, vha, 0x1088, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002300
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002301 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002302 mcp->mb[2] = MSW(stats_dma);
2303 mcp->mb[3] = LSW(stats_dma);
2304 mcp->mb[6] = MSW(MSD(stats_dma));
2305 mcp->mb[7] = LSW(MSD(stats_dma));
2306 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002307 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002308 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002309 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 -07002310 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002311 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002312 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002313 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002314
2315 if (rval == QLA_SUCCESS) {
2316 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002317 ql_dbg(ql_dbg_mbx, vha, 0x1089,
2318 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002319 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002320 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002321 ql_dbg(ql_dbg_mbx, vha, 0x108a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002322 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002323 dwords = sizeof(struct link_statistics) / 4;
2324 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002325 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002326 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002327 }
2328 } else {
2329 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002330 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002331 }
2332
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002333 return rval;
2334}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002335
2336int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002337qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002338{
2339 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002340 unsigned long flags = 0;
2341
2342 struct abort_entry_24xx *abt;
2343 dma_addr_t abt_dma;
2344 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002345 fc_port_t *fcport = sp->fcport;
2346 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002347 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07002348 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002349
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002350 ql_dbg(ql_dbg_mbx, vha, 0x108c, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002351
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002352 spin_lock_irqsave(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002353 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002354 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002355 break;
2356 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002357 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002358 if (handle == MAX_OUTSTANDING_COMMANDS) {
2359 /* Command not found. */
2360 return QLA_FUNCTION_FAILED;
2361 }
2362
2363 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2364 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002365 ql_log(ql_log_warn, vha, 0x108d,
2366 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002367 return QLA_MEMORY_ALLOC_FAILED;
2368 }
2369 memset(abt, 0, sizeof(struct abort_entry_24xx));
2370
2371 abt->entry_type = ABORT_IOCB_TYPE;
2372 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002373 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002374 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07002375 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002376 abt->port_id[0] = fcport->d_id.b.al_pa;
2377 abt->port_id[1] = fcport->d_id.b.area;
2378 abt->port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002379 abt->vp_index = fcport->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002380
2381 abt->req_que_no = cpu_to_le16(req->id);
2382
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002383 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002384 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002385 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2386 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002387 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002388 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2389 "Failed to complete IOCB -- error status (%x).\n",
2390 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002391 rval = QLA_FUNCTION_FAILED;
2392 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002393 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2394 "Failed to complete IOCB -- completion status (%x).\n",
2395 le16_to_cpu(abt->nport_handle));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002396 rval = QLA_FUNCTION_FAILED;
2397 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002398 ql_dbg(ql_dbg_mbx, vha, 0x1091, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002399 }
2400
2401 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2402
2403 return rval;
2404}
2405
2406struct tsk_mgmt_cmd {
2407 union {
2408 struct tsk_mgmt_entry tsk;
2409 struct sts_entry_24xx sts;
2410 } p;
2411};
2412
Andrew Vasquez523ec772008-04-03 13:13:24 -07002413static int
2414__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002415 unsigned int l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002416{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002417 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002418 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002419 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002420 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002421 scsi_qla_host_t *vha;
2422 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002423 struct req_que *req;
2424 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002425
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002426 vha = fcport->vha;
2427 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002428 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002429
2430 ql_dbg(ql_dbg_mbx, vha, 0x1092, "Entered %s.\n", __func__);
2431
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002432 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002433 rsp = ha->rsp_q_map[tag + 1];
2434 else
2435 rsp = req->rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002436 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002437 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002438 ql_log(ql_log_warn, vha, 0x1093,
2439 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002440 return QLA_MEMORY_ALLOC_FAILED;
2441 }
2442 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2443
2444 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2445 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002446 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002447 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002448 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002449 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002450 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2451 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2452 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002453 tsk->p.tsk.vp_index = fcport->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002454 if (type == TCF_LUN_RESET) {
2455 int_to_scsilun(l, &tsk->p.tsk.lun);
2456 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2457 sizeof(tsk->p.tsk.lun));
2458 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002459
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002460 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002461 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002462 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002463 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2464 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002465 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002466 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2467 "Failed to complete IOCB -- error status (%x).\n",
2468 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002469 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002470 } else if (sts->comp_status !=
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002471 __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002472 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2473 "Failed to complete IOCB -- completion status (%x).\n",
2474 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002475 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08002476 } else if (le16_to_cpu(sts->scsi_status) &
2477 SS_RESPONSE_INFO_LEN_VALID) {
2478 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002479 ql_dbg(ql_dbg_mbx, vha, 0x1097,
2480 "Ignoring inconsistent data length -- not enough "
2481 "response info (%d).\n",
2482 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08002483 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002484 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2485 "Failed to complete IOCB -- response (%x).\n",
2486 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08002487 rval = QLA_FUNCTION_FAILED;
2488 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002489 }
2490
2491 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002492 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002493 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2494 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002495 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2496 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002497 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002498 ql_dbg(ql_dbg_mbx, vha, 0x109a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002499 }
2500
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002501 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002502
2503 return rval;
2504}
2505
Andrew Vasquez523ec772008-04-03 13:13:24 -07002506int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002507qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002508{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002509 struct qla_hw_data *ha = fcport->vha->hw;
2510
2511 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2512 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2513
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002514 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002515}
2516
2517int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002518qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002519{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002520 struct qla_hw_data *ha = fcport->vha->hw;
2521
2522 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2523 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2524
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002525 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002526}
2527
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002528int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002529qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002530{
2531 int rval;
2532 mbx_cmd_t mc;
2533 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002534 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002535
Andrew Vasquez68af0812008-05-12 22:21:13 -07002536 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002537 return QLA_FUNCTION_FAILED;
2538
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002539 ql_dbg(ql_dbg_mbx, vha, 0x109b, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002540
2541 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2542 mcp->out_mb = MBX_0;
2543 mcp->in_mb = MBX_0;
2544 mcp->tov = 5;
2545 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002546 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002547
2548 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002549 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002550 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002551 ql_dbg(ql_dbg_mbx, vha, 0x109d, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002552 }
2553
2554 return rval;
2555}
2556
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002557/**
2558 * qla2x00_set_serdes_params() -
2559 * @ha: HA context
2560 *
2561 * Returns
2562 */
2563int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002564qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002565 uint16_t sw_em_2g, uint16_t sw_em_4g)
2566{
2567 int rval;
2568 mbx_cmd_t mc;
2569 mbx_cmd_t *mcp = &mc;
2570
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002571 ql_dbg(ql_dbg_mbx, vha, 0x109e, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002572
2573 mcp->mb[0] = MBC_SERDES_PARAMS;
2574 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08002575 mcp->mb[2] = sw_em_1g | BIT_15;
2576 mcp->mb[3] = sw_em_2g | BIT_15;
2577 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002578 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2579 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002580 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002581 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002582 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002583
2584 if (rval != QLA_SUCCESS) {
2585 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002586 ql_dbg(ql_dbg_mbx, vha, 0x109f,
2587 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002588 } else {
2589 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002590 ql_dbg(ql_dbg_mbx, vha, 0x10a0, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002591 }
2592
2593 return rval;
2594}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002595
2596int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002597qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002598{
2599 int rval;
2600 mbx_cmd_t mc;
2601 mbx_cmd_t *mcp = &mc;
2602
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002603 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002604 return QLA_FUNCTION_FAILED;
2605
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002606 ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002607
2608 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08002609 mcp->mb[1] = 0;
2610 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002611 mcp->in_mb = MBX_0;
2612 mcp->tov = 5;
2613 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002614 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002615
2616 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002617 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07002618 if (mcp->mb[0] == MBS_INVALID_COMMAND)
2619 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002620 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002621 ql_dbg(ql_dbg_mbx, vha, 0x10a3, "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002622 }
2623
2624 return rval;
2625}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002626
2627int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002628qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002629 uint16_t buffers)
2630{
2631 int rval;
2632 mbx_cmd_t mc;
2633 mbx_cmd_t *mcp = &mc;
2634
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002635 ql_dbg(ql_dbg_mbx, vha, 0x10a4, "Entered %s.\n", __func__);
2636
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002637 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002638 return QLA_FUNCTION_FAILED;
2639
Andrew Vasquez85880802009-12-15 21:29:46 -08002640 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2641 return QLA_FUNCTION_FAILED;
2642
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002643 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002644 mcp->mb[1] = TC_EFT_ENABLE;
2645 mcp->mb[2] = LSW(eft_dma);
2646 mcp->mb[3] = MSW(eft_dma);
2647 mcp->mb[4] = LSW(MSD(eft_dma));
2648 mcp->mb[5] = MSW(MSD(eft_dma));
2649 mcp->mb[6] = buffers;
2650 mcp->mb[7] = TC_AEN_DISABLE;
2651 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 -07002652 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002653 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002654 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002655 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002656 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002657 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
2658 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2659 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002660 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002661 ql_dbg(ql_dbg_mbx, vha, 0x10a6, "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002662 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002663
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002664 return rval;
2665}
2666
2667int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002668qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002669{
2670 int rval;
2671 mbx_cmd_t mc;
2672 mbx_cmd_t *mcp = &mc;
2673
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002674 ql_dbg(ql_dbg_mbx, vha, 0x10a7, "Entered %s.\n", __func__);
2675
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002676 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002677 return QLA_FUNCTION_FAILED;
2678
Andrew Vasquez85880802009-12-15 21:29:46 -08002679 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2680 return QLA_FUNCTION_FAILED;
2681
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002682 mcp->mb[0] = MBC_TRACE_CONTROL;
2683 mcp->mb[1] = TC_EFT_DISABLE;
2684 mcp->out_mb = MBX_1|MBX_0;
2685 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002686 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002687 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002688 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002689 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002690 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
2691 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2692 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002693 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002694 ql_dbg(ql_dbg_mbx, vha, 0x10a9, "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002695 }
2696
2697 return rval;
2698}
2699
Andrew Vasquez88729e52006-06-23 16:10:50 -07002700int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002701qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002702 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
2703{
2704 int rval;
2705 mbx_cmd_t mc;
2706 mbx_cmd_t *mcp = &mc;
2707
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002708 ql_dbg(ql_dbg_mbx, vha, 0x10aa, "Entered %s.\n", __func__);
2709
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002710 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
2711 !IS_QLA83XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002712 return QLA_FUNCTION_FAILED;
2713
Andrew Vasquez85880802009-12-15 21:29:46 -08002714 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2715 return QLA_FUNCTION_FAILED;
2716
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002717 mcp->mb[0] = MBC_TRACE_CONTROL;
2718 mcp->mb[1] = TC_FCE_ENABLE;
2719 mcp->mb[2] = LSW(fce_dma);
2720 mcp->mb[3] = MSW(fce_dma);
2721 mcp->mb[4] = LSW(MSD(fce_dma));
2722 mcp->mb[5] = MSW(MSD(fce_dma));
2723 mcp->mb[6] = buffers;
2724 mcp->mb[7] = TC_AEN_DISABLE;
2725 mcp->mb[8] = 0;
2726 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
2727 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
2728 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2729 MBX_1|MBX_0;
2730 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002731 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002732 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002733 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002734 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002735 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
2736 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2737 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002738 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002739 ql_dbg(ql_dbg_mbx, vha, 0x10ac, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002740
2741 if (mb)
2742 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
2743 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07002744 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002745 }
2746
2747 return rval;
2748}
2749
2750int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002751qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002752{
2753 int rval;
2754 mbx_cmd_t mc;
2755 mbx_cmd_t *mcp = &mc;
2756
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002757 ql_dbg(ql_dbg_mbx, vha, 0x10ad, "Entered %s.\n", __func__);
2758
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002759 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002760 return QLA_FUNCTION_FAILED;
2761
Andrew Vasquez85880802009-12-15 21:29:46 -08002762 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2763 return QLA_FUNCTION_FAILED;
2764
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002765 mcp->mb[0] = MBC_TRACE_CONTROL;
2766 mcp->mb[1] = TC_FCE_DISABLE;
2767 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
2768 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2769 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2770 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002771 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002772 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002773 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002774 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002775 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
2776 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2777 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002778 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002779 ql_dbg(ql_dbg_mbx, vha, 0x10af, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002780
2781 if (wr)
2782 *wr = (uint64_t) mcp->mb[5] << 48 |
2783 (uint64_t) mcp->mb[4] << 32 |
2784 (uint64_t) mcp->mb[3] << 16 |
2785 (uint64_t) mcp->mb[2];
2786 if (rd)
2787 *rd = (uint64_t) mcp->mb[9] << 48 |
2788 (uint64_t) mcp->mb[8] << 32 |
2789 (uint64_t) mcp->mb[7] << 16 |
2790 (uint64_t) mcp->mb[6];
2791 }
2792
2793 return rval;
2794}
2795
2796int
Giridhar Malavali6e980162010-03-19 17:03:58 -07002797qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
2798 uint16_t *port_speed, uint16_t *mb)
2799{
2800 int rval;
2801 mbx_cmd_t mc;
2802 mbx_cmd_t *mcp = &mc;
2803
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002804 ql_dbg(ql_dbg_mbx, vha, 0x10b0, "Entered %s.\n", __func__);
2805
Giridhar Malavali6e980162010-03-19 17:03:58 -07002806 if (!IS_IIDMA_CAPABLE(vha->hw))
2807 return QLA_FUNCTION_FAILED;
2808
Giridhar Malavali6e980162010-03-19 17:03:58 -07002809 mcp->mb[0] = MBC_PORT_PARAMS;
2810 mcp->mb[1] = loop_id;
2811 mcp->mb[2] = mcp->mb[3] = 0;
2812 mcp->mb[9] = vha->vp_idx;
2813 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2814 mcp->in_mb = MBX_3|MBX_1|MBX_0;
2815 mcp->tov = MBX_TOV_SECONDS;
2816 mcp->flags = 0;
2817 rval = qla2x00_mailbox_command(vha, mcp);
2818
2819 /* Return mailbox statuses. */
2820 if (mb != NULL) {
2821 mb[0] = mcp->mb[0];
2822 mb[1] = mcp->mb[1];
2823 mb[3] = mcp->mb[3];
2824 }
2825
2826 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002827 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002828 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002829 ql_dbg(ql_dbg_mbx, vha, 0x10b2, "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002830 if (port_speed)
2831 *port_speed = mcp->mb[3];
2832 }
2833
2834 return rval;
2835}
2836
2837int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002838qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002839 uint16_t port_speed, uint16_t *mb)
2840{
2841 int rval;
2842 mbx_cmd_t mc;
2843 mbx_cmd_t *mcp = &mc;
2844
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002845 ql_dbg(ql_dbg_mbx, vha, 0x10b3, "Entered %s.\n", __func__);
2846
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002847 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002848 return QLA_FUNCTION_FAILED;
2849
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002850 mcp->mb[0] = MBC_PORT_PARAMS;
2851 mcp->mb[1] = loop_id;
2852 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002853 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07002854 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
2855 else
2856 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
2857 mcp->mb[9] = vha->vp_idx;
2858 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2859 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002860 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002861 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002862 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002863
2864 /* Return mailbox statuses. */
2865 if (mb != NULL) {
2866 mb[0] = mcp->mb[0];
2867 mb[1] = mcp->mb[1];
2868 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002869 }
2870
2871 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002872 ql_dbg(ql_dbg_mbx, vha, 0x10b4, "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002873 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002874 ql_dbg(ql_dbg_mbx, vha, 0x10b5, "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002875 }
2876
2877 return rval;
2878}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002879
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002880void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002881qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002882 struct vp_rpt_id_entry_24xx *rptid_entry)
2883{
2884 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07002885 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002886 struct qla_hw_data *ha = vha->hw;
2887 scsi_qla_host_t *vp;
Arun Easifeafb7b2010-09-03 14:57:00 -07002888 unsigned long flags;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002889
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002890 ql_dbg(ql_dbg_mbx, vha, 0x10b6, "Entered %s.\n", __func__);
2891
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002892 if (rptid_entry->entry_status != 0)
2893 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002894
2895 if (rptid_entry->format == 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002896 ql_dbg(ql_dbg_mbx, vha, 0x10b7,
2897 "Format 0 : Number of VPs setup %d, number of "
2898 "VPs acquired %d.\n",
2899 MSB(le16_to_cpu(rptid_entry->vp_count)),
2900 LSB(le16_to_cpu(rptid_entry->vp_count)));
2901 ql_dbg(ql_dbg_mbx, vha, 0x10b8,
2902 "Primary port id %02x%02x%02x.\n",
2903 rptid_entry->port_id[2], rptid_entry->port_id[1],
2904 rptid_entry->port_id[0]);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002905 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07002906 vp_idx = LSB(stat);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002907 ql_dbg(ql_dbg_mbx, vha, 0x10b9,
2908 "Format 1: VP[%d] enabled - status %d - with "
2909 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002910 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002911 rptid_entry->port_id[0]);
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002912
2913 vp = vha;
2914 if (vp_idx == 0 && (MSB(stat) != 1))
2915 goto reg_needed;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002916
Giridhar Malavali882a9172011-11-18 09:03:12 -08002917 if (MSB(stat) != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002918 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
2919 "Could not acquire ID for VP[%d].\n", vp_idx);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002920 return;
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07002921 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002922
Arun Easifeafb7b2010-09-03 14:57:00 -07002923 spin_lock_irqsave(&ha->vport_slock, flags);
2924 list_for_each_entry(vp, &ha->vp_list, list)
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002925 if (vp_idx == vp->vp_idx)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002926 break;
Arun Easifeafb7b2010-09-03 14:57:00 -07002927 spin_unlock_irqrestore(&ha->vport_slock, flags);
2928
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002929 if (!vp)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002930 return;
2931
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002932 vp->d_id.b.domain = rptid_entry->port_id[2];
2933 vp->d_id.b.area = rptid_entry->port_id[1];
2934 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002935
2936 /*
2937 * Cannot configure here as we are still sitting on the
2938 * response queue. Handle it in dpc context.
2939 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002940 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002941
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002942reg_needed:
2943 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
2944 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
2945 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002946 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002947 }
2948}
2949
2950/*
2951 * qla24xx_modify_vp_config
2952 * Change VP configuration for vha
2953 *
2954 * Input:
2955 * vha = adapter block pointer.
2956 *
2957 * Returns:
2958 * qla2xxx local function return status code.
2959 *
2960 * Context:
2961 * Kernel context.
2962 */
2963int
2964qla24xx_modify_vp_config(scsi_qla_host_t *vha)
2965{
2966 int rval;
2967 struct vp_config_entry_24xx *vpmod;
2968 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002969 struct qla_hw_data *ha = vha->hw;
2970 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002971
2972 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002973
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002974 ql_dbg(ql_dbg_mbx, vha, 0x10bb, "Entered %s.\n", __func__);
2975
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002976 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002977 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002978 ql_log(ql_log_warn, vha, 0x10bc,
2979 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002980 return QLA_MEMORY_ALLOC_FAILED;
2981 }
2982
2983 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
2984 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
2985 vpmod->entry_count = 1;
2986 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
2987 vpmod->vp_count = 1;
2988 vpmod->vp_index1 = vha->vp_idx;
2989 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
2990 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
2991 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
2992 vpmod->entry_count = 1;
2993
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002994 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002995 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002996 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
2997 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002998 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002999 ql_dbg(ql_dbg_mbx, vha, 0x10be,
3000 "Failed to complete IOCB -- error status (%x).\n",
3001 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003002 rval = QLA_FUNCTION_FAILED;
3003 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003004 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3005 "Failed to complete IOCB -- completion status (%x).\n",
3006 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003007 rval = QLA_FUNCTION_FAILED;
3008 } else {
3009 /* EMPTY */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003010 ql_dbg(ql_dbg_mbx, vha, 0x10c0, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003011 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3012 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003013 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003014
3015 return rval;
3016}
3017
3018/*
3019 * qla24xx_control_vp
3020 * Enable a virtual port for given host
3021 *
3022 * Input:
3023 * ha = adapter block pointer.
3024 * vhba = virtual adapter (unused)
3025 * index = index number for enabled VP
3026 *
3027 * Returns:
3028 * qla2xxx local function return status code.
3029 *
3030 * Context:
3031 * Kernel context.
3032 */
3033int
3034qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
3035{
3036 int rval;
3037 int map, pos;
3038 struct vp_ctrl_entry_24xx *vce;
3039 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003040 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003041 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003042 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003043
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003044 ql_dbg(ql_dbg_mbx, vha, 0x10c1,
3045 "Entered %s enabling index %d.\n", __func__, vp_index);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003046
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08003047 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003048 return QLA_PARAMETER_ERROR;
3049
3050 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3051 if (!vce) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003052 ql_log(ql_log_warn, vha, 0x10c2,
3053 "Failed to allocate VP control IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003054 return QLA_MEMORY_ALLOC_FAILED;
3055 }
3056 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3057
3058 vce->entry_type = VP_CTRL_IOCB_TYPE;
3059 vce->entry_count = 1;
3060 vce->command = cpu_to_le16(cmd);
3061 vce->vp_count = __constant_cpu_to_le16(1);
3062
3063 /* index map in firmware starts with 1; decrement index
3064 * this is ok as we never use index 0
3065 */
3066 map = (vp_index - 1) / 8;
3067 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003068 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003069 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003070 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003071
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003072 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003073 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003074 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3075 "Failed to issue VP control IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003076 } else if (vce->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003077 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3078 "Failed to complete IOCB -- error status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003079 vce->entry_status);
3080 rval = QLA_FUNCTION_FAILED;
3081 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003082 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3083 "Failed to complet IOCB -- completion status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003084 le16_to_cpu(vce->comp_status));
3085 rval = QLA_FUNCTION_FAILED;
3086 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003087 ql_dbg(ql_dbg_mbx, vha, 0x10c6, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003088 }
3089
3090 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3091
3092 return rval;
3093}
3094
3095/*
3096 * qla2x00_send_change_request
3097 * Receive or disable RSCN request from fabric controller
3098 *
3099 * Input:
3100 * ha = adapter block pointer
3101 * format = registration format:
3102 * 0 - Reserved
3103 * 1 - Fabric detected registration
3104 * 2 - N_port detected registration
3105 * 3 - Full registration
3106 * FF - clear registration
3107 * vp_idx = Virtual port index
3108 *
3109 * Returns:
3110 * qla2x00 local function return status code.
3111 *
3112 * Context:
3113 * Kernel Context
3114 */
3115
3116int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003117qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003118 uint16_t vp_idx)
3119{
3120 int rval;
3121 mbx_cmd_t mc;
3122 mbx_cmd_t *mcp = &mc;
3123
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003124 ql_dbg(ql_dbg_mbx, vha, 0x10c7, "Entered %s.\n", __func__);
3125
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003126 /*
3127 * This command is implicitly executed by firmware during login for the
3128 * physical hosts
3129 */
3130 if (vp_idx == 0)
3131 return QLA_FUNCTION_FAILED;
3132
3133 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3134 mcp->mb[1] = format;
3135 mcp->mb[9] = vp_idx;
3136 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3137 mcp->in_mb = MBX_0|MBX_1;
3138 mcp->tov = MBX_TOV_SECONDS;
3139 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003140 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003141
3142 if (rval == QLA_SUCCESS) {
3143 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3144 rval = BIT_1;
3145 }
3146 } else
3147 rval = BIT_1;
3148
3149 return rval;
3150}
Andrew Vasquez338c9162007-09-20 14:07:33 -07003151
3152int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003153qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07003154 uint32_t size)
3155{
3156 int rval;
3157 mbx_cmd_t mc;
3158 mbx_cmd_t *mcp = &mc;
3159
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003160 ql_dbg(ql_dbg_mbx, vha, 0x1009, "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003161
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003162 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003163 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3164 mcp->mb[8] = MSW(addr);
3165 mcp->out_mb = MBX_8|MBX_0;
3166 } else {
3167 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3168 mcp->out_mb = MBX_0;
3169 }
3170 mcp->mb[1] = LSW(addr);
3171 mcp->mb[2] = MSW(req_dma);
3172 mcp->mb[3] = LSW(req_dma);
3173 mcp->mb[6] = MSW(MSD(req_dma));
3174 mcp->mb[7] = LSW(MSD(req_dma));
3175 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003176 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003177 mcp->mb[4] = MSW(size);
3178 mcp->mb[5] = LSW(size);
3179 mcp->out_mb |= MBX_5|MBX_4;
3180 } else {
3181 mcp->mb[4] = LSW(size);
3182 mcp->out_mb |= MBX_4;
3183 }
3184
3185 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003186 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07003187 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003188 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003189
3190 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003191 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3192 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003193 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003194 ql_dbg(ql_dbg_mbx, vha, 0x1007, "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003195 }
3196
3197 return rval;
3198}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003199
3200/* 84XX Support **************************************************************/
3201
3202struct cs84xx_mgmt_cmd {
3203 union {
3204 struct verify_chip_entry_84xx req;
3205 struct verify_chip_rsp_84xx rsp;
3206 } p;
3207};
3208
3209int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003210qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003211{
3212 int rval, retry;
3213 struct cs84xx_mgmt_cmd *mn;
3214 dma_addr_t mn_dma;
3215 uint16_t options;
3216 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003217 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003218
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003219 ql_dbg(ql_dbg_mbx, vha, 0x10c8, "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003220
3221 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3222 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003223 return QLA_MEMORY_ALLOC_FAILED;
3224 }
3225
3226 /* Force Update? */
3227 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3228 /* Diagnostic firmware? */
3229 /* options |= MENLO_DIAG_FW; */
3230 /* We update the firmware with only one data sequence. */
3231 options |= VCO_END_OF_DATA;
3232
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003233 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003234 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003235 memset(mn, 0, sizeof(*mn));
3236 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3237 mn->p.req.entry_count = 1;
3238 mn->p.req.options = cpu_to_le16(options);
3239
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003240 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3241 "Dump of Verify Request.\n");
3242 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3243 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003244
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003245 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003246 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003247 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3248 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003249 goto verify_done;
3250 }
3251
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003252 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3253 "Dump of Verify Response.\n");
3254 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3255 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003256
3257 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3258 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3259 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003260 ql_dbg(ql_dbg_mbx, vha, 0x10ce,
3261 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003262
3263 if (status[0] != CS_COMPLETE) {
3264 rval = QLA_FUNCTION_FAILED;
3265 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003266 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3267 "Firmware update failed. Retrying "
3268 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003269 options |= VCO_DONT_UPDATE_FW;
3270 options &= ~VCO_FORCE_UPDATE;
3271 retry = 1;
3272 }
3273 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003274 ql_dbg(ql_dbg_mbx, vha, 0x10d0,
3275 "Firmware updated to %x.\n",
3276 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003277
3278 /* NOTE: we only update OP firmware. */
3279 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3280 ha->cs84xx->op_fw_version =
3281 le32_to_cpu(mn->p.rsp.fw_ver);
3282 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3283 flags);
3284 }
3285 } while (retry);
3286
3287verify_done:
3288 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3289
3290 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003291 ql_dbg(ql_dbg_mbx, vha, 0x10d1, "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003292 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003293 ql_dbg(ql_dbg_mbx, vha, 0x10d2, "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003294 }
3295
3296 return rval;
3297}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003298
3299int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003300qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003301{
3302 int rval;
3303 unsigned long flags;
3304 mbx_cmd_t mc;
3305 mbx_cmd_t *mcp = &mc;
3306 struct device_reg_25xxmq __iomem *reg;
3307 struct qla_hw_data *ha = vha->hw;
3308
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003309 ql_dbg(ql_dbg_mbx, vha, 0x10d3, "Entered %s.\n", __func__);
3310
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003311 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003312 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003313 mcp->mb[2] = MSW(LSD(req->dma));
3314 mcp->mb[3] = LSW(LSD(req->dma));
3315 mcp->mb[6] = MSW(MSD(req->dma));
3316 mcp->mb[7] = LSW(MSD(req->dma));
3317 mcp->mb[5] = req->length;
3318 if (req->rsp)
3319 mcp->mb[10] = req->rsp->id;
3320 mcp->mb[12] = req->qos;
3321 mcp->mb[11] = req->vp_idx;
3322 mcp->mb[13] = req->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003323 if (IS_QLA83XX(ha))
3324 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003325
3326 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3327 QLA_QUE_PAGE * req->id);
3328
3329 mcp->mb[4] = req->id;
3330 /* que in ptr index */
3331 mcp->mb[8] = 0;
3332 /* que out ptr index */
3333 mcp->mb[9] = 0;
3334 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3335 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3336 mcp->in_mb = MBX_0;
3337 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003338 mcp->tov = MBX_TOV_SECONDS * 2;
3339
3340 if (IS_QLA81XX(ha) || IS_QLA83XX(ha))
3341 mcp->in_mb |= MBX_1;
3342 if (IS_QLA83XX(ha)) {
3343 mcp->out_mb |= MBX_15;
3344 /* debug q create issue in SR-IOV */
3345 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3346 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003347
3348 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003349 if (!(req->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003350 WRT_REG_DWORD(&reg->req_q_in, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003351 if (!IS_QLA83XX(ha))
3352 WRT_REG_DWORD(&reg->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003353 }
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003354 req->req_q_in = &reg->req_q_in;
3355 req->req_q_out = &reg->req_q_out;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003356 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3357
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003358 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003359 if (rval != QLA_SUCCESS) {
3360 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3361 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3362 } else {
3363 ql_dbg(ql_dbg_mbx, vha, 0x10d5, "Done %s.\n", __func__);
3364 }
3365
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003366 return rval;
3367}
3368
3369int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003370qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003371{
3372 int rval;
3373 unsigned long flags;
3374 mbx_cmd_t mc;
3375 mbx_cmd_t *mcp = &mc;
3376 struct device_reg_25xxmq __iomem *reg;
3377 struct qla_hw_data *ha = vha->hw;
3378
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003379 ql_dbg(ql_dbg_mbx, vha, 0x10d6, "Entered %s.\n", __func__);
3380
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003381 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003382 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003383 mcp->mb[2] = MSW(LSD(rsp->dma));
3384 mcp->mb[3] = LSW(LSD(rsp->dma));
3385 mcp->mb[6] = MSW(MSD(rsp->dma));
3386 mcp->mb[7] = LSW(MSD(rsp->dma));
3387 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003388 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003389 mcp->mb[13] = rsp->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003390 if (IS_QLA83XX(ha))
3391 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003392
3393 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3394 QLA_QUE_PAGE * rsp->id);
3395
3396 mcp->mb[4] = rsp->id;
3397 /* que in ptr index */
3398 mcp->mb[8] = 0;
3399 /* que out ptr index */
3400 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003401 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003402 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3403 mcp->in_mb = MBX_0;
3404 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003405 mcp->tov = MBX_TOV_SECONDS * 2;
3406
3407 if (IS_QLA81XX(ha)) {
3408 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
3409 mcp->in_mb |= MBX_1;
3410 } else if (IS_QLA83XX(ha)) {
3411 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
3412 mcp->in_mb |= MBX_1;
3413 /* debug q create issue in SR-IOV */
3414 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3415 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003416
3417 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003418 if (!(rsp->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003419 WRT_REG_DWORD(&reg->rsp_q_out, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003420 if (!IS_QLA83XX(ha))
3421 WRT_REG_DWORD(&reg->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003422 }
3423
3424 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3425
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003426 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003427 if (rval != QLA_SUCCESS) {
3428 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
3429 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3430 } else {
3431 ql_dbg(ql_dbg_mbx, vha, 0x10d8, "Done %s.\n", __func__);
3432 }
3433
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003434 return rval;
3435}
3436
Andrew Vasquez8a659572009-02-08 20:50:12 -08003437int
3438qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3439{
3440 int rval;
3441 mbx_cmd_t mc;
3442 mbx_cmd_t *mcp = &mc;
3443
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003444 ql_dbg(ql_dbg_mbx, vha, 0x10d9, "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003445
3446 mcp->mb[0] = MBC_IDC_ACK;
3447 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3448 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3449 mcp->in_mb = MBX_0;
3450 mcp->tov = MBX_TOV_SECONDS;
3451 mcp->flags = 0;
3452 rval = qla2x00_mailbox_command(vha, mcp);
3453
3454 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003455 ql_dbg(ql_dbg_mbx, vha, 0x10da,
3456 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003457 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003458 ql_dbg(ql_dbg_mbx, vha, 0x10db, "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003459 }
3460
3461 return rval;
3462}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003463
3464int
3465qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3466{
3467 int rval;
3468 mbx_cmd_t mc;
3469 mbx_cmd_t *mcp = &mc;
3470
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003471 ql_dbg(ql_dbg_mbx, vha, 0x10dc, "Entered %s.\n", __func__);
3472
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003473 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003474 return QLA_FUNCTION_FAILED;
3475
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003476 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3477 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3478 mcp->out_mb = MBX_1|MBX_0;
3479 mcp->in_mb = MBX_1|MBX_0;
3480 mcp->tov = MBX_TOV_SECONDS;
3481 mcp->flags = 0;
3482 rval = qla2x00_mailbox_command(vha, mcp);
3483
3484 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003485 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
3486 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3487 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003488 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003489 ql_dbg(ql_dbg_mbx, vha, 0x10de, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003490 *sector_size = mcp->mb[1];
3491 }
3492
3493 return rval;
3494}
3495
3496int
3497qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3498{
3499 int rval;
3500 mbx_cmd_t mc;
3501 mbx_cmd_t *mcp = &mc;
3502
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003503 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003504 return QLA_FUNCTION_FAILED;
3505
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003506 ql_dbg(ql_dbg_mbx, vha, 0x10df, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003507
3508 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3509 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3510 FAC_OPT_CMD_WRITE_PROTECT;
3511 mcp->out_mb = MBX_1|MBX_0;
3512 mcp->in_mb = MBX_1|MBX_0;
3513 mcp->tov = MBX_TOV_SECONDS;
3514 mcp->flags = 0;
3515 rval = qla2x00_mailbox_command(vha, mcp);
3516
3517 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003518 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
3519 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3520 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003521 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003522 ql_dbg(ql_dbg_mbx, vha, 0x10e1, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003523 }
3524
3525 return rval;
3526}
3527
3528int
3529qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3530{
3531 int rval;
3532 mbx_cmd_t mc;
3533 mbx_cmd_t *mcp = &mc;
3534
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003535 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003536 return QLA_FUNCTION_FAILED;
3537
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003538 ql_dbg(ql_dbg_mbx, vha, 0x10e2, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003539
3540 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3541 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3542 mcp->mb[2] = LSW(start);
3543 mcp->mb[3] = MSW(start);
3544 mcp->mb[4] = LSW(finish);
3545 mcp->mb[5] = MSW(finish);
3546 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3547 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3548 mcp->tov = MBX_TOV_SECONDS;
3549 mcp->flags = 0;
3550 rval = qla2x00_mailbox_command(vha, mcp);
3551
3552 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003553 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
3554 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3555 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003556 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003557 ql_dbg(ql_dbg_mbx, vha, 0x10e4, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003558 }
3559
3560 return rval;
3561}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003562
3563int
3564qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3565{
3566 int rval = 0;
3567 mbx_cmd_t mc;
3568 mbx_cmd_t *mcp = &mc;
3569
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003570 ql_dbg(ql_dbg_mbx, vha, 0x10e5, "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003571
3572 mcp->mb[0] = MBC_RESTART_MPI_FW;
3573 mcp->out_mb = MBX_0;
3574 mcp->in_mb = MBX_0|MBX_1;
3575 mcp->tov = MBX_TOV_SECONDS;
3576 mcp->flags = 0;
3577 rval = qla2x00_mailbox_command(vha, mcp);
3578
3579 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003580 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
3581 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3582 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003583 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003584 ql_dbg(ql_dbg_mbx, vha, 0x10e7, "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003585 }
3586
3587 return rval;
3588}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003589
3590int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003591qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3592 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003593{
3594 int rval;
3595 mbx_cmd_t mc;
3596 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003597 struct qla_hw_data *ha = vha->hw;
3598
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003599 ql_dbg(ql_dbg_mbx, vha, 0x10e8, "Entered %s.\n", __func__);
3600
Joe Carnuccio6766df92011-05-10 11:30:15 -07003601 if (!IS_FWI2_CAPABLE(ha))
3602 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003603
Joe Carnuccio6766df92011-05-10 11:30:15 -07003604 if (len == 1)
3605 opt |= BIT_0;
3606
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003607 mcp->mb[0] = MBC_READ_SFP;
3608 mcp->mb[1] = dev;
3609 mcp->mb[2] = MSW(sfp_dma);
3610 mcp->mb[3] = LSW(sfp_dma);
3611 mcp->mb[6] = MSW(MSD(sfp_dma));
3612 mcp->mb[7] = LSW(MSD(sfp_dma));
3613 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003614 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003615 mcp->mb[10] = opt;
3616 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 -07003617 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003618 mcp->tov = MBX_TOV_SECONDS;
3619 mcp->flags = 0;
3620 rval = qla2x00_mailbox_command(vha, mcp);
3621
3622 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003623 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003624
3625 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003626 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
3627 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003628 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003629 ql_dbg(ql_dbg_mbx, vha, 0x10ea, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003630 }
3631
3632 return rval;
3633}
3634
3635int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003636qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3637 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003638{
3639 int rval;
3640 mbx_cmd_t mc;
3641 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003642 struct qla_hw_data *ha = vha->hw;
3643
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003644 ql_dbg(ql_dbg_mbx, vha, 0x10eb, "Entered %s.\n", __func__);
3645
Joe Carnuccio6766df92011-05-10 11:30:15 -07003646 if (!IS_FWI2_CAPABLE(ha))
3647 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003648
Joe Carnuccio6766df92011-05-10 11:30:15 -07003649 if (len == 1)
3650 opt |= BIT_0;
3651
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003652 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003653 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003654
3655 mcp->mb[0] = MBC_WRITE_SFP;
3656 mcp->mb[1] = dev;
3657 mcp->mb[2] = MSW(sfp_dma);
3658 mcp->mb[3] = LSW(sfp_dma);
3659 mcp->mb[6] = MSW(MSD(sfp_dma));
3660 mcp->mb[7] = LSW(MSD(sfp_dma));
3661 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003662 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003663 mcp->mb[10] = opt;
3664 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 -07003665 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003666 mcp->tov = MBX_TOV_SECONDS;
3667 mcp->flags = 0;
3668 rval = qla2x00_mailbox_command(vha, mcp);
3669
3670 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003671 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
3672 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003673 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003674 ql_dbg(ql_dbg_mbx, vha, 0x10ed, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003675 }
3676
3677 return rval;
3678}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003679
3680int
3681qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
3682 uint16_t size_in_bytes, uint16_t *actual_size)
3683{
3684 int rval;
3685 mbx_cmd_t mc;
3686 mbx_cmd_t *mcp = &mc;
3687
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003688 ql_dbg(ql_dbg_mbx, vha, 0x10ee, "Entered %s.\n", __func__);
3689
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003690 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003691 return QLA_FUNCTION_FAILED;
3692
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003693 mcp->mb[0] = MBC_GET_XGMAC_STATS;
3694 mcp->mb[2] = MSW(stats_dma);
3695 mcp->mb[3] = LSW(stats_dma);
3696 mcp->mb[6] = MSW(MSD(stats_dma));
3697 mcp->mb[7] = LSW(MSD(stats_dma));
3698 mcp->mb[8] = size_in_bytes >> 2;
3699 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
3700 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3701 mcp->tov = MBX_TOV_SECONDS;
3702 mcp->flags = 0;
3703 rval = qla2x00_mailbox_command(vha, mcp);
3704
3705 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003706 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
3707 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3708 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003709 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003710 ql_dbg(ql_dbg_mbx, vha, 0x10f0, "Done %s.\n", __func__);
3711
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003712
3713 *actual_size = mcp->mb[2] << 2;
3714 }
3715
3716 return rval;
3717}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003718
3719int
3720qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
3721 uint16_t size)
3722{
3723 int rval;
3724 mbx_cmd_t mc;
3725 mbx_cmd_t *mcp = &mc;
3726
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003727 ql_dbg(ql_dbg_mbx, vha, 0x10f1, "Entered %s.\n", __func__);
3728
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003729 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003730 return QLA_FUNCTION_FAILED;
3731
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003732 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
3733 mcp->mb[1] = 0;
3734 mcp->mb[2] = MSW(tlv_dma);
3735 mcp->mb[3] = LSW(tlv_dma);
3736 mcp->mb[6] = MSW(MSD(tlv_dma));
3737 mcp->mb[7] = LSW(MSD(tlv_dma));
3738 mcp->mb[8] = size;
3739 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3740 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3741 mcp->tov = MBX_TOV_SECONDS;
3742 mcp->flags = 0;
3743 rval = qla2x00_mailbox_command(vha, mcp);
3744
3745 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003746 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
3747 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3748 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003749 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003750 ql_dbg(ql_dbg_mbx, vha, 0x10f3, "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003751 }
3752
3753 return rval;
3754}
Andrew Vasquez18e75552009-06-03 09:55:30 -07003755
3756int
3757qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
3758{
3759 int rval;
3760 mbx_cmd_t mc;
3761 mbx_cmd_t *mcp = &mc;
3762
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003763 ql_dbg(ql_dbg_mbx, vha, 0x10f4, "Entered %s.\n", __func__);
3764
Andrew Vasquez18e75552009-06-03 09:55:30 -07003765 if (!IS_FWI2_CAPABLE(vha->hw))
3766 return QLA_FUNCTION_FAILED;
3767
Andrew Vasquez18e75552009-06-03 09:55:30 -07003768 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3769 mcp->mb[1] = LSW(risc_addr);
3770 mcp->mb[8] = MSW(risc_addr);
3771 mcp->out_mb = MBX_8|MBX_1|MBX_0;
3772 mcp->in_mb = MBX_3|MBX_2|MBX_0;
3773 mcp->tov = 30;
3774 mcp->flags = 0;
3775 rval = qla2x00_mailbox_command(vha, mcp);
3776 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003777 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
3778 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003779 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003780 ql_dbg(ql_dbg_mbx, vha, 0x10f6, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003781 *data = mcp->mb[3] << 16 | mcp->mb[2];
3782 }
3783
3784 return rval;
3785}
3786
3787int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003788qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3789 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003790{
3791 int rval;
3792 mbx_cmd_t mc;
3793 mbx_cmd_t *mcp = &mc;
3794 uint32_t iter_cnt = 0x1;
3795
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003796 ql_dbg(ql_dbg_mbx, vha, 0x10f7, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003797
3798 memset(mcp->mb, 0 , sizeof(mcp->mb));
3799 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3800 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
3801
3802 /* transfer count */
3803 mcp->mb[10] = LSW(mreq->transfer_size);
3804 mcp->mb[11] = MSW(mreq->transfer_size);
3805
3806 /* send data address */
3807 mcp->mb[14] = LSW(mreq->send_dma);
3808 mcp->mb[15] = MSW(mreq->send_dma);
3809 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3810 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3811
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003812 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003813 mcp->mb[16] = LSW(mreq->rcv_dma);
3814 mcp->mb[17] = MSW(mreq->rcv_dma);
3815 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3816 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3817
3818 /* Iteration count */
3819 mcp->mb[18] = LSW(iter_cnt);
3820 mcp->mb[19] = MSW(iter_cnt);
3821
3822 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3823 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 -08003824 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003825 mcp->out_mb |= MBX_2;
3826 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3827
3828 mcp->buf_size = mreq->transfer_size;
3829 mcp->tov = MBX_TOV_SECONDS;
3830 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3831
3832 rval = qla2x00_mailbox_command(vha, mcp);
3833
3834 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003835 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
3836 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
3837 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
3838 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003839 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003840 ql_dbg(ql_dbg_mbx, vha, 0x10f9, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003841 }
3842
3843 /* Copy mailbox information */
3844 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003845 return rval;
3846}
3847
3848int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003849qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3850 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003851{
3852 int rval;
3853 mbx_cmd_t mc;
3854 mbx_cmd_t *mcp = &mc;
3855 struct qla_hw_data *ha = vha->hw;
3856
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003857 ql_dbg(ql_dbg_mbx, vha, 0x10fa, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003858
3859 memset(mcp->mb, 0 , sizeof(mcp->mb));
3860 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
3861 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003862 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003863 mcp->mb[1] |= BIT_15;
Giridhar Malavalia9083012010-04-12 17:59:55 -07003864 mcp->mb[2] = vha->fcoe_fcf_idx;
3865 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003866 mcp->mb[16] = LSW(mreq->rcv_dma);
3867 mcp->mb[17] = MSW(mreq->rcv_dma);
3868 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3869 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3870
3871 mcp->mb[10] = LSW(mreq->transfer_size);
3872
3873 mcp->mb[14] = LSW(mreq->send_dma);
3874 mcp->mb[15] = MSW(mreq->send_dma);
3875 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3876 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3877
3878 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3879 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003880 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003881 mcp->out_mb |= MBX_2;
3882
3883 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003884 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
3885 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003886 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003887 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003888 mcp->in_mb |= MBX_3;
3889
3890 mcp->tov = MBX_TOV_SECONDS;
3891 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3892 mcp->buf_size = mreq->transfer_size;
3893
3894 rval = qla2x00_mailbox_command(vha, mcp);
3895
3896 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003897 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
3898 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3899 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003900 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003901 ql_dbg(ql_dbg_mbx, vha, 0x10fc, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003902 }
3903
3904 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003905 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003906 return rval;
3907}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003908
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003909int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003910qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003911{
3912 int rval;
3913 mbx_cmd_t mc;
3914 mbx_cmd_t *mcp = &mc;
3915
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003916 ql_dbg(ql_dbg_mbx, vha, 0x10fd,
3917 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003918
3919 mcp->mb[0] = MBC_ISP84XX_RESET;
3920 mcp->mb[1] = enable_diagnostic;
3921 mcp->out_mb = MBX_1|MBX_0;
3922 mcp->in_mb = MBX_1|MBX_0;
3923 mcp->tov = MBX_TOV_SECONDS;
3924 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003925 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003926
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003927 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003928 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003929 else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003930 ql_dbg(ql_dbg_mbx, vha, 0x10ff, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003931
3932 return rval;
3933}
3934
3935int
Andrew Vasquez18e75552009-06-03 09:55:30 -07003936qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
3937{
3938 int rval;
3939 mbx_cmd_t mc;
3940 mbx_cmd_t *mcp = &mc;
3941
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003942 ql_dbg(ql_dbg_mbx, vha, 0x1100, "Entered %s.\n", __func__);
3943
Andrew Vasquez18e75552009-06-03 09:55:30 -07003944 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07003945 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07003946
Andrew Vasquez18e75552009-06-03 09:55:30 -07003947 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
3948 mcp->mb[1] = LSW(risc_addr);
3949 mcp->mb[2] = LSW(data);
3950 mcp->mb[3] = MSW(data);
3951 mcp->mb[8] = MSW(risc_addr);
3952 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3953 mcp->in_mb = MBX_0;
3954 mcp->tov = 30;
3955 mcp->flags = 0;
3956 rval = qla2x00_mailbox_command(vha, mcp);
3957 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003958 ql_dbg(ql_dbg_mbx, vha, 0x1101,
3959 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003960 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003961 ql_dbg(ql_dbg_mbx, vha, 0x1102, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003962 }
3963
3964 return rval;
3965}
Michael Hernandez3064ff32009-12-15 21:29:44 -08003966
3967int
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003968qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
3969{
3970 int rval;
3971 uint32_t stat, timer;
3972 uint16_t mb0 = 0;
3973 struct qla_hw_data *ha = vha->hw;
3974 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
3975
3976 rval = QLA_SUCCESS;
3977
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003978 ql_dbg(ql_dbg_mbx, vha, 0x1103, "Entered %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003979
3980 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
3981
3982 /* Write the MBC data to the registers */
3983 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
3984 WRT_REG_WORD(&reg->mailbox1, mb[0]);
3985 WRT_REG_WORD(&reg->mailbox2, mb[1]);
3986 WRT_REG_WORD(&reg->mailbox3, mb[2]);
3987 WRT_REG_WORD(&reg->mailbox4, mb[3]);
3988
3989 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
3990
3991 /* Poll for MBC interrupt */
3992 for (timer = 6000000; timer; timer--) {
3993 /* Check for pending interrupts. */
3994 stat = RD_REG_DWORD(&reg->host_status);
3995 if (stat & HSRX_RISC_INT) {
3996 stat &= 0xff;
3997
3998 if (stat == 0x1 || stat == 0x2 ||
3999 stat == 0x10 || stat == 0x11) {
4000 set_bit(MBX_INTERRUPT,
4001 &ha->mbx_cmd_flags);
4002 mb0 = RD_REG_WORD(&reg->mailbox0);
4003 WRT_REG_DWORD(&reg->hccr,
4004 HCCRX_CLR_RISC_INT);
4005 RD_REG_DWORD(&reg->hccr);
4006 break;
4007 }
4008 }
4009 udelay(5);
4010 }
4011
4012 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
4013 rval = mb0 & MBS_MASK;
4014 else
4015 rval = QLA_FUNCTION_FAILED;
4016
4017 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004018 ql_dbg(ql_dbg_mbx, vha, 0x1104,
4019 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004020 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004021 ql_dbg(ql_dbg_mbx, vha, 0x1105, "Done %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004022 }
4023
4024 return rval;
4025}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004026
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004027int
Michael Hernandez3064ff32009-12-15 21:29:44 -08004028qla2x00_get_data_rate(scsi_qla_host_t *vha)
4029{
4030 int rval;
4031 mbx_cmd_t mc;
4032 mbx_cmd_t *mcp = &mc;
4033 struct qla_hw_data *ha = vha->hw;
4034
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004035 ql_dbg(ql_dbg_mbx, vha, 0x1106, "Entered %s.\n", __func__);
4036
Michael Hernandez3064ff32009-12-15 21:29:44 -08004037 if (!IS_FWI2_CAPABLE(ha))
4038 return QLA_FUNCTION_FAILED;
4039
Michael Hernandez3064ff32009-12-15 21:29:44 -08004040 mcp->mb[0] = MBC_DATA_RATE;
4041 mcp->mb[1] = 0;
4042 mcp->out_mb = MBX_1|MBX_0;
4043 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004044 if (IS_QLA83XX(ha))
4045 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08004046 mcp->tov = MBX_TOV_SECONDS;
4047 mcp->flags = 0;
4048 rval = qla2x00_mailbox_command(vha, mcp);
4049 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004050 ql_dbg(ql_dbg_mbx, vha, 0x1107,
4051 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004052 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004053 ql_dbg(ql_dbg_mbx, vha, 0x1108, "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004054 if (mcp->mb[1] != 0x7)
4055 ha->link_data_rate = mcp->mb[1];
4056 }
4057
4058 return rval;
4059}
Sarang Radke09ff7012010-03-19 17:03:59 -07004060
4061int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004062qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4063{
4064 int rval;
4065 mbx_cmd_t mc;
4066 mbx_cmd_t *mcp = &mc;
4067 struct qla_hw_data *ha = vha->hw;
4068
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004069 ql_dbg(ql_dbg_mbx, vha, 0x1109, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004070
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004071 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004072 return QLA_FUNCTION_FAILED;
4073 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4074 mcp->out_mb = MBX_0;
4075 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4076 mcp->tov = MBX_TOV_SECONDS;
4077 mcp->flags = 0;
4078
4079 rval = qla2x00_mailbox_command(vha, mcp);
4080
4081 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004082 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4083 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004084 } else {
4085 /* Copy all bits to preserve original value */
4086 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4087
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004088 ql_dbg(ql_dbg_mbx, vha, 0x110b, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004089 }
4090 return rval;
4091}
4092
4093int
4094qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4095{
4096 int rval;
4097 mbx_cmd_t mc;
4098 mbx_cmd_t *mcp = &mc;
4099
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004100 ql_dbg(ql_dbg_mbx, vha, 0x110c, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004101
4102 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4103 /* Copy all bits to preserve original setting */
4104 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4105 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4106 mcp->in_mb = MBX_0;
4107 mcp->tov = MBX_TOV_SECONDS;
4108 mcp->flags = 0;
4109 rval = qla2x00_mailbox_command(vha, mcp);
4110
4111 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004112 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4113 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004114 } else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004115 ql_dbg(ql_dbg_mbx, vha, 0x110e, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004116
4117 return rval;
4118}
4119
4120
4121int
Sarang Radke09ff7012010-03-19 17:03:59 -07004122qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4123 uint16_t *mb)
4124{
4125 int rval;
4126 mbx_cmd_t mc;
4127 mbx_cmd_t *mcp = &mc;
4128 struct qla_hw_data *ha = vha->hw;
4129
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004130 ql_dbg(ql_dbg_mbx, vha, 0x110f, "Entered %s.\n", __func__);
4131
Sarang Radke09ff7012010-03-19 17:03:59 -07004132 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4133 return QLA_FUNCTION_FAILED;
4134
Sarang Radke09ff7012010-03-19 17:03:59 -07004135 mcp->mb[0] = MBC_PORT_PARAMS;
4136 mcp->mb[1] = loop_id;
4137 if (ha->flags.fcp_prio_enabled)
4138 mcp->mb[2] = BIT_1;
4139 else
4140 mcp->mb[2] = BIT_2;
4141 mcp->mb[4] = priority & 0xf;
4142 mcp->mb[9] = vha->vp_idx;
4143 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4144 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4145 mcp->tov = 30;
4146 mcp->flags = 0;
4147 rval = qla2x00_mailbox_command(vha, mcp);
4148 if (mb != NULL) {
4149 mb[0] = mcp->mb[0];
4150 mb[1] = mcp->mb[1];
4151 mb[3] = mcp->mb[3];
4152 mb[4] = mcp->mb[4];
4153 }
4154
4155 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004156 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07004157 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004158 ql_dbg(ql_dbg_mbx, vha, 0x10cc, "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07004159 }
4160
4161 return rval;
4162}
Giridhar Malavalia9083012010-04-12 17:59:55 -07004163
4164int
Andrew Vasquez794a5692010-12-21 16:00:21 -08004165qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac)
4166{
4167 int rval;
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004168 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004169 struct qla_hw_data *ha = vha->hw;
4170
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004171 ql_dbg(ql_dbg_mbx, vha, 0x10ca, "Entered %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004172
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004173 /* Integer part */
4174 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 1, BIT_13|BIT_0);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004175 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004176 ql_dbg(ql_dbg_mbx, vha, 0x10c9, "Failed=%x.\n", rval);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004177 ha->flags.thermal_supported = 0;
4178 goto fail;
4179 }
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004180 *temp = byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004181
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004182 /* Fraction part */
4183 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x10, 1, BIT_13|BIT_0);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004184 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004185 ql_dbg(ql_dbg_mbx, vha, 0x1019, "Failed=%x.\n", rval);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004186 ha->flags.thermal_supported = 0;
4187 goto fail;
4188 }
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004189 *frac = (byte >> 6) * 25;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004190
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004191 ql_dbg(ql_dbg_mbx, vha, 0x1018, "Done %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004192fail:
4193 return rval;
4194}
4195
4196int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004197qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
4198{
4199 int rval;
4200 struct qla_hw_data *ha = vha->hw;
4201 mbx_cmd_t mc;
4202 mbx_cmd_t *mcp = &mc;
4203
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004204 ql_dbg(ql_dbg_mbx, vha, 0x1017, "Entered %s.\n", __func__);
4205
Giridhar Malavalia9083012010-04-12 17:59:55 -07004206 if (!IS_FWI2_CAPABLE(ha))
4207 return QLA_FUNCTION_FAILED;
4208
Giridhar Malavalia9083012010-04-12 17:59:55 -07004209 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004210 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004211 mcp->mb[1] = 1;
4212
4213 mcp->out_mb = MBX_1|MBX_0;
4214 mcp->in_mb = MBX_0;
4215 mcp->tov = 30;
4216 mcp->flags = 0;
4217
4218 rval = qla2x00_mailbox_command(vha, mcp);
4219 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004220 ql_dbg(ql_dbg_mbx, vha, 0x1016,
4221 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004222 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004223 ql_dbg(ql_dbg_mbx, vha, 0x100e, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004224 }
4225
4226 return rval;
4227}
4228
4229int
4230qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4231{
4232 int rval;
4233 struct qla_hw_data *ha = vha->hw;
4234 mbx_cmd_t mc;
4235 mbx_cmd_t *mcp = &mc;
4236
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004237 ql_dbg(ql_dbg_mbx, vha, 0x100d, "Entered %s.\n", __func__);
4238
Giridhar Malavalia9083012010-04-12 17:59:55 -07004239 if (!IS_QLA82XX(ha))
4240 return QLA_FUNCTION_FAILED;
4241
Giridhar Malavalia9083012010-04-12 17:59:55 -07004242 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004243 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004244 mcp->mb[1] = 0;
4245
4246 mcp->out_mb = MBX_1|MBX_0;
4247 mcp->in_mb = MBX_0;
4248 mcp->tov = 30;
4249 mcp->flags = 0;
4250
4251 rval = qla2x00_mailbox_command(vha, mcp);
4252 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004253 ql_dbg(ql_dbg_mbx, vha, 0x100c,
4254 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004255 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004256 ql_dbg(ql_dbg_mbx, vha, 0x100b, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004257 }
4258
4259 return rval;
4260}
Giridhar Malavali08de2842011-08-16 11:31:44 -07004261
4262int
4263qla82xx_md_get_template_size(scsi_qla_host_t *vha)
4264{
4265 struct qla_hw_data *ha = vha->hw;
4266 mbx_cmd_t mc;
4267 mbx_cmd_t *mcp = &mc;
4268 int rval = QLA_FUNCTION_FAILED;
4269
4270 ql_dbg(ql_dbg_mbx, vha, 0x111f, "Entered %s.\n", __func__);
4271
4272 memset(mcp->mb, 0 , sizeof(mcp->mb));
4273 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4274 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4275 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
4276 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
4277
4278 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4279 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
4280 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4281
4282 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4283 mcp->tov = MBX_TOV_SECONDS;
4284 rval = qla2x00_mailbox_command(vha, mcp);
4285
4286 /* Always copy back return mailbox values. */
4287 if (rval != QLA_SUCCESS) {
4288 ql_dbg(ql_dbg_mbx, vha, 0x1120,
4289 "mailbox command FAILED=0x%x, subcode=%x.\n",
4290 (mcp->mb[1] << 16) | mcp->mb[0],
4291 (mcp->mb[3] << 16) | mcp->mb[2]);
4292 } else {
4293 ql_dbg(ql_dbg_mbx, vha, 0x1121, "Done %s.\n", __func__);
4294 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
4295 if (!ha->md_template_size) {
4296 ql_dbg(ql_dbg_mbx, vha, 0x1122,
4297 "Null template size obtained.\n");
4298 rval = QLA_FUNCTION_FAILED;
4299 }
4300 }
4301 return rval;
4302}
4303
4304int
4305qla82xx_md_get_template(scsi_qla_host_t *vha)
4306{
4307 struct qla_hw_data *ha = vha->hw;
4308 mbx_cmd_t mc;
4309 mbx_cmd_t *mcp = &mc;
4310 int rval = QLA_FUNCTION_FAILED;
4311
4312 ql_dbg(ql_dbg_mbx, vha, 0x1123, "Entered %s.\n", __func__);
4313
4314 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4315 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4316 if (!ha->md_tmplt_hdr) {
4317 ql_log(ql_log_warn, vha, 0x1124,
4318 "Unable to allocate memory for Minidump template.\n");
4319 return rval;
4320 }
4321
4322 memset(mcp->mb, 0 , sizeof(mcp->mb));
4323 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4324 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4325 mcp->mb[2] = LSW(RQST_TMPLT);
4326 mcp->mb[3] = MSW(RQST_TMPLT);
4327 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
4328 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
4329 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
4330 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
4331 mcp->mb[8] = LSW(ha->md_template_size);
4332 mcp->mb[9] = MSW(ha->md_template_size);
4333
4334 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4335 mcp->tov = MBX_TOV_SECONDS;
4336 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4337 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4338 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4339 rval = qla2x00_mailbox_command(vha, mcp);
4340
4341 if (rval != QLA_SUCCESS) {
4342 ql_dbg(ql_dbg_mbx, vha, 0x1125,
4343 "mailbox command FAILED=0x%x, subcode=%x.\n",
4344 ((mcp->mb[1] << 16) | mcp->mb[0]),
4345 ((mcp->mb[3] << 16) | mcp->mb[2]));
4346 } else
4347 ql_dbg(ql_dbg_mbx, vha, 0x1126, "Done %s.\n", __func__);
4348 return rval;
4349}
Saurav Kashyap999916d2011-08-16 11:31:45 -07004350
4351int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004352qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4353{
4354 int rval;
4355 struct qla_hw_data *ha = vha->hw;
4356 mbx_cmd_t mc;
4357 mbx_cmd_t *mcp = &mc;
4358
4359 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4360 return QLA_FUNCTION_FAILED;
4361
4362 ql_dbg(ql_dbg_mbx, vha, 0x1133, "Entered %s.\n", __func__);
4363
4364 memset(mcp, 0, sizeof(mbx_cmd_t));
4365 mcp->mb[0] = MBC_SET_LED_CONFIG;
4366 mcp->mb[1] = led_cfg[0];
4367 mcp->mb[2] = led_cfg[1];
4368 if (IS_QLA8031(ha)) {
4369 mcp->mb[3] = led_cfg[2];
4370 mcp->mb[4] = led_cfg[3];
4371 mcp->mb[5] = led_cfg[4];
4372 mcp->mb[6] = led_cfg[5];
4373 }
4374
4375 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4376 if (IS_QLA8031(ha))
4377 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4378 mcp->in_mb = MBX_0;
4379 mcp->tov = 30;
4380 mcp->flags = 0;
4381
4382 rval = qla2x00_mailbox_command(vha, mcp);
4383 if (rval != QLA_SUCCESS) {
4384 ql_dbg(ql_dbg_mbx, vha, 0x1134,
4385 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4386 } else {
4387 ql_dbg(ql_dbg_mbx, vha, 0x1135, "Done %s.\n", __func__);
4388 }
4389
4390 return rval;
4391}
4392
4393int
4394qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4395{
4396 int rval;
4397 struct qla_hw_data *ha = vha->hw;
4398 mbx_cmd_t mc;
4399 mbx_cmd_t *mcp = &mc;
4400
4401 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4402 return QLA_FUNCTION_FAILED;
4403
4404 ql_dbg(ql_dbg_mbx, vha, 0x1136, "Entered %s.\n", __func__);
4405
4406 memset(mcp, 0, sizeof(mbx_cmd_t));
4407 mcp->mb[0] = MBC_GET_LED_CONFIG;
4408
4409 mcp->out_mb = MBX_0;
4410 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4411 if (IS_QLA8031(ha))
4412 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4413 mcp->tov = 30;
4414 mcp->flags = 0;
4415
4416 rval = qla2x00_mailbox_command(vha, mcp);
4417 if (rval != QLA_SUCCESS) {
4418 ql_dbg(ql_dbg_mbx, vha, 0x1137,
4419 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4420 } else {
4421 led_cfg[0] = mcp->mb[1];
4422 led_cfg[1] = mcp->mb[2];
4423 if (IS_QLA8031(ha)) {
4424 led_cfg[2] = mcp->mb[3];
4425 led_cfg[3] = mcp->mb[4];
4426 led_cfg[4] = mcp->mb[5];
4427 led_cfg[5] = mcp->mb[6];
4428 }
4429 ql_dbg(ql_dbg_mbx, vha, 0x1138, "Done %s.\n", __func__);
4430 }
4431
4432 return rval;
4433}
4434
4435int
Saurav Kashyap999916d2011-08-16 11:31:45 -07004436qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
4437{
4438 int rval;
4439 struct qla_hw_data *ha = vha->hw;
4440 mbx_cmd_t mc;
4441 mbx_cmd_t *mcp = &mc;
4442
4443 if (!IS_QLA82XX(ha))
4444 return QLA_FUNCTION_FAILED;
4445
4446 ql_dbg(ql_dbg_mbx, vha, 0x1127,
4447 "Entered %s.\n", __func__);
4448
4449 memset(mcp, 0, sizeof(mbx_cmd_t));
4450 mcp->mb[0] = MBC_SET_LED_CONFIG;
4451 if (enable)
4452 mcp->mb[7] = 0xE;
4453 else
4454 mcp->mb[7] = 0xD;
4455
4456 mcp->out_mb = MBX_7|MBX_0;
4457 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004458 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07004459 mcp->flags = 0;
4460
4461 rval = qla2x00_mailbox_command(vha, mcp);
4462 if (rval != QLA_SUCCESS) {
4463 ql_dbg(ql_dbg_mbx, vha, 0x1128,
4464 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4465 } else {
4466 ql_dbg(ql_dbg_mbx, vha, 0x1129,
4467 "Done %s.\n", __func__);
4468 }
4469
4470 return rval;
4471}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004472
4473int
4474qla83xx_write_remote_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
4475{
4476 int rval;
4477 struct qla_hw_data *ha = vha->hw;
4478 mbx_cmd_t mc;
4479 mbx_cmd_t *mcp = &mc;
4480
4481 if (!IS_QLA83XX(ha))
4482 return QLA_FUNCTION_FAILED;
4483
4484 ql_dbg(ql_dbg_mbx, vha, 0x1130, "Entered %s.\n", __func__);
4485
4486 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
4487 mcp->mb[1] = LSW(reg);
4488 mcp->mb[2] = MSW(reg);
4489 mcp->mb[3] = LSW(data);
4490 mcp->mb[4] = MSW(data);
4491 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4492
4493 mcp->in_mb = MBX_1|MBX_0;
4494 mcp->tov = MBX_TOV_SECONDS;
4495 mcp->flags = 0;
4496 rval = qla2x00_mailbox_command(vha, mcp);
4497
4498 if (rval != QLA_SUCCESS) {
4499 ql_dbg(ql_dbg_mbx, vha, 0x1131,
4500 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4501 } else {
4502 ql_dbg(ql_dbg_mbx, vha, 0x1132,
4503 "Done %s.\n", __func__);
4504 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004505
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004506 return rval;
4507}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004508
4509int
4510qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
4511{
4512 int rval;
4513 struct qla_hw_data *ha = vha->hw;
4514 mbx_cmd_t mc;
4515 mbx_cmd_t *mcp = &mc;
4516
4517 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
4518 ql_dbg(ql_dbg_mbx, vha, 0x113b,
4519 "Implicit LOGO Unsupported.\n");
4520 return QLA_FUNCTION_FAILED;
4521 }
4522
4523
4524 ql_dbg(ql_dbg_mbx, vha, 0x113c, "Done %s.\n", __func__);
4525
4526 /* Perform Implicit LOGO. */
4527 mcp->mb[0] = MBC_PORT_LOGOUT;
4528 mcp->mb[1] = fcport->loop_id;
4529 mcp->mb[10] = BIT_15;
4530 mcp->out_mb = MBX_10|MBX_1|MBX_0;
4531 mcp->in_mb = MBX_0;
4532 mcp->tov = MBX_TOV_SECONDS;
4533 mcp->flags = 0;
4534 rval = qla2x00_mailbox_command(vha, mcp);
4535 if (rval != QLA_SUCCESS)
4536 ql_dbg(ql_dbg_mbx, vha, 0x113d,
4537 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4538 else
4539 ql_dbg(ql_dbg_mbx, vha, 0x113e, "Done %s.\n", __func__);
4540
4541 return rval;
4542}
4543