blob: 2528709c4add35699fc08b81f8a8ca2a0b3c1505 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
Saurav Kashyap1e633952013-02-08 01:57:54 -05003 * Copyright (c) 2003-2013 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"
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04008#include "qla_target.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -07009
10#include <linux/delay.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090011#include <linux/gfp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070012
Linus Torvalds1da177e2005-04-16 15:20:36 -070013
14/*
15 * qla2x00_mailbox_command
16 * Issue mailbox command and waits for completion.
17 *
18 * Input:
19 * ha = adapter block pointer.
20 * mcp = driver internal mbx struct pointer.
21 *
22 * Output:
23 * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
24 *
25 * Returns:
26 * 0 : QLA_SUCCESS = cmd performed success
27 * 1 : QLA_FUNCTION_FAILED (error encountered)
28 * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
29 *
30 * Context:
31 * Kernel context.
32 */
33static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080034qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070035{
36 int rval;
37 unsigned long flags = 0;
Chad Dupuisf73cb692014-02-26 04:15:06 -050038 device_reg_t *reg;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070039 uint8_t abort_active;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070040 uint8_t io_lock_on;
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -070041 uint16_t command = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070042 uint16_t *iptr;
43 uint16_t __iomem *optr;
44 uint32_t cnt;
45 uint32_t mboxes;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046 unsigned long wait_time;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080047 struct qla_hw_data *ha = vha->hw;
48 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070049
Arun Easi5e19ed92012-02-09 11:15:51 -080050 ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -070051
52 if (ha->pdev->error_state > pci_channel_io_frozen) {
Arun Easi5e19ed92012-02-09 11:15:51 -080053 ql_log(ql_log_warn, vha, 0x1001,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070054 "error_state is greater than pci_channel_io_frozen, "
55 "exiting.\n");
Seokmann Jub9b12f72009-03-24 09:08:18 -070056 return QLA_FUNCTION_TIMEOUT;
Saurav Kashyap7c3df132011-07-14 12:00:13 -070057 }
Seokmann Jub9b12f72009-03-24 09:08:18 -070058
Giridhar Malavalia9083012010-04-12 17:59:55 -070059 if (vha->device_flags & DFLG_DEV_FAILED) {
Arun Easi5e19ed92012-02-09 11:15:51 -080060 ql_log(ql_log_warn, vha, 0x1002,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070061 "Device in failed state, exiting.\n");
Giridhar Malavalia9083012010-04-12 17:59:55 -070062 return QLA_FUNCTION_TIMEOUT;
63 }
64
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070065 reg = ha->iobase;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080066 io_lock_on = base_vha->flags.init_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -070067
68 rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080069 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070071
Andrew Vasquez85880802009-12-15 21:29:46 -080072 if (ha->flags.pci_channel_io_perm_failure) {
Arun Easi5e19ed92012-02-09 11:15:51 -080073 ql_log(ql_log_warn, vha, 0x1003,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070074 "Perm failure on EEH timeout MBX, exiting.\n");
Andrew Vasquez85880802009-12-15 21:29:46 -080075 return QLA_FUNCTION_TIMEOUT;
76 }
77
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -040078 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Giridhar Malavali862cd012011-02-23 15:27:11 -080079 /* Setting Link-Down error */
80 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
Arun Easi5e19ed92012-02-09 11:15:51 -080081 ql_log(ql_log_warn, vha, 0x1004,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070082 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Andrew Vasquez1806fcd2011-11-18 09:02:15 -080083 return QLA_FUNCTION_TIMEOUT;
Giridhar Malavali862cd012011-02-23 15:27:11 -080084 }
85
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070087 * Wait for active mailbox commands to finish by waiting at most tov
88 * seconds. This is to serialize actual issuing of mailbox cmds during
89 * non ISP abort time.
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080091 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
92 /* Timeout occurred. Return error. */
Arun Easi5e19ed92012-02-09 11:15:51 -080093 ql_log(ql_log_warn, vha, 0x1005,
Chad Dupuisd8c0d542012-02-09 11:15:46 -080094 "Cmd access timeout, cmd=0x%x, Exiting.\n",
95 mcp->mb[0]);
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080096 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 }
98
99 ha->flags.mbox_busy = 1;
100 /* Save mailbox command for debug */
101 ha->mcp = mcp;
102
Arun Easi5e19ed92012-02-09 11:15:51 -0800103 ql_dbg(ql_dbg_mbx, vha, 0x1006,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700104 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
106 spin_lock_irqsave(&ha->hardware_lock, flags);
107
108 /* Load mailbox registers. */
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400109 if (IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -0700110 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400111 else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700112 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
113 else
114 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
116 iptr = mcp->mb;
117 command = mcp->mb[0];
118 mboxes = mcp->out_mb;
119
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700120 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1111,
121 "Mailbox registers (OUT):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
123 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700124 optr =
125 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700126 if (mboxes & BIT_0) {
127 ql_dbg(ql_dbg_mbx, vha, 0x1112,
128 "mbox[%d]<-0x%04x\n", cnt, *iptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 WRT_REG_WORD(optr, *iptr);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700130 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131
132 mboxes >>= 1;
133 optr++;
134 iptr++;
135 }
136
Arun Easi5e19ed92012-02-09 11:15:51 -0800137 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700138 "I/O Address = %p.\n", optr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139
140 /* Issue set host interrupt command to send cmd out. */
141 ha->flags.mbox_int = 0;
142 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
143
144 /* Unlock mbx registers and wait for interrupt */
Arun Easi5e19ed92012-02-09 11:15:51 -0800145 ql_dbg(ql_dbg_mbx, vha, 0x100f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700146 "Going to unlock irq & waiting for interrupts. "
147 "jiffies=%lx.\n", jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148
149 /* Wait for mbx cmd completion until timeout */
150
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800151 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
153
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400154 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700155 if (RD_REG_DWORD(&reg->isp82.hint) &
156 HINT_MBX_INT_PENDING) {
157 spin_unlock_irqrestore(&ha->hardware_lock,
158 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800159 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800160 ql_dbg(ql_dbg_mbx, vha, 0x1010,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700161 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700162 rval = QLA_FUNCTION_TIMEOUT;
163 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700164 }
165 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
166 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700167 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
168 else
169 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 spin_unlock_irqrestore(&ha->hardware_lock, flags);
171
Giridhar Malavali754d1242013-06-25 11:27:16 -0400172 if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
173 mcp->tov * HZ)) {
174 ql_dbg(ql_dbg_mbx, vha, 0x117a,
175 "cmd=%x Timeout.\n", command);
176 spin_lock_irqsave(&ha->hardware_lock, flags);
177 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
178 spin_unlock_irqrestore(&ha->hardware_lock, flags);
179 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180 } else {
Arun Easi5e19ed92012-02-09 11:15:51 -0800181 ql_dbg(ql_dbg_mbx, vha, 0x1011,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700182 "Cmd=%x Polling Mode.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400184 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700185 if (RD_REG_DWORD(&reg->isp82.hint) &
186 HINT_MBX_INT_PENDING) {
187 spin_unlock_irqrestore(&ha->hardware_lock,
188 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800189 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800190 ql_dbg(ql_dbg_mbx, vha, 0x1012,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700191 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700192 rval = QLA_FUNCTION_TIMEOUT;
193 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700194 }
195 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
196 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700197 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
198 else
199 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201
202 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
203 while (!ha->flags.mbox_int) {
204 if (time_after(jiffies, wait_time))
205 break;
206
207 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800208 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209
Andrew Vasquez85880802009-12-15 21:29:46 -0800210 if (!ha->flags.mbox_int &&
211 !(IS_QLA2200(ha) &&
212 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800213 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 } /* while */
Arun Easi5e19ed92012-02-09 11:15:51 -0800215 ql_dbg(ql_dbg_mbx, vha, 0x1013,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700216 "Waited %d sec.\n",
217 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 }
219
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 /* Check whether we timed out */
221 if (ha->flags.mbox_int) {
222 uint16_t *iptr2;
223
Arun Easi5e19ed92012-02-09 11:15:51 -0800224 ql_dbg(ql_dbg_mbx, vha, 0x1014,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700225 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226
227 /* Got interrupt. Clear the flag. */
228 ha->flags.mbox_int = 0;
229 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
230
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400231 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700232 ha->flags.mbox_busy = 0;
233 /* Setting Link-Down error */
234 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
235 ha->mcp = NULL;
236 rval = QLA_FUNCTION_FAILED;
Arun Easi5e19ed92012-02-09 11:15:51 -0800237 ql_log(ql_log_warn, vha, 0x1015,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700238 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700239 goto premature_exit;
240 }
241
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400242 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244
245 /* Load return mailbox registers. */
246 iptr2 = mcp->mb;
247 iptr = (uint16_t *)&ha->mailbox_out[0];
248 mboxes = mcp->in_mb;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700249
250 ql_dbg(ql_dbg_mbx, vha, 0x1113,
251 "Mailbox registers (IN):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700253 if (mboxes & BIT_0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 *iptr2 = *iptr;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700255 ql_dbg(ql_dbg_mbx, vha, 0x1114,
256 "mbox[%d]->0x%04x\n", cnt, *iptr2);
257 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258
259 mboxes >>= 1;
260 iptr2++;
261 iptr++;
262 }
263 } else {
264
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700265 uint16_t mb0;
266 uint32_t ictrl;
267
Andrew Vasqueze4289242007-07-19 15:05:56 -0700268 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700269 mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
270 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
271 } else {
Andrew Vasquezcca53352005-08-26 19:08:30 -0700272 mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700273 ictrl = RD_REG_WORD(&reg->isp.ictrl);
274 }
Arun Easi5e19ed92012-02-09 11:15:51 -0800275 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119,
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400276 "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
277 "mb[0]=0x%x\n", command, ictrl, jiffies, 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
Chad Dupuisb8eb4132013-06-25 11:27:20 -0400282 * of the current firmware state. We do not need to do this
283 * if we are intentionally generating a dump.
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800284 */
Chad Dupuisb8eb4132013-06-25 11:27:20 -0400285 if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR)
286 ha->isp_ops->fw_dump(vha, 0);
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800287
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 rval = QLA_FUNCTION_TIMEOUT;
289 }
290
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 ha->flags.mbox_busy = 0;
292
293 /* Clean up */
294 ha->mcp = NULL;
295
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800296 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800297 ql_dbg(ql_dbg_mbx, vha, 0x101a,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700298 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299
300 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800301 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 }
303
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700304 if (rval == QLA_FUNCTION_TIMEOUT &&
305 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800306 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
307 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 /* not in dpc. schedule it for dpc to take over. */
Arun Easi5e19ed92012-02-09 11:15:51 -0800309 ql_dbg(ql_dbg_mbx, vha, 0x101b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700310 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700311
312 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
313 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
314 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800315 if (IS_QLA82XX(ha)) {
316 ql_dbg(ql_dbg_mbx, vha, 0x112a,
317 "disabling pause transmit on port "
318 "0 & 1.\n");
319 qla82xx_wr_32(ha,
320 QLA82XX_CRB_NIU + 0x98,
321 CRB_NIU_XG_PAUSE_CTL_P0|
322 CRB_NIU_XG_PAUSE_CTL_P1);
323 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700324 ql_log(ql_log_info, base_vha, 0x101c,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400325 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800326 "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "
327 "abort.\n", command, mcp->mb[0],
328 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700329 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
330 qla2xxx_wake_dpc(vha);
331 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333 /* call abort directly since we are in the DPC thread */
Arun Easi5e19ed92012-02-09 11:15:51 -0800334 ql_dbg(ql_dbg_mbx, vha, 0x101d,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700335 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700337 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
338 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
339 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800340 if (IS_QLA82XX(ha)) {
341 ql_dbg(ql_dbg_mbx, vha, 0x112b,
342 "disabling pause transmit on port "
343 "0 & 1.\n");
344 qla82xx_wr_32(ha,
345 QLA82XX_CRB_NIU + 0x98,
346 CRB_NIU_XG_PAUSE_CTL_P0|
347 CRB_NIU_XG_PAUSE_CTL_P1);
348 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700349 ql_log(ql_log_info, base_vha, 0x101e,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400350 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800351 "mb[0]=0x%x. Scheduling ISP abort ",
352 command, mcp->mb[0]);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700353 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
354 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
Giridhar Malavalid3360962012-02-09 11:14:10 -0800355 /* Allow next mbx cmd to come in. */
356 complete(&ha->mbx_cmd_comp);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700357 if (ha->isp_ops->abort_isp(vha)) {
358 /* Failed. retry later. */
359 set_bit(ISP_ABORT_NEEDED,
360 &vha->dpc_flags);
361 }
362 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Arun Easi5e19ed92012-02-09 11:15:51 -0800363 ql_dbg(ql_dbg_mbx, vha, 0x101f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700364 "Finished abort_isp.\n");
Giridhar Malavalid3360962012-02-09 11:14:10 -0800365 goto mbx_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 }
368 }
369
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700370premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800372 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
Giridhar Malavalid3360962012-02-09 11:14:10 -0800374mbx_done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 if (rval) {
Saurav Kashyap09543c02012-08-22 14:20:59 -0400376 ql_log(ql_log_warn, base_vha, 0x1020,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800377 "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n",
378 mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700380 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 }
382
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 return rval;
384}
385
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800387qla2x00_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 -0800388 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389{
390 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800391 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 mbx_cmd_t mc;
393 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400395 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022,
396 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
Andrew Vasqueze4289242007-07-19 15:05:56 -0700398 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800399 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
400 mcp->mb[8] = MSW(risc_addr);
401 mcp->out_mb = MBX_8|MBX_0;
402 } else {
403 mcp->mb[0] = MBC_LOAD_RISC_RAM;
404 mcp->out_mb = MBX_0;
405 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 mcp->mb[1] = LSW(risc_addr);
407 mcp->mb[2] = MSW(req_dma);
408 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 mcp->mb[6] = MSW(MSD(req_dma));
410 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800411 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700412 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700413 mcp->mb[4] = MSW(risc_code_size);
414 mcp->mb[5] = LSW(risc_code_size);
415 mcp->out_mb |= MBX_5|MBX_4;
416 } else {
417 mcp->mb[4] = LSW(risc_code_size);
418 mcp->out_mb |= MBX_4;
419 }
420
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700422 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800424 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700427 ql_dbg(ql_dbg_mbx, vha, 0x1023,
428 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400430 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,
431 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 }
433
434 return rval;
435}
436
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700437#define EXTENDED_BB_CREDITS BIT_0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438/*
439 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700440 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 *
442 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700443 * ha = adapter block pointer.
444 * TARGET_QUEUE_LOCK must be released.
445 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 *
447 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700448 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 *
450 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700451 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 */
453int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800454qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455{
456 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800457 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 mbx_cmd_t mc;
459 mbx_cmd_t *mcp = &mc;
460
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400461 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,
462 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463
464 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700465 mcp->out_mb = MBX_0;
466 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700467 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700468 mcp->mb[1] = MSW(risc_addr);
469 mcp->mb[2] = LSW(risc_addr);
470 mcp->mb[3] = 0;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500471 if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
472 IS_QLA27XX(ha)) {
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700473 struct nvram_81xx *nv = ha->nvram;
474 mcp->mb[4] = (nv->enhanced_features &
475 EXTENDED_BB_CREDITS);
476 } else
477 mcp->mb[4] = 0;
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700478 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700479 mcp->in_mb |= MBX_1;
480 } else {
481 mcp->mb[1] = LSW(risc_addr);
482 mcp->out_mb |= MBX_1;
483 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
484 mcp->mb[2] = 0;
485 mcp->out_mb |= MBX_2;
486 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487 }
488
Ravi Anandb93480e2008-04-03 13:13:25 -0700489 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800491 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700493 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700494 ql_dbg(ql_dbg_mbx, vha, 0x1026,
495 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700496 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700497 if (IS_FWI2_CAPABLE(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400498 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1027,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700499 "Done exchanges=%x.\n", mcp->mb[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700500 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400501 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
502 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700503 }
504 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505
506 return rval;
507}
508
509/*
510 * qla2x00_get_fw_version
511 * Get firmware version.
512 *
513 * Input:
514 * ha: adapter state pointer.
515 * major: pointer for major number.
516 * minor: pointer for minor number.
517 * subminor: pointer for subminor number.
518 *
519 * Returns:
520 * qla2x00 local function return status code.
521 *
522 * Context:
523 * Kernel context.
524 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700525int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800526qla2x00_get_fw_version(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527{
528 int rval;
529 mbx_cmd_t mc;
530 mbx_cmd_t *mcp = &mc;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800531 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400533 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029,
534 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535
536 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
537 mcp->out_mb = MBX_0;
538 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400539 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha))
Andrew Vasquez55a96152009-03-24 09:08:03 -0700540 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Saurav Kashyapfb0effe2012-08-22 14:21:28 -0400541 if (IS_FWI2_CAPABLE(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800542 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500543 if (IS_QLA27XX(ha))
544 mcp->in_mb |= MBX_21|MBX_20|MBX_19|MBX_18;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700546 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800547 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700548 if (rval != QLA_SUCCESS)
549 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550
551 /* Return mailbox data. */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800552 ha->fw_major_version = mcp->mb[1];
553 ha->fw_minor_version = mcp->mb[2];
554 ha->fw_subminor_version = mcp->mb[3];
555 ha->fw_attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800556 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800557 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 else
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800559 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400560 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800561 ha->mpi_version[0] = mcp->mb[10] & 0xff;
562 ha->mpi_version[1] = mcp->mb[11] >> 8;
563 ha->mpi_version[2] = mcp->mb[11] & 0xff;
564 ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
565 ha->phy_version[0] = mcp->mb[8] & 0xff;
566 ha->phy_version[1] = mcp->mb[9] >> 8;
567 ha->phy_version[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800568 }
Saurav Kashyap81178772012-08-22 14:21:04 -0400569 if (IS_FWI2_CAPABLE(ha)) {
570 ha->fw_attributes_h = mcp->mb[15];
571 ha->fw_attributes_ext[0] = mcp->mb[16];
572 ha->fw_attributes_ext[1] = mcp->mb[17];
573 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,
574 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
575 __func__, mcp->mb[15], mcp->mb[6]);
576 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
577 "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
578 __func__, mcp->mb[17], mcp->mb[16]);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800579 }
Chad Dupuisf73cb692014-02-26 04:15:06 -0500580 if (IS_QLA27XX(ha)) {
581 ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18];
582 ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20];
583 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800584
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700585failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 if (rval != QLA_SUCCESS) {
587 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700588 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 } else {
590 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400591 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b,
592 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700594 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595}
596
597/*
598 * qla2x00_get_fw_options
599 * Set firmware options.
600 *
601 * Input:
602 * ha = adapter block pointer.
603 * fwopt = pointer for firmware options.
604 *
605 * Returns:
606 * qla2x00 local function return status code.
607 *
608 * Context:
609 * Kernel context.
610 */
611int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800612qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613{
614 int rval;
615 mbx_cmd_t mc;
616 mbx_cmd_t *mcp = &mc;
617
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400618 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c,
619 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620
621 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
622 mcp->out_mb = MBX_0;
623 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700624 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800626 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627
628 if (rval != QLA_SUCCESS) {
629 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700630 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700632 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 fwopts[1] = mcp->mb[1];
634 fwopts[2] = mcp->mb[2];
635 fwopts[3] = mcp->mb[3];
636
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400637 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e,
638 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 }
640
641 return rval;
642}
643
644
645/*
646 * qla2x00_set_fw_options
647 * Set firmware options.
648 *
649 * Input:
650 * ha = adapter block pointer.
651 * fwopt = pointer for firmware options.
652 *
653 * Returns:
654 * qla2x00 local function return status code.
655 *
656 * Context:
657 * Kernel context.
658 */
659int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800660qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661{
662 int rval;
663 mbx_cmd_t mc;
664 mbx_cmd_t *mcp = &mc;
665
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400666 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f,
667 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668
669 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
670 mcp->mb[1] = fwopts[1];
671 mcp->mb[2] = fwopts[2];
672 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700673 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800675 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700676 mcp->in_mb |= MBX_1;
677 } else {
678 mcp->mb[10] = fwopts[10];
679 mcp->mb[11] = fwopts[11];
680 mcp->mb[12] = 0; /* Undocumented, but used */
681 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
682 }
Ravi Anandb93480e2008-04-03 13:13:25 -0700683 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800685 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700687 fwopts[0] = mcp->mb[0];
688
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 if (rval != QLA_SUCCESS) {
690 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700691 ql_dbg(ql_dbg_mbx, vha, 0x1030,
692 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 } else {
694 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400695 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031,
696 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 }
698
699 return rval;
700}
701
702/*
703 * qla2x00_mbx_reg_test
704 * Mailbox register wrap test.
705 *
706 * Input:
707 * ha = adapter block pointer.
708 * TARGET_QUEUE_LOCK must be released.
709 * ADAPTER_STATE_LOCK must be released.
710 *
711 * Returns:
712 * qla2x00 local function return status code.
713 *
714 * Context:
715 * Kernel context.
716 */
717int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800718qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719{
720 int rval;
721 mbx_cmd_t mc;
722 mbx_cmd_t *mcp = &mc;
723
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400724 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032,
725 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726
727 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
728 mcp->mb[1] = 0xAAAA;
729 mcp->mb[2] = 0x5555;
730 mcp->mb[3] = 0xAA55;
731 mcp->mb[4] = 0x55AA;
732 mcp->mb[5] = 0xA5A5;
733 mcp->mb[6] = 0x5A5A;
734 mcp->mb[7] = 0x2525;
735 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
736 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 -0700737 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800739 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740
741 if (rval == QLA_SUCCESS) {
742 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
743 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
744 rval = QLA_FUNCTION_FAILED;
745 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
746 mcp->mb[7] != 0x2525)
747 rval = QLA_FUNCTION_FAILED;
748 }
749
750 if (rval != QLA_SUCCESS) {
751 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700752 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 } else {
754 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400755 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034,
756 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757 }
758
759 return rval;
760}
761
762/*
763 * qla2x00_verify_checksum
764 * Verify firmware checksum.
765 *
766 * Input:
767 * ha = adapter block pointer.
768 * TARGET_QUEUE_LOCK must be released.
769 * ADAPTER_STATE_LOCK must be released.
770 *
771 * Returns:
772 * qla2x00 local function return status code.
773 *
774 * Context:
775 * Kernel context.
776 */
777int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800778qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779{
780 int rval;
781 mbx_cmd_t mc;
782 mbx_cmd_t *mcp = &mc;
783
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400784 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035,
785 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786
787 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700788 mcp->out_mb = MBX_0;
789 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800790 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700791 mcp->mb[1] = MSW(risc_addr);
792 mcp->mb[2] = LSW(risc_addr);
793 mcp->out_mb |= MBX_2|MBX_1;
794 mcp->in_mb |= MBX_2|MBX_1;
795 } else {
796 mcp->mb[1] = LSW(risc_addr);
797 mcp->out_mb |= MBX_1;
798 mcp->in_mb |= MBX_1;
799 }
800
Ravi Anandb93480e2008-04-03 13:13:25 -0700801 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800803 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700804
805 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700806 ql_dbg(ql_dbg_mbx, vha, 0x1036,
807 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
808 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400810 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037,
811 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 }
813
814 return rval;
815}
816
817/*
818 * qla2x00_issue_iocb
819 * Issue IOCB using mailbox command
820 *
821 * Input:
822 * ha = adapter state pointer.
823 * buffer = buffer pointer.
824 * phys_addr = physical address of buffer.
825 * size = size of buffer.
826 * TARGET_QUEUE_LOCK must be released.
827 * ADAPTER_STATE_LOCK must be released.
828 *
829 * Returns:
830 * qla2x00 local function return status code.
831 *
832 * Context:
833 * Kernel context.
834 */
Giridhar Malavali6e980162010-03-19 17:03:58 -0700835int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800836qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700837 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838{
839 int rval;
840 mbx_cmd_t mc;
841 mbx_cmd_t *mcp = &mc;
842
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400843 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038,
844 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700845
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
847 mcp->mb[1] = 0;
848 mcp->mb[2] = MSW(phys_addr);
849 mcp->mb[3] = LSW(phys_addr);
850 mcp->mb[6] = MSW(MSD(phys_addr));
851 mcp->mb[7] = LSW(MSD(phys_addr));
852 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
853 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700854 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800856 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857
858 if (rval != QLA_SUCCESS) {
859 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700860 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700862 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
863
864 /* Mask reserved bits. */
865 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800866 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400867 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a,
868 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 }
870
871 return rval;
872}
873
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700874int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800875qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700876 size_t size)
877{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800878 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700879 MBX_TOV_SECONDS);
880}
881
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882/*
883 * qla2x00_abort_command
884 * Abort command aborts a specified IOCB.
885 *
886 * Input:
887 * ha = adapter block pointer.
888 * sp = SB structure pointer.
889 *
890 * Returns:
891 * qla2x00 local function return status code.
892 *
893 * Context:
894 * Kernel context.
895 */
896int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700897qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898{
899 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800901 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 mbx_cmd_t mc;
903 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700904 fc_port_t *fcport = sp->fcport;
905 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800906 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700907 struct req_que *req = vha->req;
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800908 struct scsi_cmnd *cmd = GET_CMD_SP(sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400910 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b,
911 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700913 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -0500914 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800915 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 break;
917 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700918 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919
Chad Dupuis8d93f552013-01-30 03:34:37 -0500920 if (handle == req->num_outstanding_cmds) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 /* command not found */
922 return QLA_FUNCTION_FAILED;
923 }
924
925 mcp->mb[0] = MBC_ABORT_COMMAND;
926 if (HAS_EXTENDED_IDS(ha))
927 mcp->mb[1] = fcport->loop_id;
928 else
929 mcp->mb[1] = fcport->loop_id << 8;
930 mcp->mb[2] = (uint16_t)handle;
931 mcp->mb[3] = (uint16_t)(handle >> 16);
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800932 mcp->mb[6] = (uint16_t)cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
934 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700935 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800937 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938
939 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700940 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700941 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400942 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d,
943 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944 }
945
946 return rval;
947}
948
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700950qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951{
Andrew Vasquez523ec772008-04-03 13:13:24 -0700952 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 mbx_cmd_t mc;
954 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800955 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800956 struct req_que *req;
957 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958
Andrew Vasquez523ec772008-04-03 13:13:24 -0700959 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800960 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700961
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400962 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e,
963 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700964
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700965 req = vha->hw->req_q_map[0];
966 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700968 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800969 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970 mcp->mb[1] = fcport->loop_id;
971 mcp->mb[10] = 0;
972 mcp->out_mb |= MBX_10;
973 } else {
974 mcp->mb[1] = fcport->loop_id << 8;
975 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800976 mcp->mb[2] = vha->hw->loop_reset_delay;
977 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978
979 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700980 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800982 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400984 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f,
985 "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700986 }
987
988 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800989 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
990 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700991 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700992 ql_dbg(ql_dbg_mbx, vha, 0x1040,
993 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400995 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041,
996 "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700997 }
998
999 return rval;
1000}
1001
1002int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001003qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07001004{
1005 int rval, rval2;
1006 mbx_cmd_t mc;
1007 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001008 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001009 struct req_que *req;
1010 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001011
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001012 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001013
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001014 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042,
1015 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001016
Giridhar Malavali7e2b8952010-05-28 15:08:17 -07001017 req = vha->hw->req_q_map[0];
1018 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001019 mcp->mb[0] = MBC_LUN_RESET;
1020 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001021 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -07001022 mcp->mb[1] = fcport->loop_id;
1023 else
1024 mcp->mb[1] = fcport->loop_id << 8;
1025 mcp->mb[2] = l;
1026 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001027 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001028
1029 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001030 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001031 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001032 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001033 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001034 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001035 }
1036
1037 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001038 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1039 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001040 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001041 ql_dbg(ql_dbg_mbx, vha, 0x1044,
1042 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001043 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001044 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045,
1045 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 }
1047
1048 return rval;
1049}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
1051/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 * qla2x00_get_adapter_id
1053 * Get adapter ID and topology.
1054 *
1055 * Input:
1056 * ha = adapter block pointer.
1057 * id = pointer for loop ID.
1058 * al_pa = pointer for AL_PA.
1059 * area = pointer for area.
1060 * domain = pointer for domain.
1061 * top = pointer for topology.
1062 * TARGET_QUEUE_LOCK must be released.
1063 * ADAPTER_STATE_LOCK must be released.
1064 *
1065 * Returns:
1066 * qla2x00 local function return status code.
1067 *
1068 * Context:
1069 * Kernel context.
1070 */
1071int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001072qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001073 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074{
1075 int rval;
1076 mbx_cmd_t mc;
1077 mbx_cmd_t *mcp = &mc;
1078
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001079 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046,
1080 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081
1082 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001083 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001084 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001085 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001086 if (IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001087 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Ravi Anandb93480e2008-04-03 13:13:25 -07001088 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001090 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001091 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1092 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001093 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1094 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
1096 /* Return data. */
1097 *id = mcp->mb[1];
1098 *al_pa = LSB(mcp->mb[2]);
1099 *area = MSB(mcp->mb[2]);
1100 *domain = LSB(mcp->mb[3]);
1101 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001102 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103
1104 if (rval != QLA_SUCCESS) {
1105 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001106 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001108 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048,
1109 "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001110
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001111 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001112 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1113 vha->fcoe_fcf_idx = mcp->mb[10];
1114 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1115 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1116 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1117 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1118 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1119 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1120 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 }
1122
1123 return rval;
1124}
1125
1126/*
1127 * qla2x00_get_retry_cnt
1128 * Get current firmware login retry count and delay.
1129 *
1130 * Input:
1131 * ha = adapter block pointer.
1132 * retry_cnt = pointer to login retry count.
1133 * tov = pointer to login timeout value.
1134 *
1135 * Returns:
1136 * qla2x00 local function return status code.
1137 *
1138 * Context:
1139 * Kernel context.
1140 */
1141int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001142qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 uint16_t *r_a_tov)
1144{
1145 int rval;
1146 uint16_t ratov;
1147 mbx_cmd_t mc;
1148 mbx_cmd_t *mcp = &mc;
1149
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001150 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049,
1151 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152
1153 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1154 mcp->out_mb = MBX_0;
1155 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001156 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001158 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001159
1160 if (rval != QLA_SUCCESS) {
1161 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001162 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1163 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 } else {
1165 /* Convert returned data and check our values. */
1166 *r_a_tov = mcp->mb[3] / 2;
1167 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1168 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1169 /* Update to the larger values */
1170 *retry_cnt = (uint8_t)mcp->mb[1];
1171 *tov = ratov;
1172 }
1173
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001174 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001175 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 }
1177
1178 return rval;
1179}
1180
1181/*
1182 * qla2x00_init_firmware
1183 * Initialize adapter firmware.
1184 *
1185 * Input:
1186 * ha = adapter block pointer.
1187 * dptr = Initialization control block pointer.
1188 * size = size of initialization control block.
1189 * TARGET_QUEUE_LOCK must be released.
1190 * ADAPTER_STATE_LOCK must be released.
1191 *
1192 * Returns:
1193 * qla2x00 local function return status code.
1194 *
1195 * Context:
1196 * Kernel context.
1197 */
1198int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001199qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200{
1201 int rval;
1202 mbx_cmd_t mc;
1203 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001204 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001206 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,
1207 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001209 if (IS_P3P_TYPE(ha) && ql2xdbwr)
Giridhar Malavalia9083012010-04-12 17:59:55 -07001210 qla82xx_wr_32(ha, ha->nxdb_wr_ptr,
1211 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1212
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001213 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001214 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1215 else
1216 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1217
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001218 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001219 mcp->mb[2] = MSW(ha->init_cb_dma);
1220 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1222 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001223 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Joe Carnuccio4ef21bd2013-10-30 03:38:11 -04001224 if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001225 mcp->mb[1] = BIT_0;
1226 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1227 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1228 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1229 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1230 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1231 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1232 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001233 /* 1 and 2 should normally be captured. */
1234 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001235 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001236 /* mb3 is additional info about the installed SFP. */
1237 mcp->in_mb |= MBX_3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 mcp->buf_size = size;
1239 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001240 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001241 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242
1243 if (rval != QLA_SUCCESS) {
1244 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001245 ql_dbg(ql_dbg_mbx, vha, 0x104d,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001246 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1247 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248 } else {
1249 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001250 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,
1251 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252 }
1253
1254 return rval;
1255}
1256
1257/*
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001258 * qla2x00_get_node_name_list
1259 * Issue get node name list mailbox command, kmalloc()
1260 * and return the resulting list. Caller must kfree() it!
1261 *
1262 * Input:
1263 * ha = adapter state pointer.
1264 * out_data = resulting list
1265 * out_len = length of the resulting list
1266 *
1267 * Returns:
1268 * qla2x00 local function return status code.
1269 *
1270 * Context:
1271 * Kernel context.
1272 */
1273int
1274qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len)
1275{
1276 struct qla_hw_data *ha = vha->hw;
1277 struct qla_port_24xx_data *list = NULL;
1278 void *pmap;
1279 mbx_cmd_t mc;
1280 dma_addr_t pmap_dma;
1281 ulong dma_size;
1282 int rval, left;
1283
1284 left = 1;
1285 while (left > 0) {
1286 dma_size = left * sizeof(*list);
1287 pmap = dma_alloc_coherent(&ha->pdev->dev, dma_size,
1288 &pmap_dma, GFP_KERNEL);
1289 if (!pmap) {
1290 ql_log(ql_log_warn, vha, 0x113f,
1291 "%s(%ld): DMA Alloc failed of %ld\n",
1292 __func__, vha->host_no, dma_size);
1293 rval = QLA_MEMORY_ALLOC_FAILED;
1294 goto out;
1295 }
1296
1297 mc.mb[0] = MBC_PORT_NODE_NAME_LIST;
1298 mc.mb[1] = BIT_1 | BIT_3;
1299 mc.mb[2] = MSW(pmap_dma);
1300 mc.mb[3] = LSW(pmap_dma);
1301 mc.mb[6] = MSW(MSD(pmap_dma));
1302 mc.mb[7] = LSW(MSD(pmap_dma));
1303 mc.mb[8] = dma_size;
1304 mc.out_mb = MBX_0|MBX_1|MBX_2|MBX_3|MBX_6|MBX_7|MBX_8;
1305 mc.in_mb = MBX_0|MBX_1;
1306 mc.tov = 30;
1307 mc.flags = MBX_DMA_IN;
1308
1309 rval = qla2x00_mailbox_command(vha, &mc);
1310 if (rval != QLA_SUCCESS) {
1311 if ((mc.mb[0] == MBS_COMMAND_ERROR) &&
1312 (mc.mb[1] == 0xA)) {
1313 left += le16_to_cpu(mc.mb[2]) /
1314 sizeof(struct qla_port_24xx_data);
1315 goto restart;
1316 }
1317 goto out_free;
1318 }
1319
1320 left = 0;
1321
1322 list = kzalloc(dma_size, GFP_KERNEL);
1323 if (!list) {
1324 ql_log(ql_log_warn, vha, 0x1140,
1325 "%s(%ld): failed to allocate node names list "
1326 "structure.\n", __func__, vha->host_no);
1327 rval = QLA_MEMORY_ALLOC_FAILED;
1328 goto out_free;
1329 }
1330
1331 memcpy(list, pmap, dma_size);
1332restart:
1333 dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
1334 }
1335
1336 *out_data = list;
1337 *out_len = dma_size;
1338
1339out:
1340 return rval;
1341
1342out_free:
1343 dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
1344 return rval;
1345}
1346
1347/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348 * qla2x00_get_port_database
1349 * Issue normal/enhanced get port database mailbox command
1350 * and copy device name as necessary.
1351 *
1352 * Input:
1353 * ha = adapter state pointer.
1354 * dev = structure pointer.
1355 * opt = enhanced cmd option byte.
1356 *
1357 * Returns:
1358 * qla2x00 local function return status code.
1359 *
1360 * Context:
1361 * Kernel context.
1362 */
1363int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001364qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365{
1366 int rval;
1367 mbx_cmd_t mc;
1368 mbx_cmd_t *mcp = &mc;
1369 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001370 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001372 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001374 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f,
1375 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001377 pd24 = NULL;
1378 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001380 ql_log(ql_log_warn, vha, 0x1050,
1381 "Failed to allocate port database structure.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 return QLA_MEMORY_ALLOC_FAILED;
1383 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001384 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001386 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001387 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389 mcp->mb[2] = MSW(pd_dma);
1390 mcp->mb[3] = LSW(pd_dma);
1391 mcp->mb[6] = MSW(MSD(pd_dma));
1392 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001393 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001394 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001396 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001397 mcp->mb[1] = fcport->loop_id;
1398 mcp->mb[10] = opt;
1399 mcp->out_mb |= MBX_10|MBX_1;
1400 mcp->in_mb |= MBX_1;
1401 } else if (HAS_EXTENDED_IDS(ha)) {
1402 mcp->mb[1] = fcport->loop_id;
1403 mcp->mb[10] = opt;
1404 mcp->out_mb |= MBX_10|MBX_1;
1405 } else {
1406 mcp->mb[1] = fcport->loop_id << 8 | opt;
1407 mcp->out_mb |= MBX_1;
1408 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001409 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1410 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 mcp->flags = MBX_DMA_IN;
1412 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001413 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414 if (rval != QLA_SUCCESS)
1415 goto gpd_error_out;
1416
Andrew Vasqueze4289242007-07-19 15:05:56 -07001417 if (IS_FWI2_CAPABLE(ha)) {
Arun Easi0eba25d2012-02-09 11:15:58 -08001418 uint64_t zero = 0;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001419 pd24 = (struct port_database_24xx *) pd;
1420
1421 /* Check for logged in state. */
1422 if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1423 pd24->last_login_state != PDS_PRLI_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001424 ql_dbg(ql_dbg_mbx, vha, 0x1051,
1425 "Unable to verify login-state (%x/%x) for "
1426 "loop_id %x.\n", pd24->current_login_state,
1427 pd24->last_login_state, fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001428 rval = QLA_FUNCTION_FAILED;
1429 goto gpd_error_out;
1430 }
1431
Arun Easi0eba25d2012-02-09 11:15:58 -08001432 if (fcport->loop_id == FC_NO_LOOP_ID ||
1433 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1434 memcmp(fcport->port_name, pd24->port_name, 8))) {
1435 /* We lost the device mid way. */
1436 rval = QLA_NOT_LOGGED_IN;
1437 goto gpd_error_out;
1438 }
1439
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001440 /* Names are little-endian. */
1441 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1442 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1443
1444 /* Get port_id of device. */
1445 fcport->d_id.b.domain = pd24->port_id[0];
1446 fcport->d_id.b.area = pd24->port_id[1];
1447 fcport->d_id.b.al_pa = pd24->port_id[2];
1448 fcport->d_id.b.rsvd_1 = 0;
1449
1450 /* If not target must be initiator or unknown type. */
1451 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1452 fcport->port_type = FCT_INITIATOR;
1453 else
1454 fcport->port_type = FCT_TARGET;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001455
1456 /* Passback COS information. */
1457 fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ?
1458 FC_COS_CLASS2 : FC_COS_CLASS3;
1459
1460 if (pd24->prli_svc_param_word_3[0] & BIT_7)
1461 fcport->flags |= FCF_CONF_COMP_SUPPORTED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001462 } else {
Arun Easi0eba25d2012-02-09 11:15:58 -08001463 uint64_t zero = 0;
1464
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001465 /* Check for logged in state. */
1466 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1467 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001468 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1469 "Unable to verify login-state (%x/%x) - "
1470 "portid=%02x%02x%02x.\n", pd->master_state,
1471 pd->slave_state, fcport->d_id.b.domain,
1472 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001473 rval = QLA_FUNCTION_FAILED;
1474 goto gpd_error_out;
1475 }
1476
Arun Easi0eba25d2012-02-09 11:15:58 -08001477 if (fcport->loop_id == FC_NO_LOOP_ID ||
1478 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1479 memcmp(fcport->port_name, pd->port_name, 8))) {
1480 /* We lost the device mid way. */
1481 rval = QLA_NOT_LOGGED_IN;
1482 goto gpd_error_out;
1483 }
1484
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001485 /* Names are little-endian. */
1486 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1487 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1488
1489 /* Get port_id of device. */
1490 fcport->d_id.b.domain = pd->port_id[0];
1491 fcport->d_id.b.area = pd->port_id[3];
1492 fcport->d_id.b.al_pa = pd->port_id[2];
1493 fcport->d_id.b.rsvd_1 = 0;
1494
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001495 /* If not target must be initiator or unknown type. */
1496 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1497 fcport->port_type = FCT_INITIATOR;
1498 else
1499 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001500
1501 /* Passback COS information. */
1502 fcport->supported_classes = (pd->options & BIT_4) ?
1503 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 }
1505
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506gpd_error_out:
1507 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1508
1509 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001510 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1511 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1512 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001514 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053,
1515 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 }
1517
1518 return rval;
1519}
1520
1521/*
1522 * qla2x00_get_firmware_state
1523 * Get adapter firmware state.
1524 *
1525 * Input:
1526 * ha = adapter block pointer.
1527 * dptr = pointer for firmware state.
1528 * TARGET_QUEUE_LOCK must be released.
1529 * ADAPTER_STATE_LOCK must be released.
1530 *
1531 * Returns:
1532 * qla2x00 local function return status code.
1533 *
1534 * Context:
1535 * Kernel context.
1536 */
1537int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001538qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539{
1540 int rval;
1541 mbx_cmd_t mc;
1542 mbx_cmd_t *mcp = &mc;
1543
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001544 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
1545 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546
1547 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1548 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001549 if (IS_FWI2_CAPABLE(vha->hw))
1550 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1551 else
1552 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001553 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001555 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001557 /* Return firmware states. */
1558 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001559 if (IS_FWI2_CAPABLE(vha->hw)) {
1560 states[1] = mcp->mb[2];
1561 states[2] = mcp->mb[3];
1562 states[3] = mcp->mb[4];
1563 states[4] = mcp->mb[5];
1564 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565
1566 if (rval != QLA_SUCCESS) {
1567 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001568 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569 } else {
1570 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001571 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,
1572 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573 }
1574
1575 return rval;
1576}
1577
1578/*
1579 * qla2x00_get_port_name
1580 * Issue get port name mailbox command.
1581 * Returned name is in big endian format.
1582 *
1583 * Input:
1584 * ha = adapter block pointer.
1585 * loop_id = loop ID of device.
1586 * name = pointer for name.
1587 * TARGET_QUEUE_LOCK must be released.
1588 * ADAPTER_STATE_LOCK must be released.
1589 *
1590 * Returns:
1591 * qla2x00 local function return status code.
1592 *
1593 * Context:
1594 * Kernel context.
1595 */
1596int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001597qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 uint8_t opt)
1599{
1600 int rval;
1601 mbx_cmd_t mc;
1602 mbx_cmd_t *mcp = &mc;
1603
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001604 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057,
1605 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606
1607 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001608 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001609 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001610 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 mcp->mb[1] = loop_id;
1612 mcp->mb[10] = opt;
1613 mcp->out_mb |= MBX_10;
1614 } else {
1615 mcp->mb[1] = loop_id << 8 | opt;
1616 }
1617
1618 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001619 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001621 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622
1623 if (rval != QLA_SUCCESS) {
1624 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001625 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 } else {
1627 if (name != NULL) {
1628 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05001629 name[0] = MSB(mcp->mb[2]);
1630 name[1] = LSB(mcp->mb[2]);
1631 name[2] = MSB(mcp->mb[3]);
1632 name[3] = LSB(mcp->mb[3]);
1633 name[4] = MSB(mcp->mb[6]);
1634 name[5] = LSB(mcp->mb[6]);
1635 name[6] = MSB(mcp->mb[7]);
1636 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 }
1638
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001639 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059,
1640 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 }
1642
1643 return rval;
1644}
1645
1646/*
Joe Carnuccio61e1b262013-02-08 01:57:48 -05001647 * qla24xx_link_initialization
1648 * Issue link initialization mailbox command.
1649 *
1650 * Input:
1651 * ha = adapter block pointer.
1652 * TARGET_QUEUE_LOCK must be released.
1653 * ADAPTER_STATE_LOCK must be released.
1654 *
1655 * Returns:
1656 * qla2x00 local function return status code.
1657 *
1658 * Context:
1659 * Kernel context.
1660 */
1661int
1662qla24xx_link_initialize(scsi_qla_host_t *vha)
1663{
1664 int rval;
1665 mbx_cmd_t mc;
1666 mbx_cmd_t *mcp = &mc;
1667
1668 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152,
1669 "Entered %s.\n", __func__);
1670
1671 if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw))
1672 return QLA_FUNCTION_FAILED;
1673
1674 mcp->mb[0] = MBC_LINK_INITIALIZATION;
Joe Carnuccio5a5c27b2013-08-27 01:37:49 -04001675 mcp->mb[1] = BIT_4;
1676 if (vha->hw->operating_mode == LOOP)
1677 mcp->mb[1] |= BIT_6;
1678 else
1679 mcp->mb[1] |= BIT_5;
Joe Carnuccio61e1b262013-02-08 01:57:48 -05001680 mcp->mb[2] = 0;
1681 mcp->mb[3] = 0;
1682 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1683 mcp->in_mb = MBX_0;
1684 mcp->tov = MBX_TOV_SECONDS;
1685 mcp->flags = 0;
1686 rval = qla2x00_mailbox_command(vha, mcp);
1687
1688 if (rval != QLA_SUCCESS) {
1689 ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval);
1690 } else {
1691 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154,
1692 "Done %s.\n", __func__);
1693 }
1694
1695 return rval;
1696}
1697
1698/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 * qla2x00_lip_reset
1700 * Issue LIP reset mailbox command.
1701 *
1702 * Input:
1703 * ha = adapter block pointer.
1704 * TARGET_QUEUE_LOCK must be released.
1705 * ADAPTER_STATE_LOCK must be released.
1706 *
1707 * Returns:
1708 * qla2x00 local function return status code.
1709 *
1710 * Context:
1711 * Kernel context.
1712 */
1713int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001714qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715{
1716 int rval;
1717 mbx_cmd_t mc;
1718 mbx_cmd_t *mcp = &mc;
1719
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001720 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a,
1721 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001723 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001724 /* Logout across all FCFs. */
1725 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1726 mcp->mb[1] = BIT_1;
1727 mcp->mb[2] = 0;
1728 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1729 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001730 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001731 mcp->mb[1] = BIT_6;
1732 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001733 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001734 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001736 mcp->mb[0] = MBC_LIP_RESET;
1737 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001738 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001739 mcp->mb[1] = 0x00ff;
1740 mcp->mb[10] = 0;
1741 mcp->out_mb |= MBX_10;
1742 } else {
1743 mcp->mb[1] = 0xff00;
1744 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001745 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001746 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001748 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001749 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001751 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752
1753 if (rval != QLA_SUCCESS) {
1754 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001755 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 } else {
1757 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001758 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c,
1759 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 }
1761
1762 return rval;
1763}
1764
1765/*
1766 * qla2x00_send_sns
1767 * Send SNS command.
1768 *
1769 * Input:
1770 * ha = adapter block pointer.
1771 * sns = pointer for command.
1772 * cmd_size = command size.
1773 * buf_size = response/command size.
1774 * TARGET_QUEUE_LOCK must be released.
1775 * ADAPTER_STATE_LOCK must be released.
1776 *
1777 * Returns:
1778 * qla2x00 local function return status code.
1779 *
1780 * Context:
1781 * Kernel context.
1782 */
1783int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001784qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 uint16_t cmd_size, size_t buf_size)
1786{
1787 int rval;
1788 mbx_cmd_t mc;
1789 mbx_cmd_t *mcp = &mc;
1790
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001791 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d,
1792 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001794 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001795 "Retry cnt=%d ratov=%d total tov=%d.\n",
1796 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
1798 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1799 mcp->mb[1] = cmd_size;
1800 mcp->mb[2] = MSW(sns_phys_address);
1801 mcp->mb[3] = LSW(sns_phys_address);
1802 mcp->mb[6] = MSW(MSD(sns_phys_address));
1803 mcp->mb[7] = LSW(MSD(sns_phys_address));
1804 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1805 mcp->in_mb = MBX_0|MBX_1;
1806 mcp->buf_size = buf_size;
1807 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001808 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1809 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810
1811 if (rval != QLA_SUCCESS) {
1812 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001813 ql_dbg(ql_dbg_mbx, vha, 0x105f,
1814 "Failed=%x mb[0]=%x mb[1]=%x.\n",
1815 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 } else {
1817 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001818 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060,
1819 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820 }
1821
1822 return rval;
1823}
1824
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001825int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001826qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001827 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1828{
1829 int rval;
1830
1831 struct logio_entry_24xx *lg;
1832 dma_addr_t lg_dma;
1833 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001834 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001835 struct req_que *req;
1836 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001837
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001838 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061,
1839 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001840
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07001841 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07001842 req = ha->req_q_map[0];
1843 else
1844 req = vha->req;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001845 rsp = req->rsp;
1846
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001847 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1848 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001849 ql_log(ql_log_warn, vha, 0x1062,
1850 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001851 return QLA_MEMORY_ALLOC_FAILED;
1852 }
1853 memset(lg, 0, sizeof(struct logio_entry_24xx));
1854
1855 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1856 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001857 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001858 lg->nport_handle = cpu_to_le16(loop_id);
1859 lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
1860 if (opt & BIT_0)
1861 lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07001862 if (opt & BIT_1)
1863 lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001864 lg->port_id[0] = al_pa;
1865 lg->port_id[1] = area;
1866 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001867 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08001868 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
1869 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001870 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001871 ql_dbg(ql_dbg_mbx, vha, 0x1063,
1872 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001873 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001874 ql_dbg(ql_dbg_mbx, vha, 0x1064,
1875 "Failed to complete IOCB -- error status (%x).\n",
1876 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001877 rval = QLA_FUNCTION_FAILED;
1878 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1879 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1880 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1881
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001882 ql_dbg(ql_dbg_mbx, vha, 0x1065,
1883 "Failed to complete IOCB -- completion status (%x) "
1884 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
1885 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001886
1887 switch (iop[0]) {
1888 case LSC_SCODE_PORTID_USED:
1889 mb[0] = MBS_PORT_ID_USED;
1890 mb[1] = LSW(iop[1]);
1891 break;
1892 case LSC_SCODE_NPORT_USED:
1893 mb[0] = MBS_LOOP_ID_USED;
1894 break;
1895 case LSC_SCODE_NOLINK:
1896 case LSC_SCODE_NOIOCB:
1897 case LSC_SCODE_NOXCB:
1898 case LSC_SCODE_CMD_FAILED:
1899 case LSC_SCODE_NOFABRIC:
1900 case LSC_SCODE_FW_NOT_READY:
1901 case LSC_SCODE_NOT_LOGGED_IN:
1902 case LSC_SCODE_NOPCB:
1903 case LSC_SCODE_ELS_REJECT:
1904 case LSC_SCODE_CMD_PARAM_ERR:
1905 case LSC_SCODE_NONPORT:
1906 case LSC_SCODE_LOGGED_IN:
1907 case LSC_SCODE_NOFLOGI_ACC:
1908 default:
1909 mb[0] = MBS_COMMAND_ERROR;
1910 break;
1911 }
1912 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001913 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066,
1914 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001915
1916 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1917
1918 mb[0] = MBS_COMMAND_COMPLETE;
1919 mb[1] = 0;
1920 if (iop[0] & BIT_4) {
1921 if (iop[0] & BIT_8)
1922 mb[1] |= BIT_1;
1923 } else
1924 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001925
1926 /* Passback COS information. */
1927 mb[10] = 0;
1928 if (lg->io_parameter[7] || lg->io_parameter[8])
1929 mb[10] |= BIT_0; /* Class 2. */
1930 if (lg->io_parameter[9] || lg->io_parameter[10])
1931 mb[10] |= BIT_1; /* Class 3. */
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001932 if (lg->io_parameter[0] & __constant_cpu_to_le32(BIT_7))
1933 mb[10] |= BIT_7; /* Confirmed Completion
1934 * Allowed
1935 */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001936 }
1937
1938 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1939
1940 return rval;
1941}
1942
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943/*
1944 * qla2x00_login_fabric
1945 * Issue login fabric port mailbox command.
1946 *
1947 * Input:
1948 * ha = adapter block pointer.
1949 * loop_id = device loop ID.
1950 * domain = device domain.
1951 * area = device area.
1952 * al_pa = device AL_PA.
1953 * status = pointer for return status.
1954 * opt = command options.
1955 * TARGET_QUEUE_LOCK must be released.
1956 * ADAPTER_STATE_LOCK must be released.
1957 *
1958 * Returns:
1959 * qla2x00 local function return status code.
1960 *
1961 * Context:
1962 * Kernel context.
1963 */
1964int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001965qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001966 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1967{
1968 int rval;
1969 mbx_cmd_t mc;
1970 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001971 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001973 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067,
1974 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975
1976 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1977 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1978 if (HAS_EXTENDED_IDS(ha)) {
1979 mcp->mb[1] = loop_id;
1980 mcp->mb[10] = opt;
1981 mcp->out_mb |= MBX_10;
1982 } else {
1983 mcp->mb[1] = (loop_id << 8) | opt;
1984 }
1985 mcp->mb[2] = domain;
1986 mcp->mb[3] = area << 8 | al_pa;
1987
1988 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1989 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1990 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001991 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001992
1993 /* Return mailbox statuses. */
1994 if (mb != NULL) {
1995 mb[0] = mcp->mb[0];
1996 mb[1] = mcp->mb[1];
1997 mb[2] = mcp->mb[2];
1998 mb[6] = mcp->mb[6];
1999 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07002000 /* COS retrieved from Get-Port-Database mailbox command. */
2001 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002 }
2003
2004 if (rval != QLA_SUCCESS) {
2005 /* RLU tmp code: need to change main mailbox_command function to
2006 * return ok even when the mailbox completion value is not
2007 * SUCCESS. The caller needs to be responsible to interpret
2008 * the return values of this mailbox command if we're not
2009 * to change too much of the existing code.
2010 */
2011 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
2012 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
2013 mcp->mb[0] == 0x4006)
2014 rval = QLA_SUCCESS;
2015
2016 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002017 ql_dbg(ql_dbg_mbx, vha, 0x1068,
2018 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
2019 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020 } else {
2021 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002022 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069,
2023 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024 }
2025
2026 return rval;
2027}
2028
2029/*
2030 * qla2x00_login_local_device
2031 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002032 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033 * Input:
2034 * ha = adapter block pointer.
2035 * loop_id = device loop ID.
2036 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002037 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038 * Returns:
2039 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002040 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 * Context:
2042 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002043 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044 */
2045int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002046qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 uint16_t *mb_ret, uint8_t opt)
2048{
2049 int rval;
2050 mbx_cmd_t mc;
2051 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002052 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002054 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a,
2055 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002056
Andrew Vasqueze4289242007-07-19 15:05:56 -07002057 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002058 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08002059 fcport->d_id.b.domain, fcport->d_id.b.area,
2060 fcport->d_id.b.al_pa, mb_ret, opt);
2061
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
2063 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08002064 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065 else
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08002066 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002067 mcp->mb[2] = opt;
2068 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2069 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
2070 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2071 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002072 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073
2074 /* Return mailbox statuses. */
2075 if (mb_ret != NULL) {
2076 mb_ret[0] = mcp->mb[0];
2077 mb_ret[1] = mcp->mb[1];
2078 mb_ret[6] = mcp->mb[6];
2079 mb_ret[7] = mcp->mb[7];
2080 }
2081
2082 if (rval != QLA_SUCCESS) {
2083 /* AV tmp code: need to change main mailbox_command function to
2084 * return ok even when the mailbox completion value is not
2085 * SUCCESS. The caller needs to be responsible to interpret
2086 * the return values of this mailbox command if we're not
2087 * to change too much of the existing code.
2088 */
2089 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
2090 rval = QLA_SUCCESS;
2091
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002092 ql_dbg(ql_dbg_mbx, vha, 0x106b,
2093 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
2094 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095 } else {
2096 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002097 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c,
2098 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002099 }
2100
2101 return (rval);
2102}
2103
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002104int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002105qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002106 uint8_t area, uint8_t al_pa)
2107{
2108 int rval;
2109 struct logio_entry_24xx *lg;
2110 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002111 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002112 struct req_que *req;
2113 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002114
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002115 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d,
2116 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002117
2118 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
2119 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002120 ql_log(ql_log_warn, vha, 0x106e,
2121 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002122 return QLA_MEMORY_ALLOC_FAILED;
2123 }
2124 memset(lg, 0, sizeof(struct logio_entry_24xx));
2125
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002126 if (ql2xmaxqueues > 1)
2127 req = ha->req_q_map[0];
2128 else
2129 req = vha->req;
2130 rsp = req->rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002131 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2132 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002133 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002134 lg->nport_handle = cpu_to_le16(loop_id);
2135 lg->control_flags =
Andrew Vasquezc8d66912011-03-30 11:46:21 -07002136 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
2137 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002138 lg->port_id[0] = al_pa;
2139 lg->port_id[1] = area;
2140 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002141 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08002142 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2143 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002144 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002145 ql_dbg(ql_dbg_mbx, vha, 0x106f,
2146 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002147 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002148 ql_dbg(ql_dbg_mbx, vha, 0x1070,
2149 "Failed to complete IOCB -- error status (%x).\n",
2150 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002151 rval = QLA_FUNCTION_FAILED;
2152 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002153 ql_dbg(ql_dbg_mbx, vha, 0x1071,
2154 "Failed to complete IOCB -- completion status (%x) "
2155 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002156 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002157 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002158 } else {
2159 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002160 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072,
2161 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002162 }
2163
2164 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2165
2166 return rval;
2167}
2168
Linus Torvalds1da177e2005-04-16 15:20:36 -07002169/*
2170 * qla2x00_fabric_logout
2171 * Issue logout fabric port mailbox command.
2172 *
2173 * Input:
2174 * ha = adapter block pointer.
2175 * loop_id = device loop ID.
2176 * TARGET_QUEUE_LOCK must be released.
2177 * ADAPTER_STATE_LOCK must be released.
2178 *
2179 * Returns:
2180 * qla2x00 local function return status code.
2181 *
2182 * Context:
2183 * Kernel context.
2184 */
2185int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002186qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002187 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188{
2189 int rval;
2190 mbx_cmd_t mc;
2191 mbx_cmd_t *mcp = &mc;
2192
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002193 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073,
2194 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195
2196 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
2197 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002198 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199 mcp->mb[1] = loop_id;
2200 mcp->mb[10] = 0;
2201 mcp->out_mb |= MBX_10;
2202 } else {
2203 mcp->mb[1] = loop_id << 8;
2204 }
2205
2206 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002207 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002209 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002210
2211 if (rval != QLA_SUCCESS) {
2212 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002213 ql_dbg(ql_dbg_mbx, vha, 0x1074,
2214 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215 } else {
2216 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002217 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075,
2218 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219 }
2220
2221 return rval;
2222}
2223
2224/*
2225 * qla2x00_full_login_lip
2226 * Issue full login LIP mailbox command.
2227 *
2228 * Input:
2229 * ha = adapter block pointer.
2230 * TARGET_QUEUE_LOCK must be released.
2231 * ADAPTER_STATE_LOCK must be released.
2232 *
2233 * Returns:
2234 * qla2x00 local function return status code.
2235 *
2236 * Context:
2237 * Kernel context.
2238 */
2239int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002240qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241{
2242 int rval;
2243 mbx_cmd_t mc;
2244 mbx_cmd_t *mcp = &mc;
2245
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002246 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076,
2247 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248
2249 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002250 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002251 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252 mcp->mb[3] = 0;
2253 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2254 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002255 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002257 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002258
2259 if (rval != QLA_SUCCESS) {
2260 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002261 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262 } else {
2263 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002264 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078,
2265 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266 }
2267
2268 return rval;
2269}
2270
2271/*
2272 * qla2x00_get_id_list
2273 *
2274 * Input:
2275 * ha = adapter block pointer.
2276 *
2277 * Returns:
2278 * qla2x00 local function return status code.
2279 *
2280 * Context:
2281 * Kernel context.
2282 */
2283int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002284qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285 uint16_t *entries)
2286{
2287 int rval;
2288 mbx_cmd_t mc;
2289 mbx_cmd_t *mcp = &mc;
2290
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002291 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079,
2292 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293
2294 if (id_list == NULL)
2295 return QLA_FUNCTION_FAILED;
2296
2297 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002298 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002299 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002300 mcp->mb[2] = MSW(id_list_dma);
2301 mcp->mb[3] = LSW(id_list_dma);
2302 mcp->mb[6] = MSW(MSD(id_list_dma));
2303 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002304 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002305 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002306 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002307 } else {
2308 mcp->mb[1] = MSW(id_list_dma);
2309 mcp->mb[2] = LSW(id_list_dma);
2310 mcp->mb[3] = MSW(MSD(id_list_dma));
2311 mcp->mb[6] = LSW(MSD(id_list_dma));
2312 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2313 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002315 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002317 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002318
2319 if (rval != QLA_SUCCESS) {
2320 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002321 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322 } else {
2323 *entries = mcp->mb[1];
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002324 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b,
2325 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002326 }
2327
2328 return rval;
2329}
2330
2331/*
2332 * qla2x00_get_resource_cnts
2333 * Get current firmware resource counts.
2334 *
2335 * Input:
2336 * ha = adapter block pointer.
2337 *
2338 * Returns:
2339 * qla2x00 local function return status code.
2340 *
2341 * Context:
2342 * Kernel context.
2343 */
2344int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002345qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002346 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002347 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348{
2349 int rval;
2350 mbx_cmd_t mc;
2351 mbx_cmd_t *mcp = &mc;
2352
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002353 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c,
2354 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355
2356 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2357 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002358 mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05002359 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) || IS_QLA27XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002360 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002361 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002363 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364
2365 if (rval != QLA_SUCCESS) {
2366 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002367 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2368 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002369 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002370 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002371 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2372 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2373 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2374 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375
2376 if (cur_xchg_cnt)
2377 *cur_xchg_cnt = mcp->mb[3];
2378 if (orig_xchg_cnt)
2379 *orig_xchg_cnt = mcp->mb[6];
2380 if (cur_iocb_cnt)
2381 *cur_iocb_cnt = mcp->mb[7];
2382 if (orig_iocb_cnt)
2383 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002384 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002385 *max_npiv_vports = mcp->mb[11];
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002386 if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) && max_fcfs)
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002387 *max_fcfs = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002388 }
2389
2390 return (rval);
2391}
2392
Linus Torvalds1da177e2005-04-16 15:20:36 -07002393/*
2394 * qla2x00_get_fcal_position_map
2395 * Get FCAL (LILP) position map using mailbox command
2396 *
2397 * Input:
2398 * ha = adapter state pointer.
2399 * pos_map = buffer pointer (can be NULL).
2400 *
2401 * Returns:
2402 * qla2x00 local function return status code.
2403 *
2404 * Context:
2405 * Kernel context.
2406 */
2407int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002408qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409{
2410 int rval;
2411 mbx_cmd_t mc;
2412 mbx_cmd_t *mcp = &mc;
2413 char *pmap;
2414 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002415 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002417 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f,
2418 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002419
Andrew Vasquez4b892582008-09-11 21:22:48 -07002420 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002422 ql_log(ql_log_warn, vha, 0x1080,
2423 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424 return QLA_MEMORY_ALLOC_FAILED;
2425 }
2426 memset(pmap, 0, FCAL_MAP_SIZE);
2427
2428 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2429 mcp->mb[2] = MSW(pmap_dma);
2430 mcp->mb[3] = LSW(pmap_dma);
2431 mcp->mb[6] = MSW(MSD(pmap_dma));
2432 mcp->mb[7] = LSW(MSD(pmap_dma));
2433 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2434 mcp->in_mb = MBX_1|MBX_0;
2435 mcp->buf_size = FCAL_MAP_SIZE;
2436 mcp->flags = MBX_DMA_IN;
2437 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002438 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439
2440 if (rval == QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002441 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002442 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2443 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2444 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2445 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446
2447 if (pos_map)
2448 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2449 }
2450 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2451
2452 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002453 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002455 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083,
2456 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457 }
2458
2459 return rval;
2460}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002461
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002462/*
2463 * qla2x00_get_link_status
2464 *
2465 * Input:
2466 * ha = adapter block pointer.
2467 * loop_id = device loop ID.
2468 * ret_buf = pointer to link status return buffer.
2469 *
2470 * Returns:
2471 * 0 = success.
2472 * BIT_0 = mem alloc error.
2473 * BIT_1 = mailbox error.
2474 */
2475int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002476qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002477 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002478{
2479 int rval;
2480 mbx_cmd_t mc;
2481 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002482 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002483 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002484
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002485 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084,
2486 "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002487
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002488 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002489 mcp->mb[2] = MSW(stats_dma);
2490 mcp->mb[3] = LSW(stats_dma);
2491 mcp->mb[6] = MSW(MSD(stats_dma));
2492 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002493 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2494 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002495 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002496 mcp->mb[1] = loop_id;
2497 mcp->mb[4] = 0;
2498 mcp->mb[10] = 0;
2499 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2500 mcp->in_mb |= MBX_1;
2501 } else if (HAS_EXTENDED_IDS(ha)) {
2502 mcp->mb[1] = loop_id;
2503 mcp->mb[10] = 0;
2504 mcp->out_mb |= MBX_10|MBX_1;
2505 } else {
2506 mcp->mb[1] = loop_id << 8;
2507 mcp->out_mb |= MBX_1;
2508 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002509 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002510 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002511 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002512
2513 if (rval == QLA_SUCCESS) {
2514 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002515 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2516 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002517 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002518 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002519 /* Copy over data -- firmware data is LE. */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002520 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086,
2521 "Done %s.\n", __func__);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002522 dwords = offsetof(struct link_statistics, unused1) / 4;
2523 siter = diter = &stats->link_fail_cnt;
2524 while (dwords--)
2525 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002526 }
2527 } else {
2528 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002529 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002530 }
2531
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002532 return rval;
2533}
2534
2535int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002536qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002537 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002538{
2539 int rval;
2540 mbx_cmd_t mc;
2541 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002542 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002543
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002544 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,
2545 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002546
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002547 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002548 mcp->mb[2] = MSW(stats_dma);
2549 mcp->mb[3] = LSW(stats_dma);
2550 mcp->mb[6] = MSW(MSD(stats_dma));
2551 mcp->mb[7] = LSW(MSD(stats_dma));
2552 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002553 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002554 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002555 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 -07002556 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002557 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002558 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002559 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002560
2561 if (rval == QLA_SUCCESS) {
2562 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002563 ql_dbg(ql_dbg_mbx, vha, 0x1089,
2564 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002565 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002566 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002567 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a,
2568 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002569 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002570 dwords = sizeof(struct link_statistics) / 4;
2571 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002572 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002573 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002574 }
2575 } else {
2576 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002577 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002578 }
2579
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002580 return rval;
2581}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002582
2583int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002584qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002585{
2586 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002587 unsigned long flags = 0;
2588
2589 struct abort_entry_24xx *abt;
2590 dma_addr_t abt_dma;
2591 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002592 fc_port_t *fcport = sp->fcport;
2593 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002594 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07002595 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002596
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002597 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,
2598 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002599
Armen Baloyan4440e462014-02-26 04:15:18 -05002600 if (ql2xasynctmfenable)
2601 return qla24xx_async_abort_command(sp);
2602
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002603 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05002604 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002605 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002606 break;
2607 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002608 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05002609 if (handle == req->num_outstanding_cmds) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002610 /* Command not found. */
2611 return QLA_FUNCTION_FAILED;
2612 }
2613
2614 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2615 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002616 ql_log(ql_log_warn, vha, 0x108d,
2617 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002618 return QLA_MEMORY_ALLOC_FAILED;
2619 }
2620 memset(abt, 0, sizeof(struct abort_entry_24xx));
2621
2622 abt->entry_type = ABORT_IOCB_TYPE;
2623 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002624 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002625 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07002626 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002627 abt->port_id[0] = fcport->d_id.b.al_pa;
2628 abt->port_id[1] = fcport->d_id.b.area;
2629 abt->port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04002630 abt->vp_index = fcport->vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002631
2632 abt->req_que_no = cpu_to_le16(req->id);
2633
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002634 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002635 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002636 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2637 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002638 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002639 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2640 "Failed to complete IOCB -- error status (%x).\n",
2641 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002642 rval = QLA_FUNCTION_FAILED;
2643 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002644 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2645 "Failed to complete IOCB -- completion status (%x).\n",
2646 le16_to_cpu(abt->nport_handle));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002647 rval = QLA_FUNCTION_FAILED;
2648 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002649 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
2650 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002651 }
2652
2653 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2654
2655 return rval;
2656}
2657
2658struct tsk_mgmt_cmd {
2659 union {
2660 struct tsk_mgmt_entry tsk;
2661 struct sts_entry_24xx sts;
2662 } p;
2663};
2664
Andrew Vasquez523ec772008-04-03 13:13:24 -07002665static int
2666__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002667 unsigned int l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002668{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002669 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002670 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002671 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002672 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002673 scsi_qla_host_t *vha;
2674 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002675 struct req_que *req;
2676 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002677
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002678 vha = fcport->vha;
2679 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002680 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002681
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002682 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092,
2683 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002684
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002685 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002686 rsp = ha->rsp_q_map[tag + 1];
2687 else
2688 rsp = req->rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002689 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002690 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002691 ql_log(ql_log_warn, vha, 0x1093,
2692 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002693 return QLA_MEMORY_ALLOC_FAILED;
2694 }
2695 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2696
2697 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2698 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002699 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002700 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002701 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002702 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002703 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2704 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2705 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04002706 tsk->p.tsk.vp_index = fcport->vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002707 if (type == TCF_LUN_RESET) {
2708 int_to_scsilun(l, &tsk->p.tsk.lun);
2709 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2710 sizeof(tsk->p.tsk.lun));
2711 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002712
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002713 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002714 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002715 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002716 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2717 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002718 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002719 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2720 "Failed to complete IOCB -- error status (%x).\n",
2721 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002722 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002723 } else if (sts->comp_status !=
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002724 __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002725 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2726 "Failed to complete IOCB -- completion status (%x).\n",
2727 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002728 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08002729 } else if (le16_to_cpu(sts->scsi_status) &
2730 SS_RESPONSE_INFO_LEN_VALID) {
2731 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002732 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002733 "Ignoring inconsistent data length -- not enough "
2734 "response info (%d).\n",
2735 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08002736 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002737 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2738 "Failed to complete IOCB -- response (%x).\n",
2739 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08002740 rval = QLA_FUNCTION_FAILED;
2741 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002742 }
2743
2744 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002745 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002746 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2747 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002748 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2749 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002750 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002751 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a,
2752 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002753 }
2754
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002755 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002756
2757 return rval;
2758}
2759
Andrew Vasquez523ec772008-04-03 13:13:24 -07002760int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002761qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002762{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002763 struct qla_hw_data *ha = fcport->vha->hw;
2764
2765 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2766 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2767
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002768 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002769}
2770
2771int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002772qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002773{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002774 struct qla_hw_data *ha = fcport->vha->hw;
2775
2776 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2777 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2778
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002779 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002780}
2781
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002782int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002783qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002784{
2785 int rval;
2786 mbx_cmd_t mc;
2787 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002788 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002789
Andrew Vasquez68af0812008-05-12 22:21:13 -07002790 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002791 return QLA_FUNCTION_FAILED;
2792
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002793 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b,
2794 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002795
2796 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2797 mcp->out_mb = MBX_0;
2798 mcp->in_mb = MBX_0;
2799 mcp->tov = 5;
2800 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002801 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002802
2803 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002804 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002805 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002806 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d,
2807 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002808 }
2809
2810 return rval;
2811}
2812
Joe Carnucciodb64e932013-10-30 03:38:18 -04002813int
2814qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data)
2815{
2816 int rval;
2817 mbx_cmd_t mc;
2818 mbx_cmd_t *mcp = &mc;
2819
2820 if (!IS_QLA2031(vha->hw))
2821 return QLA_FUNCTION_FAILED;
2822
2823 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182,
2824 "Entered %s.\n", __func__);
2825
2826 mcp->mb[0] = MBC_WRITE_SERDES;
2827 mcp->mb[1] = addr;
2828 mcp->mb[2] = data & 0xff;
2829 mcp->mb[3] = 0;
2830 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2831 mcp->in_mb = MBX_0;
2832 mcp->tov = MBX_TOV_SECONDS;
2833 mcp->flags = 0;
2834 rval = qla2x00_mailbox_command(vha, mcp);
2835
2836 if (rval != QLA_SUCCESS) {
2837 ql_dbg(ql_dbg_mbx, vha, 0x1183,
2838 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
2839 } else {
2840 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184,
2841 "Done %s.\n", __func__);
2842 }
2843
2844 return rval;
2845}
2846
2847int
2848qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)
2849{
2850 int rval;
2851 mbx_cmd_t mc;
2852 mbx_cmd_t *mcp = &mc;
2853
2854 if (!IS_QLA2031(vha->hw))
2855 return QLA_FUNCTION_FAILED;
2856
2857 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185,
2858 "Entered %s.\n", __func__);
2859
2860 mcp->mb[0] = MBC_READ_SERDES;
2861 mcp->mb[1] = addr;
2862 mcp->mb[3] = 0;
2863 mcp->out_mb = MBX_3|MBX_1|MBX_0;
2864 mcp->in_mb = MBX_1|MBX_0;
2865 mcp->tov = MBX_TOV_SECONDS;
2866 mcp->flags = 0;
2867 rval = qla2x00_mailbox_command(vha, mcp);
2868
2869 *data = mcp->mb[1] & 0xff;
2870
2871 if (rval != QLA_SUCCESS) {
2872 ql_dbg(ql_dbg_mbx, vha, 0x1186,
2873 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
2874 } else {
2875 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187,
2876 "Done %s.\n", __func__);
2877 }
2878
2879 return rval;
2880}
2881
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002882/**
2883 * qla2x00_set_serdes_params() -
2884 * @ha: HA context
2885 *
2886 * Returns
2887 */
2888int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002889qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002890 uint16_t sw_em_2g, uint16_t sw_em_4g)
2891{
2892 int rval;
2893 mbx_cmd_t mc;
2894 mbx_cmd_t *mcp = &mc;
2895
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002896 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e,
2897 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002898
2899 mcp->mb[0] = MBC_SERDES_PARAMS;
2900 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08002901 mcp->mb[2] = sw_em_1g | BIT_15;
2902 mcp->mb[3] = sw_em_2g | BIT_15;
2903 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002904 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2905 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002906 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002907 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002908 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002909
2910 if (rval != QLA_SUCCESS) {
2911 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002912 ql_dbg(ql_dbg_mbx, vha, 0x109f,
2913 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002914 } else {
2915 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002916 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0,
2917 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002918 }
2919
2920 return rval;
2921}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002922
2923int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002924qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002925{
2926 int rval;
2927 mbx_cmd_t mc;
2928 mbx_cmd_t *mcp = &mc;
2929
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002930 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002931 return QLA_FUNCTION_FAILED;
2932
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002933 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1,
2934 "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002935
2936 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08002937 mcp->mb[1] = 0;
2938 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002939 mcp->in_mb = MBX_0;
2940 mcp->tov = 5;
2941 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002942 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002943
2944 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002945 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07002946 if (mcp->mb[0] == MBS_INVALID_COMMAND)
2947 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002948 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002949 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3,
2950 "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002951 }
2952
2953 return rval;
2954}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002955
2956int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002957qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002958 uint16_t buffers)
2959{
2960 int rval;
2961 mbx_cmd_t mc;
2962 mbx_cmd_t *mcp = &mc;
2963
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002964 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4,
2965 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002966
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002967 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002968 return QLA_FUNCTION_FAILED;
2969
Andrew Vasquez85880802009-12-15 21:29:46 -08002970 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2971 return QLA_FUNCTION_FAILED;
2972
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002973 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002974 mcp->mb[1] = TC_EFT_ENABLE;
2975 mcp->mb[2] = LSW(eft_dma);
2976 mcp->mb[3] = MSW(eft_dma);
2977 mcp->mb[4] = LSW(MSD(eft_dma));
2978 mcp->mb[5] = MSW(MSD(eft_dma));
2979 mcp->mb[6] = buffers;
2980 mcp->mb[7] = TC_AEN_DISABLE;
2981 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 -07002982 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002983 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002984 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002985 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002986 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002987 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
2988 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2989 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002990 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002991 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6,
2992 "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002993 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002994
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002995 return rval;
2996}
2997
2998int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002999qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003000{
3001 int rval;
3002 mbx_cmd_t mc;
3003 mbx_cmd_t *mcp = &mc;
3004
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003005 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7,
3006 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003007
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003008 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003009 return QLA_FUNCTION_FAILED;
3010
Andrew Vasquez85880802009-12-15 21:29:46 -08003011 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3012 return QLA_FUNCTION_FAILED;
3013
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003014 mcp->mb[0] = MBC_TRACE_CONTROL;
3015 mcp->mb[1] = TC_EFT_DISABLE;
3016 mcp->out_mb = MBX_1|MBX_0;
3017 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003018 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003019 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003020 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003021 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003022 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
3023 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3024 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003025 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003026 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9,
3027 "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003028 }
3029
3030 return rval;
3031}
3032
Andrew Vasquez88729e52006-06-23 16:10:50 -07003033int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003034qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003035 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
3036{
3037 int rval;
3038 mbx_cmd_t mc;
3039 mbx_cmd_t *mcp = &mc;
3040
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003041 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa,
3042 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003043
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003044 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
Chad Dupuisf73cb692014-02-26 04:15:06 -05003045 !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003046 return QLA_FUNCTION_FAILED;
3047
Andrew Vasquez85880802009-12-15 21:29:46 -08003048 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3049 return QLA_FUNCTION_FAILED;
3050
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003051 mcp->mb[0] = MBC_TRACE_CONTROL;
3052 mcp->mb[1] = TC_FCE_ENABLE;
3053 mcp->mb[2] = LSW(fce_dma);
3054 mcp->mb[3] = MSW(fce_dma);
3055 mcp->mb[4] = LSW(MSD(fce_dma));
3056 mcp->mb[5] = MSW(MSD(fce_dma));
3057 mcp->mb[6] = buffers;
3058 mcp->mb[7] = TC_AEN_DISABLE;
3059 mcp->mb[8] = 0;
3060 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
3061 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
3062 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3063 MBX_1|MBX_0;
3064 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003065 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003066 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003067 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003068 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003069 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
3070 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3071 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003072 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003073 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac,
3074 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003075
3076 if (mb)
3077 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
3078 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07003079 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003080 }
3081
3082 return rval;
3083}
3084
3085int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003086qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003087{
3088 int rval;
3089 mbx_cmd_t mc;
3090 mbx_cmd_t *mcp = &mc;
3091
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003092 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad,
3093 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003094
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003095 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003096 return QLA_FUNCTION_FAILED;
3097
Andrew Vasquez85880802009-12-15 21:29:46 -08003098 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3099 return QLA_FUNCTION_FAILED;
3100
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003101 mcp->mb[0] = MBC_TRACE_CONTROL;
3102 mcp->mb[1] = TC_FCE_DISABLE;
3103 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
3104 mcp->out_mb = MBX_2|MBX_1|MBX_0;
3105 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3106 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003107 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003108 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003109 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003110 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003111 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
3112 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3113 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003114 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003115 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af,
3116 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003117
3118 if (wr)
3119 *wr = (uint64_t) mcp->mb[5] << 48 |
3120 (uint64_t) mcp->mb[4] << 32 |
3121 (uint64_t) mcp->mb[3] << 16 |
3122 (uint64_t) mcp->mb[2];
3123 if (rd)
3124 *rd = (uint64_t) mcp->mb[9] << 48 |
3125 (uint64_t) mcp->mb[8] << 32 |
3126 (uint64_t) mcp->mb[7] << 16 |
3127 (uint64_t) mcp->mb[6];
3128 }
3129
3130 return rval;
3131}
3132
3133int
Giridhar Malavali6e980162010-03-19 17:03:58 -07003134qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
3135 uint16_t *port_speed, uint16_t *mb)
3136{
3137 int rval;
3138 mbx_cmd_t mc;
3139 mbx_cmd_t *mcp = &mc;
3140
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003141 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0,
3142 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003143
Giridhar Malavali6e980162010-03-19 17:03:58 -07003144 if (!IS_IIDMA_CAPABLE(vha->hw))
3145 return QLA_FUNCTION_FAILED;
3146
Giridhar Malavali6e980162010-03-19 17:03:58 -07003147 mcp->mb[0] = MBC_PORT_PARAMS;
3148 mcp->mb[1] = loop_id;
3149 mcp->mb[2] = mcp->mb[3] = 0;
3150 mcp->mb[9] = vha->vp_idx;
3151 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3152 mcp->in_mb = MBX_3|MBX_1|MBX_0;
3153 mcp->tov = MBX_TOV_SECONDS;
3154 mcp->flags = 0;
3155 rval = qla2x00_mailbox_command(vha, mcp);
3156
3157 /* Return mailbox statuses. */
3158 if (mb != NULL) {
3159 mb[0] = mcp->mb[0];
3160 mb[1] = mcp->mb[1];
3161 mb[3] = mcp->mb[3];
3162 }
3163
3164 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003165 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003166 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003167 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2,
3168 "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003169 if (port_speed)
3170 *port_speed = mcp->mb[3];
3171 }
3172
3173 return rval;
3174}
3175
3176int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003177qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003178 uint16_t port_speed, uint16_t *mb)
3179{
3180 int rval;
3181 mbx_cmd_t mc;
3182 mbx_cmd_t *mcp = &mc;
3183
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003184 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3,
3185 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003186
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003187 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003188 return QLA_FUNCTION_FAILED;
3189
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003190 mcp->mb[0] = MBC_PORT_PARAMS;
3191 mcp->mb[1] = loop_id;
3192 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003193 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07003194 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
3195 else
3196 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
3197 mcp->mb[9] = vha->vp_idx;
3198 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3199 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003200 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003201 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003202 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003203
3204 /* Return mailbox statuses. */
3205 if (mb != NULL) {
3206 mb[0] = mcp->mb[0];
3207 mb[1] = mcp->mb[1];
3208 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003209 }
3210
3211 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003212 ql_dbg(ql_dbg_mbx, vha, 0x10b4,
3213 "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003214 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003215 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5,
3216 "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003217 }
3218
3219 return rval;
3220}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003221
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003222void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003223qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003224 struct vp_rpt_id_entry_24xx *rptid_entry)
3225{
3226 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07003227 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003228 struct qla_hw_data *ha = vha->hw;
3229 scsi_qla_host_t *vp;
Arun Easifeafb7b2010-09-03 14:57:00 -07003230 unsigned long flags;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003231 int found;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003232
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003233 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
3234 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003235
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003236 if (rptid_entry->entry_status != 0)
3237 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003238
3239 if (rptid_entry->format == 0) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003240 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003241 "Format 0 : Number of VPs setup %d, number of "
3242 "VPs acquired %d.\n",
3243 MSB(le16_to_cpu(rptid_entry->vp_count)),
3244 LSB(le16_to_cpu(rptid_entry->vp_count)));
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003245 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b8,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003246 "Primary port id %02x%02x%02x.\n",
3247 rptid_entry->port_id[2], rptid_entry->port_id[1],
3248 rptid_entry->port_id[0]);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003249 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07003250 vp_idx = LSB(stat);
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003251 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b9,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003252 "Format 1: VP[%d] enabled - status %d - with "
3253 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003254 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003255 rptid_entry->port_id[0]);
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003256
3257 vp = vha;
3258 if (vp_idx == 0 && (MSB(stat) != 1))
3259 goto reg_needed;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003260
Saurav Kashyap681e0142012-11-21 02:40:28 -05003261 if (MSB(stat) != 0 && MSB(stat) != 2) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003262 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
3263 "Could not acquire ID for VP[%d].\n", vp_idx);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003264 return;
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07003265 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003266
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003267 found = 0;
Arun Easifeafb7b2010-09-03 14:57:00 -07003268 spin_lock_irqsave(&ha->vport_slock, flags);
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003269 list_for_each_entry(vp, &ha->vp_list, list) {
3270 if (vp_idx == vp->vp_idx) {
3271 found = 1;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003272 break;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003273 }
3274 }
Arun Easifeafb7b2010-09-03 14:57:00 -07003275 spin_unlock_irqrestore(&ha->vport_slock, flags);
3276
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003277 if (!found)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003278 return;
3279
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003280 vp->d_id.b.domain = rptid_entry->port_id[2];
3281 vp->d_id.b.area = rptid_entry->port_id[1];
3282 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003283
3284 /*
3285 * Cannot configure here as we are still sitting on the
3286 * response queue. Handle it in dpc context.
3287 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003288 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003289
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003290reg_needed:
3291 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
3292 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
3293 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003294 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003295 }
3296}
3297
3298/*
3299 * qla24xx_modify_vp_config
3300 * Change VP configuration for vha
3301 *
3302 * Input:
3303 * vha = adapter block pointer.
3304 *
3305 * Returns:
3306 * qla2xxx local function return status code.
3307 *
3308 * Context:
3309 * Kernel context.
3310 */
3311int
3312qla24xx_modify_vp_config(scsi_qla_host_t *vha)
3313{
3314 int rval;
3315 struct vp_config_entry_24xx *vpmod;
3316 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003317 struct qla_hw_data *ha = vha->hw;
3318 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003319
3320 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003321
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003322 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb,
3323 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003324
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003325 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003326 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003327 ql_log(ql_log_warn, vha, 0x10bc,
3328 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003329 return QLA_MEMORY_ALLOC_FAILED;
3330 }
3331
3332 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
3333 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
3334 vpmod->entry_count = 1;
3335 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
3336 vpmod->vp_count = 1;
3337 vpmod->vp_index1 = vha->vp_idx;
3338 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04003339
3340 qlt_modify_vp_config(vha, vpmod);
3341
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003342 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
3343 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
3344 vpmod->entry_count = 1;
3345
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003346 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003347 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003348 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
3349 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003350 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003351 ql_dbg(ql_dbg_mbx, vha, 0x10be,
3352 "Failed to complete IOCB -- error status (%x).\n",
3353 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003354 rval = QLA_FUNCTION_FAILED;
3355 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003356 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3357 "Failed to complete IOCB -- completion status (%x).\n",
3358 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003359 rval = QLA_FUNCTION_FAILED;
3360 } else {
3361 /* EMPTY */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003362 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0,
3363 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003364 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3365 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003366 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003367
3368 return rval;
3369}
3370
3371/*
3372 * qla24xx_control_vp
3373 * Enable a virtual port for given host
3374 *
3375 * Input:
3376 * ha = adapter block pointer.
3377 * vhba = virtual adapter (unused)
3378 * index = index number for enabled VP
3379 *
3380 * Returns:
3381 * qla2xxx local function return status code.
3382 *
3383 * Context:
3384 * Kernel context.
3385 */
3386int
3387qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
3388{
3389 int rval;
3390 int map, pos;
3391 struct vp_ctrl_entry_24xx *vce;
3392 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003393 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003394 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003395 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003396
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003397 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c1,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003398 "Entered %s enabling index %d.\n", __func__, vp_index);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003399
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08003400 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003401 return QLA_PARAMETER_ERROR;
3402
3403 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3404 if (!vce) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003405 ql_log(ql_log_warn, vha, 0x10c2,
3406 "Failed to allocate VP control IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003407 return QLA_MEMORY_ALLOC_FAILED;
3408 }
3409 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3410
3411 vce->entry_type = VP_CTRL_IOCB_TYPE;
3412 vce->entry_count = 1;
3413 vce->command = cpu_to_le16(cmd);
3414 vce->vp_count = __constant_cpu_to_le16(1);
3415
3416 /* index map in firmware starts with 1; decrement index
3417 * this is ok as we never use index 0
3418 */
3419 map = (vp_index - 1) / 8;
3420 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003421 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003422 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003423 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003424
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003425 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003426 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003427 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3428 "Failed to issue VP control IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003429 } else if (vce->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003430 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3431 "Failed to complete IOCB -- error status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003432 vce->entry_status);
3433 rval = QLA_FUNCTION_FAILED;
3434 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003435 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3436 "Failed to complet IOCB -- completion status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003437 le16_to_cpu(vce->comp_status));
3438 rval = QLA_FUNCTION_FAILED;
3439 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003440 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c6,
3441 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003442 }
3443
3444 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3445
3446 return rval;
3447}
3448
3449/*
3450 * qla2x00_send_change_request
3451 * Receive or disable RSCN request from fabric controller
3452 *
3453 * Input:
3454 * ha = adapter block pointer
3455 * format = registration format:
3456 * 0 - Reserved
3457 * 1 - Fabric detected registration
3458 * 2 - N_port detected registration
3459 * 3 - Full registration
3460 * FF - clear registration
3461 * vp_idx = Virtual port index
3462 *
3463 * Returns:
3464 * qla2x00 local function return status code.
3465 *
3466 * Context:
3467 * Kernel Context
3468 */
3469
3470int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003471qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003472 uint16_t vp_idx)
3473{
3474 int rval;
3475 mbx_cmd_t mc;
3476 mbx_cmd_t *mcp = &mc;
3477
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003478 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7,
3479 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003480
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003481 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3482 mcp->mb[1] = format;
3483 mcp->mb[9] = vp_idx;
3484 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3485 mcp->in_mb = MBX_0|MBX_1;
3486 mcp->tov = MBX_TOV_SECONDS;
3487 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003488 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003489
3490 if (rval == QLA_SUCCESS) {
3491 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3492 rval = BIT_1;
3493 }
3494 } else
3495 rval = BIT_1;
3496
3497 return rval;
3498}
Andrew Vasquez338c9162007-09-20 14:07:33 -07003499
3500int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003501qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07003502 uint32_t size)
3503{
3504 int rval;
3505 mbx_cmd_t mc;
3506 mbx_cmd_t *mcp = &mc;
3507
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003508 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009,
3509 "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003510
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003511 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003512 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3513 mcp->mb[8] = MSW(addr);
3514 mcp->out_mb = MBX_8|MBX_0;
3515 } else {
3516 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3517 mcp->out_mb = MBX_0;
3518 }
3519 mcp->mb[1] = LSW(addr);
3520 mcp->mb[2] = MSW(req_dma);
3521 mcp->mb[3] = LSW(req_dma);
3522 mcp->mb[6] = MSW(MSD(req_dma));
3523 mcp->mb[7] = LSW(MSD(req_dma));
3524 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003525 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003526 mcp->mb[4] = MSW(size);
3527 mcp->mb[5] = LSW(size);
3528 mcp->out_mb |= MBX_5|MBX_4;
3529 } else {
3530 mcp->mb[4] = LSW(size);
3531 mcp->out_mb |= MBX_4;
3532 }
3533
3534 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003535 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07003536 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003537 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003538
3539 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003540 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3541 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003542 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003543 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007,
3544 "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003545 }
3546
3547 return rval;
3548}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003549/* 84XX Support **************************************************************/
3550
3551struct cs84xx_mgmt_cmd {
3552 union {
3553 struct verify_chip_entry_84xx req;
3554 struct verify_chip_rsp_84xx rsp;
3555 } p;
3556};
3557
3558int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003559qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003560{
3561 int rval, retry;
3562 struct cs84xx_mgmt_cmd *mn;
3563 dma_addr_t mn_dma;
3564 uint16_t options;
3565 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003566 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003567
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003568 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8,
3569 "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003570
3571 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3572 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003573 return QLA_MEMORY_ALLOC_FAILED;
3574 }
3575
3576 /* Force Update? */
3577 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3578 /* Diagnostic firmware? */
3579 /* options |= MENLO_DIAG_FW; */
3580 /* We update the firmware with only one data sequence. */
3581 options |= VCO_END_OF_DATA;
3582
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003583 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003584 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003585 memset(mn, 0, sizeof(*mn));
3586 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3587 mn->p.req.entry_count = 1;
3588 mn->p.req.options = cpu_to_le16(options);
3589
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003590 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3591 "Dump of Verify Request.\n");
3592 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3593 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003594
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003595 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003596 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003597 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3598 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003599 goto verify_done;
3600 }
3601
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003602 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3603 "Dump of Verify Response.\n");
3604 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3605 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003606
3607 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3608 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3609 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003610 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003611 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003612
3613 if (status[0] != CS_COMPLETE) {
3614 rval = QLA_FUNCTION_FAILED;
3615 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003616 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3617 "Firmware update failed. Retrying "
3618 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003619 options |= VCO_DONT_UPDATE_FW;
3620 options &= ~VCO_FORCE_UPDATE;
3621 retry = 1;
3622 }
3623 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003624 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003625 "Firmware updated to %x.\n",
3626 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003627
3628 /* NOTE: we only update OP firmware. */
3629 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3630 ha->cs84xx->op_fw_version =
3631 le32_to_cpu(mn->p.rsp.fw_ver);
3632 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3633 flags);
3634 }
3635 } while (retry);
3636
3637verify_done:
3638 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3639
3640 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003641 ql_dbg(ql_dbg_mbx, vha, 0x10d1,
3642 "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003643 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003644 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2,
3645 "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003646 }
3647
3648 return rval;
3649}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003650
3651int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003652qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003653{
3654 int rval;
3655 unsigned long flags;
3656 mbx_cmd_t mc;
3657 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003658 struct qla_hw_data *ha = vha->hw;
3659
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003660 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
3661 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003662
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003663 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003664 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003665 mcp->mb[2] = MSW(LSD(req->dma));
3666 mcp->mb[3] = LSW(LSD(req->dma));
3667 mcp->mb[6] = MSW(MSD(req->dma));
3668 mcp->mb[7] = LSW(MSD(req->dma));
3669 mcp->mb[5] = req->length;
3670 if (req->rsp)
3671 mcp->mb[10] = req->rsp->id;
3672 mcp->mb[12] = req->qos;
3673 mcp->mb[11] = req->vp_idx;
3674 mcp->mb[13] = req->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003675 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003676 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003677
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003678 mcp->mb[4] = req->id;
3679 /* que in ptr index */
3680 mcp->mb[8] = 0;
3681 /* que out ptr index */
3682 mcp->mb[9] = 0;
3683 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3684 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3685 mcp->in_mb = MBX_0;
3686 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003687 mcp->tov = MBX_TOV_SECONDS * 2;
3688
Chad Dupuisf73cb692014-02-26 04:15:06 -05003689 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003690 mcp->in_mb |= MBX_1;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003691 if (IS_QLA83XX(ha) || !IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003692 mcp->out_mb |= MBX_15;
3693 /* debug q create issue in SR-IOV */
3694 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3695 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003696
3697 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003698 if (!(req->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003699 WRT_REG_DWORD(req->req_q_in, 0);
Chad Dupuisf73cb692014-02-26 04:15:06 -05003700 if (!IS_QLA83XX(ha) || !IS_QLA27XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003701 WRT_REG_DWORD(req->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003702 }
3703 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3704
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003705 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003706 if (rval != QLA_SUCCESS) {
3707 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3708 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3709 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003710 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5,
3711 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003712 }
3713
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003714 return rval;
3715}
3716
3717int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003718qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003719{
3720 int rval;
3721 unsigned long flags;
3722 mbx_cmd_t mc;
3723 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003724 struct qla_hw_data *ha = vha->hw;
3725
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003726 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
3727 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003728
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003729 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003730 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003731 mcp->mb[2] = MSW(LSD(rsp->dma));
3732 mcp->mb[3] = LSW(LSD(rsp->dma));
3733 mcp->mb[6] = MSW(MSD(rsp->dma));
3734 mcp->mb[7] = LSW(MSD(rsp->dma));
3735 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003736 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003737 mcp->mb[13] = rsp->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003738 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003739 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003740
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003741 mcp->mb[4] = rsp->id;
3742 /* que in ptr index */
3743 mcp->mb[8] = 0;
3744 /* que out ptr index */
3745 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003746 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003747 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3748 mcp->in_mb = MBX_0;
3749 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003750 mcp->tov = MBX_TOV_SECONDS * 2;
3751
3752 if (IS_QLA81XX(ha)) {
3753 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
3754 mcp->in_mb |= MBX_1;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003755 } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003756 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
3757 mcp->in_mb |= MBX_1;
3758 /* debug q create issue in SR-IOV */
3759 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3760 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003761
3762 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003763 if (!(rsp->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003764 WRT_REG_DWORD(rsp->rsp_q_out, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003765 if (!IS_QLA83XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003766 WRT_REG_DWORD(rsp->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003767 }
3768
3769 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3770
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003771 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003772 if (rval != QLA_SUCCESS) {
3773 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
3774 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3775 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003776 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8,
3777 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003778 }
3779
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003780 return rval;
3781}
3782
Andrew Vasquez8a659572009-02-08 20:50:12 -08003783int
3784qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3785{
3786 int rval;
3787 mbx_cmd_t mc;
3788 mbx_cmd_t *mcp = &mc;
3789
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003790 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9,
3791 "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003792
3793 mcp->mb[0] = MBC_IDC_ACK;
3794 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3795 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3796 mcp->in_mb = MBX_0;
3797 mcp->tov = MBX_TOV_SECONDS;
3798 mcp->flags = 0;
3799 rval = qla2x00_mailbox_command(vha, mcp);
3800
3801 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003802 ql_dbg(ql_dbg_mbx, vha, 0x10da,
3803 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003804 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003805 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db,
3806 "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003807 }
3808
3809 return rval;
3810}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003811
3812int
3813qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3814{
3815 int rval;
3816 mbx_cmd_t mc;
3817 mbx_cmd_t *mcp = &mc;
3818
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003819 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc,
3820 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003821
Chad Dupuisf73cb692014-02-26 04:15:06 -05003822 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
3823 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003824 return QLA_FUNCTION_FAILED;
3825
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003826 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3827 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3828 mcp->out_mb = MBX_1|MBX_0;
3829 mcp->in_mb = MBX_1|MBX_0;
3830 mcp->tov = MBX_TOV_SECONDS;
3831 mcp->flags = 0;
3832 rval = qla2x00_mailbox_command(vha, mcp);
3833
3834 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003835 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
3836 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3837 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003838 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003839 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de,
3840 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003841 *sector_size = mcp->mb[1];
3842 }
3843
3844 return rval;
3845}
3846
3847int
3848qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3849{
3850 int rval;
3851 mbx_cmd_t mc;
3852 mbx_cmd_t *mcp = &mc;
3853
Chad Dupuisf73cb692014-02-26 04:15:06 -05003854 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
3855 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003856 return QLA_FUNCTION_FAILED;
3857
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003858 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df,
3859 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003860
3861 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3862 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3863 FAC_OPT_CMD_WRITE_PROTECT;
3864 mcp->out_mb = MBX_1|MBX_0;
3865 mcp->in_mb = MBX_1|MBX_0;
3866 mcp->tov = MBX_TOV_SECONDS;
3867 mcp->flags = 0;
3868 rval = qla2x00_mailbox_command(vha, mcp);
3869
3870 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003871 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
3872 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3873 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003874 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003875 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1,
3876 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003877 }
3878
3879 return rval;
3880}
3881
3882int
3883qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3884{
3885 int rval;
3886 mbx_cmd_t mc;
3887 mbx_cmd_t *mcp = &mc;
3888
Chad Dupuisf73cb692014-02-26 04:15:06 -05003889 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
3890 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003891 return QLA_FUNCTION_FAILED;
3892
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003893 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,
3894 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003895
3896 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3897 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3898 mcp->mb[2] = LSW(start);
3899 mcp->mb[3] = MSW(start);
3900 mcp->mb[4] = LSW(finish);
3901 mcp->mb[5] = MSW(finish);
3902 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3903 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3904 mcp->tov = MBX_TOV_SECONDS;
3905 mcp->flags = 0;
3906 rval = qla2x00_mailbox_command(vha, mcp);
3907
3908 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003909 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
3910 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3911 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003912 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003913 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,
3914 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003915 }
3916
3917 return rval;
3918}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003919
3920int
3921qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3922{
3923 int rval = 0;
3924 mbx_cmd_t mc;
3925 mbx_cmd_t *mcp = &mc;
3926
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003927 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5,
3928 "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003929
3930 mcp->mb[0] = MBC_RESTART_MPI_FW;
3931 mcp->out_mb = MBX_0;
3932 mcp->in_mb = MBX_0|MBX_1;
3933 mcp->tov = MBX_TOV_SECONDS;
3934 mcp->flags = 0;
3935 rval = qla2x00_mailbox_command(vha, mcp);
3936
3937 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003938 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
3939 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3940 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003941 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003942 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7,
3943 "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003944 }
3945
3946 return rval;
3947}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003948
Joe Carnuccioc46e65c2013-08-27 01:37:35 -04003949int
3950qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version)
3951{
3952 int rval;
3953 mbx_cmd_t mc;
3954 mbx_cmd_t *mcp = &mc;
3955 int i;
3956 int len;
3957 uint16_t *str;
3958 struct qla_hw_data *ha = vha->hw;
3959
3960 if (!IS_P3P_TYPE(ha))
3961 return QLA_FUNCTION_FAILED;
3962
3963 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b,
3964 "Entered %s.\n", __func__);
3965
3966 str = (void *)version;
3967 len = strlen(version);
3968
3969 mcp->mb[0] = MBC_SET_RNID_PARAMS;
3970 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8;
3971 mcp->out_mb = MBX_1|MBX_0;
3972 for (i = 4; i < 16 && len; i++, str++, len -= 2) {
3973 mcp->mb[i] = cpu_to_le16p(str);
3974 mcp->out_mb |= 1<<i;
3975 }
3976 for (; i < 16; i++) {
3977 mcp->mb[i] = 0;
3978 mcp->out_mb |= 1<<i;
3979 }
3980 mcp->in_mb = MBX_1|MBX_0;
3981 mcp->tov = MBX_TOV_SECONDS;
3982 mcp->flags = 0;
3983 rval = qla2x00_mailbox_command(vha, mcp);
3984
3985 if (rval != QLA_SUCCESS) {
3986 ql_dbg(ql_dbg_mbx, vha, 0x117c,
3987 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
3988 } else {
3989 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d,
3990 "Done %s.\n", __func__);
3991 }
3992
3993 return rval;
3994}
3995
3996int
3997qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version)
3998{
3999 int rval;
4000 mbx_cmd_t mc;
4001 mbx_cmd_t *mcp = &mc;
4002 int len;
4003 uint16_t dwlen;
4004 uint8_t *str;
4005 dma_addr_t str_dma;
4006 struct qla_hw_data *ha = vha->hw;
4007
4008 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) ||
4009 IS_P3P_TYPE(ha))
4010 return QLA_FUNCTION_FAILED;
4011
4012 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e,
4013 "Entered %s.\n", __func__);
4014
4015 str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);
4016 if (!str) {
4017 ql_log(ql_log_warn, vha, 0x117f,
4018 "Failed to allocate driver version param.\n");
4019 return QLA_MEMORY_ALLOC_FAILED;
4020 }
4021
4022 memcpy(str, "\x7\x3\x11\x0", 4);
4023 dwlen = str[0];
4024 len = dwlen * 4 - 4;
4025 memset(str + 4, 0, len);
4026 if (len > strlen(version))
4027 len = strlen(version);
4028 memcpy(str + 4, version, len);
4029
4030 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4031 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;
4032 mcp->mb[2] = MSW(LSD(str_dma));
4033 mcp->mb[3] = LSW(LSD(str_dma));
4034 mcp->mb[6] = MSW(MSD(str_dma));
4035 mcp->mb[7] = LSW(MSD(str_dma));
4036 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4037 mcp->in_mb = MBX_1|MBX_0;
4038 mcp->tov = MBX_TOV_SECONDS;
4039 mcp->flags = 0;
4040 rval = qla2x00_mailbox_command(vha, mcp);
4041
4042 if (rval != QLA_SUCCESS) {
4043 ql_dbg(ql_dbg_mbx, vha, 0x1180,
4044 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4045 } else {
4046 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181,
4047 "Done %s.\n", __func__);
4048 }
4049
4050 dma_pool_free(ha->s_dma_pool, str, str_dma);
4051
4052 return rval;
4053}
4054
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004055static int
4056qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
4057{
4058 int rval;
4059 mbx_cmd_t mc;
4060 mbx_cmd_t *mcp = &mc;
4061
4062 if (!IS_FWI2_CAPABLE(vha->hw))
4063 return QLA_FUNCTION_FAILED;
4064
4065 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4066 "Entered %s.\n", __func__);
4067
4068 mcp->mb[0] = MBC_GET_RNID_PARAMS;
4069 mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8;
4070 mcp->out_mb = MBX_1|MBX_0;
4071 mcp->in_mb = MBX_1|MBX_0;
4072 mcp->tov = MBX_TOV_SECONDS;
4073 mcp->flags = 0;
4074 rval = qla2x00_mailbox_command(vha, mcp);
4075 *temp = mcp->mb[1];
4076
4077 if (rval != QLA_SUCCESS) {
4078 ql_dbg(ql_dbg_mbx, vha, 0x115a,
4079 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4080 } else {
4081 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4082 "Done %s.\n", __func__);
4083 }
4084
4085 return rval;
4086}
4087
Joe Carnuccio3a117112013-02-08 01:58:00 -05004088int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004089qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4090 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004091{
4092 int rval;
4093 mbx_cmd_t mc;
4094 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004095 struct qla_hw_data *ha = vha->hw;
4096
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004097 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,
4098 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004099
Joe Carnuccio6766df92011-05-10 11:30:15 -07004100 if (!IS_FWI2_CAPABLE(ha))
4101 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004102
Joe Carnuccio6766df92011-05-10 11:30:15 -07004103 if (len == 1)
4104 opt |= BIT_0;
4105
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004106 mcp->mb[0] = MBC_READ_SFP;
4107 mcp->mb[1] = dev;
4108 mcp->mb[2] = MSW(sfp_dma);
4109 mcp->mb[3] = LSW(sfp_dma);
4110 mcp->mb[6] = MSW(MSD(sfp_dma));
4111 mcp->mb[7] = LSW(MSD(sfp_dma));
4112 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004113 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004114 mcp->mb[10] = opt;
4115 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 -07004116 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004117 mcp->tov = MBX_TOV_SECONDS;
4118 mcp->flags = 0;
4119 rval = qla2x00_mailbox_command(vha, mcp);
4120
4121 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004122 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004123
4124 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004125 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
4126 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004127 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004128 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
4129 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004130 }
4131
4132 return rval;
4133}
4134
4135int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004136qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4137 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004138{
4139 int rval;
4140 mbx_cmd_t mc;
4141 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004142 struct qla_hw_data *ha = vha->hw;
4143
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004144 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb,
4145 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004146
Joe Carnuccio6766df92011-05-10 11:30:15 -07004147 if (!IS_FWI2_CAPABLE(ha))
4148 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004149
Joe Carnuccio6766df92011-05-10 11:30:15 -07004150 if (len == 1)
4151 opt |= BIT_0;
4152
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004153 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004154 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004155
4156 mcp->mb[0] = MBC_WRITE_SFP;
4157 mcp->mb[1] = dev;
4158 mcp->mb[2] = MSW(sfp_dma);
4159 mcp->mb[3] = LSW(sfp_dma);
4160 mcp->mb[6] = MSW(MSD(sfp_dma));
4161 mcp->mb[7] = LSW(MSD(sfp_dma));
4162 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004163 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004164 mcp->mb[10] = opt;
4165 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 -07004166 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004167 mcp->tov = MBX_TOV_SECONDS;
4168 mcp->flags = 0;
4169 rval = qla2x00_mailbox_command(vha, mcp);
4170
4171 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004172 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
4173 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004174 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004175 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed,
4176 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004177 }
4178
4179 return rval;
4180}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004181
4182int
4183qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
4184 uint16_t size_in_bytes, uint16_t *actual_size)
4185{
4186 int rval;
4187 mbx_cmd_t mc;
4188 mbx_cmd_t *mcp = &mc;
4189
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004190 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee,
4191 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004192
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004193 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004194 return QLA_FUNCTION_FAILED;
4195
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004196 mcp->mb[0] = MBC_GET_XGMAC_STATS;
4197 mcp->mb[2] = MSW(stats_dma);
4198 mcp->mb[3] = LSW(stats_dma);
4199 mcp->mb[6] = MSW(MSD(stats_dma));
4200 mcp->mb[7] = LSW(MSD(stats_dma));
4201 mcp->mb[8] = size_in_bytes >> 2;
4202 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4203 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4204 mcp->tov = MBX_TOV_SECONDS;
4205 mcp->flags = 0;
4206 rval = qla2x00_mailbox_command(vha, mcp);
4207
4208 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004209 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
4210 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4211 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004212 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004213 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0,
4214 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004215
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004216
4217 *actual_size = mcp->mb[2] << 2;
4218 }
4219
4220 return rval;
4221}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004222
4223int
4224qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
4225 uint16_t size)
4226{
4227 int rval;
4228 mbx_cmd_t mc;
4229 mbx_cmd_t *mcp = &mc;
4230
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004231 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1,
4232 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004233
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004234 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004235 return QLA_FUNCTION_FAILED;
4236
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004237 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4238 mcp->mb[1] = 0;
4239 mcp->mb[2] = MSW(tlv_dma);
4240 mcp->mb[3] = LSW(tlv_dma);
4241 mcp->mb[6] = MSW(MSD(tlv_dma));
4242 mcp->mb[7] = LSW(MSD(tlv_dma));
4243 mcp->mb[8] = size;
4244 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4245 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4246 mcp->tov = MBX_TOV_SECONDS;
4247 mcp->flags = 0;
4248 rval = qla2x00_mailbox_command(vha, mcp);
4249
4250 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004251 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
4252 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4253 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004254 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004255 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3,
4256 "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004257 }
4258
4259 return rval;
4260}
Andrew Vasquez18e75552009-06-03 09:55:30 -07004261
4262int
4263qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
4264{
4265 int rval;
4266 mbx_cmd_t mc;
4267 mbx_cmd_t *mcp = &mc;
4268
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004269 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4,
4270 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004271
Andrew Vasquez18e75552009-06-03 09:55:30 -07004272 if (!IS_FWI2_CAPABLE(vha->hw))
4273 return QLA_FUNCTION_FAILED;
4274
Andrew Vasquez18e75552009-06-03 09:55:30 -07004275 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
4276 mcp->mb[1] = LSW(risc_addr);
4277 mcp->mb[8] = MSW(risc_addr);
4278 mcp->out_mb = MBX_8|MBX_1|MBX_0;
4279 mcp->in_mb = MBX_3|MBX_2|MBX_0;
4280 mcp->tov = 30;
4281 mcp->flags = 0;
4282 rval = qla2x00_mailbox_command(vha, mcp);
4283 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004284 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
4285 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004286 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004287 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6,
4288 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004289 *data = mcp->mb[3] << 16 | mcp->mb[2];
4290 }
4291
4292 return rval;
4293}
4294
4295int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004296qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4297 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004298{
4299 int rval;
4300 mbx_cmd_t mc;
4301 mbx_cmd_t *mcp = &mc;
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004302
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004303 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7,
4304 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004305
4306 memset(mcp->mb, 0 , sizeof(mcp->mb));
4307 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
4308 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
4309
4310 /* transfer count */
4311 mcp->mb[10] = LSW(mreq->transfer_size);
4312 mcp->mb[11] = MSW(mreq->transfer_size);
4313
4314 /* send data address */
4315 mcp->mb[14] = LSW(mreq->send_dma);
4316 mcp->mb[15] = MSW(mreq->send_dma);
4317 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4318 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4319
Lucas De Marchi25985ed2011-03-30 22:57:33 -03004320 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004321 mcp->mb[16] = LSW(mreq->rcv_dma);
4322 mcp->mb[17] = MSW(mreq->rcv_dma);
4323 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4324 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4325
4326 /* Iteration count */
Joe Carnuccio1b98b422013-03-28 08:21:26 -04004327 mcp->mb[18] = LSW(mreq->iteration_count);
4328 mcp->mb[19] = MSW(mreq->iteration_count);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004329
4330 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
4331 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 -08004332 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004333 mcp->out_mb |= MBX_2;
4334 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
4335
4336 mcp->buf_size = mreq->transfer_size;
4337 mcp->tov = MBX_TOV_SECONDS;
4338 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4339
4340 rval = qla2x00_mailbox_command(vha, mcp);
4341
4342 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004343 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
4344 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
4345 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
4346 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004347 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004348 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9,
4349 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004350 }
4351
4352 /* Copy mailbox information */
4353 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004354 return rval;
4355}
4356
4357int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004358qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4359 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004360{
4361 int rval;
4362 mbx_cmd_t mc;
4363 mbx_cmd_t *mcp = &mc;
4364 struct qla_hw_data *ha = vha->hw;
4365
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004366 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa,
4367 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004368
4369 memset(mcp->mb, 0 , sizeof(mcp->mb));
4370 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
4371 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004372 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004373 mcp->mb[1] |= BIT_15;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004374 mcp->mb[2] = vha->fcoe_fcf_idx;
4375 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004376 mcp->mb[16] = LSW(mreq->rcv_dma);
4377 mcp->mb[17] = MSW(mreq->rcv_dma);
4378 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4379 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4380
4381 mcp->mb[10] = LSW(mreq->transfer_size);
4382
4383 mcp->mb[14] = LSW(mreq->send_dma);
4384 mcp->mb[15] = MSW(mreq->send_dma);
4385 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4386 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4387
4388 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
4389 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004390 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004391 mcp->out_mb |= MBX_2;
4392
4393 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004394 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
4395 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004396 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004397 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004398 mcp->in_mb |= MBX_3;
4399
4400 mcp->tov = MBX_TOV_SECONDS;
4401 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4402 mcp->buf_size = mreq->transfer_size;
4403
4404 rval = qla2x00_mailbox_command(vha, mcp);
4405
4406 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004407 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
4408 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4409 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004410 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004411 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc,
4412 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004413 }
4414
4415 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07004416 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004417 return rval;
4418}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07004419
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004420int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004421qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004422{
4423 int rval;
4424 mbx_cmd_t mc;
4425 mbx_cmd_t *mcp = &mc;
4426
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004427 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004428 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004429
4430 mcp->mb[0] = MBC_ISP84XX_RESET;
4431 mcp->mb[1] = enable_diagnostic;
4432 mcp->out_mb = MBX_1|MBX_0;
4433 mcp->in_mb = MBX_1|MBX_0;
4434 mcp->tov = MBX_TOV_SECONDS;
4435 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004436 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004437
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004438 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004439 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004440 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004441 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff,
4442 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004443
4444 return rval;
4445}
4446
4447int
Andrew Vasquez18e75552009-06-03 09:55:30 -07004448qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
4449{
4450 int rval;
4451 mbx_cmd_t mc;
4452 mbx_cmd_t *mcp = &mc;
4453
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004454 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100,
4455 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004456
Andrew Vasquez18e75552009-06-03 09:55:30 -07004457 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07004458 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07004459
Andrew Vasquez18e75552009-06-03 09:55:30 -07004460 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
4461 mcp->mb[1] = LSW(risc_addr);
4462 mcp->mb[2] = LSW(data);
4463 mcp->mb[3] = MSW(data);
4464 mcp->mb[8] = MSW(risc_addr);
4465 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
4466 mcp->in_mb = MBX_0;
4467 mcp->tov = 30;
4468 mcp->flags = 0;
4469 rval = qla2x00_mailbox_command(vha, mcp);
4470 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004471 ql_dbg(ql_dbg_mbx, vha, 0x1101,
4472 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004473 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004474 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
4475 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004476 }
4477
4478 return rval;
4479}
Michael Hernandez3064ff32009-12-15 21:29:44 -08004480
4481int
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004482qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
4483{
4484 int rval;
4485 uint32_t stat, timer;
4486 uint16_t mb0 = 0;
4487 struct qla_hw_data *ha = vha->hw;
4488 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
4489
4490 rval = QLA_SUCCESS;
4491
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004492 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103,
4493 "Entered %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004494
4495 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
4496
4497 /* Write the MBC data to the registers */
4498 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
4499 WRT_REG_WORD(&reg->mailbox1, mb[0]);
4500 WRT_REG_WORD(&reg->mailbox2, mb[1]);
4501 WRT_REG_WORD(&reg->mailbox3, mb[2]);
4502 WRT_REG_WORD(&reg->mailbox4, mb[3]);
4503
4504 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
4505
4506 /* Poll for MBC interrupt */
4507 for (timer = 6000000; timer; timer--) {
4508 /* Check for pending interrupts. */
4509 stat = RD_REG_DWORD(&reg->host_status);
4510 if (stat & HSRX_RISC_INT) {
4511 stat &= 0xff;
4512
4513 if (stat == 0x1 || stat == 0x2 ||
4514 stat == 0x10 || stat == 0x11) {
4515 set_bit(MBX_INTERRUPT,
4516 &ha->mbx_cmd_flags);
4517 mb0 = RD_REG_WORD(&reg->mailbox0);
4518 WRT_REG_DWORD(&reg->hccr,
4519 HCCRX_CLR_RISC_INT);
4520 RD_REG_DWORD(&reg->hccr);
4521 break;
4522 }
4523 }
4524 udelay(5);
4525 }
4526
4527 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
4528 rval = mb0 & MBS_MASK;
4529 else
4530 rval = QLA_FUNCTION_FAILED;
4531
4532 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004533 ql_dbg(ql_dbg_mbx, vha, 0x1104,
4534 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004535 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004536 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105,
4537 "Done %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004538 }
4539
4540 return rval;
4541}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004542
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004543int
Michael Hernandez3064ff32009-12-15 21:29:44 -08004544qla2x00_get_data_rate(scsi_qla_host_t *vha)
4545{
4546 int rval;
4547 mbx_cmd_t mc;
4548 mbx_cmd_t *mcp = &mc;
4549 struct qla_hw_data *ha = vha->hw;
4550
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004551 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
4552 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004553
Michael Hernandez3064ff32009-12-15 21:29:44 -08004554 if (!IS_FWI2_CAPABLE(ha))
4555 return QLA_FUNCTION_FAILED;
4556
Michael Hernandez3064ff32009-12-15 21:29:44 -08004557 mcp->mb[0] = MBC_DATA_RATE;
4558 mcp->mb[1] = 0;
4559 mcp->out_mb = MBX_1|MBX_0;
4560 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004561 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004562 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08004563 mcp->tov = MBX_TOV_SECONDS;
4564 mcp->flags = 0;
4565 rval = qla2x00_mailbox_command(vha, mcp);
4566 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004567 ql_dbg(ql_dbg_mbx, vha, 0x1107,
4568 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004569 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004570 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
4571 "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004572 if (mcp->mb[1] != 0x7)
4573 ha->link_data_rate = mcp->mb[1];
4574 }
4575
4576 return rval;
4577}
Sarang Radke09ff7012010-03-19 17:03:59 -07004578
4579int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004580qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4581{
4582 int rval;
4583 mbx_cmd_t mc;
4584 mbx_cmd_t *mcp = &mc;
4585 struct qla_hw_data *ha = vha->hw;
4586
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004587 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
4588 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004589
Chad Dupuisf73cb692014-02-26 04:15:06 -05004590 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) &&
4591 !IS_QLA27XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004592 return QLA_FUNCTION_FAILED;
4593 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4594 mcp->out_mb = MBX_0;
4595 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4596 mcp->tov = MBX_TOV_SECONDS;
4597 mcp->flags = 0;
4598
4599 rval = qla2x00_mailbox_command(vha, mcp);
4600
4601 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004602 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4603 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004604 } else {
4605 /* Copy all bits to preserve original value */
4606 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4607
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004608 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b,
4609 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004610 }
4611 return rval;
4612}
4613
4614int
4615qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4616{
4617 int rval;
4618 mbx_cmd_t mc;
4619 mbx_cmd_t *mcp = &mc;
4620
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004621 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c,
4622 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004623
4624 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4625 /* Copy all bits to preserve original setting */
4626 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4627 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4628 mcp->in_mb = MBX_0;
4629 mcp->tov = MBX_TOV_SECONDS;
4630 mcp->flags = 0;
4631 rval = qla2x00_mailbox_command(vha, mcp);
4632
4633 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004634 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4635 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004636 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004637 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e,
4638 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004639
4640 return rval;
4641}
4642
4643
4644int
Sarang Radke09ff7012010-03-19 17:03:59 -07004645qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4646 uint16_t *mb)
4647{
4648 int rval;
4649 mbx_cmd_t mc;
4650 mbx_cmd_t *mcp = &mc;
4651 struct qla_hw_data *ha = vha->hw;
4652
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004653 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f,
4654 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004655
Sarang Radke09ff7012010-03-19 17:03:59 -07004656 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4657 return QLA_FUNCTION_FAILED;
4658
Sarang Radke09ff7012010-03-19 17:03:59 -07004659 mcp->mb[0] = MBC_PORT_PARAMS;
4660 mcp->mb[1] = loop_id;
4661 if (ha->flags.fcp_prio_enabled)
4662 mcp->mb[2] = BIT_1;
4663 else
4664 mcp->mb[2] = BIT_2;
4665 mcp->mb[4] = priority & 0xf;
4666 mcp->mb[9] = vha->vp_idx;
4667 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4668 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4669 mcp->tov = 30;
4670 mcp->flags = 0;
4671 rval = qla2x00_mailbox_command(vha, mcp);
4672 if (mb != NULL) {
4673 mb[0] = mcp->mb[0];
4674 mb[1] = mcp->mb[1];
4675 mb[3] = mcp->mb[3];
4676 mb[4] = mcp->mb[4];
4677 }
4678
4679 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004680 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07004681 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004682 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc,
4683 "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07004684 }
4685
4686 return rval;
4687}
Giridhar Malavalia9083012010-04-12 17:59:55 -07004688
4689int
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004690qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)
Andrew Vasquez794a5692010-12-21 16:00:21 -08004691{
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004692 int rval = QLA_FUNCTION_FAILED;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004693 struct qla_hw_data *ha = vha->hw;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004694 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004695
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004696 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) {
4697 ql_dbg(ql_dbg_mbx, vha, 0x1150,
4698 "Thermal not supported by this card.\n");
4699 return rval;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004700 }
Andrew Vasquez794a5692010-12-21 16:00:21 -08004701
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004702 if (IS_QLA25XX(ha)) {
4703 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
4704 ha->pdev->subsystem_device == 0x0175) {
4705 rval = qla2x00_read_sfp(vha, 0, &byte,
4706 0x98, 0x1, 1, BIT_13|BIT_0);
4707 *temp = byte;
4708 return rval;
4709 }
4710 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
4711 ha->pdev->subsystem_device == 0x338e) {
4712 rval = qla2x00_read_sfp(vha, 0, &byte,
4713 0x98, 0x1, 1, BIT_15|BIT_14|BIT_0);
4714 *temp = byte;
4715 return rval;
4716 }
4717 ql_dbg(ql_dbg_mbx, vha, 0x10c9,
4718 "Thermal not supported by this card.\n");
4719 return rval;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004720 }
4721
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004722 if (IS_QLA82XX(ha)) {
4723 *temp = qla82xx_read_temperature(vha);
4724 rval = QLA_SUCCESS;
4725 return rval;
4726 } else if (IS_QLA8044(ha)) {
4727 *temp = qla8044_read_temperature(vha);
4728 rval = QLA_SUCCESS;
4729 return rval;
4730 }
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004731
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004732 rval = qla2x00_read_asic_temperature(vha, temp);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004733 return rval;
4734}
4735
4736int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004737qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
4738{
4739 int rval;
4740 struct qla_hw_data *ha = vha->hw;
4741 mbx_cmd_t mc;
4742 mbx_cmd_t *mcp = &mc;
4743
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004744 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017,
4745 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004746
Giridhar Malavalia9083012010-04-12 17:59:55 -07004747 if (!IS_FWI2_CAPABLE(ha))
4748 return QLA_FUNCTION_FAILED;
4749
Giridhar Malavalia9083012010-04-12 17:59:55 -07004750 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004751 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004752 mcp->mb[1] = 1;
4753
4754 mcp->out_mb = MBX_1|MBX_0;
4755 mcp->in_mb = MBX_0;
4756 mcp->tov = 30;
4757 mcp->flags = 0;
4758
4759 rval = qla2x00_mailbox_command(vha, mcp);
4760 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004761 ql_dbg(ql_dbg_mbx, vha, 0x1016,
4762 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004763 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004764 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e,
4765 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004766 }
4767
4768 return rval;
4769}
4770
4771int
4772qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4773{
4774 int rval;
4775 struct qla_hw_data *ha = vha->hw;
4776 mbx_cmd_t mc;
4777 mbx_cmd_t *mcp = &mc;
4778
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004779 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
4780 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004781
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04004782 if (!IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -07004783 return QLA_FUNCTION_FAILED;
4784
Giridhar Malavalia9083012010-04-12 17:59:55 -07004785 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004786 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004787 mcp->mb[1] = 0;
4788
4789 mcp->out_mb = MBX_1|MBX_0;
4790 mcp->in_mb = MBX_0;
4791 mcp->tov = 30;
4792 mcp->flags = 0;
4793
4794 rval = qla2x00_mailbox_command(vha, mcp);
4795 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004796 ql_dbg(ql_dbg_mbx, vha, 0x100c,
4797 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004798 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004799 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b,
4800 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004801 }
4802
4803 return rval;
4804}
Giridhar Malavali08de2842011-08-16 11:31:44 -07004805
4806int
4807qla82xx_md_get_template_size(scsi_qla_host_t *vha)
4808{
4809 struct qla_hw_data *ha = vha->hw;
4810 mbx_cmd_t mc;
4811 mbx_cmd_t *mcp = &mc;
4812 int rval = QLA_FUNCTION_FAILED;
4813
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004814 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f,
4815 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004816
4817 memset(mcp->mb, 0 , sizeof(mcp->mb));
4818 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4819 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4820 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
4821 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
4822
4823 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4824 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
4825 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4826
4827 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4828 mcp->tov = MBX_TOV_SECONDS;
4829 rval = qla2x00_mailbox_command(vha, mcp);
4830
4831 /* Always copy back return mailbox values. */
4832 if (rval != QLA_SUCCESS) {
4833 ql_dbg(ql_dbg_mbx, vha, 0x1120,
4834 "mailbox command FAILED=0x%x, subcode=%x.\n",
4835 (mcp->mb[1] << 16) | mcp->mb[0],
4836 (mcp->mb[3] << 16) | mcp->mb[2]);
4837 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004838 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121,
4839 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004840 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
4841 if (!ha->md_template_size) {
4842 ql_dbg(ql_dbg_mbx, vha, 0x1122,
4843 "Null template size obtained.\n");
4844 rval = QLA_FUNCTION_FAILED;
4845 }
4846 }
4847 return rval;
4848}
4849
4850int
4851qla82xx_md_get_template(scsi_qla_host_t *vha)
4852{
4853 struct qla_hw_data *ha = vha->hw;
4854 mbx_cmd_t mc;
4855 mbx_cmd_t *mcp = &mc;
4856 int rval = QLA_FUNCTION_FAILED;
4857
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004858 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123,
4859 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004860
4861 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4862 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4863 if (!ha->md_tmplt_hdr) {
4864 ql_log(ql_log_warn, vha, 0x1124,
4865 "Unable to allocate memory for Minidump template.\n");
4866 return rval;
4867 }
4868
4869 memset(mcp->mb, 0 , sizeof(mcp->mb));
4870 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4871 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4872 mcp->mb[2] = LSW(RQST_TMPLT);
4873 mcp->mb[3] = MSW(RQST_TMPLT);
4874 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
4875 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
4876 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
4877 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
4878 mcp->mb[8] = LSW(ha->md_template_size);
4879 mcp->mb[9] = MSW(ha->md_template_size);
4880
4881 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4882 mcp->tov = MBX_TOV_SECONDS;
4883 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4884 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4885 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4886 rval = qla2x00_mailbox_command(vha, mcp);
4887
4888 if (rval != QLA_SUCCESS) {
4889 ql_dbg(ql_dbg_mbx, vha, 0x1125,
4890 "mailbox command FAILED=0x%x, subcode=%x.\n",
4891 ((mcp->mb[1] << 16) | mcp->mb[0]),
4892 ((mcp->mb[3] << 16) | mcp->mb[2]));
4893 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004894 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126,
4895 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004896 return rval;
4897}
Saurav Kashyap999916d2011-08-16 11:31:45 -07004898
4899int
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04004900qla8044_md_get_template(scsi_qla_host_t *vha)
4901{
4902 struct qla_hw_data *ha = vha->hw;
4903 mbx_cmd_t mc;
4904 mbx_cmd_t *mcp = &mc;
4905 int rval = QLA_FUNCTION_FAILED;
4906 int offset = 0, size = MINIDUMP_SIZE_36K;
4907 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,
4908 "Entered %s.\n", __func__);
4909
4910 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4911 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4912 if (!ha->md_tmplt_hdr) {
4913 ql_log(ql_log_warn, vha, 0xb11b,
4914 "Unable to allocate memory for Minidump template.\n");
4915 return rval;
4916 }
4917
4918 memset(mcp->mb, 0 , sizeof(mcp->mb));
4919 while (offset < ha->md_template_size) {
4920 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4921 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4922 mcp->mb[2] = LSW(RQST_TMPLT);
4923 mcp->mb[3] = MSW(RQST_TMPLT);
4924 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));
4925 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));
4926 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));
4927 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));
4928 mcp->mb[8] = LSW(size);
4929 mcp->mb[9] = MSW(size);
4930 mcp->mb[10] = offset & 0x0000FFFF;
4931 mcp->mb[11] = offset & 0xFFFF0000;
4932 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4933 mcp->tov = MBX_TOV_SECONDS;
4934 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4935 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4936 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4937 rval = qla2x00_mailbox_command(vha, mcp);
4938
4939 if (rval != QLA_SUCCESS) {
4940 ql_dbg(ql_dbg_mbx, vha, 0xb11c,
4941 "mailbox command FAILED=0x%x, subcode=%x.\n",
4942 ((mcp->mb[1] << 16) | mcp->mb[0]),
4943 ((mcp->mb[3] << 16) | mcp->mb[2]));
4944 return rval;
4945 } else
4946 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,
4947 "Done %s.\n", __func__);
4948 offset = offset + size;
4949 }
4950 return rval;
4951}
4952
4953int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004954qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4955{
4956 int rval;
4957 struct qla_hw_data *ha = vha->hw;
4958 mbx_cmd_t mc;
4959 mbx_cmd_t *mcp = &mc;
4960
4961 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4962 return QLA_FUNCTION_FAILED;
4963
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004964 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133,
4965 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004966
4967 memset(mcp, 0, sizeof(mbx_cmd_t));
4968 mcp->mb[0] = MBC_SET_LED_CONFIG;
4969 mcp->mb[1] = led_cfg[0];
4970 mcp->mb[2] = led_cfg[1];
4971 if (IS_QLA8031(ha)) {
4972 mcp->mb[3] = led_cfg[2];
4973 mcp->mb[4] = led_cfg[3];
4974 mcp->mb[5] = led_cfg[4];
4975 mcp->mb[6] = led_cfg[5];
4976 }
4977
4978 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4979 if (IS_QLA8031(ha))
4980 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4981 mcp->in_mb = MBX_0;
4982 mcp->tov = 30;
4983 mcp->flags = 0;
4984
4985 rval = qla2x00_mailbox_command(vha, mcp);
4986 if (rval != QLA_SUCCESS) {
4987 ql_dbg(ql_dbg_mbx, vha, 0x1134,
4988 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4989 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004990 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135,
4991 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004992 }
4993
4994 return rval;
4995}
4996
4997int
4998qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4999{
5000 int rval;
5001 struct qla_hw_data *ha = vha->hw;
5002 mbx_cmd_t mc;
5003 mbx_cmd_t *mcp = &mc;
5004
5005 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5006 return QLA_FUNCTION_FAILED;
5007
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005008 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136,
5009 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005010
5011 memset(mcp, 0, sizeof(mbx_cmd_t));
5012 mcp->mb[0] = MBC_GET_LED_CONFIG;
5013
5014 mcp->out_mb = MBX_0;
5015 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5016 if (IS_QLA8031(ha))
5017 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5018 mcp->tov = 30;
5019 mcp->flags = 0;
5020
5021 rval = qla2x00_mailbox_command(vha, mcp);
5022 if (rval != QLA_SUCCESS) {
5023 ql_dbg(ql_dbg_mbx, vha, 0x1137,
5024 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5025 } else {
5026 led_cfg[0] = mcp->mb[1];
5027 led_cfg[1] = mcp->mb[2];
5028 if (IS_QLA8031(ha)) {
5029 led_cfg[2] = mcp->mb[3];
5030 led_cfg[3] = mcp->mb[4];
5031 led_cfg[4] = mcp->mb[5];
5032 led_cfg[5] = mcp->mb[6];
5033 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005034 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138,
5035 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005036 }
5037
5038 return rval;
5039}
5040
5041int
Saurav Kashyap999916d2011-08-16 11:31:45 -07005042qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
5043{
5044 int rval;
5045 struct qla_hw_data *ha = vha->hw;
5046 mbx_cmd_t mc;
5047 mbx_cmd_t *mcp = &mc;
5048
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005049 if (!IS_P3P_TYPE(ha))
Saurav Kashyap999916d2011-08-16 11:31:45 -07005050 return QLA_FUNCTION_FAILED;
5051
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005052 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005053 "Entered %s.\n", __func__);
5054
5055 memset(mcp, 0, sizeof(mbx_cmd_t));
5056 mcp->mb[0] = MBC_SET_LED_CONFIG;
5057 if (enable)
5058 mcp->mb[7] = 0xE;
5059 else
5060 mcp->mb[7] = 0xD;
5061
5062 mcp->out_mb = MBX_7|MBX_0;
5063 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005064 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07005065 mcp->flags = 0;
5066
5067 rval = qla2x00_mailbox_command(vha, mcp);
5068 if (rval != QLA_SUCCESS) {
5069 ql_dbg(ql_dbg_mbx, vha, 0x1128,
5070 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5071 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005072 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005073 "Done %s.\n", __func__);
5074 }
5075
5076 return rval;
5077}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005078
5079int
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005080qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005081{
5082 int rval;
5083 struct qla_hw_data *ha = vha->hw;
5084 mbx_cmd_t mc;
5085 mbx_cmd_t *mcp = &mc;
5086
Chad Dupuisf73cb692014-02-26 04:15:06 -05005087 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005088 return QLA_FUNCTION_FAILED;
5089
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005090 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130,
5091 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005092
5093 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
5094 mcp->mb[1] = LSW(reg);
5095 mcp->mb[2] = MSW(reg);
5096 mcp->mb[3] = LSW(data);
5097 mcp->mb[4] = MSW(data);
5098 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5099
5100 mcp->in_mb = MBX_1|MBX_0;
5101 mcp->tov = MBX_TOV_SECONDS;
5102 mcp->flags = 0;
5103 rval = qla2x00_mailbox_command(vha, mcp);
5104
5105 if (rval != QLA_SUCCESS) {
5106 ql_dbg(ql_dbg_mbx, vha, 0x1131,
5107 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5108 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005109 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005110 "Done %s.\n", __func__);
5111 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005112
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005113 return rval;
5114}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005115
5116int
5117qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
5118{
5119 int rval;
5120 struct qla_hw_data *ha = vha->hw;
5121 mbx_cmd_t mc;
5122 mbx_cmd_t *mcp = &mc;
5123
5124 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005125 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b,
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005126 "Implicit LOGO Unsupported.\n");
5127 return QLA_FUNCTION_FAILED;
5128 }
5129
5130
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005131 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c,
5132 "Entering %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005133
5134 /* Perform Implicit LOGO. */
5135 mcp->mb[0] = MBC_PORT_LOGOUT;
5136 mcp->mb[1] = fcport->loop_id;
5137 mcp->mb[10] = BIT_15;
5138 mcp->out_mb = MBX_10|MBX_1|MBX_0;
5139 mcp->in_mb = MBX_0;
5140 mcp->tov = MBX_TOV_SECONDS;
5141 mcp->flags = 0;
5142 rval = qla2x00_mailbox_command(vha, mcp);
5143 if (rval != QLA_SUCCESS)
5144 ql_dbg(ql_dbg_mbx, vha, 0x113d,
5145 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5146 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005147 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e,
5148 "Done %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005149
5150 return rval;
5151}
5152
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005153int
5154qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
5155{
5156 int rval;
5157 mbx_cmd_t mc;
5158 mbx_cmd_t *mcp = &mc;
5159 struct qla_hw_data *ha = vha->hw;
5160 unsigned long retry_max_time = jiffies + (2 * HZ);
5161
Chad Dupuisf73cb692014-02-26 04:15:06 -05005162 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005163 return QLA_FUNCTION_FAILED;
5164
5165 ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
5166
5167retry_rd_reg:
5168 mcp->mb[0] = MBC_READ_REMOTE_REG;
5169 mcp->mb[1] = LSW(reg);
5170 mcp->mb[2] = MSW(reg);
5171 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5172 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5173 mcp->tov = MBX_TOV_SECONDS;
5174 mcp->flags = 0;
5175 rval = qla2x00_mailbox_command(vha, mcp);
5176
5177 if (rval != QLA_SUCCESS) {
5178 ql_dbg(ql_dbg_mbx, vha, 0x114c,
5179 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5180 rval, mcp->mb[0], mcp->mb[1]);
5181 } else {
5182 *data = (mcp->mb[3] | (mcp->mb[4] << 16));
5183 if (*data == QLA8XXX_BAD_VALUE) {
5184 /*
5185 * During soft-reset CAMRAM register reads might
5186 * return 0xbad0bad0. So retry for MAX of 2 sec
5187 * while reading camram registers.
5188 */
5189 if (time_after(jiffies, retry_max_time)) {
5190 ql_dbg(ql_dbg_mbx, vha, 0x1141,
5191 "Failure to read CAMRAM register. "
5192 "data=0x%x.\n", *data);
5193 return QLA_FUNCTION_FAILED;
5194 }
5195 msleep(100);
5196 goto retry_rd_reg;
5197 }
5198 ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
5199 }
5200
5201 return rval;
5202}
5203
5204int
5205qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
5206{
5207 int rval;
5208 mbx_cmd_t mc;
5209 mbx_cmd_t *mcp = &mc;
5210 struct qla_hw_data *ha = vha->hw;
5211
5212 if (!IS_QLA83XX(ha))
5213 return QLA_FUNCTION_FAILED;
5214
5215 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
5216
5217 mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
5218 mcp->out_mb = MBX_0;
5219 mcp->in_mb = MBX_1|MBX_0;
5220 mcp->tov = MBX_TOV_SECONDS;
5221 mcp->flags = 0;
5222 rval = qla2x00_mailbox_command(vha, mcp);
5223
5224 if (rval != QLA_SUCCESS) {
5225 ql_dbg(ql_dbg_mbx, vha, 0x1144,
5226 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5227 rval, mcp->mb[0], mcp->mb[1]);
5228 ha->isp_ops->fw_dump(vha, 0);
5229 } else {
5230 ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
5231 }
5232
5233 return rval;
5234}
5235
5236int
5237qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
5238 uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
5239{
5240 int rval;
5241 mbx_cmd_t mc;
5242 mbx_cmd_t *mcp = &mc;
5243 uint8_t subcode = (uint8_t)options;
5244 struct qla_hw_data *ha = vha->hw;
5245
5246 if (!IS_QLA8031(ha))
5247 return QLA_FUNCTION_FAILED;
5248
5249 ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
5250
5251 mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
5252 mcp->mb[1] = options;
5253 mcp->out_mb = MBX_1|MBX_0;
5254 if (subcode & BIT_2) {
5255 mcp->mb[2] = LSW(start_addr);
5256 mcp->mb[3] = MSW(start_addr);
5257 mcp->mb[4] = LSW(end_addr);
5258 mcp->mb[5] = MSW(end_addr);
5259 mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
5260 }
5261 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5262 if (!(subcode & (BIT_2 | BIT_5)))
5263 mcp->in_mb |= MBX_4|MBX_3;
5264 mcp->tov = MBX_TOV_SECONDS;
5265 mcp->flags = 0;
5266 rval = qla2x00_mailbox_command(vha, mcp);
5267
5268 if (rval != QLA_SUCCESS) {
5269 ql_dbg(ql_dbg_mbx, vha, 0x1147,
5270 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
5271 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
5272 mcp->mb[4]);
5273 ha->isp_ops->fw_dump(vha, 0);
5274 } else {
5275 if (subcode & BIT_5)
5276 *sector_size = mcp->mb[1];
5277 else if (subcode & (BIT_6 | BIT_7)) {
5278 ql_dbg(ql_dbg_mbx, vha, 0x1148,
5279 "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5280 } else if (subcode & (BIT_3 | BIT_4)) {
5281 ql_dbg(ql_dbg_mbx, vha, 0x1149,
5282 "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5283 }
5284 ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
5285 }
5286
5287 return rval;
5288}
Saurav Kashyap81178772012-08-22 14:21:04 -04005289
5290int
5291qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
5292 uint32_t size)
5293{
5294 int rval;
5295 mbx_cmd_t mc;
5296 mbx_cmd_t *mcp = &mc;
5297
5298 if (!IS_MCTP_CAPABLE(vha->hw))
5299 return QLA_FUNCTION_FAILED;
5300
5301 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,
5302 "Entered %s.\n", __func__);
5303
5304 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
5305 mcp->mb[1] = LSW(addr);
5306 mcp->mb[2] = MSW(req_dma);
5307 mcp->mb[3] = LSW(req_dma);
5308 mcp->mb[4] = MSW(size);
5309 mcp->mb[5] = LSW(size);
5310 mcp->mb[6] = MSW(MSD(req_dma));
5311 mcp->mb[7] = LSW(MSD(req_dma));
5312 mcp->mb[8] = MSW(addr);
5313 /* Setting RAM ID to valid */
5314 mcp->mb[10] |= BIT_7;
5315 /* For MCTP RAM ID is 0x40 */
5316 mcp->mb[10] |= 0x40;
5317
5318 mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
5319 MBX_0;
5320
5321 mcp->in_mb = MBX_0;
5322 mcp->tov = MBX_TOV_SECONDS;
5323 mcp->flags = 0;
5324 rval = qla2x00_mailbox_command(vha, mcp);
5325
5326 if (rval != QLA_SUCCESS) {
5327 ql_dbg(ql_dbg_mbx, vha, 0x114e,
5328 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5329 } else {
5330 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,
5331 "Done %s.\n", __func__);
5332 }
5333
5334 return rval;
5335}