blob: adc2b14b03f5ea53122a144f1cc6f14a469bb992 [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
Arun Easi5e19ed92012-02-09 11:15:51 -080049 ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -070050
51 if (ha->pdev->error_state > pci_channel_io_frozen) {
Arun Easi5e19ed92012-02-09 11:15:51 -080052 ql_log(ql_log_warn, vha, 0x1001,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070053 "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) {
Arun Easi5e19ed92012-02-09 11:15:51 -080059 ql_log(ql_log_warn, vha, 0x1002,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070060 "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) {
Arun Easi5e19ed92012-02-09 11:15:51 -080072 ql_log(ql_log_warn, vha, 0x1003,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070073 "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;
Arun Easi5e19ed92012-02-09 11:15:51 -080080 ql_log(ql_log_warn, vha, 0x1004,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070081 "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. */
Arun Easi5e19ed92012-02-09 11:15:51 -080092 ql_log(ql_log_warn, vha, 0x1005,
Chad Dupuisd8c0d542012-02-09 11:15:46 -080093 "Cmd access timeout, cmd=0x%x, Exiting.\n",
94 mcp->mb[0]);
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080095 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 }
97
98 ha->flags.mbox_busy = 1;
99 /* Save mailbox command for debug */
100 ha->mcp = mcp;
101
Arun Easi5e19ed92012-02-09 11:15:51 -0800102 ql_dbg(ql_dbg_mbx, vha, 0x1006,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700103 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104
105 spin_lock_irqsave(&ha->hardware_lock, flags);
106
107 /* Load mailbox registers. */
Giridhar Malavalia9083012010-04-12 17:59:55 -0700108 if (IS_QLA82XX(ha))
109 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
110 else if (IS_FWI2_CAPABLE(ha) && !IS_QLA82XX(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700111 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
112 else
113 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
115 iptr = mcp->mb;
116 command = mcp->mb[0];
117 mboxes = mcp->out_mb;
118
119 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
120 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700121 optr =
122 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 if (mboxes & BIT_0)
124 WRT_REG_WORD(optr, *iptr);
125
126 mboxes >>= 1;
127 optr++;
128 iptr++;
129 }
130
Arun Easi5e19ed92012-02-09 11:15:51 -0800131 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1111,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700132 "Loaded MBX registers (displayed in bytes) =.\n");
Arun Easi5e19ed92012-02-09 11:15:51 -0800133 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1112,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700134 (uint8_t *)mcp->mb, 16);
Arun Easi5e19ed92012-02-09 11:15:51 -0800135 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1113,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700136 ".\n");
Arun Easi5e19ed92012-02-09 11:15:51 -0800137 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1114,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700138 ((uint8_t *)mcp->mb + 0x10), 16);
Arun Easi5e19ed92012-02-09 11:15:51 -0800139 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1115,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700140 ".\n");
Arun Easi5e19ed92012-02-09 11:15:51 -0800141 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1116,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700142 ((uint8_t *)mcp->mb + 0x20), 8);
Arun Easi5e19ed92012-02-09 11:15:51 -0800143 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700144 "I/O Address = %p.\n", optr);
Arun Easi5e19ed92012-02-09 11:15:51 -0800145 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x100e);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146
147 /* Issue set host interrupt command to send cmd out. */
148 ha->flags.mbox_int = 0;
149 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
150
151 /* Unlock mbx registers and wait for interrupt */
Arun Easi5e19ed92012-02-09 11:15:51 -0800152 ql_dbg(ql_dbg_mbx, vha, 0x100f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700153 "Going to unlock irq & waiting for interrupts. "
154 "jiffies=%lx.\n", jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155
156 /* Wait for mbx cmd completion until timeout */
157
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800158 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
160
Giridhar Malavalia9083012010-04-12 17:59:55 -0700161 if (IS_QLA82XX(ha)) {
162 if (RD_REG_DWORD(&reg->isp82.hint) &
163 HINT_MBX_INT_PENDING) {
164 spin_unlock_irqrestore(&ha->hardware_lock,
165 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800166 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800167 ql_dbg(ql_dbg_mbx, vha, 0x1010,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700168 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700169 rval = QLA_FUNCTION_TIMEOUT;
170 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700171 }
172 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
173 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700174 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
175 else
176 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 spin_unlock_irqrestore(&ha->hardware_lock, flags);
178
Marcus Barrow0b05a1f2008-01-17 09:02:13 -0800179 wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
182
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 } else {
Arun Easi5e19ed92012-02-09 11:15:51 -0800184 ql_dbg(ql_dbg_mbx, vha, 0x1011,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700185 "Cmd=%x Polling Mode.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
Giridhar Malavalia9083012010-04-12 17:59:55 -0700187 if (IS_QLA82XX(ha)) {
188 if (RD_REG_DWORD(&reg->isp82.hint) &
189 HINT_MBX_INT_PENDING) {
190 spin_unlock_irqrestore(&ha->hardware_lock,
191 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800192 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800193 ql_dbg(ql_dbg_mbx, vha, 0x1012,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700194 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700195 rval = QLA_FUNCTION_TIMEOUT;
196 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700197 }
198 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
199 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700200 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
201 else
202 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204
205 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
206 while (!ha->flags.mbox_int) {
207 if (time_after(jiffies, wait_time))
208 break;
209
210 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800211 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212
Andrew Vasquez85880802009-12-15 21:29:46 -0800213 if (!ha->flags.mbox_int &&
214 !(IS_QLA2200(ha) &&
215 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800216 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217 } /* while */
Arun Easi5e19ed92012-02-09 11:15:51 -0800218 ql_dbg(ql_dbg_mbx, vha, 0x1013,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700219 "Waited %d sec.\n",
220 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 }
222
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 /* Check whether we timed out */
224 if (ha->flags.mbox_int) {
225 uint16_t *iptr2;
226
Arun Easi5e19ed92012-02-09 11:15:51 -0800227 ql_dbg(ql_dbg_mbx, vha, 0x1014,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700228 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229
230 /* Got interrupt. Clear the flag. */
231 ha->flags.mbox_int = 0;
232 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
233
Giridhar Malavali71905752011-02-23 15:27:10 -0800234 if (ha->flags.isp82xx_fw_hung) {
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700235 ha->flags.mbox_busy = 0;
236 /* Setting Link-Down error */
237 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
238 ha->mcp = NULL;
239 rval = QLA_FUNCTION_FAILED;
Arun Easi5e19ed92012-02-09 11:15:51 -0800240 ql_log(ql_log_warn, vha, 0x1015,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700241 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700242 goto premature_exit;
243 }
244
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400245 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247
248 /* Load return mailbox registers. */
249 iptr2 = mcp->mb;
250 iptr = (uint16_t *)&ha->mailbox_out[0];
251 mboxes = mcp->in_mb;
252 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
253 if (mboxes & BIT_0)
254 *iptr2 = *iptr;
255
256 mboxes >>= 1;
257 iptr2++;
258 iptr++;
259 }
260 } else {
261
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700262 uint16_t mb0;
263 uint32_t ictrl;
264
Andrew Vasqueze4289242007-07-19 15:05:56 -0700265 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700266 mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
267 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
268 } else {
Andrew Vasquezcca53352005-08-26 19:08:30 -0700269 mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700270 ictrl = RD_REG_WORD(&reg->isp.ictrl);
271 }
Arun Easi5e19ed92012-02-09 11:15:51 -0800272 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700273 "MBX Command timeout for cmd %x.\n", command);
Arun Easi5e19ed92012-02-09 11:15:51 -0800274 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111a,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700275 "iocontrol=%x jiffies=%lx.\n", ictrl, jiffies);
Arun Easi5e19ed92012-02-09 11:15:51 -0800276 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700277 "mb[0] = 0x%x.\n", mb0);
Arun Easi5e19ed92012-02-09 11:15:51 -0800278 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800280 /*
281 * Attempt to capture a firmware dump for further analysis
282 * of the current firmware state
283 */
284 ha->isp_ops->fw_dump(vha, 0);
285
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 rval = QLA_FUNCTION_TIMEOUT;
287 }
288
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 ha->flags.mbox_busy = 0;
290
291 /* Clean up */
292 ha->mcp = NULL;
293
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800294 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800295 ql_dbg(ql_dbg_mbx, vha, 0x101a,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700296 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297
298 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800299 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 }
301
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700302 if (rval == QLA_FUNCTION_TIMEOUT &&
303 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800304 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
305 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 /* not in dpc. schedule it for dpc to take over. */
Arun Easi5e19ed92012-02-09 11:15:51 -0800307 ql_dbg(ql_dbg_mbx, vha, 0x101b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700308 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700309
310 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
311 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
312 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800313 if (IS_QLA82XX(ha)) {
314 ql_dbg(ql_dbg_mbx, vha, 0x112a,
315 "disabling pause transmit on port "
316 "0 & 1.\n");
317 qla82xx_wr_32(ha,
318 QLA82XX_CRB_NIU + 0x98,
319 CRB_NIU_XG_PAUSE_CTL_P0|
320 CRB_NIU_XG_PAUSE_CTL_P1);
321 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700322 ql_log(ql_log_info, base_vha, 0x101c,
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800323 "Mailbox cmd timeout occured, cmd=0x%x, "
324 "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "
325 "abort.\n", command, mcp->mb[0],
326 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700327 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
328 qla2xxx_wake_dpc(vha);
329 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 /* call abort directly since we are in the DPC thread */
Arun Easi5e19ed92012-02-09 11:15:51 -0800332 ql_dbg(ql_dbg_mbx, vha, 0x101d,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700333 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700335 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
336 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
337 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800338 if (IS_QLA82XX(ha)) {
339 ql_dbg(ql_dbg_mbx, vha, 0x112b,
340 "disabling pause transmit on port "
341 "0 & 1.\n");
342 qla82xx_wr_32(ha,
343 QLA82XX_CRB_NIU + 0x98,
344 CRB_NIU_XG_PAUSE_CTL_P0|
345 CRB_NIU_XG_PAUSE_CTL_P1);
346 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700347 ql_log(ql_log_info, base_vha, 0x101e,
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800348 "Mailbox cmd timeout occured, cmd=0x%x, "
349 "mb[0]=0x%x. Scheduling ISP abort ",
350 command, mcp->mb[0]);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700351 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
352 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
Giridhar Malavalid3360962012-02-09 11:14:10 -0800353 /* Allow next mbx cmd to come in. */
354 complete(&ha->mbx_cmd_comp);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700355 if (ha->isp_ops->abort_isp(vha)) {
356 /* Failed. retry later. */
357 set_bit(ISP_ABORT_NEEDED,
358 &vha->dpc_flags);
359 }
360 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Arun Easi5e19ed92012-02-09 11:15:51 -0800361 ql_dbg(ql_dbg_mbx, vha, 0x101f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700362 "Finished abort_isp.\n");
Giridhar Malavalid3360962012-02-09 11:14:10 -0800363 goto mbx_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 }
366 }
367
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700368premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800370 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
Giridhar Malavalid3360962012-02-09 11:14:10 -0800372mbx_done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 if (rval) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700374 ql_dbg(ql_dbg_mbx, base_vha, 0x1020,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800375 "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n",
376 mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700378 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 }
380
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 return rval;
382}
383
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800385qla2x00_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 -0800386 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387{
388 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800389 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390 mbx_cmd_t mc;
391 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700393 ql_dbg(ql_dbg_mbx, vha, 0x1022, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394
Andrew Vasqueze4289242007-07-19 15:05:56 -0700395 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800396 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
397 mcp->mb[8] = MSW(risc_addr);
398 mcp->out_mb = MBX_8|MBX_0;
399 } else {
400 mcp->mb[0] = MBC_LOAD_RISC_RAM;
401 mcp->out_mb = MBX_0;
402 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403 mcp->mb[1] = LSW(risc_addr);
404 mcp->mb[2] = MSW(req_dma);
405 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 mcp->mb[6] = MSW(MSD(req_dma));
407 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800408 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700409 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700410 mcp->mb[4] = MSW(risc_code_size);
411 mcp->mb[5] = LSW(risc_code_size);
412 mcp->out_mb |= MBX_5|MBX_4;
413 } else {
414 mcp->mb[4] = LSW(risc_code_size);
415 mcp->out_mb |= MBX_4;
416 }
417
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700419 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800421 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700424 ql_dbg(ql_dbg_mbx, vha, 0x1023,
425 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700427 ql_dbg(ql_dbg_mbx, vha, 0x1024, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 }
429
430 return rval;
431}
432
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700433#define EXTENDED_BB_CREDITS BIT_0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700434/*
435 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700436 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 *
438 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700439 * ha = adapter block pointer.
440 * TARGET_QUEUE_LOCK must be released.
441 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 *
443 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700444 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 *
446 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700447 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 */
449int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800450qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451{
452 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800453 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 mbx_cmd_t mc;
455 mbx_cmd_t *mcp = &mc;
456
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700457 ql_dbg(ql_dbg_mbx, vha, 0x1025, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458
459 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700460 mcp->out_mb = MBX_0;
461 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700462 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700463 mcp->mb[1] = MSW(risc_addr);
464 mcp->mb[2] = LSW(risc_addr);
465 mcp->mb[3] = 0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800466 if (IS_QLA81XX(ha) || IS_QLA83XX(ha)) {
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700467 struct nvram_81xx *nv = ha->nvram;
468 mcp->mb[4] = (nv->enhanced_features &
469 EXTENDED_BB_CREDITS);
470 } else
471 mcp->mb[4] = 0;
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700472 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700473 mcp->in_mb |= MBX_1;
474 } else {
475 mcp->mb[1] = LSW(risc_addr);
476 mcp->out_mb |= MBX_1;
477 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
478 mcp->mb[2] = 0;
479 mcp->out_mb |= MBX_2;
480 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 }
482
Ravi Anandb93480e2008-04-03 13:13:25 -0700483 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800485 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700487 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700488 ql_dbg(ql_dbg_mbx, vha, 0x1026,
489 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700490 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700491 if (IS_FWI2_CAPABLE(ha)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700492 ql_dbg(ql_dbg_mbx, vha, 0x1027,
493 "Done exchanges=%x.\n", mcp->mb[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700494 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700495 ql_dbg(ql_dbg_mbx, vha, 0x1028, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700496 }
497 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498
499 return rval;
500}
501
502/*
503 * qla2x00_get_fw_version
504 * Get firmware version.
505 *
506 * Input:
507 * ha: adapter state pointer.
508 * major: pointer for major number.
509 * minor: pointer for minor number.
510 * subminor: pointer for subminor number.
511 *
512 * Returns:
513 * qla2x00 local function return status code.
514 *
515 * Context:
516 * Kernel context.
517 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700518int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800519qla2x00_get_fw_version(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520{
521 int rval;
522 mbx_cmd_t mc;
523 mbx_cmd_t *mcp = &mc;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800524 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700526 ql_dbg(ql_dbg_mbx, vha, 0x1029, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527
528 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
529 mcp->out_mb = MBX_0;
530 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800531 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha))
Andrew Vasquez55a96152009-03-24 09:08:03 -0700532 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800533 if (IS_QLA83XX(vha->hw))
534 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700536 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800537 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700538 if (rval != QLA_SUCCESS)
539 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540
541 /* Return mailbox data. */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800542 ha->fw_major_version = mcp->mb[1];
543 ha->fw_minor_version = mcp->mb[2];
544 ha->fw_subminor_version = mcp->mb[3];
545 ha->fw_attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800546 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800547 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 else
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800549 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
550 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw)) {
551 ha->mpi_version[0] = mcp->mb[10] & 0xff;
552 ha->mpi_version[1] = mcp->mb[11] >> 8;
553 ha->mpi_version[2] = mcp->mb[11] & 0xff;
554 ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
555 ha->phy_version[0] = mcp->mb[8] & 0xff;
556 ha->phy_version[1] = mcp->mb[9] >> 8;
557 ha->phy_version[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800558 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800559 if (IS_QLA83XX(ha)) {
560 if (mcp->mb[6] & BIT_15) {
561 ha->fw_attributes_h = mcp->mb[15];
562 ha->fw_attributes_ext[0] = mcp->mb[16];
563 ha->fw_attributes_ext[1] = mcp->mb[17];
564 ql_dbg(ql_dbg_mbx, vha, 0x1139,
565 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
566 __func__, mcp->mb[15], mcp->mb[6]);
567 } else
568 ql_dbg(ql_dbg_mbx, vha, 0x112f,
569 "%s: FwAttributes [Upper] invalid, MB6:%04x\n",
570 __func__, mcp->mb[6]);
571 }
572
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700573failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 if (rval != QLA_SUCCESS) {
575 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700576 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 } else {
578 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700579 ql_dbg(ql_dbg_mbx, vha, 0x102b, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700581 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582}
583
584/*
585 * qla2x00_get_fw_options
586 * Set firmware options.
587 *
588 * Input:
589 * ha = adapter block pointer.
590 * fwopt = pointer for firmware options.
591 *
592 * Returns:
593 * qla2x00 local function return status code.
594 *
595 * Context:
596 * Kernel context.
597 */
598int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800599qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600{
601 int rval;
602 mbx_cmd_t mc;
603 mbx_cmd_t *mcp = &mc;
604
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700605 ql_dbg(ql_dbg_mbx, vha, 0x102c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606
607 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
608 mcp->out_mb = MBX_0;
609 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700610 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800612 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
614 if (rval != QLA_SUCCESS) {
615 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700616 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700618 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 fwopts[1] = mcp->mb[1];
620 fwopts[2] = mcp->mb[2];
621 fwopts[3] = mcp->mb[3];
622
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700623 ql_dbg(ql_dbg_mbx, vha, 0x102e, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 }
625
626 return rval;
627}
628
629
630/*
631 * qla2x00_set_fw_options
632 * Set firmware options.
633 *
634 * Input:
635 * ha = adapter block pointer.
636 * fwopt = pointer for firmware options.
637 *
638 * Returns:
639 * qla2x00 local function return status code.
640 *
641 * Context:
642 * Kernel context.
643 */
644int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800645qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646{
647 int rval;
648 mbx_cmd_t mc;
649 mbx_cmd_t *mcp = &mc;
650
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700651 ql_dbg(ql_dbg_mbx, vha, 0x102f, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652
653 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
654 mcp->mb[1] = fwopts[1];
655 mcp->mb[2] = fwopts[2];
656 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700657 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800659 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700660 mcp->in_mb |= MBX_1;
661 } else {
662 mcp->mb[10] = fwopts[10];
663 mcp->mb[11] = fwopts[11];
664 mcp->mb[12] = 0; /* Undocumented, but used */
665 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
666 }
Ravi Anandb93480e2008-04-03 13:13:25 -0700667 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800669 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700671 fwopts[0] = mcp->mb[0];
672
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 if (rval != QLA_SUCCESS) {
674 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700675 ql_dbg(ql_dbg_mbx, vha, 0x1030,
676 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 } else {
678 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700679 ql_dbg(ql_dbg_mbx, vha, 0x1031, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 }
681
682 return rval;
683}
684
685/*
686 * qla2x00_mbx_reg_test
687 * Mailbox register wrap test.
688 *
689 * Input:
690 * ha = adapter block pointer.
691 * TARGET_QUEUE_LOCK must be released.
692 * ADAPTER_STATE_LOCK must be released.
693 *
694 * Returns:
695 * qla2x00 local function return status code.
696 *
697 * Context:
698 * Kernel context.
699 */
700int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800701qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702{
703 int rval;
704 mbx_cmd_t mc;
705 mbx_cmd_t *mcp = &mc;
706
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700707 ql_dbg(ql_dbg_mbx, vha, 0x1032, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708
709 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
710 mcp->mb[1] = 0xAAAA;
711 mcp->mb[2] = 0x5555;
712 mcp->mb[3] = 0xAA55;
713 mcp->mb[4] = 0x55AA;
714 mcp->mb[5] = 0xA5A5;
715 mcp->mb[6] = 0x5A5A;
716 mcp->mb[7] = 0x2525;
717 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
718 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 -0700719 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800721 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
723 if (rval == QLA_SUCCESS) {
724 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
725 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
726 rval = QLA_FUNCTION_FAILED;
727 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
728 mcp->mb[7] != 0x2525)
729 rval = QLA_FUNCTION_FAILED;
730 }
731
732 if (rval != QLA_SUCCESS) {
733 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700734 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 } else {
736 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700737 ql_dbg(ql_dbg_mbx, vha, 0x1034, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 }
739
740 return rval;
741}
742
743/*
744 * qla2x00_verify_checksum
745 * Verify firmware checksum.
746 *
747 * Input:
748 * ha = adapter block pointer.
749 * TARGET_QUEUE_LOCK must be released.
750 * ADAPTER_STATE_LOCK must be released.
751 *
752 * Returns:
753 * qla2x00 local function return status code.
754 *
755 * Context:
756 * Kernel context.
757 */
758int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800759qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760{
761 int rval;
762 mbx_cmd_t mc;
763 mbx_cmd_t *mcp = &mc;
764
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700765 ql_dbg(ql_dbg_mbx, vha, 0x1035, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766
767 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700768 mcp->out_mb = MBX_0;
769 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800770 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700771 mcp->mb[1] = MSW(risc_addr);
772 mcp->mb[2] = LSW(risc_addr);
773 mcp->out_mb |= MBX_2|MBX_1;
774 mcp->in_mb |= MBX_2|MBX_1;
775 } else {
776 mcp->mb[1] = LSW(risc_addr);
777 mcp->out_mb |= MBX_1;
778 mcp->in_mb |= MBX_1;
779 }
780
Ravi Anandb93480e2008-04-03 13:13:25 -0700781 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800783 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784
785 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700786 ql_dbg(ql_dbg_mbx, vha, 0x1036,
787 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
788 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700790 ql_dbg(ql_dbg_mbx, vha, 0x1037, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 }
792
793 return rval;
794}
795
796/*
797 * qla2x00_issue_iocb
798 * Issue IOCB using mailbox command
799 *
800 * Input:
801 * ha = adapter state pointer.
802 * buffer = buffer pointer.
803 * phys_addr = physical address of buffer.
804 * size = size of buffer.
805 * TARGET_QUEUE_LOCK must be released.
806 * ADAPTER_STATE_LOCK must be released.
807 *
808 * Returns:
809 * qla2x00 local function return status code.
810 *
811 * Context:
812 * Kernel context.
813 */
Giridhar Malavali6e980162010-03-19 17:03:58 -0700814int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800815qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700816 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817{
818 int rval;
819 mbx_cmd_t mc;
820 mbx_cmd_t *mcp = &mc;
821
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700822 ql_dbg(ql_dbg_mbx, vha, 0x1038, "Entered %s.\n", __func__);
823
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
825 mcp->mb[1] = 0;
826 mcp->mb[2] = MSW(phys_addr);
827 mcp->mb[3] = LSW(phys_addr);
828 mcp->mb[6] = MSW(MSD(phys_addr));
829 mcp->mb[7] = LSW(MSD(phys_addr));
830 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
831 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700832 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800834 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835
836 if (rval != QLA_SUCCESS) {
837 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700838 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700840 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
841
842 /* Mask reserved bits. */
843 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800844 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700845 ql_dbg(ql_dbg_mbx, vha, 0x103a, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 }
847
848 return rval;
849}
850
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700851int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800852qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700853 size_t size)
854{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800855 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700856 MBX_TOV_SECONDS);
857}
858
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859/*
860 * qla2x00_abort_command
861 * Abort command aborts a specified IOCB.
862 *
863 * Input:
864 * ha = adapter block pointer.
865 * sp = SB structure pointer.
866 *
867 * Returns:
868 * qla2x00 local function return status code.
869 *
870 * Context:
871 * Kernel context.
872 */
873int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700874qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875{
876 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800878 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 mbx_cmd_t mc;
880 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700881 fc_port_t *fcport = sp->fcport;
882 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800883 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700884 struct req_que *req = vha->req;
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800885 struct scsi_cmnd *cmd = GET_CMD_SP(sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700887 ql_dbg(ql_dbg_mbx, vha, 0x103b, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700889 spin_lock_irqsave(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800891 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 break;
893 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700894 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895
896 if (handle == MAX_OUTSTANDING_COMMANDS) {
897 /* command not found */
898 return QLA_FUNCTION_FAILED;
899 }
900
901 mcp->mb[0] = MBC_ABORT_COMMAND;
902 if (HAS_EXTENDED_IDS(ha))
903 mcp->mb[1] = fcport->loop_id;
904 else
905 mcp->mb[1] = fcport->loop_id << 8;
906 mcp->mb[2] = (uint16_t)handle;
907 mcp->mb[3] = (uint16_t)(handle >> 16);
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800908 mcp->mb[6] = (uint16_t)cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
910 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700911 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800913 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914
915 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700916 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700917 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700918 ql_dbg(ql_dbg_mbx, vha, 0x103d, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 }
920
921 return rval;
922}
923
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700925qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926{
Andrew Vasquez523ec772008-04-03 13:13:24 -0700927 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 mbx_cmd_t mc;
929 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800930 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800931 struct req_que *req;
932 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933
Andrew Vasquez523ec772008-04-03 13:13:24 -0700934 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800935 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700936
937 ql_dbg(ql_dbg_mbx, vha, 0x103e, "Entered %s.\n", __func__);
938
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700939 req = vha->hw->req_q_map[0];
940 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700942 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800943 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944 mcp->mb[1] = fcport->loop_id;
945 mcp->mb[10] = 0;
946 mcp->out_mb |= MBX_10;
947 } else {
948 mcp->mb[1] = fcport->loop_id << 8;
949 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800950 mcp->mb[2] = vha->hw->loop_reset_delay;
951 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952
953 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700954 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800956 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700958 ql_dbg(ql_dbg_mbx, vha, 0x103f, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700959 }
960
961 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800962 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
963 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700964 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700965 ql_dbg(ql_dbg_mbx, vha, 0x1040,
966 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700968 ql_dbg(ql_dbg_mbx, vha, 0x1041, "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700969 }
970
971 return rval;
972}
973
974int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700975qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -0700976{
977 int rval, rval2;
978 mbx_cmd_t mc;
979 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800980 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800981 struct req_que *req;
982 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700983
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800984 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700985
986 ql_dbg(ql_dbg_mbx, vha, 0x1042, "Entered %s.\n", __func__);
987
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700988 req = vha->hw->req_q_map[0];
989 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700990 mcp->mb[0] = MBC_LUN_RESET;
991 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800992 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -0700993 mcp->mb[1] = fcport->loop_id;
994 else
995 mcp->mb[1] = fcport->loop_id << 8;
996 mcp->mb[2] = l;
997 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800998 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700999
1000 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001001 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001002 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001003 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001004 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001005 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001006 }
1007
1008 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001009 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1010 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001011 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001012 ql_dbg(ql_dbg_mbx, vha, 0x1044,
1013 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001014 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001015 ql_dbg(ql_dbg_mbx, vha, 0x1045, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 }
1017
1018 return rval;
1019}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020
1021/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022 * qla2x00_get_adapter_id
1023 * Get adapter ID and topology.
1024 *
1025 * Input:
1026 * ha = adapter block pointer.
1027 * id = pointer for loop ID.
1028 * al_pa = pointer for AL_PA.
1029 * area = pointer for area.
1030 * domain = pointer for domain.
1031 * top = pointer for topology.
1032 * TARGET_QUEUE_LOCK must be released.
1033 * ADAPTER_STATE_LOCK must be released.
1034 *
1035 * Returns:
1036 * qla2x00 local function return status code.
1037 *
1038 * Context:
1039 * Kernel context.
1040 */
1041int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001042qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001043 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044{
1045 int rval;
1046 mbx_cmd_t mc;
1047 mbx_cmd_t *mcp = &mc;
1048
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001049 ql_dbg(ql_dbg_mbx, vha, 0x1046, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
1051 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001052 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001053 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001054 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001055 if (IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001056 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Ravi Anandb93480e2008-04-03 13:13:25 -07001057 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001059 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001060 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1061 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001062 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1063 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064
1065 /* Return data. */
1066 *id = mcp->mb[1];
1067 *al_pa = LSB(mcp->mb[2]);
1068 *area = MSB(mcp->mb[2]);
1069 *domain = LSB(mcp->mb[3]);
1070 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001071 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072
1073 if (rval != QLA_SUCCESS) {
1074 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001075 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001077 ql_dbg(ql_dbg_mbx, vha, 0x1048, "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001078
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001079 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001080 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1081 vha->fcoe_fcf_idx = mcp->mb[10];
1082 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1083 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1084 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1085 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1086 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1087 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1088 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 }
1090
1091 return rval;
1092}
1093
1094/*
1095 * qla2x00_get_retry_cnt
1096 * Get current firmware login retry count and delay.
1097 *
1098 * Input:
1099 * ha = adapter block pointer.
1100 * retry_cnt = pointer to login retry count.
1101 * tov = pointer to login timeout value.
1102 *
1103 * Returns:
1104 * qla2x00 local function return status code.
1105 *
1106 * Context:
1107 * Kernel context.
1108 */
1109int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001110qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 uint16_t *r_a_tov)
1112{
1113 int rval;
1114 uint16_t ratov;
1115 mbx_cmd_t mc;
1116 mbx_cmd_t *mcp = &mc;
1117
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001118 ql_dbg(ql_dbg_mbx, vha, 0x1049, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119
1120 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1121 mcp->out_mb = MBX_0;
1122 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001123 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001125 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126
1127 if (rval != QLA_SUCCESS) {
1128 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001129 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1130 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131 } else {
1132 /* Convert returned data and check our values. */
1133 *r_a_tov = mcp->mb[3] / 2;
1134 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1135 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1136 /* Update to the larger values */
1137 *retry_cnt = (uint8_t)mcp->mb[1];
1138 *tov = ratov;
1139 }
1140
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001141 ql_dbg(ql_dbg_mbx, vha, 0x104b,
1142 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 }
1144
1145 return rval;
1146}
1147
1148/*
1149 * qla2x00_init_firmware
1150 * Initialize adapter firmware.
1151 *
1152 * Input:
1153 * ha = adapter block pointer.
1154 * dptr = Initialization control block pointer.
1155 * size = size of initialization control block.
1156 * TARGET_QUEUE_LOCK must be released.
1157 * ADAPTER_STATE_LOCK must be released.
1158 *
1159 * Returns:
1160 * qla2x00 local function return status code.
1161 *
1162 * Context:
1163 * Kernel context.
1164 */
1165int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001166qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167{
1168 int rval;
1169 mbx_cmd_t mc;
1170 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001171 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001173 ql_dbg(ql_dbg_mbx, vha, 0x104c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174
Giridhar Malavalia9083012010-04-12 17:59:55 -07001175 if (IS_QLA82XX(ha) && ql2xdbwr)
1176 qla82xx_wr_32(ha, ha->nxdb_wr_ptr,
1177 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1178
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001179 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001180 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1181 else
1182 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1183
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001184 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185 mcp->mb[2] = MSW(ha->init_cb_dma);
1186 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1188 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001189 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001190 if ((IS_QLA81XX(ha) || IS_QLA83XX(ha)) && ha->ex_init_cb->ex_version) {
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001191 mcp->mb[1] = BIT_0;
1192 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1193 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1194 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1195 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1196 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1197 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1198 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001199 /* 1 and 2 should normally be captured. */
1200 mcp->in_mb = MBX_2|MBX_1|MBX_0;
1201 if (IS_QLA83XX(ha))
1202 /* mb3 is additional info about the installed SFP. */
1203 mcp->in_mb |= MBX_3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001204 mcp->buf_size = size;
1205 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001206 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001207 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208
1209 if (rval != QLA_SUCCESS) {
1210 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001211 ql_dbg(ql_dbg_mbx, vha, 0x104d,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001212 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1213 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 } else {
1215 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001216 ql_dbg(ql_dbg_mbx, vha, 0x104e, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 }
1218
1219 return rval;
1220}
1221
1222/*
1223 * qla2x00_get_port_database
1224 * Issue normal/enhanced get port database mailbox command
1225 * and copy device name as necessary.
1226 *
1227 * Input:
1228 * ha = adapter state pointer.
1229 * dev = structure pointer.
1230 * opt = enhanced cmd option byte.
1231 *
1232 * Returns:
1233 * qla2x00 local function return status code.
1234 *
1235 * Context:
1236 * Kernel context.
1237 */
1238int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001239qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240{
1241 int rval;
1242 mbx_cmd_t mc;
1243 mbx_cmd_t *mcp = &mc;
1244 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001245 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001247 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001249 ql_dbg(ql_dbg_mbx, vha, 0x104f, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001251 pd24 = NULL;
1252 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001254 ql_log(ql_log_warn, vha, 0x1050,
1255 "Failed to allocate port database structure.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 return QLA_MEMORY_ALLOC_FAILED;
1257 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001258 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001260 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001261 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263 mcp->mb[2] = MSW(pd_dma);
1264 mcp->mb[3] = LSW(pd_dma);
1265 mcp->mb[6] = MSW(MSD(pd_dma));
1266 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001267 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001268 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001270 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001271 mcp->mb[1] = fcport->loop_id;
1272 mcp->mb[10] = opt;
1273 mcp->out_mb |= MBX_10|MBX_1;
1274 mcp->in_mb |= MBX_1;
1275 } else if (HAS_EXTENDED_IDS(ha)) {
1276 mcp->mb[1] = fcport->loop_id;
1277 mcp->mb[10] = opt;
1278 mcp->out_mb |= MBX_10|MBX_1;
1279 } else {
1280 mcp->mb[1] = fcport->loop_id << 8 | opt;
1281 mcp->out_mb |= MBX_1;
1282 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001283 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1284 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 mcp->flags = MBX_DMA_IN;
1286 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001287 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 if (rval != QLA_SUCCESS)
1289 goto gpd_error_out;
1290
Andrew Vasqueze4289242007-07-19 15:05:56 -07001291 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001292 pd24 = (struct port_database_24xx *) pd;
1293
1294 /* Check for logged in state. */
1295 if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1296 pd24->last_login_state != PDS_PRLI_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001297 ql_dbg(ql_dbg_mbx, vha, 0x1051,
1298 "Unable to verify login-state (%x/%x) for "
1299 "loop_id %x.\n", pd24->current_login_state,
1300 pd24->last_login_state, fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001301 rval = QLA_FUNCTION_FAILED;
1302 goto gpd_error_out;
1303 }
1304
1305 /* Names are little-endian. */
1306 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1307 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1308
1309 /* Get port_id of device. */
1310 fcport->d_id.b.domain = pd24->port_id[0];
1311 fcport->d_id.b.area = pd24->port_id[1];
1312 fcport->d_id.b.al_pa = pd24->port_id[2];
1313 fcport->d_id.b.rsvd_1 = 0;
1314
1315 /* If not target must be initiator or unknown type. */
1316 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1317 fcport->port_type = FCT_INITIATOR;
1318 else
1319 fcport->port_type = FCT_TARGET;
1320 } else {
1321 /* Check for logged in state. */
1322 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1323 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001324 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1325 "Unable to verify login-state (%x/%x) - "
1326 "portid=%02x%02x%02x.\n", pd->master_state,
1327 pd->slave_state, fcport->d_id.b.domain,
1328 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001329 rval = QLA_FUNCTION_FAILED;
1330 goto gpd_error_out;
1331 }
1332
1333 /* Names are little-endian. */
1334 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1335 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1336
1337 /* Get port_id of device. */
1338 fcport->d_id.b.domain = pd->port_id[0];
1339 fcport->d_id.b.area = pd->port_id[3];
1340 fcport->d_id.b.al_pa = pd->port_id[2];
1341 fcport->d_id.b.rsvd_1 = 0;
1342
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001343 /* If not target must be initiator or unknown type. */
1344 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1345 fcport->port_type = FCT_INITIATOR;
1346 else
1347 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001348
1349 /* Passback COS information. */
1350 fcport->supported_classes = (pd->options & BIT_4) ?
1351 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 }
1353
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354gpd_error_out:
1355 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1356
1357 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001358 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1359 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1360 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001362 ql_dbg(ql_dbg_mbx, vha, 0x1053, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363 }
1364
1365 return rval;
1366}
1367
1368/*
1369 * qla2x00_get_firmware_state
1370 * Get adapter firmware state.
1371 *
1372 * Input:
1373 * ha = adapter block pointer.
1374 * dptr = pointer for firmware state.
1375 * TARGET_QUEUE_LOCK must be released.
1376 * ADAPTER_STATE_LOCK must be released.
1377 *
1378 * Returns:
1379 * qla2x00 local function return status code.
1380 *
1381 * Context:
1382 * Kernel context.
1383 */
1384int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001385qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386{
1387 int rval;
1388 mbx_cmd_t mc;
1389 mbx_cmd_t *mcp = &mc;
1390
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001391 ql_dbg(ql_dbg_mbx, vha, 0x1054, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392
1393 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1394 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001395 if (IS_FWI2_CAPABLE(vha->hw))
1396 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1397 else
1398 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001399 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001401 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001403 /* Return firmware states. */
1404 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001405 if (IS_FWI2_CAPABLE(vha->hw)) {
1406 states[1] = mcp->mb[2];
1407 states[2] = mcp->mb[3];
1408 states[3] = mcp->mb[4];
1409 states[4] = mcp->mb[5];
1410 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411
1412 if (rval != QLA_SUCCESS) {
1413 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001414 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 } else {
1416 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001417 ql_dbg(ql_dbg_mbx, vha, 0x1056, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 }
1419
1420 return rval;
1421}
1422
1423/*
1424 * qla2x00_get_port_name
1425 * Issue get port name mailbox command.
1426 * Returned name is in big endian format.
1427 *
1428 * Input:
1429 * ha = adapter block pointer.
1430 * loop_id = loop ID of device.
1431 * name = pointer for name.
1432 * TARGET_QUEUE_LOCK must be released.
1433 * ADAPTER_STATE_LOCK must be released.
1434 *
1435 * Returns:
1436 * qla2x00 local function return status code.
1437 *
1438 * Context:
1439 * Kernel context.
1440 */
1441int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001442qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 uint8_t opt)
1444{
1445 int rval;
1446 mbx_cmd_t mc;
1447 mbx_cmd_t *mcp = &mc;
1448
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001449 ql_dbg(ql_dbg_mbx, vha, 0x1057, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450
1451 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001452 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001453 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001454 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455 mcp->mb[1] = loop_id;
1456 mcp->mb[10] = opt;
1457 mcp->out_mb |= MBX_10;
1458 } else {
1459 mcp->mb[1] = loop_id << 8 | opt;
1460 }
1461
1462 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001463 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001465 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466
1467 if (rval != QLA_SUCCESS) {
1468 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001469 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 } else {
1471 if (name != NULL) {
1472 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05001473 name[0] = MSB(mcp->mb[2]);
1474 name[1] = LSB(mcp->mb[2]);
1475 name[2] = MSB(mcp->mb[3]);
1476 name[3] = LSB(mcp->mb[3]);
1477 name[4] = MSB(mcp->mb[6]);
1478 name[5] = LSB(mcp->mb[6]);
1479 name[6] = MSB(mcp->mb[7]);
1480 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 }
1482
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001483 ql_dbg(ql_dbg_mbx, vha, 0x1059, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 }
1485
1486 return rval;
1487}
1488
1489/*
1490 * qla2x00_lip_reset
1491 * Issue LIP reset mailbox command.
1492 *
1493 * Input:
1494 * ha = adapter block pointer.
1495 * TARGET_QUEUE_LOCK must be released.
1496 * ADAPTER_STATE_LOCK must be released.
1497 *
1498 * Returns:
1499 * qla2x00 local function return status code.
1500 *
1501 * Context:
1502 * Kernel context.
1503 */
1504int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001505qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506{
1507 int rval;
1508 mbx_cmd_t mc;
1509 mbx_cmd_t *mcp = &mc;
1510
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001511 ql_dbg(ql_dbg_mbx, vha, 0x105a, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001513 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001514 /* Logout across all FCFs. */
1515 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1516 mcp->mb[1] = BIT_1;
1517 mcp->mb[2] = 0;
1518 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1519 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001520 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001521 mcp->mb[1] = BIT_6;
1522 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001523 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001524 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001526 mcp->mb[0] = MBC_LIP_RESET;
1527 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001528 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001529 mcp->mb[1] = 0x00ff;
1530 mcp->mb[10] = 0;
1531 mcp->out_mb |= MBX_10;
1532 } else {
1533 mcp->mb[1] = 0xff00;
1534 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001535 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001536 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001539 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001541 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542
1543 if (rval != QLA_SUCCESS) {
1544 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001545 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 } else {
1547 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001548 ql_dbg(ql_dbg_mbx, vha, 0x105c, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 }
1550
1551 return rval;
1552}
1553
1554/*
1555 * qla2x00_send_sns
1556 * Send SNS command.
1557 *
1558 * Input:
1559 * ha = adapter block pointer.
1560 * sns = pointer for command.
1561 * cmd_size = command size.
1562 * buf_size = response/command size.
1563 * TARGET_QUEUE_LOCK must be released.
1564 * ADAPTER_STATE_LOCK must be released.
1565 *
1566 * Returns:
1567 * qla2x00 local function return status code.
1568 *
1569 * Context:
1570 * Kernel context.
1571 */
1572int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001573qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 uint16_t cmd_size, size_t buf_size)
1575{
1576 int rval;
1577 mbx_cmd_t mc;
1578 mbx_cmd_t *mcp = &mc;
1579
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001580 ql_dbg(ql_dbg_mbx, vha, 0x105d, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001582 ql_dbg(ql_dbg_mbx, vha, 0x105e,
1583 "Retry cnt=%d ratov=%d total tov=%d.\n",
1584 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585
1586 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1587 mcp->mb[1] = cmd_size;
1588 mcp->mb[2] = MSW(sns_phys_address);
1589 mcp->mb[3] = LSW(sns_phys_address);
1590 mcp->mb[6] = MSW(MSD(sns_phys_address));
1591 mcp->mb[7] = LSW(MSD(sns_phys_address));
1592 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1593 mcp->in_mb = MBX_0|MBX_1;
1594 mcp->buf_size = buf_size;
1595 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001596 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1597 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598
1599 if (rval != QLA_SUCCESS) {
1600 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001601 ql_dbg(ql_dbg_mbx, vha, 0x105f,
1602 "Failed=%x mb[0]=%x mb[1]=%x.\n",
1603 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 } else {
1605 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001606 ql_dbg(ql_dbg_mbx, vha, 0x1060, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 }
1608
1609 return rval;
1610}
1611
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001612int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001613qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001614 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1615{
1616 int rval;
1617
1618 struct logio_entry_24xx *lg;
1619 dma_addr_t lg_dma;
1620 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001621 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001622 struct req_que *req;
1623 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001624
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001625 ql_dbg(ql_dbg_mbx, vha, 0x1061, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001626
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07001627 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07001628 req = ha->req_q_map[0];
1629 else
1630 req = vha->req;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001631 rsp = req->rsp;
1632
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001633 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1634 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001635 ql_log(ql_log_warn, vha, 0x1062,
1636 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001637 return QLA_MEMORY_ALLOC_FAILED;
1638 }
1639 memset(lg, 0, sizeof(struct logio_entry_24xx));
1640
1641 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1642 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001643 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001644 lg->nport_handle = cpu_to_le16(loop_id);
1645 lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
1646 if (opt & BIT_0)
1647 lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07001648 if (opt & BIT_1)
1649 lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001650 lg->port_id[0] = al_pa;
1651 lg->port_id[1] = area;
1652 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001653 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08001654 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
1655 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001656 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001657 ql_dbg(ql_dbg_mbx, vha, 0x1063,
1658 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001659 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001660 ql_dbg(ql_dbg_mbx, vha, 0x1064,
1661 "Failed to complete IOCB -- error status (%x).\n",
1662 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001663 rval = QLA_FUNCTION_FAILED;
1664 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1665 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1666 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1667
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001668 ql_dbg(ql_dbg_mbx, vha, 0x1065,
1669 "Failed to complete IOCB -- completion status (%x) "
1670 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
1671 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001672
1673 switch (iop[0]) {
1674 case LSC_SCODE_PORTID_USED:
1675 mb[0] = MBS_PORT_ID_USED;
1676 mb[1] = LSW(iop[1]);
1677 break;
1678 case LSC_SCODE_NPORT_USED:
1679 mb[0] = MBS_LOOP_ID_USED;
1680 break;
1681 case LSC_SCODE_NOLINK:
1682 case LSC_SCODE_NOIOCB:
1683 case LSC_SCODE_NOXCB:
1684 case LSC_SCODE_CMD_FAILED:
1685 case LSC_SCODE_NOFABRIC:
1686 case LSC_SCODE_FW_NOT_READY:
1687 case LSC_SCODE_NOT_LOGGED_IN:
1688 case LSC_SCODE_NOPCB:
1689 case LSC_SCODE_ELS_REJECT:
1690 case LSC_SCODE_CMD_PARAM_ERR:
1691 case LSC_SCODE_NONPORT:
1692 case LSC_SCODE_LOGGED_IN:
1693 case LSC_SCODE_NOFLOGI_ACC:
1694 default:
1695 mb[0] = MBS_COMMAND_ERROR;
1696 break;
1697 }
1698 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001699 ql_dbg(ql_dbg_mbx, vha, 0x1066, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001700
1701 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1702
1703 mb[0] = MBS_COMMAND_COMPLETE;
1704 mb[1] = 0;
1705 if (iop[0] & BIT_4) {
1706 if (iop[0] & BIT_8)
1707 mb[1] |= BIT_1;
1708 } else
1709 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001710
1711 /* Passback COS information. */
1712 mb[10] = 0;
1713 if (lg->io_parameter[7] || lg->io_parameter[8])
1714 mb[10] |= BIT_0; /* Class 2. */
1715 if (lg->io_parameter[9] || lg->io_parameter[10])
1716 mb[10] |= BIT_1; /* Class 3. */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001717 }
1718
1719 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1720
1721 return rval;
1722}
1723
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724/*
1725 * qla2x00_login_fabric
1726 * Issue login fabric port mailbox command.
1727 *
1728 * Input:
1729 * ha = adapter block pointer.
1730 * loop_id = device loop ID.
1731 * domain = device domain.
1732 * area = device area.
1733 * al_pa = device AL_PA.
1734 * status = pointer for return status.
1735 * opt = command options.
1736 * TARGET_QUEUE_LOCK must be released.
1737 * ADAPTER_STATE_LOCK must be released.
1738 *
1739 * Returns:
1740 * qla2x00 local function return status code.
1741 *
1742 * Context:
1743 * Kernel context.
1744 */
1745int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001746qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1748{
1749 int rval;
1750 mbx_cmd_t mc;
1751 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001752 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001754 ql_dbg(ql_dbg_mbx, vha, 0x1067, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755
1756 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1757 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1758 if (HAS_EXTENDED_IDS(ha)) {
1759 mcp->mb[1] = loop_id;
1760 mcp->mb[10] = opt;
1761 mcp->out_mb |= MBX_10;
1762 } else {
1763 mcp->mb[1] = (loop_id << 8) | opt;
1764 }
1765 mcp->mb[2] = domain;
1766 mcp->mb[3] = area << 8 | al_pa;
1767
1768 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1769 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1770 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001771 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772
1773 /* Return mailbox statuses. */
1774 if (mb != NULL) {
1775 mb[0] = mcp->mb[0];
1776 mb[1] = mcp->mb[1];
1777 mb[2] = mcp->mb[2];
1778 mb[6] = mcp->mb[6];
1779 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001780 /* COS retrieved from Get-Port-Database mailbox command. */
1781 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 }
1783
1784 if (rval != QLA_SUCCESS) {
1785 /* RLU tmp code: need to change main mailbox_command function to
1786 * return ok even when the mailbox completion value is not
1787 * SUCCESS. The caller needs to be responsible to interpret
1788 * the return values of this mailbox command if we're not
1789 * to change too much of the existing code.
1790 */
1791 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
1792 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
1793 mcp->mb[0] == 0x4006)
1794 rval = QLA_SUCCESS;
1795
1796 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001797 ql_dbg(ql_dbg_mbx, vha, 0x1068,
1798 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
1799 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800 } else {
1801 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001802 ql_dbg(ql_dbg_mbx, vha, 0x1069, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 }
1804
1805 return rval;
1806}
1807
1808/*
1809 * qla2x00_login_local_device
1810 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001811 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 * Input:
1813 * ha = adapter block pointer.
1814 * loop_id = device loop ID.
1815 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001816 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 * Returns:
1818 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001819 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 * Context:
1821 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07001822 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 */
1824int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001825qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001826 uint16_t *mb_ret, uint8_t opt)
1827{
1828 int rval;
1829 mbx_cmd_t mc;
1830 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001831 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001833 ql_dbg(ql_dbg_mbx, vha, 0x106a, "Entered %s.\n", __func__);
1834
Andrew Vasqueze4289242007-07-19 15:05:56 -07001835 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001836 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001837 fcport->d_id.b.domain, fcport->d_id.b.area,
1838 fcport->d_id.b.al_pa, mb_ret, opt);
1839
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
1841 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001842 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 else
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08001844 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845 mcp->mb[2] = opt;
1846 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1847 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
1848 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1849 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001850 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851
1852 /* Return mailbox statuses. */
1853 if (mb_ret != NULL) {
1854 mb_ret[0] = mcp->mb[0];
1855 mb_ret[1] = mcp->mb[1];
1856 mb_ret[6] = mcp->mb[6];
1857 mb_ret[7] = mcp->mb[7];
1858 }
1859
1860 if (rval != QLA_SUCCESS) {
1861 /* AV tmp code: need to change main mailbox_command function to
1862 * return ok even when the mailbox completion value is not
1863 * SUCCESS. The caller needs to be responsible to interpret
1864 * the return values of this mailbox command if we're not
1865 * to change too much of the existing code.
1866 */
1867 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
1868 rval = QLA_SUCCESS;
1869
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001870 ql_dbg(ql_dbg_mbx, vha, 0x106b,
1871 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
1872 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873 } else {
1874 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001875 ql_dbg(ql_dbg_mbx, vha, 0x106c, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 }
1877
1878 return (rval);
1879}
1880
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001881int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001882qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001883 uint8_t area, uint8_t al_pa)
1884{
1885 int rval;
1886 struct logio_entry_24xx *lg;
1887 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001888 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001889 struct req_que *req;
1890 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001891
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001892 ql_dbg(ql_dbg_mbx, vha, 0x106d, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001893
1894 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1895 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001896 ql_log(ql_log_warn, vha, 0x106e,
1897 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001898 return QLA_MEMORY_ALLOC_FAILED;
1899 }
1900 memset(lg, 0, sizeof(struct logio_entry_24xx));
1901
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001902 if (ql2xmaxqueues > 1)
1903 req = ha->req_q_map[0];
1904 else
1905 req = vha->req;
1906 rsp = req->rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001907 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1908 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001909 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001910 lg->nport_handle = cpu_to_le16(loop_id);
1911 lg->control_flags =
Andrew Vasquezc8d66912011-03-30 11:46:21 -07001912 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
1913 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001914 lg->port_id[0] = al_pa;
1915 lg->port_id[1] = area;
1916 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001917 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08001918 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
1919 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001920 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001921 ql_dbg(ql_dbg_mbx, vha, 0x106f,
1922 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001923 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001924 ql_dbg(ql_dbg_mbx, vha, 0x1070,
1925 "Failed to complete IOCB -- error status (%x).\n",
1926 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001927 rval = QLA_FUNCTION_FAILED;
1928 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001929 ql_dbg(ql_dbg_mbx, vha, 0x1071,
1930 "Failed to complete IOCB -- completion status (%x) "
1931 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001932 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001933 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001934 } else {
1935 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001936 ql_dbg(ql_dbg_mbx, vha, 0x1072, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001937 }
1938
1939 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1940
1941 return rval;
1942}
1943
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944/*
1945 * qla2x00_fabric_logout
1946 * Issue logout fabric port mailbox command.
1947 *
1948 * Input:
1949 * ha = adapter block pointer.
1950 * loop_id = device loop ID.
1951 * TARGET_QUEUE_LOCK must be released.
1952 * ADAPTER_STATE_LOCK must be released.
1953 *
1954 * Returns:
1955 * qla2x00 local function return status code.
1956 *
1957 * Context:
1958 * Kernel context.
1959 */
1960int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001961qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001962 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001963{
1964 int rval;
1965 mbx_cmd_t mc;
1966 mbx_cmd_t *mcp = &mc;
1967
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001968 ql_dbg(ql_dbg_mbx, vha, 0x1073, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969
1970 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
1971 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001972 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973 mcp->mb[1] = loop_id;
1974 mcp->mb[10] = 0;
1975 mcp->out_mb |= MBX_10;
1976 } else {
1977 mcp->mb[1] = loop_id << 8;
1978 }
1979
1980 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001981 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001983 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984
1985 if (rval != QLA_SUCCESS) {
1986 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001987 ql_dbg(ql_dbg_mbx, vha, 0x1074,
1988 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 } else {
1990 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001991 ql_dbg(ql_dbg_mbx, vha, 0x1075, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992 }
1993
1994 return rval;
1995}
1996
1997/*
1998 * qla2x00_full_login_lip
1999 * Issue full login LIP mailbox command.
2000 *
2001 * Input:
2002 * ha = adapter block pointer.
2003 * TARGET_QUEUE_LOCK must be released.
2004 * ADAPTER_STATE_LOCK must be released.
2005 *
2006 * Returns:
2007 * qla2x00 local function return status code.
2008 *
2009 * Context:
2010 * Kernel context.
2011 */
2012int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002013qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014{
2015 int rval;
2016 mbx_cmd_t mc;
2017 mbx_cmd_t *mcp = &mc;
2018
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002019 ql_dbg(ql_dbg_mbx, vha, 0x1076, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020
2021 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002022 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002023 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024 mcp->mb[3] = 0;
2025 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2026 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002027 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002028 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002029 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030
2031 if (rval != QLA_SUCCESS) {
2032 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002033 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034 } else {
2035 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002036 ql_dbg(ql_dbg_mbx, vha, 0x1078, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002037 }
2038
2039 return rval;
2040}
2041
2042/*
2043 * qla2x00_get_id_list
2044 *
2045 * Input:
2046 * ha = adapter block pointer.
2047 *
2048 * Returns:
2049 * qla2x00 local function return status code.
2050 *
2051 * Context:
2052 * Kernel context.
2053 */
2054int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002055qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056 uint16_t *entries)
2057{
2058 int rval;
2059 mbx_cmd_t mc;
2060 mbx_cmd_t *mcp = &mc;
2061
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002062 ql_dbg(ql_dbg_mbx, vha, 0x1079, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063
2064 if (id_list == NULL)
2065 return QLA_FUNCTION_FAILED;
2066
2067 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002068 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002069 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002070 mcp->mb[2] = MSW(id_list_dma);
2071 mcp->mb[3] = LSW(id_list_dma);
2072 mcp->mb[6] = MSW(MSD(id_list_dma));
2073 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002074 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002075 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002076 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002077 } else {
2078 mcp->mb[1] = MSW(id_list_dma);
2079 mcp->mb[2] = LSW(id_list_dma);
2080 mcp->mb[3] = MSW(MSD(id_list_dma));
2081 mcp->mb[6] = LSW(MSD(id_list_dma));
2082 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2083 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002085 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002087 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088
2089 if (rval != QLA_SUCCESS) {
2090 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002091 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092 } else {
2093 *entries = mcp->mb[1];
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002094 ql_dbg(ql_dbg_mbx, vha, 0x107b, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095 }
2096
2097 return rval;
2098}
2099
2100/*
2101 * qla2x00_get_resource_cnts
2102 * Get current firmware resource counts.
2103 *
2104 * Input:
2105 * ha = adapter block pointer.
2106 *
2107 * Returns:
2108 * qla2x00 local function return status code.
2109 *
2110 * Context:
2111 * Kernel context.
2112 */
2113int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002114qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002115 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002116 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117{
2118 int rval;
2119 mbx_cmd_t mc;
2120 mbx_cmd_t *mcp = &mc;
2121
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002122 ql_dbg(ql_dbg_mbx, vha, 0x107c, "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123
2124 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2125 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002126 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 -08002127 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002128 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002129 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002130 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002131 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002132
2133 if (rval != QLA_SUCCESS) {
2134 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002135 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2136 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002138 ql_dbg(ql_dbg_mbx, vha, 0x107e,
2139 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2140 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2141 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2142 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143
2144 if (cur_xchg_cnt)
2145 *cur_xchg_cnt = mcp->mb[3];
2146 if (orig_xchg_cnt)
2147 *orig_xchg_cnt = mcp->mb[6];
2148 if (cur_iocb_cnt)
2149 *cur_iocb_cnt = mcp->mb[7];
2150 if (orig_iocb_cnt)
2151 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002152 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002153 *max_npiv_vports = mcp->mb[11];
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002154 if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) && max_fcfs)
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002155 *max_fcfs = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156 }
2157
2158 return (rval);
2159}
2160
Linus Torvalds1da177e2005-04-16 15:20:36 -07002161/*
2162 * qla2x00_get_fcal_position_map
2163 * Get FCAL (LILP) position map using mailbox command
2164 *
2165 * Input:
2166 * ha = adapter state pointer.
2167 * pos_map = buffer pointer (can be NULL).
2168 *
2169 * Returns:
2170 * qla2x00 local function return status code.
2171 *
2172 * Context:
2173 * Kernel context.
2174 */
2175int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002176qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177{
2178 int rval;
2179 mbx_cmd_t mc;
2180 mbx_cmd_t *mcp = &mc;
2181 char *pmap;
2182 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002183 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002185 ql_dbg(ql_dbg_mbx, vha, 0x107f, "Entered %s.\n", __func__);
2186
Andrew Vasquez4b892582008-09-11 21:22:48 -07002187 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002189 ql_log(ql_log_warn, vha, 0x1080,
2190 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191 return QLA_MEMORY_ALLOC_FAILED;
2192 }
2193 memset(pmap, 0, FCAL_MAP_SIZE);
2194
2195 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2196 mcp->mb[2] = MSW(pmap_dma);
2197 mcp->mb[3] = LSW(pmap_dma);
2198 mcp->mb[6] = MSW(MSD(pmap_dma));
2199 mcp->mb[7] = LSW(MSD(pmap_dma));
2200 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2201 mcp->in_mb = MBX_1|MBX_0;
2202 mcp->buf_size = FCAL_MAP_SIZE;
2203 mcp->flags = MBX_DMA_IN;
2204 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002205 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002206
2207 if (rval == QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002208 ql_dbg(ql_dbg_mbx, vha, 0x1081,
2209 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2210 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2211 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2212 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002213
2214 if (pos_map)
2215 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2216 }
2217 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2218
2219 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002220 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002222 ql_dbg(ql_dbg_mbx, vha, 0x1083, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002223 }
2224
2225 return rval;
2226}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002227
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002228/*
2229 * qla2x00_get_link_status
2230 *
2231 * Input:
2232 * ha = adapter block pointer.
2233 * loop_id = device loop ID.
2234 * ret_buf = pointer to link status return buffer.
2235 *
2236 * Returns:
2237 * 0 = success.
2238 * BIT_0 = mem alloc error.
2239 * BIT_1 = mailbox error.
2240 */
2241int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002242qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002243 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002244{
2245 int rval;
2246 mbx_cmd_t mc;
2247 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002248 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002249 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002250
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002251 ql_dbg(ql_dbg_mbx, vha, 0x1084, "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002252
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002253 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002254 mcp->mb[2] = MSW(stats_dma);
2255 mcp->mb[3] = LSW(stats_dma);
2256 mcp->mb[6] = MSW(MSD(stats_dma));
2257 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002258 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2259 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002260 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002261 mcp->mb[1] = loop_id;
2262 mcp->mb[4] = 0;
2263 mcp->mb[10] = 0;
2264 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2265 mcp->in_mb |= MBX_1;
2266 } else if (HAS_EXTENDED_IDS(ha)) {
2267 mcp->mb[1] = loop_id;
2268 mcp->mb[10] = 0;
2269 mcp->out_mb |= MBX_10|MBX_1;
2270 } else {
2271 mcp->mb[1] = loop_id << 8;
2272 mcp->out_mb |= MBX_1;
2273 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002274 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002275 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002276 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002277
2278 if (rval == QLA_SUCCESS) {
2279 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002280 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2281 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002282 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002283 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002284 /* Copy over data -- firmware data is LE. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002285 ql_dbg(ql_dbg_mbx, vha, 0x1086, "Done %s.\n", __func__);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002286 dwords = offsetof(struct link_statistics, unused1) / 4;
2287 siter = diter = &stats->link_fail_cnt;
2288 while (dwords--)
2289 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002290 }
2291 } else {
2292 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002293 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002294 }
2295
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002296 return rval;
2297}
2298
2299int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002300qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002301 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002302{
2303 int rval;
2304 mbx_cmd_t mc;
2305 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002306 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002307
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002308 ql_dbg(ql_dbg_mbx, vha, 0x1088, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002309
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002310 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002311 mcp->mb[2] = MSW(stats_dma);
2312 mcp->mb[3] = LSW(stats_dma);
2313 mcp->mb[6] = MSW(MSD(stats_dma));
2314 mcp->mb[7] = LSW(MSD(stats_dma));
2315 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002316 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002317 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002318 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 -07002319 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002320 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002321 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002322 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002323
2324 if (rval == QLA_SUCCESS) {
2325 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002326 ql_dbg(ql_dbg_mbx, vha, 0x1089,
2327 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002328 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002329 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002330 ql_dbg(ql_dbg_mbx, vha, 0x108a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002331 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002332 dwords = sizeof(struct link_statistics) / 4;
2333 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002334 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002335 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002336 }
2337 } else {
2338 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002339 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002340 }
2341
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002342 return rval;
2343}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002344
2345int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002346qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002347{
2348 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002349 unsigned long flags = 0;
2350
2351 struct abort_entry_24xx *abt;
2352 dma_addr_t abt_dma;
2353 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002354 fc_port_t *fcport = sp->fcport;
2355 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002356 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07002357 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002358
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002359 ql_dbg(ql_dbg_mbx, vha, 0x108c, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002360
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002361 spin_lock_irqsave(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002362 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002363 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002364 break;
2365 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002366 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002367 if (handle == MAX_OUTSTANDING_COMMANDS) {
2368 /* Command not found. */
2369 return QLA_FUNCTION_FAILED;
2370 }
2371
2372 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2373 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002374 ql_log(ql_log_warn, vha, 0x108d,
2375 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002376 return QLA_MEMORY_ALLOC_FAILED;
2377 }
2378 memset(abt, 0, sizeof(struct abort_entry_24xx));
2379
2380 abt->entry_type = ABORT_IOCB_TYPE;
2381 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002382 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002383 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07002384 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002385 abt->port_id[0] = fcport->d_id.b.al_pa;
2386 abt->port_id[1] = fcport->d_id.b.area;
2387 abt->port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002388 abt->vp_index = fcport->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002389
2390 abt->req_que_no = cpu_to_le16(req->id);
2391
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002392 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002393 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002394 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2395 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002396 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002397 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2398 "Failed to complete IOCB -- error status (%x).\n",
2399 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002400 rval = QLA_FUNCTION_FAILED;
2401 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002402 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2403 "Failed to complete IOCB -- completion status (%x).\n",
2404 le16_to_cpu(abt->nport_handle));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002405 rval = QLA_FUNCTION_FAILED;
2406 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002407 ql_dbg(ql_dbg_mbx, vha, 0x1091, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002408 }
2409
2410 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2411
2412 return rval;
2413}
2414
2415struct tsk_mgmt_cmd {
2416 union {
2417 struct tsk_mgmt_entry tsk;
2418 struct sts_entry_24xx sts;
2419 } p;
2420};
2421
Andrew Vasquez523ec772008-04-03 13:13:24 -07002422static int
2423__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002424 unsigned int l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002425{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002426 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002427 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002428 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002429 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002430 scsi_qla_host_t *vha;
2431 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002432 struct req_que *req;
2433 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002434
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002435 vha = fcport->vha;
2436 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002437 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002438
2439 ql_dbg(ql_dbg_mbx, vha, 0x1092, "Entered %s.\n", __func__);
2440
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002441 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002442 rsp = ha->rsp_q_map[tag + 1];
2443 else
2444 rsp = req->rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002445 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002446 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002447 ql_log(ql_log_warn, vha, 0x1093,
2448 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002449 return QLA_MEMORY_ALLOC_FAILED;
2450 }
2451 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2452
2453 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2454 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002455 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002456 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002457 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002458 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002459 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2460 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2461 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002462 tsk->p.tsk.vp_index = fcport->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002463 if (type == TCF_LUN_RESET) {
2464 int_to_scsilun(l, &tsk->p.tsk.lun);
2465 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2466 sizeof(tsk->p.tsk.lun));
2467 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002468
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002469 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002470 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002471 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002472 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2473 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002474 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002475 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2476 "Failed to complete IOCB -- error status (%x).\n",
2477 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002478 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002479 } else if (sts->comp_status !=
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002480 __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002481 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2482 "Failed to complete IOCB -- completion status (%x).\n",
2483 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002484 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08002485 } else if (le16_to_cpu(sts->scsi_status) &
2486 SS_RESPONSE_INFO_LEN_VALID) {
2487 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002488 ql_dbg(ql_dbg_mbx, vha, 0x1097,
2489 "Ignoring inconsistent data length -- not enough "
2490 "response info (%d).\n",
2491 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08002492 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002493 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2494 "Failed to complete IOCB -- response (%x).\n",
2495 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08002496 rval = QLA_FUNCTION_FAILED;
2497 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002498 }
2499
2500 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002501 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002502 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2503 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002504 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2505 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002506 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002507 ql_dbg(ql_dbg_mbx, vha, 0x109a, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002508 }
2509
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002510 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002511
2512 return rval;
2513}
2514
Andrew Vasquez523ec772008-04-03 13:13:24 -07002515int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002516qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002517{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002518 struct qla_hw_data *ha = fcport->vha->hw;
2519
2520 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2521 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2522
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002523 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002524}
2525
2526int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002527qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002528{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002529 struct qla_hw_data *ha = fcport->vha->hw;
2530
2531 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2532 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2533
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002534 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002535}
2536
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002537int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002538qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002539{
2540 int rval;
2541 mbx_cmd_t mc;
2542 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002543 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002544
Andrew Vasquez68af0812008-05-12 22:21:13 -07002545 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002546 return QLA_FUNCTION_FAILED;
2547
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002548 ql_dbg(ql_dbg_mbx, vha, 0x109b, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002549
2550 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2551 mcp->out_mb = MBX_0;
2552 mcp->in_mb = MBX_0;
2553 mcp->tov = 5;
2554 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002555 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002556
2557 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002558 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002559 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002560 ql_dbg(ql_dbg_mbx, vha, 0x109d, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002561 }
2562
2563 return rval;
2564}
2565
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002566/**
2567 * qla2x00_set_serdes_params() -
2568 * @ha: HA context
2569 *
2570 * Returns
2571 */
2572int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002573qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002574 uint16_t sw_em_2g, uint16_t sw_em_4g)
2575{
2576 int rval;
2577 mbx_cmd_t mc;
2578 mbx_cmd_t *mcp = &mc;
2579
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002580 ql_dbg(ql_dbg_mbx, vha, 0x109e, "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002581
2582 mcp->mb[0] = MBC_SERDES_PARAMS;
2583 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08002584 mcp->mb[2] = sw_em_1g | BIT_15;
2585 mcp->mb[3] = sw_em_2g | BIT_15;
2586 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002587 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2588 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002589 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002590 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002591 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002592
2593 if (rval != QLA_SUCCESS) {
2594 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002595 ql_dbg(ql_dbg_mbx, vha, 0x109f,
2596 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002597 } else {
2598 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002599 ql_dbg(ql_dbg_mbx, vha, 0x10a0, "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002600 }
2601
2602 return rval;
2603}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002604
2605int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002606qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002607{
2608 int rval;
2609 mbx_cmd_t mc;
2610 mbx_cmd_t *mcp = &mc;
2611
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002612 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002613 return QLA_FUNCTION_FAILED;
2614
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002615 ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002616
2617 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08002618 mcp->mb[1] = 0;
2619 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002620 mcp->in_mb = MBX_0;
2621 mcp->tov = 5;
2622 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002623 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002624
2625 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002626 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07002627 if (mcp->mb[0] == MBS_INVALID_COMMAND)
2628 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002629 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002630 ql_dbg(ql_dbg_mbx, vha, 0x10a3, "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002631 }
2632
2633 return rval;
2634}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002635
2636int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002637qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002638 uint16_t buffers)
2639{
2640 int rval;
2641 mbx_cmd_t mc;
2642 mbx_cmd_t *mcp = &mc;
2643
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002644 ql_dbg(ql_dbg_mbx, vha, 0x10a4, "Entered %s.\n", __func__);
2645
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002646 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002647 return QLA_FUNCTION_FAILED;
2648
Andrew Vasquez85880802009-12-15 21:29:46 -08002649 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2650 return QLA_FUNCTION_FAILED;
2651
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002652 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002653 mcp->mb[1] = TC_EFT_ENABLE;
2654 mcp->mb[2] = LSW(eft_dma);
2655 mcp->mb[3] = MSW(eft_dma);
2656 mcp->mb[4] = LSW(MSD(eft_dma));
2657 mcp->mb[5] = MSW(MSD(eft_dma));
2658 mcp->mb[6] = buffers;
2659 mcp->mb[7] = TC_AEN_DISABLE;
2660 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 -07002661 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002662 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002663 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002664 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002665 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002666 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
2667 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2668 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002669 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002670 ql_dbg(ql_dbg_mbx, vha, 0x10a6, "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002671 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002672
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002673 return rval;
2674}
2675
2676int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002677qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002678{
2679 int rval;
2680 mbx_cmd_t mc;
2681 mbx_cmd_t *mcp = &mc;
2682
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002683 ql_dbg(ql_dbg_mbx, vha, 0x10a7, "Entered %s.\n", __func__);
2684
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002685 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002686 return QLA_FUNCTION_FAILED;
2687
Andrew Vasquez85880802009-12-15 21:29:46 -08002688 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2689 return QLA_FUNCTION_FAILED;
2690
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002691 mcp->mb[0] = MBC_TRACE_CONTROL;
2692 mcp->mb[1] = TC_EFT_DISABLE;
2693 mcp->out_mb = MBX_1|MBX_0;
2694 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002695 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002696 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002697 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002698 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002699 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
2700 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2701 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002702 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002703 ql_dbg(ql_dbg_mbx, vha, 0x10a9, "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002704 }
2705
2706 return rval;
2707}
2708
Andrew Vasquez88729e52006-06-23 16:10:50 -07002709int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002710qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002711 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
2712{
2713 int rval;
2714 mbx_cmd_t mc;
2715 mbx_cmd_t *mcp = &mc;
2716
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002717 ql_dbg(ql_dbg_mbx, vha, 0x10aa, "Entered %s.\n", __func__);
2718
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002719 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
2720 !IS_QLA83XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002721 return QLA_FUNCTION_FAILED;
2722
Andrew Vasquez85880802009-12-15 21:29:46 -08002723 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2724 return QLA_FUNCTION_FAILED;
2725
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002726 mcp->mb[0] = MBC_TRACE_CONTROL;
2727 mcp->mb[1] = TC_FCE_ENABLE;
2728 mcp->mb[2] = LSW(fce_dma);
2729 mcp->mb[3] = MSW(fce_dma);
2730 mcp->mb[4] = LSW(MSD(fce_dma));
2731 mcp->mb[5] = MSW(MSD(fce_dma));
2732 mcp->mb[6] = buffers;
2733 mcp->mb[7] = TC_AEN_DISABLE;
2734 mcp->mb[8] = 0;
2735 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
2736 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
2737 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2738 MBX_1|MBX_0;
2739 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002740 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002741 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002742 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002743 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002744 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
2745 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2746 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002747 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002748 ql_dbg(ql_dbg_mbx, vha, 0x10ac, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002749
2750 if (mb)
2751 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
2752 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07002753 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002754 }
2755
2756 return rval;
2757}
2758
2759int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002760qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002761{
2762 int rval;
2763 mbx_cmd_t mc;
2764 mbx_cmd_t *mcp = &mc;
2765
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002766 ql_dbg(ql_dbg_mbx, vha, 0x10ad, "Entered %s.\n", __func__);
2767
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002768 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002769 return QLA_FUNCTION_FAILED;
2770
Andrew Vasquez85880802009-12-15 21:29:46 -08002771 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2772 return QLA_FUNCTION_FAILED;
2773
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002774 mcp->mb[0] = MBC_TRACE_CONTROL;
2775 mcp->mb[1] = TC_FCE_DISABLE;
2776 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
2777 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2778 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2779 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002780 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002781 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002782 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002783 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002784 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
2785 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2786 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002787 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002788 ql_dbg(ql_dbg_mbx, vha, 0x10af, "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002789
2790 if (wr)
2791 *wr = (uint64_t) mcp->mb[5] << 48 |
2792 (uint64_t) mcp->mb[4] << 32 |
2793 (uint64_t) mcp->mb[3] << 16 |
2794 (uint64_t) mcp->mb[2];
2795 if (rd)
2796 *rd = (uint64_t) mcp->mb[9] << 48 |
2797 (uint64_t) mcp->mb[8] << 32 |
2798 (uint64_t) mcp->mb[7] << 16 |
2799 (uint64_t) mcp->mb[6];
2800 }
2801
2802 return rval;
2803}
2804
2805int
Giridhar Malavali6e980162010-03-19 17:03:58 -07002806qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
2807 uint16_t *port_speed, uint16_t *mb)
2808{
2809 int rval;
2810 mbx_cmd_t mc;
2811 mbx_cmd_t *mcp = &mc;
2812
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002813 ql_dbg(ql_dbg_mbx, vha, 0x10b0, "Entered %s.\n", __func__);
2814
Giridhar Malavali6e980162010-03-19 17:03:58 -07002815 if (!IS_IIDMA_CAPABLE(vha->hw))
2816 return QLA_FUNCTION_FAILED;
2817
Giridhar Malavali6e980162010-03-19 17:03:58 -07002818 mcp->mb[0] = MBC_PORT_PARAMS;
2819 mcp->mb[1] = loop_id;
2820 mcp->mb[2] = mcp->mb[3] = 0;
2821 mcp->mb[9] = vha->vp_idx;
2822 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2823 mcp->in_mb = MBX_3|MBX_1|MBX_0;
2824 mcp->tov = MBX_TOV_SECONDS;
2825 mcp->flags = 0;
2826 rval = qla2x00_mailbox_command(vha, mcp);
2827
2828 /* Return mailbox statuses. */
2829 if (mb != NULL) {
2830 mb[0] = mcp->mb[0];
2831 mb[1] = mcp->mb[1];
2832 mb[3] = mcp->mb[3];
2833 }
2834
2835 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002836 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002837 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002838 ql_dbg(ql_dbg_mbx, vha, 0x10b2, "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07002839 if (port_speed)
2840 *port_speed = mcp->mb[3];
2841 }
2842
2843 return rval;
2844}
2845
2846int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002847qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002848 uint16_t port_speed, uint16_t *mb)
2849{
2850 int rval;
2851 mbx_cmd_t mc;
2852 mbx_cmd_t *mcp = &mc;
2853
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002854 ql_dbg(ql_dbg_mbx, vha, 0x10b3, "Entered %s.\n", __func__);
2855
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002856 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002857 return QLA_FUNCTION_FAILED;
2858
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002859 mcp->mb[0] = MBC_PORT_PARAMS;
2860 mcp->mb[1] = loop_id;
2861 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002862 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07002863 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
2864 else
2865 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
2866 mcp->mb[9] = vha->vp_idx;
2867 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
2868 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002869 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002870 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002871 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002872
2873 /* Return mailbox statuses. */
2874 if (mb != NULL) {
2875 mb[0] = mcp->mb[0];
2876 mb[1] = mcp->mb[1];
2877 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002878 }
2879
2880 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002881 ql_dbg(ql_dbg_mbx, vha, 0x10b4, "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002882 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002883 ql_dbg(ql_dbg_mbx, vha, 0x10b5, "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07002884 }
2885
2886 return rval;
2887}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002888
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002889void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002890qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002891 struct vp_rpt_id_entry_24xx *rptid_entry)
2892{
2893 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07002894 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002895 struct qla_hw_data *ha = vha->hw;
2896 scsi_qla_host_t *vp;
Arun Easifeafb7b2010-09-03 14:57:00 -07002897 unsigned long flags;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002898
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002899 ql_dbg(ql_dbg_mbx, vha, 0x10b6, "Entered %s.\n", __func__);
2900
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002901 if (rptid_entry->entry_status != 0)
2902 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002903
2904 if (rptid_entry->format == 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002905 ql_dbg(ql_dbg_mbx, vha, 0x10b7,
2906 "Format 0 : Number of VPs setup %d, number of "
2907 "VPs acquired %d.\n",
2908 MSB(le16_to_cpu(rptid_entry->vp_count)),
2909 LSB(le16_to_cpu(rptid_entry->vp_count)));
2910 ql_dbg(ql_dbg_mbx, vha, 0x10b8,
2911 "Primary port id %02x%02x%02x.\n",
2912 rptid_entry->port_id[2], rptid_entry->port_id[1],
2913 rptid_entry->port_id[0]);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002914 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07002915 vp_idx = LSB(stat);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002916 ql_dbg(ql_dbg_mbx, vha, 0x10b9,
2917 "Format 1: VP[%d] enabled - status %d - with "
2918 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002919 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002920 rptid_entry->port_id[0]);
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002921
2922 vp = vha;
2923 if (vp_idx == 0 && (MSB(stat) != 1))
2924 goto reg_needed;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002925
Giridhar Malavali882a9172011-11-18 09:03:12 -08002926 if (MSB(stat) != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002927 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
2928 "Could not acquire ID for VP[%d].\n", vp_idx);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002929 return;
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07002930 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002931
Arun Easifeafb7b2010-09-03 14:57:00 -07002932 spin_lock_irqsave(&ha->vport_slock, flags);
2933 list_for_each_entry(vp, &ha->vp_list, list)
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002934 if (vp_idx == vp->vp_idx)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002935 break;
Arun Easifeafb7b2010-09-03 14:57:00 -07002936 spin_unlock_irqrestore(&ha->vport_slock, flags);
2937
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002938 if (!vp)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002939 return;
2940
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002941 vp->d_id.b.domain = rptid_entry->port_id[2];
2942 vp->d_id.b.area = rptid_entry->port_id[1];
2943 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002944
2945 /*
2946 * Cannot configure here as we are still sitting on the
2947 * response queue. Handle it in dpc context.
2948 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002949 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002950
Andrew Vasquez531a82d2009-10-13 15:16:51 -07002951reg_needed:
2952 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
2953 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
2954 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002955 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002956 }
2957}
2958
2959/*
2960 * qla24xx_modify_vp_config
2961 * Change VP configuration for vha
2962 *
2963 * Input:
2964 * vha = adapter block pointer.
2965 *
2966 * Returns:
2967 * qla2xxx local function return status code.
2968 *
2969 * Context:
2970 * Kernel context.
2971 */
2972int
2973qla24xx_modify_vp_config(scsi_qla_host_t *vha)
2974{
2975 int rval;
2976 struct vp_config_entry_24xx *vpmod;
2977 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002978 struct qla_hw_data *ha = vha->hw;
2979 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002980
2981 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002982
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002983 ql_dbg(ql_dbg_mbx, vha, 0x10bb, "Entered %s.\n", __func__);
2984
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002985 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002986 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002987 ql_log(ql_log_warn, vha, 0x10bc,
2988 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002989 return QLA_MEMORY_ALLOC_FAILED;
2990 }
2991
2992 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
2993 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
2994 vpmod->entry_count = 1;
2995 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
2996 vpmod->vp_count = 1;
2997 vpmod->vp_index1 = vha->vp_idx;
2998 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
2999 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
3000 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
3001 vpmod->entry_count = 1;
3002
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003003 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003004 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003005 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
3006 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003007 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003008 ql_dbg(ql_dbg_mbx, vha, 0x10be,
3009 "Failed to complete IOCB -- error status (%x).\n",
3010 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003011 rval = QLA_FUNCTION_FAILED;
3012 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003013 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3014 "Failed to complete IOCB -- completion status (%x).\n",
3015 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003016 rval = QLA_FUNCTION_FAILED;
3017 } else {
3018 /* EMPTY */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003019 ql_dbg(ql_dbg_mbx, vha, 0x10c0, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003020 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3021 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003022 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003023
3024 return rval;
3025}
3026
3027/*
3028 * qla24xx_control_vp
3029 * Enable a virtual port for given host
3030 *
3031 * Input:
3032 * ha = adapter block pointer.
3033 * vhba = virtual adapter (unused)
3034 * index = index number for enabled VP
3035 *
3036 * Returns:
3037 * qla2xxx local function return status code.
3038 *
3039 * Context:
3040 * Kernel context.
3041 */
3042int
3043qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
3044{
3045 int rval;
3046 int map, pos;
3047 struct vp_ctrl_entry_24xx *vce;
3048 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003049 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003050 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003051 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003052
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003053 ql_dbg(ql_dbg_mbx, vha, 0x10c1,
3054 "Entered %s enabling index %d.\n", __func__, vp_index);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003055
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08003056 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003057 return QLA_PARAMETER_ERROR;
3058
3059 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3060 if (!vce) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003061 ql_log(ql_log_warn, vha, 0x10c2,
3062 "Failed to allocate VP control IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003063 return QLA_MEMORY_ALLOC_FAILED;
3064 }
3065 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3066
3067 vce->entry_type = VP_CTRL_IOCB_TYPE;
3068 vce->entry_count = 1;
3069 vce->command = cpu_to_le16(cmd);
3070 vce->vp_count = __constant_cpu_to_le16(1);
3071
3072 /* index map in firmware starts with 1; decrement index
3073 * this is ok as we never use index 0
3074 */
3075 map = (vp_index - 1) / 8;
3076 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003077 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003078 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003079 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003080
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003081 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003082 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003083 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3084 "Failed to issue VP control IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003085 } else if (vce->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003086 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3087 "Failed to complete IOCB -- error status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003088 vce->entry_status);
3089 rval = QLA_FUNCTION_FAILED;
3090 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003091 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3092 "Failed to complet IOCB -- completion status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003093 le16_to_cpu(vce->comp_status));
3094 rval = QLA_FUNCTION_FAILED;
3095 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003096 ql_dbg(ql_dbg_mbx, vha, 0x10c6, "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003097 }
3098
3099 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3100
3101 return rval;
3102}
3103
3104/*
3105 * qla2x00_send_change_request
3106 * Receive or disable RSCN request from fabric controller
3107 *
3108 * Input:
3109 * ha = adapter block pointer
3110 * format = registration format:
3111 * 0 - Reserved
3112 * 1 - Fabric detected registration
3113 * 2 - N_port detected registration
3114 * 3 - Full registration
3115 * FF - clear registration
3116 * vp_idx = Virtual port index
3117 *
3118 * Returns:
3119 * qla2x00 local function return status code.
3120 *
3121 * Context:
3122 * Kernel Context
3123 */
3124
3125int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003126qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003127 uint16_t vp_idx)
3128{
3129 int rval;
3130 mbx_cmd_t mc;
3131 mbx_cmd_t *mcp = &mc;
3132
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003133 ql_dbg(ql_dbg_mbx, vha, 0x10c7, "Entered %s.\n", __func__);
3134
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003135 /*
3136 * This command is implicitly executed by firmware during login for the
3137 * physical hosts
3138 */
3139 if (vp_idx == 0)
3140 return QLA_FUNCTION_FAILED;
3141
3142 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3143 mcp->mb[1] = format;
3144 mcp->mb[9] = vp_idx;
3145 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3146 mcp->in_mb = MBX_0|MBX_1;
3147 mcp->tov = MBX_TOV_SECONDS;
3148 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003149 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003150
3151 if (rval == QLA_SUCCESS) {
3152 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3153 rval = BIT_1;
3154 }
3155 } else
3156 rval = BIT_1;
3157
3158 return rval;
3159}
Andrew Vasquez338c9162007-09-20 14:07:33 -07003160
3161int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003162qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07003163 uint32_t size)
3164{
3165 int rval;
3166 mbx_cmd_t mc;
3167 mbx_cmd_t *mcp = &mc;
3168
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003169 ql_dbg(ql_dbg_mbx, vha, 0x1009, "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003170
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003171 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003172 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3173 mcp->mb[8] = MSW(addr);
3174 mcp->out_mb = MBX_8|MBX_0;
3175 } else {
3176 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3177 mcp->out_mb = MBX_0;
3178 }
3179 mcp->mb[1] = LSW(addr);
3180 mcp->mb[2] = MSW(req_dma);
3181 mcp->mb[3] = LSW(req_dma);
3182 mcp->mb[6] = MSW(MSD(req_dma));
3183 mcp->mb[7] = LSW(MSD(req_dma));
3184 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003185 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003186 mcp->mb[4] = MSW(size);
3187 mcp->mb[5] = LSW(size);
3188 mcp->out_mb |= MBX_5|MBX_4;
3189 } else {
3190 mcp->mb[4] = LSW(size);
3191 mcp->out_mb |= MBX_4;
3192 }
3193
3194 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003195 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07003196 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003197 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003198
3199 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003200 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3201 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003202 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003203 ql_dbg(ql_dbg_mbx, vha, 0x1007, "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003204 }
3205
3206 return rval;
3207}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003208
3209/* 84XX Support **************************************************************/
3210
3211struct cs84xx_mgmt_cmd {
3212 union {
3213 struct verify_chip_entry_84xx req;
3214 struct verify_chip_rsp_84xx rsp;
3215 } p;
3216};
3217
3218int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003219qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003220{
3221 int rval, retry;
3222 struct cs84xx_mgmt_cmd *mn;
3223 dma_addr_t mn_dma;
3224 uint16_t options;
3225 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003226 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003227
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003228 ql_dbg(ql_dbg_mbx, vha, 0x10c8, "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003229
3230 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3231 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003232 return QLA_MEMORY_ALLOC_FAILED;
3233 }
3234
3235 /* Force Update? */
3236 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3237 /* Diagnostic firmware? */
3238 /* options |= MENLO_DIAG_FW; */
3239 /* We update the firmware with only one data sequence. */
3240 options |= VCO_END_OF_DATA;
3241
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003242 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003243 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003244 memset(mn, 0, sizeof(*mn));
3245 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3246 mn->p.req.entry_count = 1;
3247 mn->p.req.options = cpu_to_le16(options);
3248
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003249 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3250 "Dump of Verify Request.\n");
3251 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3252 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003253
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003254 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003255 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003256 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3257 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003258 goto verify_done;
3259 }
3260
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003261 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3262 "Dump of Verify Response.\n");
3263 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3264 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003265
3266 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3267 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3268 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003269 ql_dbg(ql_dbg_mbx, vha, 0x10ce,
3270 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003271
3272 if (status[0] != CS_COMPLETE) {
3273 rval = QLA_FUNCTION_FAILED;
3274 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003275 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3276 "Firmware update failed. Retrying "
3277 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003278 options |= VCO_DONT_UPDATE_FW;
3279 options &= ~VCO_FORCE_UPDATE;
3280 retry = 1;
3281 }
3282 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003283 ql_dbg(ql_dbg_mbx, vha, 0x10d0,
3284 "Firmware updated to %x.\n",
3285 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003286
3287 /* NOTE: we only update OP firmware. */
3288 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3289 ha->cs84xx->op_fw_version =
3290 le32_to_cpu(mn->p.rsp.fw_ver);
3291 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3292 flags);
3293 }
3294 } while (retry);
3295
3296verify_done:
3297 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3298
3299 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003300 ql_dbg(ql_dbg_mbx, vha, 0x10d1, "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003301 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003302 ql_dbg(ql_dbg_mbx, vha, 0x10d2, "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003303 }
3304
3305 return rval;
3306}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003307
3308int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003309qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003310{
3311 int rval;
3312 unsigned long flags;
3313 mbx_cmd_t mc;
3314 mbx_cmd_t *mcp = &mc;
3315 struct device_reg_25xxmq __iomem *reg;
3316 struct qla_hw_data *ha = vha->hw;
3317
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003318 ql_dbg(ql_dbg_mbx, vha, 0x10d3, "Entered %s.\n", __func__);
3319
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003320 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003321 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003322 mcp->mb[2] = MSW(LSD(req->dma));
3323 mcp->mb[3] = LSW(LSD(req->dma));
3324 mcp->mb[6] = MSW(MSD(req->dma));
3325 mcp->mb[7] = LSW(MSD(req->dma));
3326 mcp->mb[5] = req->length;
3327 if (req->rsp)
3328 mcp->mb[10] = req->rsp->id;
3329 mcp->mb[12] = req->qos;
3330 mcp->mb[11] = req->vp_idx;
3331 mcp->mb[13] = req->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003332 if (IS_QLA83XX(ha))
3333 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003334
3335 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3336 QLA_QUE_PAGE * req->id);
3337
3338 mcp->mb[4] = req->id;
3339 /* que in ptr index */
3340 mcp->mb[8] = 0;
3341 /* que out ptr index */
3342 mcp->mb[9] = 0;
3343 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3344 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3345 mcp->in_mb = MBX_0;
3346 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003347 mcp->tov = MBX_TOV_SECONDS * 2;
3348
3349 if (IS_QLA81XX(ha) || IS_QLA83XX(ha))
3350 mcp->in_mb |= MBX_1;
3351 if (IS_QLA83XX(ha)) {
3352 mcp->out_mb |= MBX_15;
3353 /* debug q create issue in SR-IOV */
3354 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3355 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003356
3357 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003358 if (!(req->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003359 WRT_REG_DWORD(&reg->req_q_in, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003360 if (!IS_QLA83XX(ha))
3361 WRT_REG_DWORD(&reg->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003362 }
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003363 req->req_q_in = &reg->req_q_in;
3364 req->req_q_out = &reg->req_q_out;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003365 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3366
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003367 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003368 if (rval != QLA_SUCCESS) {
3369 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3370 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3371 } else {
3372 ql_dbg(ql_dbg_mbx, vha, 0x10d5, "Done %s.\n", __func__);
3373 }
3374
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003375 return rval;
3376}
3377
3378int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003379qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003380{
3381 int rval;
3382 unsigned long flags;
3383 mbx_cmd_t mc;
3384 mbx_cmd_t *mcp = &mc;
3385 struct device_reg_25xxmq __iomem *reg;
3386 struct qla_hw_data *ha = vha->hw;
3387
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003388 ql_dbg(ql_dbg_mbx, vha, 0x10d6, "Entered %s.\n", __func__);
3389
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003390 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003391 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003392 mcp->mb[2] = MSW(LSD(rsp->dma));
3393 mcp->mb[3] = LSW(LSD(rsp->dma));
3394 mcp->mb[6] = MSW(MSD(rsp->dma));
3395 mcp->mb[7] = LSW(MSD(rsp->dma));
3396 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003397 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003398 mcp->mb[13] = rsp->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003399 if (IS_QLA83XX(ha))
3400 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003401
3402 reg = (struct device_reg_25xxmq *)((void *)(ha->mqiobase) +
3403 QLA_QUE_PAGE * rsp->id);
3404
3405 mcp->mb[4] = rsp->id;
3406 /* que in ptr index */
3407 mcp->mb[8] = 0;
3408 /* que out ptr index */
3409 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003410 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003411 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3412 mcp->in_mb = MBX_0;
3413 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003414 mcp->tov = MBX_TOV_SECONDS * 2;
3415
3416 if (IS_QLA81XX(ha)) {
3417 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
3418 mcp->in_mb |= MBX_1;
3419 } else if (IS_QLA83XX(ha)) {
3420 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
3421 mcp->in_mb |= MBX_1;
3422 /* debug q create issue in SR-IOV */
3423 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3424 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003425
3426 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003427 if (!(rsp->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003428 WRT_REG_DWORD(&reg->rsp_q_out, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003429 if (!IS_QLA83XX(ha))
3430 WRT_REG_DWORD(&reg->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003431 }
3432
3433 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3434
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003435 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003436 if (rval != QLA_SUCCESS) {
3437 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
3438 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3439 } else {
3440 ql_dbg(ql_dbg_mbx, vha, 0x10d8, "Done %s.\n", __func__);
3441 }
3442
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003443 return rval;
3444}
3445
Andrew Vasquez8a659572009-02-08 20:50:12 -08003446int
3447qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3448{
3449 int rval;
3450 mbx_cmd_t mc;
3451 mbx_cmd_t *mcp = &mc;
3452
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003453 ql_dbg(ql_dbg_mbx, vha, 0x10d9, "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003454
3455 mcp->mb[0] = MBC_IDC_ACK;
3456 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3457 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3458 mcp->in_mb = MBX_0;
3459 mcp->tov = MBX_TOV_SECONDS;
3460 mcp->flags = 0;
3461 rval = qla2x00_mailbox_command(vha, mcp);
3462
3463 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003464 ql_dbg(ql_dbg_mbx, vha, 0x10da,
3465 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003466 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003467 ql_dbg(ql_dbg_mbx, vha, 0x10db, "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003468 }
3469
3470 return rval;
3471}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003472
3473int
3474qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3475{
3476 int rval;
3477 mbx_cmd_t mc;
3478 mbx_cmd_t *mcp = &mc;
3479
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003480 ql_dbg(ql_dbg_mbx, vha, 0x10dc, "Entered %s.\n", __func__);
3481
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003482 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003483 return QLA_FUNCTION_FAILED;
3484
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003485 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3486 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3487 mcp->out_mb = MBX_1|MBX_0;
3488 mcp->in_mb = MBX_1|MBX_0;
3489 mcp->tov = MBX_TOV_SECONDS;
3490 mcp->flags = 0;
3491 rval = qla2x00_mailbox_command(vha, mcp);
3492
3493 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003494 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
3495 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3496 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003497 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003498 ql_dbg(ql_dbg_mbx, vha, 0x10de, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003499 *sector_size = mcp->mb[1];
3500 }
3501
3502 return rval;
3503}
3504
3505int
3506qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3507{
3508 int rval;
3509 mbx_cmd_t mc;
3510 mbx_cmd_t *mcp = &mc;
3511
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003512 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003513 return QLA_FUNCTION_FAILED;
3514
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003515 ql_dbg(ql_dbg_mbx, vha, 0x10df, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003516
3517 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3518 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3519 FAC_OPT_CMD_WRITE_PROTECT;
3520 mcp->out_mb = MBX_1|MBX_0;
3521 mcp->in_mb = MBX_1|MBX_0;
3522 mcp->tov = MBX_TOV_SECONDS;
3523 mcp->flags = 0;
3524 rval = qla2x00_mailbox_command(vha, mcp);
3525
3526 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003527 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
3528 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3529 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003530 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003531 ql_dbg(ql_dbg_mbx, vha, 0x10e1, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003532 }
3533
3534 return rval;
3535}
3536
3537int
3538qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3539{
3540 int rval;
3541 mbx_cmd_t mc;
3542 mbx_cmd_t *mcp = &mc;
3543
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003544 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003545 return QLA_FUNCTION_FAILED;
3546
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003547 ql_dbg(ql_dbg_mbx, vha, 0x10e2, "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003548
3549 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3550 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3551 mcp->mb[2] = LSW(start);
3552 mcp->mb[3] = MSW(start);
3553 mcp->mb[4] = LSW(finish);
3554 mcp->mb[5] = MSW(finish);
3555 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3556 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3557 mcp->tov = MBX_TOV_SECONDS;
3558 mcp->flags = 0;
3559 rval = qla2x00_mailbox_command(vha, mcp);
3560
3561 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003562 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
3563 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3564 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003565 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003566 ql_dbg(ql_dbg_mbx, vha, 0x10e4, "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003567 }
3568
3569 return rval;
3570}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003571
3572int
3573qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3574{
3575 int rval = 0;
3576 mbx_cmd_t mc;
3577 mbx_cmd_t *mcp = &mc;
3578
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003579 ql_dbg(ql_dbg_mbx, vha, 0x10e5, "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003580
3581 mcp->mb[0] = MBC_RESTART_MPI_FW;
3582 mcp->out_mb = MBX_0;
3583 mcp->in_mb = MBX_0|MBX_1;
3584 mcp->tov = MBX_TOV_SECONDS;
3585 mcp->flags = 0;
3586 rval = qla2x00_mailbox_command(vha, mcp);
3587
3588 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003589 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
3590 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3591 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003592 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003593 ql_dbg(ql_dbg_mbx, vha, 0x10e7, "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003594 }
3595
3596 return rval;
3597}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003598
3599int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003600qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3601 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003602{
3603 int rval;
3604 mbx_cmd_t mc;
3605 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003606 struct qla_hw_data *ha = vha->hw;
3607
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003608 ql_dbg(ql_dbg_mbx, vha, 0x10e8, "Entered %s.\n", __func__);
3609
Joe Carnuccio6766df92011-05-10 11:30:15 -07003610 if (!IS_FWI2_CAPABLE(ha))
3611 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003612
Joe Carnuccio6766df92011-05-10 11:30:15 -07003613 if (len == 1)
3614 opt |= BIT_0;
3615
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003616 mcp->mb[0] = MBC_READ_SFP;
3617 mcp->mb[1] = dev;
3618 mcp->mb[2] = MSW(sfp_dma);
3619 mcp->mb[3] = LSW(sfp_dma);
3620 mcp->mb[6] = MSW(MSD(sfp_dma));
3621 mcp->mb[7] = LSW(MSD(sfp_dma));
3622 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003623 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003624 mcp->mb[10] = opt;
3625 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 -07003626 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003627 mcp->tov = MBX_TOV_SECONDS;
3628 mcp->flags = 0;
3629 rval = qla2x00_mailbox_command(vha, mcp);
3630
3631 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003632 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003633
3634 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003635 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
3636 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003637 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003638 ql_dbg(ql_dbg_mbx, vha, 0x10ea, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003639 }
3640
3641 return rval;
3642}
3643
3644int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003645qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3646 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003647{
3648 int rval;
3649 mbx_cmd_t mc;
3650 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003651 struct qla_hw_data *ha = vha->hw;
3652
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003653 ql_dbg(ql_dbg_mbx, vha, 0x10eb, "Entered %s.\n", __func__);
3654
Joe Carnuccio6766df92011-05-10 11:30:15 -07003655 if (!IS_FWI2_CAPABLE(ha))
3656 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003657
Joe Carnuccio6766df92011-05-10 11:30:15 -07003658 if (len == 1)
3659 opt |= BIT_0;
3660
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003661 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003662 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003663
3664 mcp->mb[0] = MBC_WRITE_SFP;
3665 mcp->mb[1] = dev;
3666 mcp->mb[2] = MSW(sfp_dma);
3667 mcp->mb[3] = LSW(sfp_dma);
3668 mcp->mb[6] = MSW(MSD(sfp_dma));
3669 mcp->mb[7] = LSW(MSD(sfp_dma));
3670 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003671 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003672 mcp->mb[10] = opt;
3673 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 -07003674 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003675 mcp->tov = MBX_TOV_SECONDS;
3676 mcp->flags = 0;
3677 rval = qla2x00_mailbox_command(vha, mcp);
3678
3679 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003680 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
3681 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003682 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003683 ql_dbg(ql_dbg_mbx, vha, 0x10ed, "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003684 }
3685
3686 return rval;
3687}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003688
3689int
3690qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
3691 uint16_t size_in_bytes, uint16_t *actual_size)
3692{
3693 int rval;
3694 mbx_cmd_t mc;
3695 mbx_cmd_t *mcp = &mc;
3696
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003697 ql_dbg(ql_dbg_mbx, vha, 0x10ee, "Entered %s.\n", __func__);
3698
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003699 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003700 return QLA_FUNCTION_FAILED;
3701
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003702 mcp->mb[0] = MBC_GET_XGMAC_STATS;
3703 mcp->mb[2] = MSW(stats_dma);
3704 mcp->mb[3] = LSW(stats_dma);
3705 mcp->mb[6] = MSW(MSD(stats_dma));
3706 mcp->mb[7] = LSW(MSD(stats_dma));
3707 mcp->mb[8] = size_in_bytes >> 2;
3708 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
3709 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3710 mcp->tov = MBX_TOV_SECONDS;
3711 mcp->flags = 0;
3712 rval = qla2x00_mailbox_command(vha, mcp);
3713
3714 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003715 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
3716 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3717 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003718 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003719 ql_dbg(ql_dbg_mbx, vha, 0x10f0, "Done %s.\n", __func__);
3720
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003721
3722 *actual_size = mcp->mb[2] << 2;
3723 }
3724
3725 return rval;
3726}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003727
3728int
3729qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
3730 uint16_t size)
3731{
3732 int rval;
3733 mbx_cmd_t mc;
3734 mbx_cmd_t *mcp = &mc;
3735
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003736 ql_dbg(ql_dbg_mbx, vha, 0x10f1, "Entered %s.\n", __func__);
3737
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003738 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003739 return QLA_FUNCTION_FAILED;
3740
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003741 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
3742 mcp->mb[1] = 0;
3743 mcp->mb[2] = MSW(tlv_dma);
3744 mcp->mb[3] = LSW(tlv_dma);
3745 mcp->mb[6] = MSW(MSD(tlv_dma));
3746 mcp->mb[7] = LSW(MSD(tlv_dma));
3747 mcp->mb[8] = size;
3748 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
3749 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3750 mcp->tov = MBX_TOV_SECONDS;
3751 mcp->flags = 0;
3752 rval = qla2x00_mailbox_command(vha, mcp);
3753
3754 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003755 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
3756 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3757 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003758 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003759 ql_dbg(ql_dbg_mbx, vha, 0x10f3, "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07003760 }
3761
3762 return rval;
3763}
Andrew Vasquez18e75552009-06-03 09:55:30 -07003764
3765int
3766qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
3767{
3768 int rval;
3769 mbx_cmd_t mc;
3770 mbx_cmd_t *mcp = &mc;
3771
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003772 ql_dbg(ql_dbg_mbx, vha, 0x10f4, "Entered %s.\n", __func__);
3773
Andrew Vasquez18e75552009-06-03 09:55:30 -07003774 if (!IS_FWI2_CAPABLE(vha->hw))
3775 return QLA_FUNCTION_FAILED;
3776
Andrew Vasquez18e75552009-06-03 09:55:30 -07003777 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
3778 mcp->mb[1] = LSW(risc_addr);
3779 mcp->mb[8] = MSW(risc_addr);
3780 mcp->out_mb = MBX_8|MBX_1|MBX_0;
3781 mcp->in_mb = MBX_3|MBX_2|MBX_0;
3782 mcp->tov = 30;
3783 mcp->flags = 0;
3784 rval = qla2x00_mailbox_command(vha, mcp);
3785 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003786 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
3787 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003788 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003789 ql_dbg(ql_dbg_mbx, vha, 0x10f6, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003790 *data = mcp->mb[3] << 16 | mcp->mb[2];
3791 }
3792
3793 return rval;
3794}
3795
3796int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003797qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3798 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003799{
3800 int rval;
3801 mbx_cmd_t mc;
3802 mbx_cmd_t *mcp = &mc;
3803 uint32_t iter_cnt = 0x1;
3804
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003805 ql_dbg(ql_dbg_mbx, vha, 0x10f7, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003806
3807 memset(mcp->mb, 0 , sizeof(mcp->mb));
3808 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
3809 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
3810
3811 /* transfer count */
3812 mcp->mb[10] = LSW(mreq->transfer_size);
3813 mcp->mb[11] = MSW(mreq->transfer_size);
3814
3815 /* send data address */
3816 mcp->mb[14] = LSW(mreq->send_dma);
3817 mcp->mb[15] = MSW(mreq->send_dma);
3818 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3819 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3820
Lucas De Marchi25985ed2011-03-30 22:57:33 -03003821 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003822 mcp->mb[16] = LSW(mreq->rcv_dma);
3823 mcp->mb[17] = MSW(mreq->rcv_dma);
3824 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3825 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3826
3827 /* Iteration count */
3828 mcp->mb[18] = LSW(iter_cnt);
3829 mcp->mb[19] = MSW(iter_cnt);
3830
3831 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
3832 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 -08003833 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003834 mcp->out_mb |= MBX_2;
3835 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
3836
3837 mcp->buf_size = mreq->transfer_size;
3838 mcp->tov = MBX_TOV_SECONDS;
3839 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3840
3841 rval = qla2x00_mailbox_command(vha, mcp);
3842
3843 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003844 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
3845 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
3846 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
3847 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003848 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003849 ql_dbg(ql_dbg_mbx, vha, 0x10f9, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003850 }
3851
3852 /* Copy mailbox information */
3853 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003854 return rval;
3855}
3856
3857int
Giridhar Malavalia9083012010-04-12 17:59:55 -07003858qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
3859 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003860{
3861 int rval;
3862 mbx_cmd_t mc;
3863 mbx_cmd_t *mcp = &mc;
3864 struct qla_hw_data *ha = vha->hw;
3865
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003866 ql_dbg(ql_dbg_mbx, vha, 0x10fa, "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003867
3868 memset(mcp->mb, 0 , sizeof(mcp->mb));
3869 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
3870 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003871 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003872 mcp->mb[1] |= BIT_15;
Giridhar Malavalia9083012010-04-12 17:59:55 -07003873 mcp->mb[2] = vha->fcoe_fcf_idx;
3874 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003875 mcp->mb[16] = LSW(mreq->rcv_dma);
3876 mcp->mb[17] = MSW(mreq->rcv_dma);
3877 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
3878 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
3879
3880 mcp->mb[10] = LSW(mreq->transfer_size);
3881
3882 mcp->mb[14] = LSW(mreq->send_dma);
3883 mcp->mb[15] = MSW(mreq->send_dma);
3884 mcp->mb[20] = LSW(MSD(mreq->send_dma));
3885 mcp->mb[21] = MSW(MSD(mreq->send_dma));
3886
3887 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
3888 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003889 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003890 mcp->out_mb |= MBX_2;
3891
3892 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003893 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
3894 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003895 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003896 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003897 mcp->in_mb |= MBX_3;
3898
3899 mcp->tov = MBX_TOV_SECONDS;
3900 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
3901 mcp->buf_size = mreq->transfer_size;
3902
3903 rval = qla2x00_mailbox_command(vha, mcp);
3904
3905 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003906 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
3907 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3908 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003909 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003910 ql_dbg(ql_dbg_mbx, vha, 0x10fc, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003911 }
3912
3913 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003914 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003915 return rval;
3916}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07003917
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003918int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003919qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003920{
3921 int rval;
3922 mbx_cmd_t mc;
3923 mbx_cmd_t *mcp = &mc;
3924
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003925 ql_dbg(ql_dbg_mbx, vha, 0x10fd,
3926 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003927
3928 mcp->mb[0] = MBC_ISP84XX_RESET;
3929 mcp->mb[1] = enable_diagnostic;
3930 mcp->out_mb = MBX_1|MBX_0;
3931 mcp->in_mb = MBX_1|MBX_0;
3932 mcp->tov = MBX_TOV_SECONDS;
3933 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003934 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003935
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003936 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003937 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003938 else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003939 ql_dbg(ql_dbg_mbx, vha, 0x10ff, "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08003940
3941 return rval;
3942}
3943
3944int
Andrew Vasquez18e75552009-06-03 09:55:30 -07003945qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
3946{
3947 int rval;
3948 mbx_cmd_t mc;
3949 mbx_cmd_t *mcp = &mc;
3950
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003951 ql_dbg(ql_dbg_mbx, vha, 0x1100, "Entered %s.\n", __func__);
3952
Andrew Vasquez18e75552009-06-03 09:55:30 -07003953 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07003954 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07003955
Andrew Vasquez18e75552009-06-03 09:55:30 -07003956 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
3957 mcp->mb[1] = LSW(risc_addr);
3958 mcp->mb[2] = LSW(data);
3959 mcp->mb[3] = MSW(data);
3960 mcp->mb[8] = MSW(risc_addr);
3961 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
3962 mcp->in_mb = MBX_0;
3963 mcp->tov = 30;
3964 mcp->flags = 0;
3965 rval = qla2x00_mailbox_command(vha, mcp);
3966 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003967 ql_dbg(ql_dbg_mbx, vha, 0x1101,
3968 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003969 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003970 ql_dbg(ql_dbg_mbx, vha, 0x1102, "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07003971 }
3972
3973 return rval;
3974}
Michael Hernandez3064ff32009-12-15 21:29:44 -08003975
3976int
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003977qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
3978{
3979 int rval;
3980 uint32_t stat, timer;
3981 uint16_t mb0 = 0;
3982 struct qla_hw_data *ha = vha->hw;
3983 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
3984
3985 rval = QLA_SUCCESS;
3986
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003987 ql_dbg(ql_dbg_mbx, vha, 0x1103, "Entered %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07003988
3989 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
3990
3991 /* Write the MBC data to the registers */
3992 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
3993 WRT_REG_WORD(&reg->mailbox1, mb[0]);
3994 WRT_REG_WORD(&reg->mailbox2, mb[1]);
3995 WRT_REG_WORD(&reg->mailbox3, mb[2]);
3996 WRT_REG_WORD(&reg->mailbox4, mb[3]);
3997
3998 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
3999
4000 /* Poll for MBC interrupt */
4001 for (timer = 6000000; timer; timer--) {
4002 /* Check for pending interrupts. */
4003 stat = RD_REG_DWORD(&reg->host_status);
4004 if (stat & HSRX_RISC_INT) {
4005 stat &= 0xff;
4006
4007 if (stat == 0x1 || stat == 0x2 ||
4008 stat == 0x10 || stat == 0x11) {
4009 set_bit(MBX_INTERRUPT,
4010 &ha->mbx_cmd_flags);
4011 mb0 = RD_REG_WORD(&reg->mailbox0);
4012 WRT_REG_DWORD(&reg->hccr,
4013 HCCRX_CLR_RISC_INT);
4014 RD_REG_DWORD(&reg->hccr);
4015 break;
4016 }
4017 }
4018 udelay(5);
4019 }
4020
4021 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
4022 rval = mb0 & MBS_MASK;
4023 else
4024 rval = QLA_FUNCTION_FAILED;
4025
4026 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004027 ql_dbg(ql_dbg_mbx, vha, 0x1104,
4028 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004029 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004030 ql_dbg(ql_dbg_mbx, vha, 0x1105, "Done %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004031 }
4032
4033 return rval;
4034}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004035
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004036int
Michael Hernandez3064ff32009-12-15 21:29:44 -08004037qla2x00_get_data_rate(scsi_qla_host_t *vha)
4038{
4039 int rval;
4040 mbx_cmd_t mc;
4041 mbx_cmd_t *mcp = &mc;
4042 struct qla_hw_data *ha = vha->hw;
4043
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004044 ql_dbg(ql_dbg_mbx, vha, 0x1106, "Entered %s.\n", __func__);
4045
Michael Hernandez3064ff32009-12-15 21:29:44 -08004046 if (!IS_FWI2_CAPABLE(ha))
4047 return QLA_FUNCTION_FAILED;
4048
Michael Hernandez3064ff32009-12-15 21:29:44 -08004049 mcp->mb[0] = MBC_DATA_RATE;
4050 mcp->mb[1] = 0;
4051 mcp->out_mb = MBX_1|MBX_0;
4052 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004053 if (IS_QLA83XX(ha))
4054 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08004055 mcp->tov = MBX_TOV_SECONDS;
4056 mcp->flags = 0;
4057 rval = qla2x00_mailbox_command(vha, mcp);
4058 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004059 ql_dbg(ql_dbg_mbx, vha, 0x1107,
4060 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004061 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004062 ql_dbg(ql_dbg_mbx, vha, 0x1108, "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004063 if (mcp->mb[1] != 0x7)
4064 ha->link_data_rate = mcp->mb[1];
4065 }
4066
4067 return rval;
4068}
Sarang Radke09ff7012010-03-19 17:03:59 -07004069
4070int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004071qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4072{
4073 int rval;
4074 mbx_cmd_t mc;
4075 mbx_cmd_t *mcp = &mc;
4076 struct qla_hw_data *ha = vha->hw;
4077
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004078 ql_dbg(ql_dbg_mbx, vha, 0x1109, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004079
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004080 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004081 return QLA_FUNCTION_FAILED;
4082 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4083 mcp->out_mb = MBX_0;
4084 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4085 mcp->tov = MBX_TOV_SECONDS;
4086 mcp->flags = 0;
4087
4088 rval = qla2x00_mailbox_command(vha, mcp);
4089
4090 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004091 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4092 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004093 } else {
4094 /* Copy all bits to preserve original value */
4095 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4096
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004097 ql_dbg(ql_dbg_mbx, vha, 0x110b, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004098 }
4099 return rval;
4100}
4101
4102int
4103qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4104{
4105 int rval;
4106 mbx_cmd_t mc;
4107 mbx_cmd_t *mcp = &mc;
4108
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004109 ql_dbg(ql_dbg_mbx, vha, 0x110c, "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004110
4111 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4112 /* Copy all bits to preserve original setting */
4113 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4114 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4115 mcp->in_mb = MBX_0;
4116 mcp->tov = MBX_TOV_SECONDS;
4117 mcp->flags = 0;
4118 rval = qla2x00_mailbox_command(vha, mcp);
4119
4120 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004121 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4122 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004123 } else
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004124 ql_dbg(ql_dbg_mbx, vha, 0x110e, "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004125
4126 return rval;
4127}
4128
4129
4130int
Sarang Radke09ff7012010-03-19 17:03:59 -07004131qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4132 uint16_t *mb)
4133{
4134 int rval;
4135 mbx_cmd_t mc;
4136 mbx_cmd_t *mcp = &mc;
4137 struct qla_hw_data *ha = vha->hw;
4138
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004139 ql_dbg(ql_dbg_mbx, vha, 0x110f, "Entered %s.\n", __func__);
4140
Sarang Radke09ff7012010-03-19 17:03:59 -07004141 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4142 return QLA_FUNCTION_FAILED;
4143
Sarang Radke09ff7012010-03-19 17:03:59 -07004144 mcp->mb[0] = MBC_PORT_PARAMS;
4145 mcp->mb[1] = loop_id;
4146 if (ha->flags.fcp_prio_enabled)
4147 mcp->mb[2] = BIT_1;
4148 else
4149 mcp->mb[2] = BIT_2;
4150 mcp->mb[4] = priority & 0xf;
4151 mcp->mb[9] = vha->vp_idx;
4152 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4153 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4154 mcp->tov = 30;
4155 mcp->flags = 0;
4156 rval = qla2x00_mailbox_command(vha, mcp);
4157 if (mb != NULL) {
4158 mb[0] = mcp->mb[0];
4159 mb[1] = mcp->mb[1];
4160 mb[3] = mcp->mb[3];
4161 mb[4] = mcp->mb[4];
4162 }
4163
4164 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004165 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07004166 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004167 ql_dbg(ql_dbg_mbx, vha, 0x10cc, "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07004168 }
4169
4170 return rval;
4171}
Giridhar Malavalia9083012010-04-12 17:59:55 -07004172
4173int
Andrew Vasquez794a5692010-12-21 16:00:21 -08004174qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac)
4175{
4176 int rval;
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004177 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004178 struct qla_hw_data *ha = vha->hw;
4179
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004180 ql_dbg(ql_dbg_mbx, vha, 0x10ca, "Entered %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004181
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004182 /* Integer part */
4183 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 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, 0x10c9, "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 *temp = byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004190
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004191 /* Fraction part */
4192 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x10, 1, BIT_13|BIT_0);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004193 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004194 ql_dbg(ql_dbg_mbx, vha, 0x1019, "Failed=%x.\n", rval);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004195 ha->flags.thermal_supported = 0;
4196 goto fail;
4197 }
Joe Carnuccio6ad11ea2011-05-10 11:30:16 -07004198 *frac = (byte >> 6) * 25;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004199
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004200 ql_dbg(ql_dbg_mbx, vha, 0x1018, "Done %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004201fail:
4202 return rval;
4203}
4204
4205int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004206qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
4207{
4208 int rval;
4209 struct qla_hw_data *ha = vha->hw;
4210 mbx_cmd_t mc;
4211 mbx_cmd_t *mcp = &mc;
4212
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004213 ql_dbg(ql_dbg_mbx, vha, 0x1017, "Entered %s.\n", __func__);
4214
Giridhar Malavalia9083012010-04-12 17:59:55 -07004215 if (!IS_FWI2_CAPABLE(ha))
4216 return QLA_FUNCTION_FAILED;
4217
Giridhar Malavalia9083012010-04-12 17:59:55 -07004218 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004219 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004220 mcp->mb[1] = 1;
4221
4222 mcp->out_mb = MBX_1|MBX_0;
4223 mcp->in_mb = MBX_0;
4224 mcp->tov = 30;
4225 mcp->flags = 0;
4226
4227 rval = qla2x00_mailbox_command(vha, mcp);
4228 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004229 ql_dbg(ql_dbg_mbx, vha, 0x1016,
4230 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004231 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004232 ql_dbg(ql_dbg_mbx, vha, 0x100e, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004233 }
4234
4235 return rval;
4236}
4237
4238int
4239qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4240{
4241 int rval;
4242 struct qla_hw_data *ha = vha->hw;
4243 mbx_cmd_t mc;
4244 mbx_cmd_t *mcp = &mc;
4245
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004246 ql_dbg(ql_dbg_mbx, vha, 0x100d, "Entered %s.\n", __func__);
4247
Giridhar Malavalia9083012010-04-12 17:59:55 -07004248 if (!IS_QLA82XX(ha))
4249 return QLA_FUNCTION_FAILED;
4250
Giridhar Malavalia9083012010-04-12 17:59:55 -07004251 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004252 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004253 mcp->mb[1] = 0;
4254
4255 mcp->out_mb = MBX_1|MBX_0;
4256 mcp->in_mb = MBX_0;
4257 mcp->tov = 30;
4258 mcp->flags = 0;
4259
4260 rval = qla2x00_mailbox_command(vha, mcp);
4261 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004262 ql_dbg(ql_dbg_mbx, vha, 0x100c,
4263 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004264 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004265 ql_dbg(ql_dbg_mbx, vha, 0x100b, "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004266 }
4267
4268 return rval;
4269}
Giridhar Malavali08de2842011-08-16 11:31:44 -07004270
4271int
4272qla82xx_md_get_template_size(scsi_qla_host_t *vha)
4273{
4274 struct qla_hw_data *ha = vha->hw;
4275 mbx_cmd_t mc;
4276 mbx_cmd_t *mcp = &mc;
4277 int rval = QLA_FUNCTION_FAILED;
4278
4279 ql_dbg(ql_dbg_mbx, vha, 0x111f, "Entered %s.\n", __func__);
4280
4281 memset(mcp->mb, 0 , sizeof(mcp->mb));
4282 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4283 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4284 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
4285 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
4286
4287 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4288 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
4289 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4290
4291 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4292 mcp->tov = MBX_TOV_SECONDS;
4293 rval = qla2x00_mailbox_command(vha, mcp);
4294
4295 /* Always copy back return mailbox values. */
4296 if (rval != QLA_SUCCESS) {
4297 ql_dbg(ql_dbg_mbx, vha, 0x1120,
4298 "mailbox command FAILED=0x%x, subcode=%x.\n",
4299 (mcp->mb[1] << 16) | mcp->mb[0],
4300 (mcp->mb[3] << 16) | mcp->mb[2]);
4301 } else {
4302 ql_dbg(ql_dbg_mbx, vha, 0x1121, "Done %s.\n", __func__);
4303 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
4304 if (!ha->md_template_size) {
4305 ql_dbg(ql_dbg_mbx, vha, 0x1122,
4306 "Null template size obtained.\n");
4307 rval = QLA_FUNCTION_FAILED;
4308 }
4309 }
4310 return rval;
4311}
4312
4313int
4314qla82xx_md_get_template(scsi_qla_host_t *vha)
4315{
4316 struct qla_hw_data *ha = vha->hw;
4317 mbx_cmd_t mc;
4318 mbx_cmd_t *mcp = &mc;
4319 int rval = QLA_FUNCTION_FAILED;
4320
4321 ql_dbg(ql_dbg_mbx, vha, 0x1123, "Entered %s.\n", __func__);
4322
4323 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4324 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4325 if (!ha->md_tmplt_hdr) {
4326 ql_log(ql_log_warn, vha, 0x1124,
4327 "Unable to allocate memory for Minidump template.\n");
4328 return rval;
4329 }
4330
4331 memset(mcp->mb, 0 , sizeof(mcp->mb));
4332 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4333 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4334 mcp->mb[2] = LSW(RQST_TMPLT);
4335 mcp->mb[3] = MSW(RQST_TMPLT);
4336 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
4337 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
4338 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
4339 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
4340 mcp->mb[8] = LSW(ha->md_template_size);
4341 mcp->mb[9] = MSW(ha->md_template_size);
4342
4343 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4344 mcp->tov = MBX_TOV_SECONDS;
4345 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4346 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4347 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4348 rval = qla2x00_mailbox_command(vha, mcp);
4349
4350 if (rval != QLA_SUCCESS) {
4351 ql_dbg(ql_dbg_mbx, vha, 0x1125,
4352 "mailbox command FAILED=0x%x, subcode=%x.\n",
4353 ((mcp->mb[1] << 16) | mcp->mb[0]),
4354 ((mcp->mb[3] << 16) | mcp->mb[2]));
4355 } else
4356 ql_dbg(ql_dbg_mbx, vha, 0x1126, "Done %s.\n", __func__);
4357 return rval;
4358}
Saurav Kashyap999916d2011-08-16 11:31:45 -07004359
4360int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004361qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4362{
4363 int rval;
4364 struct qla_hw_data *ha = vha->hw;
4365 mbx_cmd_t mc;
4366 mbx_cmd_t *mcp = &mc;
4367
4368 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4369 return QLA_FUNCTION_FAILED;
4370
4371 ql_dbg(ql_dbg_mbx, vha, 0x1133, "Entered %s.\n", __func__);
4372
4373 memset(mcp, 0, sizeof(mbx_cmd_t));
4374 mcp->mb[0] = MBC_SET_LED_CONFIG;
4375 mcp->mb[1] = led_cfg[0];
4376 mcp->mb[2] = led_cfg[1];
4377 if (IS_QLA8031(ha)) {
4378 mcp->mb[3] = led_cfg[2];
4379 mcp->mb[4] = led_cfg[3];
4380 mcp->mb[5] = led_cfg[4];
4381 mcp->mb[6] = led_cfg[5];
4382 }
4383
4384 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4385 if (IS_QLA8031(ha))
4386 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4387 mcp->in_mb = MBX_0;
4388 mcp->tov = 30;
4389 mcp->flags = 0;
4390
4391 rval = qla2x00_mailbox_command(vha, mcp);
4392 if (rval != QLA_SUCCESS) {
4393 ql_dbg(ql_dbg_mbx, vha, 0x1134,
4394 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4395 } else {
4396 ql_dbg(ql_dbg_mbx, vha, 0x1135, "Done %s.\n", __func__);
4397 }
4398
4399 return rval;
4400}
4401
4402int
4403qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4404{
4405 int rval;
4406 struct qla_hw_data *ha = vha->hw;
4407 mbx_cmd_t mc;
4408 mbx_cmd_t *mcp = &mc;
4409
4410 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4411 return QLA_FUNCTION_FAILED;
4412
4413 ql_dbg(ql_dbg_mbx, vha, 0x1136, "Entered %s.\n", __func__);
4414
4415 memset(mcp, 0, sizeof(mbx_cmd_t));
4416 mcp->mb[0] = MBC_GET_LED_CONFIG;
4417
4418 mcp->out_mb = MBX_0;
4419 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4420 if (IS_QLA8031(ha))
4421 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4422 mcp->tov = 30;
4423 mcp->flags = 0;
4424
4425 rval = qla2x00_mailbox_command(vha, mcp);
4426 if (rval != QLA_SUCCESS) {
4427 ql_dbg(ql_dbg_mbx, vha, 0x1137,
4428 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4429 } else {
4430 led_cfg[0] = mcp->mb[1];
4431 led_cfg[1] = mcp->mb[2];
4432 if (IS_QLA8031(ha)) {
4433 led_cfg[2] = mcp->mb[3];
4434 led_cfg[3] = mcp->mb[4];
4435 led_cfg[4] = mcp->mb[5];
4436 led_cfg[5] = mcp->mb[6];
4437 }
4438 ql_dbg(ql_dbg_mbx, vha, 0x1138, "Done %s.\n", __func__);
4439 }
4440
4441 return rval;
4442}
4443
4444int
Saurav Kashyap999916d2011-08-16 11:31:45 -07004445qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
4446{
4447 int rval;
4448 struct qla_hw_data *ha = vha->hw;
4449 mbx_cmd_t mc;
4450 mbx_cmd_t *mcp = &mc;
4451
4452 if (!IS_QLA82XX(ha))
4453 return QLA_FUNCTION_FAILED;
4454
4455 ql_dbg(ql_dbg_mbx, vha, 0x1127,
4456 "Entered %s.\n", __func__);
4457
4458 memset(mcp, 0, sizeof(mbx_cmd_t));
4459 mcp->mb[0] = MBC_SET_LED_CONFIG;
4460 if (enable)
4461 mcp->mb[7] = 0xE;
4462 else
4463 mcp->mb[7] = 0xD;
4464
4465 mcp->out_mb = MBX_7|MBX_0;
4466 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004467 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07004468 mcp->flags = 0;
4469
4470 rval = qla2x00_mailbox_command(vha, mcp);
4471 if (rval != QLA_SUCCESS) {
4472 ql_dbg(ql_dbg_mbx, vha, 0x1128,
4473 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4474 } else {
4475 ql_dbg(ql_dbg_mbx, vha, 0x1129,
4476 "Done %s.\n", __func__);
4477 }
4478
4479 return rval;
4480}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004481
4482int
4483qla83xx_write_remote_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
4484{
4485 int rval;
4486 struct qla_hw_data *ha = vha->hw;
4487 mbx_cmd_t mc;
4488 mbx_cmd_t *mcp = &mc;
4489
4490 if (!IS_QLA83XX(ha))
4491 return QLA_FUNCTION_FAILED;
4492
4493 ql_dbg(ql_dbg_mbx, vha, 0x1130, "Entered %s.\n", __func__);
4494
4495 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
4496 mcp->mb[1] = LSW(reg);
4497 mcp->mb[2] = MSW(reg);
4498 mcp->mb[3] = LSW(data);
4499 mcp->mb[4] = MSW(data);
4500 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4501
4502 mcp->in_mb = MBX_1|MBX_0;
4503 mcp->tov = MBX_TOV_SECONDS;
4504 mcp->flags = 0;
4505 rval = qla2x00_mailbox_command(vha, mcp);
4506
4507 if (rval != QLA_SUCCESS) {
4508 ql_dbg(ql_dbg_mbx, vha, 0x1131,
4509 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4510 } else {
4511 ql_dbg(ql_dbg_mbx, vha, 0x1132,
4512 "Done %s.\n", __func__);
4513 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004514
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004515 return rval;
4516}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004517
4518int
4519qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
4520{
4521 int rval;
4522 struct qla_hw_data *ha = vha->hw;
4523 mbx_cmd_t mc;
4524 mbx_cmd_t *mcp = &mc;
4525
4526 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
4527 ql_dbg(ql_dbg_mbx, vha, 0x113b,
4528 "Implicit LOGO Unsupported.\n");
4529 return QLA_FUNCTION_FAILED;
4530 }
4531
4532
4533 ql_dbg(ql_dbg_mbx, vha, 0x113c, "Done %s.\n", __func__);
4534
4535 /* Perform Implicit LOGO. */
4536 mcp->mb[0] = MBC_PORT_LOGOUT;
4537 mcp->mb[1] = fcport->loop_id;
4538 mcp->mb[10] = BIT_15;
4539 mcp->out_mb = MBX_10|MBX_1|MBX_0;
4540 mcp->in_mb = MBX_0;
4541 mcp->tov = MBX_TOV_SECONDS;
4542 mcp->flags = 0;
4543 rval = qla2x00_mailbox_command(vha, mcp);
4544 if (rval != QLA_SUCCESS)
4545 ql_dbg(ql_dbg_mbx, vha, 0x113d,
4546 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4547 else
4548 ql_dbg(ql_dbg_mbx, vha, 0x113e, "Done %s.\n", __func__);
4549
4550 return rval;
4551}
4552