blob: b4f7cd5fa75cdbb7b00d4251d60080be03351cbf [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 Kashyap09543c092012-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
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002600 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05002601 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002602 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002603 break;
2604 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002605 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05002606 if (handle == req->num_outstanding_cmds) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002607 /* Command not found. */
2608 return QLA_FUNCTION_FAILED;
2609 }
2610
2611 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2612 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002613 ql_log(ql_log_warn, vha, 0x108d,
2614 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002615 return QLA_MEMORY_ALLOC_FAILED;
2616 }
2617 memset(abt, 0, sizeof(struct abort_entry_24xx));
2618
2619 abt->entry_type = ABORT_IOCB_TYPE;
2620 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002621 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002622 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07002623 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002624 abt->port_id[0] = fcport->d_id.b.al_pa;
2625 abt->port_id[1] = fcport->d_id.b.area;
2626 abt->port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04002627 abt->vp_index = fcport->vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002628
2629 abt->req_que_no = cpu_to_le16(req->id);
2630
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002631 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002632 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002633 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2634 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002635 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002636 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2637 "Failed to complete IOCB -- error status (%x).\n",
2638 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002639 rval = QLA_FUNCTION_FAILED;
2640 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002641 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2642 "Failed to complete IOCB -- completion status (%x).\n",
2643 le16_to_cpu(abt->nport_handle));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002644 rval = QLA_FUNCTION_FAILED;
2645 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002646 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
2647 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002648 }
2649
2650 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2651
2652 return rval;
2653}
2654
2655struct tsk_mgmt_cmd {
2656 union {
2657 struct tsk_mgmt_entry tsk;
2658 struct sts_entry_24xx sts;
2659 } p;
2660};
2661
Andrew Vasquez523ec772008-04-03 13:13:24 -07002662static int
2663__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002664 unsigned int l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002665{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002666 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002667 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002668 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002669 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002670 scsi_qla_host_t *vha;
2671 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002672 struct req_que *req;
2673 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002674
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002675 vha = fcport->vha;
2676 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002677 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002678
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002679 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092,
2680 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002681
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002682 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002683 rsp = ha->rsp_q_map[tag + 1];
2684 else
2685 rsp = req->rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002686 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002687 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002688 ql_log(ql_log_warn, vha, 0x1093,
2689 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002690 return QLA_MEMORY_ALLOC_FAILED;
2691 }
2692 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2693
2694 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2695 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002696 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002697 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002698 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002699 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002700 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2701 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2702 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04002703 tsk->p.tsk.vp_index = fcport->vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002704 if (type == TCF_LUN_RESET) {
2705 int_to_scsilun(l, &tsk->p.tsk.lun);
2706 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2707 sizeof(tsk->p.tsk.lun));
2708 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002709
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002710 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002711 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002712 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002713 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2714 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002715 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002716 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2717 "Failed to complete IOCB -- error status (%x).\n",
2718 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002719 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002720 } else if (sts->comp_status !=
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002721 __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002722 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2723 "Failed to complete IOCB -- completion status (%x).\n",
2724 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002725 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08002726 } else if (le16_to_cpu(sts->scsi_status) &
2727 SS_RESPONSE_INFO_LEN_VALID) {
2728 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002729 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002730 "Ignoring inconsistent data length -- not enough "
2731 "response info (%d).\n",
2732 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08002733 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002734 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2735 "Failed to complete IOCB -- response (%x).\n",
2736 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08002737 rval = QLA_FUNCTION_FAILED;
2738 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002739 }
2740
2741 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002742 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002743 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2744 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002745 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2746 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002747 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002748 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a,
2749 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002750 }
2751
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002752 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002753
2754 return rval;
2755}
2756
Andrew Vasquez523ec772008-04-03 13:13:24 -07002757int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002758qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002759{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002760 struct qla_hw_data *ha = fcport->vha->hw;
2761
2762 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2763 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2764
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002765 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002766}
2767
2768int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002769qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002770{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002771 struct qla_hw_data *ha = fcport->vha->hw;
2772
2773 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2774 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2775
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002776 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002777}
2778
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002779int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002780qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002781{
2782 int rval;
2783 mbx_cmd_t mc;
2784 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002785 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002786
Andrew Vasquez68af0812008-05-12 22:21:13 -07002787 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002788 return QLA_FUNCTION_FAILED;
2789
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002790 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b,
2791 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002792
2793 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2794 mcp->out_mb = MBX_0;
2795 mcp->in_mb = MBX_0;
2796 mcp->tov = 5;
2797 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002798 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002799
2800 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002801 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002802 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002803 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d,
2804 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002805 }
2806
2807 return rval;
2808}
2809
Joe Carnucciodb64e932013-10-30 03:38:18 -04002810int
2811qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data)
2812{
2813 int rval;
2814 mbx_cmd_t mc;
2815 mbx_cmd_t *mcp = &mc;
2816
2817 if (!IS_QLA2031(vha->hw))
2818 return QLA_FUNCTION_FAILED;
2819
2820 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182,
2821 "Entered %s.\n", __func__);
2822
2823 mcp->mb[0] = MBC_WRITE_SERDES;
2824 mcp->mb[1] = addr;
2825 mcp->mb[2] = data & 0xff;
2826 mcp->mb[3] = 0;
2827 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2828 mcp->in_mb = MBX_0;
2829 mcp->tov = MBX_TOV_SECONDS;
2830 mcp->flags = 0;
2831 rval = qla2x00_mailbox_command(vha, mcp);
2832
2833 if (rval != QLA_SUCCESS) {
2834 ql_dbg(ql_dbg_mbx, vha, 0x1183,
2835 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
2836 } else {
2837 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184,
2838 "Done %s.\n", __func__);
2839 }
2840
2841 return rval;
2842}
2843
2844int
2845qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)
2846{
2847 int rval;
2848 mbx_cmd_t mc;
2849 mbx_cmd_t *mcp = &mc;
2850
2851 if (!IS_QLA2031(vha->hw))
2852 return QLA_FUNCTION_FAILED;
2853
2854 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185,
2855 "Entered %s.\n", __func__);
2856
2857 mcp->mb[0] = MBC_READ_SERDES;
2858 mcp->mb[1] = addr;
2859 mcp->mb[3] = 0;
2860 mcp->out_mb = MBX_3|MBX_1|MBX_0;
2861 mcp->in_mb = MBX_1|MBX_0;
2862 mcp->tov = MBX_TOV_SECONDS;
2863 mcp->flags = 0;
2864 rval = qla2x00_mailbox_command(vha, mcp);
2865
2866 *data = mcp->mb[1] & 0xff;
2867
2868 if (rval != QLA_SUCCESS) {
2869 ql_dbg(ql_dbg_mbx, vha, 0x1186,
2870 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
2871 } else {
2872 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187,
2873 "Done %s.\n", __func__);
2874 }
2875
2876 return rval;
2877}
2878
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002879/**
2880 * qla2x00_set_serdes_params() -
2881 * @ha: HA context
2882 *
2883 * Returns
2884 */
2885int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002886qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002887 uint16_t sw_em_2g, uint16_t sw_em_4g)
2888{
2889 int rval;
2890 mbx_cmd_t mc;
2891 mbx_cmd_t *mcp = &mc;
2892
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002893 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e,
2894 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002895
2896 mcp->mb[0] = MBC_SERDES_PARAMS;
2897 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08002898 mcp->mb[2] = sw_em_1g | BIT_15;
2899 mcp->mb[3] = sw_em_2g | BIT_15;
2900 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002901 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2902 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002903 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002904 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002905 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002906
2907 if (rval != QLA_SUCCESS) {
2908 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002909 ql_dbg(ql_dbg_mbx, vha, 0x109f,
2910 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002911 } else {
2912 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002913 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0,
2914 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002915 }
2916
2917 return rval;
2918}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002919
2920int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002921qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002922{
2923 int rval;
2924 mbx_cmd_t mc;
2925 mbx_cmd_t *mcp = &mc;
2926
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002927 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002928 return QLA_FUNCTION_FAILED;
2929
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002930 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1,
2931 "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002932
2933 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08002934 mcp->mb[1] = 0;
2935 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002936 mcp->in_mb = MBX_0;
2937 mcp->tov = 5;
2938 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002939 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002940
2941 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002942 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07002943 if (mcp->mb[0] == MBS_INVALID_COMMAND)
2944 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002945 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002946 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3,
2947 "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002948 }
2949
2950 return rval;
2951}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002952
2953int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002954qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002955 uint16_t buffers)
2956{
2957 int rval;
2958 mbx_cmd_t mc;
2959 mbx_cmd_t *mcp = &mc;
2960
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002961 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4,
2962 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002963
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002964 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002965 return QLA_FUNCTION_FAILED;
2966
Andrew Vasquez85880802009-12-15 21:29:46 -08002967 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2968 return QLA_FUNCTION_FAILED;
2969
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002970 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002971 mcp->mb[1] = TC_EFT_ENABLE;
2972 mcp->mb[2] = LSW(eft_dma);
2973 mcp->mb[3] = MSW(eft_dma);
2974 mcp->mb[4] = LSW(MSD(eft_dma));
2975 mcp->mb[5] = MSW(MSD(eft_dma));
2976 mcp->mb[6] = buffers;
2977 mcp->mb[7] = TC_AEN_DISABLE;
2978 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 -07002979 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002980 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002981 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002982 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002983 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002984 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
2985 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2986 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002987 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002988 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6,
2989 "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002990 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002991
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002992 return rval;
2993}
2994
2995int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002996qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002997{
2998 int rval;
2999 mbx_cmd_t mc;
3000 mbx_cmd_t *mcp = &mc;
3001
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003002 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7,
3003 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003004
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003005 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003006 return QLA_FUNCTION_FAILED;
3007
Andrew Vasquez85880802009-12-15 21:29:46 -08003008 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3009 return QLA_FUNCTION_FAILED;
3010
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003011 mcp->mb[0] = MBC_TRACE_CONTROL;
3012 mcp->mb[1] = TC_EFT_DISABLE;
3013 mcp->out_mb = MBX_1|MBX_0;
3014 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003015 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003016 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003017 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003018 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003019 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
3020 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3021 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003022 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003023 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9,
3024 "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003025 }
3026
3027 return rval;
3028}
3029
Andrew Vasquez88729e52006-06-23 16:10:50 -07003030int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003031qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003032 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
3033{
3034 int rval;
3035 mbx_cmd_t mc;
3036 mbx_cmd_t *mcp = &mc;
3037
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003038 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa,
3039 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003040
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003041 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
Chad Dupuisf73cb692014-02-26 04:15:06 -05003042 !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003043 return QLA_FUNCTION_FAILED;
3044
Andrew Vasquez85880802009-12-15 21:29:46 -08003045 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3046 return QLA_FUNCTION_FAILED;
3047
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003048 mcp->mb[0] = MBC_TRACE_CONTROL;
3049 mcp->mb[1] = TC_FCE_ENABLE;
3050 mcp->mb[2] = LSW(fce_dma);
3051 mcp->mb[3] = MSW(fce_dma);
3052 mcp->mb[4] = LSW(MSD(fce_dma));
3053 mcp->mb[5] = MSW(MSD(fce_dma));
3054 mcp->mb[6] = buffers;
3055 mcp->mb[7] = TC_AEN_DISABLE;
3056 mcp->mb[8] = 0;
3057 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
3058 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
3059 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3060 MBX_1|MBX_0;
3061 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003062 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003063 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003064 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003065 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003066 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
3067 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3068 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003069 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003070 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac,
3071 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003072
3073 if (mb)
3074 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
3075 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07003076 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003077 }
3078
3079 return rval;
3080}
3081
3082int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003083qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003084{
3085 int rval;
3086 mbx_cmd_t mc;
3087 mbx_cmd_t *mcp = &mc;
3088
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003089 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad,
3090 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003091
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003092 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003093 return QLA_FUNCTION_FAILED;
3094
Andrew Vasquez85880802009-12-15 21:29:46 -08003095 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3096 return QLA_FUNCTION_FAILED;
3097
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003098 mcp->mb[0] = MBC_TRACE_CONTROL;
3099 mcp->mb[1] = TC_FCE_DISABLE;
3100 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
3101 mcp->out_mb = MBX_2|MBX_1|MBX_0;
3102 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3103 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003104 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003105 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003106 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003107 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003108 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
3109 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3110 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003111 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003112 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af,
3113 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003114
3115 if (wr)
3116 *wr = (uint64_t) mcp->mb[5] << 48 |
3117 (uint64_t) mcp->mb[4] << 32 |
3118 (uint64_t) mcp->mb[3] << 16 |
3119 (uint64_t) mcp->mb[2];
3120 if (rd)
3121 *rd = (uint64_t) mcp->mb[9] << 48 |
3122 (uint64_t) mcp->mb[8] << 32 |
3123 (uint64_t) mcp->mb[7] << 16 |
3124 (uint64_t) mcp->mb[6];
3125 }
3126
3127 return rval;
3128}
3129
3130int
Giridhar Malavali6e980162010-03-19 17:03:58 -07003131qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
3132 uint16_t *port_speed, uint16_t *mb)
3133{
3134 int rval;
3135 mbx_cmd_t mc;
3136 mbx_cmd_t *mcp = &mc;
3137
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003138 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0,
3139 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003140
Giridhar Malavali6e980162010-03-19 17:03:58 -07003141 if (!IS_IIDMA_CAPABLE(vha->hw))
3142 return QLA_FUNCTION_FAILED;
3143
Giridhar Malavali6e980162010-03-19 17:03:58 -07003144 mcp->mb[0] = MBC_PORT_PARAMS;
3145 mcp->mb[1] = loop_id;
3146 mcp->mb[2] = mcp->mb[3] = 0;
3147 mcp->mb[9] = vha->vp_idx;
3148 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3149 mcp->in_mb = MBX_3|MBX_1|MBX_0;
3150 mcp->tov = MBX_TOV_SECONDS;
3151 mcp->flags = 0;
3152 rval = qla2x00_mailbox_command(vha, mcp);
3153
3154 /* Return mailbox statuses. */
3155 if (mb != NULL) {
3156 mb[0] = mcp->mb[0];
3157 mb[1] = mcp->mb[1];
3158 mb[3] = mcp->mb[3];
3159 }
3160
3161 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003162 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003163 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003164 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2,
3165 "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003166 if (port_speed)
3167 *port_speed = mcp->mb[3];
3168 }
3169
3170 return rval;
3171}
3172
3173int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003174qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003175 uint16_t port_speed, uint16_t *mb)
3176{
3177 int rval;
3178 mbx_cmd_t mc;
3179 mbx_cmd_t *mcp = &mc;
3180
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003181 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3,
3182 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003183
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003184 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003185 return QLA_FUNCTION_FAILED;
3186
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003187 mcp->mb[0] = MBC_PORT_PARAMS;
3188 mcp->mb[1] = loop_id;
3189 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003190 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07003191 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
3192 else
3193 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
3194 mcp->mb[9] = vha->vp_idx;
3195 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3196 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003197 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003198 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003199 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003200
3201 /* Return mailbox statuses. */
3202 if (mb != NULL) {
3203 mb[0] = mcp->mb[0];
3204 mb[1] = mcp->mb[1];
3205 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003206 }
3207
3208 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003209 ql_dbg(ql_dbg_mbx, vha, 0x10b4,
3210 "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003211 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003212 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5,
3213 "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003214 }
3215
3216 return rval;
3217}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003218
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003219void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003220qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003221 struct vp_rpt_id_entry_24xx *rptid_entry)
3222{
3223 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07003224 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003225 struct qla_hw_data *ha = vha->hw;
3226 scsi_qla_host_t *vp;
Arun Easifeafb7b2010-09-03 14:57:00 -07003227 unsigned long flags;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003228 int found;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003229
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003230 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
3231 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003232
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003233 if (rptid_entry->entry_status != 0)
3234 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003235
3236 if (rptid_entry->format == 0) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003237 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003238 "Format 0 : Number of VPs setup %d, number of "
3239 "VPs acquired %d.\n",
3240 MSB(le16_to_cpu(rptid_entry->vp_count)),
3241 LSB(le16_to_cpu(rptid_entry->vp_count)));
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003242 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b8,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003243 "Primary port id %02x%02x%02x.\n",
3244 rptid_entry->port_id[2], rptid_entry->port_id[1],
3245 rptid_entry->port_id[0]);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003246 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07003247 vp_idx = LSB(stat);
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003248 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b9,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003249 "Format 1: VP[%d] enabled - status %d - with "
3250 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003251 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003252 rptid_entry->port_id[0]);
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003253
3254 vp = vha;
3255 if (vp_idx == 0 && (MSB(stat) != 1))
3256 goto reg_needed;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003257
Saurav Kashyap681e0142012-11-21 02:40:28 -05003258 if (MSB(stat) != 0 && MSB(stat) != 2) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003259 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
3260 "Could not acquire ID for VP[%d].\n", vp_idx);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003261 return;
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07003262 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003263
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003264 found = 0;
Arun Easifeafb7b2010-09-03 14:57:00 -07003265 spin_lock_irqsave(&ha->vport_slock, flags);
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003266 list_for_each_entry(vp, &ha->vp_list, list) {
3267 if (vp_idx == vp->vp_idx) {
3268 found = 1;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003269 break;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003270 }
3271 }
Arun Easifeafb7b2010-09-03 14:57:00 -07003272 spin_unlock_irqrestore(&ha->vport_slock, flags);
3273
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003274 if (!found)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003275 return;
3276
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003277 vp->d_id.b.domain = rptid_entry->port_id[2];
3278 vp->d_id.b.area = rptid_entry->port_id[1];
3279 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003280
3281 /*
3282 * Cannot configure here as we are still sitting on the
3283 * response queue. Handle it in dpc context.
3284 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003285 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003286
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003287reg_needed:
3288 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
3289 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
3290 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003291 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003292 }
3293}
3294
3295/*
3296 * qla24xx_modify_vp_config
3297 * Change VP configuration for vha
3298 *
3299 * Input:
3300 * vha = adapter block pointer.
3301 *
3302 * Returns:
3303 * qla2xxx local function return status code.
3304 *
3305 * Context:
3306 * Kernel context.
3307 */
3308int
3309qla24xx_modify_vp_config(scsi_qla_host_t *vha)
3310{
3311 int rval;
3312 struct vp_config_entry_24xx *vpmod;
3313 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003314 struct qla_hw_data *ha = vha->hw;
3315 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003316
3317 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003318
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003319 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb,
3320 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003321
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003322 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003323 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003324 ql_log(ql_log_warn, vha, 0x10bc,
3325 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003326 return QLA_MEMORY_ALLOC_FAILED;
3327 }
3328
3329 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
3330 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
3331 vpmod->entry_count = 1;
3332 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
3333 vpmod->vp_count = 1;
3334 vpmod->vp_index1 = vha->vp_idx;
3335 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04003336
3337 qlt_modify_vp_config(vha, vpmod);
3338
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003339 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
3340 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
3341 vpmod->entry_count = 1;
3342
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003343 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003344 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003345 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
3346 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003347 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003348 ql_dbg(ql_dbg_mbx, vha, 0x10be,
3349 "Failed to complete IOCB -- error status (%x).\n",
3350 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003351 rval = QLA_FUNCTION_FAILED;
3352 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003353 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3354 "Failed to complete IOCB -- completion status (%x).\n",
3355 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003356 rval = QLA_FUNCTION_FAILED;
3357 } else {
3358 /* EMPTY */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003359 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0,
3360 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003361 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3362 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003363 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003364
3365 return rval;
3366}
3367
3368/*
3369 * qla24xx_control_vp
3370 * Enable a virtual port for given host
3371 *
3372 * Input:
3373 * ha = adapter block pointer.
3374 * vhba = virtual adapter (unused)
3375 * index = index number for enabled VP
3376 *
3377 * Returns:
3378 * qla2xxx local function return status code.
3379 *
3380 * Context:
3381 * Kernel context.
3382 */
3383int
3384qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
3385{
3386 int rval;
3387 int map, pos;
3388 struct vp_ctrl_entry_24xx *vce;
3389 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003390 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003391 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003392 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003393
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003394 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c1,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003395 "Entered %s enabling index %d.\n", __func__, vp_index);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003396
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08003397 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003398 return QLA_PARAMETER_ERROR;
3399
3400 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3401 if (!vce) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003402 ql_log(ql_log_warn, vha, 0x10c2,
3403 "Failed to allocate VP control IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003404 return QLA_MEMORY_ALLOC_FAILED;
3405 }
3406 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3407
3408 vce->entry_type = VP_CTRL_IOCB_TYPE;
3409 vce->entry_count = 1;
3410 vce->command = cpu_to_le16(cmd);
3411 vce->vp_count = __constant_cpu_to_le16(1);
3412
3413 /* index map in firmware starts with 1; decrement index
3414 * this is ok as we never use index 0
3415 */
3416 map = (vp_index - 1) / 8;
3417 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003418 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003419 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003420 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003421
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003422 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003423 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003424 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3425 "Failed to issue VP control IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003426 } else if (vce->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003427 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3428 "Failed to complete IOCB -- error status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003429 vce->entry_status);
3430 rval = QLA_FUNCTION_FAILED;
3431 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003432 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3433 "Failed to complet IOCB -- completion status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003434 le16_to_cpu(vce->comp_status));
3435 rval = QLA_FUNCTION_FAILED;
3436 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003437 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c6,
3438 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003439 }
3440
3441 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3442
3443 return rval;
3444}
3445
3446/*
3447 * qla2x00_send_change_request
3448 * Receive or disable RSCN request from fabric controller
3449 *
3450 * Input:
3451 * ha = adapter block pointer
3452 * format = registration format:
3453 * 0 - Reserved
3454 * 1 - Fabric detected registration
3455 * 2 - N_port detected registration
3456 * 3 - Full registration
3457 * FF - clear registration
3458 * vp_idx = Virtual port index
3459 *
3460 * Returns:
3461 * qla2x00 local function return status code.
3462 *
3463 * Context:
3464 * Kernel Context
3465 */
3466
3467int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003468qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003469 uint16_t vp_idx)
3470{
3471 int rval;
3472 mbx_cmd_t mc;
3473 mbx_cmd_t *mcp = &mc;
3474
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003475 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7,
3476 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003477
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003478 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3479 mcp->mb[1] = format;
3480 mcp->mb[9] = vp_idx;
3481 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3482 mcp->in_mb = MBX_0|MBX_1;
3483 mcp->tov = MBX_TOV_SECONDS;
3484 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003485 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003486
3487 if (rval == QLA_SUCCESS) {
3488 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3489 rval = BIT_1;
3490 }
3491 } else
3492 rval = BIT_1;
3493
3494 return rval;
3495}
Andrew Vasquez338c9162007-09-20 14:07:33 -07003496
3497int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003498qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07003499 uint32_t size)
3500{
3501 int rval;
3502 mbx_cmd_t mc;
3503 mbx_cmd_t *mcp = &mc;
3504
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003505 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009,
3506 "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003507
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003508 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003509 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3510 mcp->mb[8] = MSW(addr);
3511 mcp->out_mb = MBX_8|MBX_0;
3512 } else {
3513 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3514 mcp->out_mb = MBX_0;
3515 }
3516 mcp->mb[1] = LSW(addr);
3517 mcp->mb[2] = MSW(req_dma);
3518 mcp->mb[3] = LSW(req_dma);
3519 mcp->mb[6] = MSW(MSD(req_dma));
3520 mcp->mb[7] = LSW(MSD(req_dma));
3521 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003522 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003523 mcp->mb[4] = MSW(size);
3524 mcp->mb[5] = LSW(size);
3525 mcp->out_mb |= MBX_5|MBX_4;
3526 } else {
3527 mcp->mb[4] = LSW(size);
3528 mcp->out_mb |= MBX_4;
3529 }
3530
3531 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003532 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07003533 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003534 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003535
3536 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003537 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3538 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003539 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003540 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007,
3541 "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003542 }
3543
3544 return rval;
3545}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003546/* 84XX Support **************************************************************/
3547
3548struct cs84xx_mgmt_cmd {
3549 union {
3550 struct verify_chip_entry_84xx req;
3551 struct verify_chip_rsp_84xx rsp;
3552 } p;
3553};
3554
3555int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003556qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003557{
3558 int rval, retry;
3559 struct cs84xx_mgmt_cmd *mn;
3560 dma_addr_t mn_dma;
3561 uint16_t options;
3562 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003563 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003564
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003565 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8,
3566 "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003567
3568 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3569 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003570 return QLA_MEMORY_ALLOC_FAILED;
3571 }
3572
3573 /* Force Update? */
3574 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3575 /* Diagnostic firmware? */
3576 /* options |= MENLO_DIAG_FW; */
3577 /* We update the firmware with only one data sequence. */
3578 options |= VCO_END_OF_DATA;
3579
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003580 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003581 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003582 memset(mn, 0, sizeof(*mn));
3583 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3584 mn->p.req.entry_count = 1;
3585 mn->p.req.options = cpu_to_le16(options);
3586
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003587 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3588 "Dump of Verify Request.\n");
3589 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3590 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003591
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003592 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003593 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003594 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3595 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003596 goto verify_done;
3597 }
3598
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003599 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3600 "Dump of Verify Response.\n");
3601 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3602 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003603
3604 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3605 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3606 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003607 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003608 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003609
3610 if (status[0] != CS_COMPLETE) {
3611 rval = QLA_FUNCTION_FAILED;
3612 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003613 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3614 "Firmware update failed. Retrying "
3615 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003616 options |= VCO_DONT_UPDATE_FW;
3617 options &= ~VCO_FORCE_UPDATE;
3618 retry = 1;
3619 }
3620 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003621 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003622 "Firmware updated to %x.\n",
3623 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003624
3625 /* NOTE: we only update OP firmware. */
3626 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3627 ha->cs84xx->op_fw_version =
3628 le32_to_cpu(mn->p.rsp.fw_ver);
3629 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3630 flags);
3631 }
3632 } while (retry);
3633
3634verify_done:
3635 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3636
3637 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003638 ql_dbg(ql_dbg_mbx, vha, 0x10d1,
3639 "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003640 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003641 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2,
3642 "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003643 }
3644
3645 return rval;
3646}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003647
3648int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003649qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003650{
3651 int rval;
3652 unsigned long flags;
3653 mbx_cmd_t mc;
3654 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003655 struct qla_hw_data *ha = vha->hw;
3656
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003657 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
3658 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003659
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003660 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003661 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003662 mcp->mb[2] = MSW(LSD(req->dma));
3663 mcp->mb[3] = LSW(LSD(req->dma));
3664 mcp->mb[6] = MSW(MSD(req->dma));
3665 mcp->mb[7] = LSW(MSD(req->dma));
3666 mcp->mb[5] = req->length;
3667 if (req->rsp)
3668 mcp->mb[10] = req->rsp->id;
3669 mcp->mb[12] = req->qos;
3670 mcp->mb[11] = req->vp_idx;
3671 mcp->mb[13] = req->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003672 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003673 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003674
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003675 mcp->mb[4] = req->id;
3676 /* que in ptr index */
3677 mcp->mb[8] = 0;
3678 /* que out ptr index */
3679 mcp->mb[9] = 0;
3680 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3681 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3682 mcp->in_mb = MBX_0;
3683 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003684 mcp->tov = MBX_TOV_SECONDS * 2;
3685
Chad Dupuisf73cb692014-02-26 04:15:06 -05003686 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003687 mcp->in_mb |= MBX_1;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003688 if (IS_QLA83XX(ha) || !IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003689 mcp->out_mb |= MBX_15;
3690 /* debug q create issue in SR-IOV */
3691 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3692 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003693
3694 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003695 if (!(req->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003696 WRT_REG_DWORD(req->req_q_in, 0);
Chad Dupuisf73cb692014-02-26 04:15:06 -05003697 if (!IS_QLA83XX(ha) || !IS_QLA27XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003698 WRT_REG_DWORD(req->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003699 }
3700 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3701
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003702 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003703 if (rval != QLA_SUCCESS) {
3704 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3705 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3706 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003707 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5,
3708 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003709 }
3710
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003711 return rval;
3712}
3713
3714int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003715qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003716{
3717 int rval;
3718 unsigned long flags;
3719 mbx_cmd_t mc;
3720 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003721 struct qla_hw_data *ha = vha->hw;
3722
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003723 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
3724 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003725
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003726 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003727 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003728 mcp->mb[2] = MSW(LSD(rsp->dma));
3729 mcp->mb[3] = LSW(LSD(rsp->dma));
3730 mcp->mb[6] = MSW(MSD(rsp->dma));
3731 mcp->mb[7] = LSW(MSD(rsp->dma));
3732 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003733 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003734 mcp->mb[13] = rsp->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003735 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003736 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003737
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003738 mcp->mb[4] = rsp->id;
3739 /* que in ptr index */
3740 mcp->mb[8] = 0;
3741 /* que out ptr index */
3742 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003743 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003744 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3745 mcp->in_mb = MBX_0;
3746 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003747 mcp->tov = MBX_TOV_SECONDS * 2;
3748
3749 if (IS_QLA81XX(ha)) {
3750 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
3751 mcp->in_mb |= MBX_1;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003752 } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003753 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
3754 mcp->in_mb |= MBX_1;
3755 /* debug q create issue in SR-IOV */
3756 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3757 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003758
3759 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003760 if (!(rsp->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003761 WRT_REG_DWORD(rsp->rsp_q_out, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003762 if (!IS_QLA83XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003763 WRT_REG_DWORD(rsp->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003764 }
3765
3766 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3767
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003768 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003769 if (rval != QLA_SUCCESS) {
3770 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
3771 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3772 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003773 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8,
3774 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003775 }
3776
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003777 return rval;
3778}
3779
Andrew Vasquez8a659572009-02-08 20:50:12 -08003780int
3781qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3782{
3783 int rval;
3784 mbx_cmd_t mc;
3785 mbx_cmd_t *mcp = &mc;
3786
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003787 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9,
3788 "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003789
3790 mcp->mb[0] = MBC_IDC_ACK;
3791 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3792 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3793 mcp->in_mb = MBX_0;
3794 mcp->tov = MBX_TOV_SECONDS;
3795 mcp->flags = 0;
3796 rval = qla2x00_mailbox_command(vha, mcp);
3797
3798 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003799 ql_dbg(ql_dbg_mbx, vha, 0x10da,
3800 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003801 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003802 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db,
3803 "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003804 }
3805
3806 return rval;
3807}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003808
3809int
3810qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3811{
3812 int rval;
3813 mbx_cmd_t mc;
3814 mbx_cmd_t *mcp = &mc;
3815
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003816 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc,
3817 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003818
Chad Dupuisf73cb692014-02-26 04:15:06 -05003819 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
3820 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003821 return QLA_FUNCTION_FAILED;
3822
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003823 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3824 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3825 mcp->out_mb = MBX_1|MBX_0;
3826 mcp->in_mb = MBX_1|MBX_0;
3827 mcp->tov = MBX_TOV_SECONDS;
3828 mcp->flags = 0;
3829 rval = qla2x00_mailbox_command(vha, mcp);
3830
3831 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003832 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
3833 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3834 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003835 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003836 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de,
3837 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003838 *sector_size = mcp->mb[1];
3839 }
3840
3841 return rval;
3842}
3843
3844int
3845qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3846{
3847 int rval;
3848 mbx_cmd_t mc;
3849 mbx_cmd_t *mcp = &mc;
3850
Chad Dupuisf73cb692014-02-26 04:15:06 -05003851 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
3852 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003853 return QLA_FUNCTION_FAILED;
3854
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003855 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df,
3856 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003857
3858 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3859 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3860 FAC_OPT_CMD_WRITE_PROTECT;
3861 mcp->out_mb = MBX_1|MBX_0;
3862 mcp->in_mb = MBX_1|MBX_0;
3863 mcp->tov = MBX_TOV_SECONDS;
3864 mcp->flags = 0;
3865 rval = qla2x00_mailbox_command(vha, mcp);
3866
3867 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003868 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
3869 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3870 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003871 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003872 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1,
3873 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003874 }
3875
3876 return rval;
3877}
3878
3879int
3880qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3881{
3882 int rval;
3883 mbx_cmd_t mc;
3884 mbx_cmd_t *mcp = &mc;
3885
Chad Dupuisf73cb692014-02-26 04:15:06 -05003886 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
3887 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003888 return QLA_FUNCTION_FAILED;
3889
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003890 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,
3891 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003892
3893 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3894 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3895 mcp->mb[2] = LSW(start);
3896 mcp->mb[3] = MSW(start);
3897 mcp->mb[4] = LSW(finish);
3898 mcp->mb[5] = MSW(finish);
3899 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3900 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3901 mcp->tov = MBX_TOV_SECONDS;
3902 mcp->flags = 0;
3903 rval = qla2x00_mailbox_command(vha, mcp);
3904
3905 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003906 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
3907 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3908 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003909 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003910 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,
3911 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003912 }
3913
3914 return rval;
3915}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003916
3917int
3918qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3919{
3920 int rval = 0;
3921 mbx_cmd_t mc;
3922 mbx_cmd_t *mcp = &mc;
3923
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003924 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5,
3925 "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003926
3927 mcp->mb[0] = MBC_RESTART_MPI_FW;
3928 mcp->out_mb = MBX_0;
3929 mcp->in_mb = MBX_0|MBX_1;
3930 mcp->tov = MBX_TOV_SECONDS;
3931 mcp->flags = 0;
3932 rval = qla2x00_mailbox_command(vha, mcp);
3933
3934 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003935 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
3936 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3937 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003938 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003939 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7,
3940 "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003941 }
3942
3943 return rval;
3944}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003945
Joe Carnuccioc46e65c2013-08-27 01:37:35 -04003946int
3947qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version)
3948{
3949 int rval;
3950 mbx_cmd_t mc;
3951 mbx_cmd_t *mcp = &mc;
3952 int i;
3953 int len;
3954 uint16_t *str;
3955 struct qla_hw_data *ha = vha->hw;
3956
3957 if (!IS_P3P_TYPE(ha))
3958 return QLA_FUNCTION_FAILED;
3959
3960 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b,
3961 "Entered %s.\n", __func__);
3962
3963 str = (void *)version;
3964 len = strlen(version);
3965
3966 mcp->mb[0] = MBC_SET_RNID_PARAMS;
3967 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8;
3968 mcp->out_mb = MBX_1|MBX_0;
3969 for (i = 4; i < 16 && len; i++, str++, len -= 2) {
3970 mcp->mb[i] = cpu_to_le16p(str);
3971 mcp->out_mb |= 1<<i;
3972 }
3973 for (; i < 16; i++) {
3974 mcp->mb[i] = 0;
3975 mcp->out_mb |= 1<<i;
3976 }
3977 mcp->in_mb = MBX_1|MBX_0;
3978 mcp->tov = MBX_TOV_SECONDS;
3979 mcp->flags = 0;
3980 rval = qla2x00_mailbox_command(vha, mcp);
3981
3982 if (rval != QLA_SUCCESS) {
3983 ql_dbg(ql_dbg_mbx, vha, 0x117c,
3984 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
3985 } else {
3986 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d,
3987 "Done %s.\n", __func__);
3988 }
3989
3990 return rval;
3991}
3992
3993int
3994qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version)
3995{
3996 int rval;
3997 mbx_cmd_t mc;
3998 mbx_cmd_t *mcp = &mc;
3999 int len;
4000 uint16_t dwlen;
4001 uint8_t *str;
4002 dma_addr_t str_dma;
4003 struct qla_hw_data *ha = vha->hw;
4004
4005 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) ||
4006 IS_P3P_TYPE(ha))
4007 return QLA_FUNCTION_FAILED;
4008
4009 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e,
4010 "Entered %s.\n", __func__);
4011
4012 str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);
4013 if (!str) {
4014 ql_log(ql_log_warn, vha, 0x117f,
4015 "Failed to allocate driver version param.\n");
4016 return QLA_MEMORY_ALLOC_FAILED;
4017 }
4018
4019 memcpy(str, "\x7\x3\x11\x0", 4);
4020 dwlen = str[0];
4021 len = dwlen * 4 - 4;
4022 memset(str + 4, 0, len);
4023 if (len > strlen(version))
4024 len = strlen(version);
4025 memcpy(str + 4, version, len);
4026
4027 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4028 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;
4029 mcp->mb[2] = MSW(LSD(str_dma));
4030 mcp->mb[3] = LSW(LSD(str_dma));
4031 mcp->mb[6] = MSW(MSD(str_dma));
4032 mcp->mb[7] = LSW(MSD(str_dma));
4033 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4034 mcp->in_mb = MBX_1|MBX_0;
4035 mcp->tov = MBX_TOV_SECONDS;
4036 mcp->flags = 0;
4037 rval = qla2x00_mailbox_command(vha, mcp);
4038
4039 if (rval != QLA_SUCCESS) {
4040 ql_dbg(ql_dbg_mbx, vha, 0x1180,
4041 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4042 } else {
4043 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181,
4044 "Done %s.\n", __func__);
4045 }
4046
4047 dma_pool_free(ha->s_dma_pool, str, str_dma);
4048
4049 return rval;
4050}
4051
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004052static int
4053qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
4054{
4055 int rval;
4056 mbx_cmd_t mc;
4057 mbx_cmd_t *mcp = &mc;
4058
4059 if (!IS_FWI2_CAPABLE(vha->hw))
4060 return QLA_FUNCTION_FAILED;
4061
4062 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4063 "Entered %s.\n", __func__);
4064
4065 mcp->mb[0] = MBC_GET_RNID_PARAMS;
4066 mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8;
4067 mcp->out_mb = MBX_1|MBX_0;
4068 mcp->in_mb = MBX_1|MBX_0;
4069 mcp->tov = MBX_TOV_SECONDS;
4070 mcp->flags = 0;
4071 rval = qla2x00_mailbox_command(vha, mcp);
4072 *temp = mcp->mb[1];
4073
4074 if (rval != QLA_SUCCESS) {
4075 ql_dbg(ql_dbg_mbx, vha, 0x115a,
4076 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4077 } else {
4078 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4079 "Done %s.\n", __func__);
4080 }
4081
4082 return rval;
4083}
4084
Joe Carnuccio3a117112013-02-08 01:58:00 -05004085int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004086qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4087 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004088{
4089 int rval;
4090 mbx_cmd_t mc;
4091 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004092 struct qla_hw_data *ha = vha->hw;
4093
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004094 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,
4095 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004096
Joe Carnuccio6766df92011-05-10 11:30:15 -07004097 if (!IS_FWI2_CAPABLE(ha))
4098 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004099
Joe Carnuccio6766df92011-05-10 11:30:15 -07004100 if (len == 1)
4101 opt |= BIT_0;
4102
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004103 mcp->mb[0] = MBC_READ_SFP;
4104 mcp->mb[1] = dev;
4105 mcp->mb[2] = MSW(sfp_dma);
4106 mcp->mb[3] = LSW(sfp_dma);
4107 mcp->mb[6] = MSW(MSD(sfp_dma));
4108 mcp->mb[7] = LSW(MSD(sfp_dma));
4109 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004110 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004111 mcp->mb[10] = opt;
4112 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 -07004113 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004114 mcp->tov = MBX_TOV_SECONDS;
4115 mcp->flags = 0;
4116 rval = qla2x00_mailbox_command(vha, mcp);
4117
4118 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004119 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004120
4121 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004122 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
4123 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004124 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004125 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
4126 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004127 }
4128
4129 return rval;
4130}
4131
4132int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004133qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4134 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004135{
4136 int rval;
4137 mbx_cmd_t mc;
4138 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004139 struct qla_hw_data *ha = vha->hw;
4140
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004141 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb,
4142 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004143
Joe Carnuccio6766df92011-05-10 11:30:15 -07004144 if (!IS_FWI2_CAPABLE(ha))
4145 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004146
Joe Carnuccio6766df92011-05-10 11:30:15 -07004147 if (len == 1)
4148 opt |= BIT_0;
4149
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004150 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004151 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004152
4153 mcp->mb[0] = MBC_WRITE_SFP;
4154 mcp->mb[1] = dev;
4155 mcp->mb[2] = MSW(sfp_dma);
4156 mcp->mb[3] = LSW(sfp_dma);
4157 mcp->mb[6] = MSW(MSD(sfp_dma));
4158 mcp->mb[7] = LSW(MSD(sfp_dma));
4159 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004160 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004161 mcp->mb[10] = opt;
4162 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 -07004163 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004164 mcp->tov = MBX_TOV_SECONDS;
4165 mcp->flags = 0;
4166 rval = qla2x00_mailbox_command(vha, mcp);
4167
4168 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004169 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
4170 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004171 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004172 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed,
4173 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004174 }
4175
4176 return rval;
4177}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004178
4179int
4180qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
4181 uint16_t size_in_bytes, uint16_t *actual_size)
4182{
4183 int rval;
4184 mbx_cmd_t mc;
4185 mbx_cmd_t *mcp = &mc;
4186
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004187 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee,
4188 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004189
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004190 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004191 return QLA_FUNCTION_FAILED;
4192
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004193 mcp->mb[0] = MBC_GET_XGMAC_STATS;
4194 mcp->mb[2] = MSW(stats_dma);
4195 mcp->mb[3] = LSW(stats_dma);
4196 mcp->mb[6] = MSW(MSD(stats_dma));
4197 mcp->mb[7] = LSW(MSD(stats_dma));
4198 mcp->mb[8] = size_in_bytes >> 2;
4199 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4200 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4201 mcp->tov = MBX_TOV_SECONDS;
4202 mcp->flags = 0;
4203 rval = qla2x00_mailbox_command(vha, mcp);
4204
4205 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004206 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
4207 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4208 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004209 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004210 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0,
4211 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004212
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004213
4214 *actual_size = mcp->mb[2] << 2;
4215 }
4216
4217 return rval;
4218}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004219
4220int
4221qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
4222 uint16_t size)
4223{
4224 int rval;
4225 mbx_cmd_t mc;
4226 mbx_cmd_t *mcp = &mc;
4227
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004228 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1,
4229 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004230
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004231 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004232 return QLA_FUNCTION_FAILED;
4233
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004234 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4235 mcp->mb[1] = 0;
4236 mcp->mb[2] = MSW(tlv_dma);
4237 mcp->mb[3] = LSW(tlv_dma);
4238 mcp->mb[6] = MSW(MSD(tlv_dma));
4239 mcp->mb[7] = LSW(MSD(tlv_dma));
4240 mcp->mb[8] = size;
4241 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4242 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4243 mcp->tov = MBX_TOV_SECONDS;
4244 mcp->flags = 0;
4245 rval = qla2x00_mailbox_command(vha, mcp);
4246
4247 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004248 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
4249 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4250 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004251 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004252 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3,
4253 "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004254 }
4255
4256 return rval;
4257}
Andrew Vasquez18e75552009-06-03 09:55:30 -07004258
4259int
4260qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
4261{
4262 int rval;
4263 mbx_cmd_t mc;
4264 mbx_cmd_t *mcp = &mc;
4265
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004266 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4,
4267 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004268
Andrew Vasquez18e75552009-06-03 09:55:30 -07004269 if (!IS_FWI2_CAPABLE(vha->hw))
4270 return QLA_FUNCTION_FAILED;
4271
Andrew Vasquez18e75552009-06-03 09:55:30 -07004272 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
4273 mcp->mb[1] = LSW(risc_addr);
4274 mcp->mb[8] = MSW(risc_addr);
4275 mcp->out_mb = MBX_8|MBX_1|MBX_0;
4276 mcp->in_mb = MBX_3|MBX_2|MBX_0;
4277 mcp->tov = 30;
4278 mcp->flags = 0;
4279 rval = qla2x00_mailbox_command(vha, mcp);
4280 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004281 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
4282 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004283 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004284 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6,
4285 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004286 *data = mcp->mb[3] << 16 | mcp->mb[2];
4287 }
4288
4289 return rval;
4290}
4291
4292int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004293qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4294 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004295{
4296 int rval;
4297 mbx_cmd_t mc;
4298 mbx_cmd_t *mcp = &mc;
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004299
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004300 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7,
4301 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004302
4303 memset(mcp->mb, 0 , sizeof(mcp->mb));
4304 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
4305 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
4306
4307 /* transfer count */
4308 mcp->mb[10] = LSW(mreq->transfer_size);
4309 mcp->mb[11] = MSW(mreq->transfer_size);
4310
4311 /* send data address */
4312 mcp->mb[14] = LSW(mreq->send_dma);
4313 mcp->mb[15] = MSW(mreq->send_dma);
4314 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4315 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4316
Lucas De Marchi25985ed2011-03-30 22:57:33 -03004317 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004318 mcp->mb[16] = LSW(mreq->rcv_dma);
4319 mcp->mb[17] = MSW(mreq->rcv_dma);
4320 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4321 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4322
4323 /* Iteration count */
Joe Carnuccio1b98b422013-03-28 08:21:26 -04004324 mcp->mb[18] = LSW(mreq->iteration_count);
4325 mcp->mb[19] = MSW(mreq->iteration_count);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004326
4327 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
4328 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 -08004329 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004330 mcp->out_mb |= MBX_2;
4331 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
4332
4333 mcp->buf_size = mreq->transfer_size;
4334 mcp->tov = MBX_TOV_SECONDS;
4335 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4336
4337 rval = qla2x00_mailbox_command(vha, mcp);
4338
4339 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004340 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
4341 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
4342 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
4343 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004344 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004345 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9,
4346 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004347 }
4348
4349 /* Copy mailbox information */
4350 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004351 return rval;
4352}
4353
4354int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004355qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4356 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004357{
4358 int rval;
4359 mbx_cmd_t mc;
4360 mbx_cmd_t *mcp = &mc;
4361 struct qla_hw_data *ha = vha->hw;
4362
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004363 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa,
4364 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004365
4366 memset(mcp->mb, 0 , sizeof(mcp->mb));
4367 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
4368 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004369 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004370 mcp->mb[1] |= BIT_15;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004371 mcp->mb[2] = vha->fcoe_fcf_idx;
4372 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004373 mcp->mb[16] = LSW(mreq->rcv_dma);
4374 mcp->mb[17] = MSW(mreq->rcv_dma);
4375 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4376 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4377
4378 mcp->mb[10] = LSW(mreq->transfer_size);
4379
4380 mcp->mb[14] = LSW(mreq->send_dma);
4381 mcp->mb[15] = MSW(mreq->send_dma);
4382 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4383 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4384
4385 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
4386 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004387 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004388 mcp->out_mb |= MBX_2;
4389
4390 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004391 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
4392 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004393 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004394 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004395 mcp->in_mb |= MBX_3;
4396
4397 mcp->tov = MBX_TOV_SECONDS;
4398 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4399 mcp->buf_size = mreq->transfer_size;
4400
4401 rval = qla2x00_mailbox_command(vha, mcp);
4402
4403 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004404 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
4405 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4406 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004407 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004408 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc,
4409 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004410 }
4411
4412 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07004413 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004414 return rval;
4415}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07004416
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004417int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004418qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004419{
4420 int rval;
4421 mbx_cmd_t mc;
4422 mbx_cmd_t *mcp = &mc;
4423
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004424 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004425 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004426
4427 mcp->mb[0] = MBC_ISP84XX_RESET;
4428 mcp->mb[1] = enable_diagnostic;
4429 mcp->out_mb = MBX_1|MBX_0;
4430 mcp->in_mb = MBX_1|MBX_0;
4431 mcp->tov = MBX_TOV_SECONDS;
4432 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004433 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004434
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004435 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004436 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004437 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004438 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff,
4439 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004440
4441 return rval;
4442}
4443
4444int
Andrew Vasquez18e75552009-06-03 09:55:30 -07004445qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
4446{
4447 int rval;
4448 mbx_cmd_t mc;
4449 mbx_cmd_t *mcp = &mc;
4450
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004451 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100,
4452 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004453
Andrew Vasquez18e75552009-06-03 09:55:30 -07004454 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07004455 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07004456
Andrew Vasquez18e75552009-06-03 09:55:30 -07004457 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
4458 mcp->mb[1] = LSW(risc_addr);
4459 mcp->mb[2] = LSW(data);
4460 mcp->mb[3] = MSW(data);
4461 mcp->mb[8] = MSW(risc_addr);
4462 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
4463 mcp->in_mb = MBX_0;
4464 mcp->tov = 30;
4465 mcp->flags = 0;
4466 rval = qla2x00_mailbox_command(vha, mcp);
4467 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004468 ql_dbg(ql_dbg_mbx, vha, 0x1101,
4469 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004470 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004471 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
4472 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004473 }
4474
4475 return rval;
4476}
Michael Hernandez3064ff32009-12-15 21:29:44 -08004477
4478int
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004479qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
4480{
4481 int rval;
4482 uint32_t stat, timer;
4483 uint16_t mb0 = 0;
4484 struct qla_hw_data *ha = vha->hw;
4485 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
4486
4487 rval = QLA_SUCCESS;
4488
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004489 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103,
4490 "Entered %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004491
4492 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
4493
4494 /* Write the MBC data to the registers */
4495 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
4496 WRT_REG_WORD(&reg->mailbox1, mb[0]);
4497 WRT_REG_WORD(&reg->mailbox2, mb[1]);
4498 WRT_REG_WORD(&reg->mailbox3, mb[2]);
4499 WRT_REG_WORD(&reg->mailbox4, mb[3]);
4500
4501 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
4502
4503 /* Poll for MBC interrupt */
4504 for (timer = 6000000; timer; timer--) {
4505 /* Check for pending interrupts. */
4506 stat = RD_REG_DWORD(&reg->host_status);
4507 if (stat & HSRX_RISC_INT) {
4508 stat &= 0xff;
4509
4510 if (stat == 0x1 || stat == 0x2 ||
4511 stat == 0x10 || stat == 0x11) {
4512 set_bit(MBX_INTERRUPT,
4513 &ha->mbx_cmd_flags);
4514 mb0 = RD_REG_WORD(&reg->mailbox0);
4515 WRT_REG_DWORD(&reg->hccr,
4516 HCCRX_CLR_RISC_INT);
4517 RD_REG_DWORD(&reg->hccr);
4518 break;
4519 }
4520 }
4521 udelay(5);
4522 }
4523
4524 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
4525 rval = mb0 & MBS_MASK;
4526 else
4527 rval = QLA_FUNCTION_FAILED;
4528
4529 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004530 ql_dbg(ql_dbg_mbx, vha, 0x1104,
4531 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004532 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004533 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105,
4534 "Done %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004535 }
4536
4537 return rval;
4538}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004539
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004540int
Michael Hernandez3064ff32009-12-15 21:29:44 -08004541qla2x00_get_data_rate(scsi_qla_host_t *vha)
4542{
4543 int rval;
4544 mbx_cmd_t mc;
4545 mbx_cmd_t *mcp = &mc;
4546 struct qla_hw_data *ha = vha->hw;
4547
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004548 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
4549 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004550
Michael Hernandez3064ff32009-12-15 21:29:44 -08004551 if (!IS_FWI2_CAPABLE(ha))
4552 return QLA_FUNCTION_FAILED;
4553
Michael Hernandez3064ff32009-12-15 21:29:44 -08004554 mcp->mb[0] = MBC_DATA_RATE;
4555 mcp->mb[1] = 0;
4556 mcp->out_mb = MBX_1|MBX_0;
4557 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004558 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004559 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08004560 mcp->tov = MBX_TOV_SECONDS;
4561 mcp->flags = 0;
4562 rval = qla2x00_mailbox_command(vha, mcp);
4563 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004564 ql_dbg(ql_dbg_mbx, vha, 0x1107,
4565 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004566 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004567 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
4568 "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004569 if (mcp->mb[1] != 0x7)
4570 ha->link_data_rate = mcp->mb[1];
4571 }
4572
4573 return rval;
4574}
Sarang Radke09ff7012010-03-19 17:03:59 -07004575
4576int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004577qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4578{
4579 int rval;
4580 mbx_cmd_t mc;
4581 mbx_cmd_t *mcp = &mc;
4582 struct qla_hw_data *ha = vha->hw;
4583
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004584 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
4585 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004586
Chad Dupuisf73cb692014-02-26 04:15:06 -05004587 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) &&
4588 !IS_QLA27XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004589 return QLA_FUNCTION_FAILED;
4590 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4591 mcp->out_mb = MBX_0;
4592 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4593 mcp->tov = MBX_TOV_SECONDS;
4594 mcp->flags = 0;
4595
4596 rval = qla2x00_mailbox_command(vha, mcp);
4597
4598 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004599 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4600 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004601 } else {
4602 /* Copy all bits to preserve original value */
4603 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4604
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004605 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b,
4606 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004607 }
4608 return rval;
4609}
4610
4611int
4612qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4613{
4614 int rval;
4615 mbx_cmd_t mc;
4616 mbx_cmd_t *mcp = &mc;
4617
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004618 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c,
4619 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004620
4621 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4622 /* Copy all bits to preserve original setting */
4623 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4624 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4625 mcp->in_mb = MBX_0;
4626 mcp->tov = MBX_TOV_SECONDS;
4627 mcp->flags = 0;
4628 rval = qla2x00_mailbox_command(vha, mcp);
4629
4630 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004631 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4632 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004633 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004634 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e,
4635 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004636
4637 return rval;
4638}
4639
4640
4641int
Sarang Radke09ff7012010-03-19 17:03:59 -07004642qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4643 uint16_t *mb)
4644{
4645 int rval;
4646 mbx_cmd_t mc;
4647 mbx_cmd_t *mcp = &mc;
4648 struct qla_hw_data *ha = vha->hw;
4649
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004650 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f,
4651 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004652
Sarang Radke09ff7012010-03-19 17:03:59 -07004653 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4654 return QLA_FUNCTION_FAILED;
4655
Sarang Radke09ff7012010-03-19 17:03:59 -07004656 mcp->mb[0] = MBC_PORT_PARAMS;
4657 mcp->mb[1] = loop_id;
4658 if (ha->flags.fcp_prio_enabled)
4659 mcp->mb[2] = BIT_1;
4660 else
4661 mcp->mb[2] = BIT_2;
4662 mcp->mb[4] = priority & 0xf;
4663 mcp->mb[9] = vha->vp_idx;
4664 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4665 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4666 mcp->tov = 30;
4667 mcp->flags = 0;
4668 rval = qla2x00_mailbox_command(vha, mcp);
4669 if (mb != NULL) {
4670 mb[0] = mcp->mb[0];
4671 mb[1] = mcp->mb[1];
4672 mb[3] = mcp->mb[3];
4673 mb[4] = mcp->mb[4];
4674 }
4675
4676 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004677 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07004678 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004679 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc,
4680 "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07004681 }
4682
4683 return rval;
4684}
Giridhar Malavalia9083012010-04-12 17:59:55 -07004685
4686int
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004687qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)
Andrew Vasquez794a5692010-12-21 16:00:21 -08004688{
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004689 int rval = QLA_FUNCTION_FAILED;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004690 struct qla_hw_data *ha = vha->hw;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004691 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004692
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004693 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) {
4694 ql_dbg(ql_dbg_mbx, vha, 0x1150,
4695 "Thermal not supported by this card.\n");
4696 return rval;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004697 }
Andrew Vasquez794a5692010-12-21 16:00:21 -08004698
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004699 if (IS_QLA25XX(ha)) {
4700 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
4701 ha->pdev->subsystem_device == 0x0175) {
4702 rval = qla2x00_read_sfp(vha, 0, &byte,
4703 0x98, 0x1, 1, BIT_13|BIT_0);
4704 *temp = byte;
4705 return rval;
4706 }
4707 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
4708 ha->pdev->subsystem_device == 0x338e) {
4709 rval = qla2x00_read_sfp(vha, 0, &byte,
4710 0x98, 0x1, 1, BIT_15|BIT_14|BIT_0);
4711 *temp = byte;
4712 return rval;
4713 }
4714 ql_dbg(ql_dbg_mbx, vha, 0x10c9,
4715 "Thermal not supported by this card.\n");
4716 return rval;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004717 }
4718
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004719 if (IS_QLA82XX(ha)) {
4720 *temp = qla82xx_read_temperature(vha);
4721 rval = QLA_SUCCESS;
4722 return rval;
4723 } else if (IS_QLA8044(ha)) {
4724 *temp = qla8044_read_temperature(vha);
4725 rval = QLA_SUCCESS;
4726 return rval;
4727 }
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004728
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004729 rval = qla2x00_read_asic_temperature(vha, temp);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004730 return rval;
4731}
4732
4733int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004734qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
4735{
4736 int rval;
4737 struct qla_hw_data *ha = vha->hw;
4738 mbx_cmd_t mc;
4739 mbx_cmd_t *mcp = &mc;
4740
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004741 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017,
4742 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004743
Giridhar Malavalia9083012010-04-12 17:59:55 -07004744 if (!IS_FWI2_CAPABLE(ha))
4745 return QLA_FUNCTION_FAILED;
4746
Giridhar Malavalia9083012010-04-12 17:59:55 -07004747 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004748 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004749 mcp->mb[1] = 1;
4750
4751 mcp->out_mb = MBX_1|MBX_0;
4752 mcp->in_mb = MBX_0;
4753 mcp->tov = 30;
4754 mcp->flags = 0;
4755
4756 rval = qla2x00_mailbox_command(vha, mcp);
4757 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004758 ql_dbg(ql_dbg_mbx, vha, 0x1016,
4759 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004760 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004761 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e,
4762 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004763 }
4764
4765 return rval;
4766}
4767
4768int
4769qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4770{
4771 int rval;
4772 struct qla_hw_data *ha = vha->hw;
4773 mbx_cmd_t mc;
4774 mbx_cmd_t *mcp = &mc;
4775
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004776 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
4777 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004778
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04004779 if (!IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -07004780 return QLA_FUNCTION_FAILED;
4781
Giridhar Malavalia9083012010-04-12 17:59:55 -07004782 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004783 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004784 mcp->mb[1] = 0;
4785
4786 mcp->out_mb = MBX_1|MBX_0;
4787 mcp->in_mb = MBX_0;
4788 mcp->tov = 30;
4789 mcp->flags = 0;
4790
4791 rval = qla2x00_mailbox_command(vha, mcp);
4792 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004793 ql_dbg(ql_dbg_mbx, vha, 0x100c,
4794 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004795 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004796 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b,
4797 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004798 }
4799
4800 return rval;
4801}
Giridhar Malavali08de2842011-08-16 11:31:44 -07004802
4803int
4804qla82xx_md_get_template_size(scsi_qla_host_t *vha)
4805{
4806 struct qla_hw_data *ha = vha->hw;
4807 mbx_cmd_t mc;
4808 mbx_cmd_t *mcp = &mc;
4809 int rval = QLA_FUNCTION_FAILED;
4810
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004811 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f,
4812 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004813
4814 memset(mcp->mb, 0 , sizeof(mcp->mb));
4815 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4816 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4817 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
4818 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
4819
4820 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4821 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
4822 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4823
4824 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4825 mcp->tov = MBX_TOV_SECONDS;
4826 rval = qla2x00_mailbox_command(vha, mcp);
4827
4828 /* Always copy back return mailbox values. */
4829 if (rval != QLA_SUCCESS) {
4830 ql_dbg(ql_dbg_mbx, vha, 0x1120,
4831 "mailbox command FAILED=0x%x, subcode=%x.\n",
4832 (mcp->mb[1] << 16) | mcp->mb[0],
4833 (mcp->mb[3] << 16) | mcp->mb[2]);
4834 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004835 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121,
4836 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004837 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
4838 if (!ha->md_template_size) {
4839 ql_dbg(ql_dbg_mbx, vha, 0x1122,
4840 "Null template size obtained.\n");
4841 rval = QLA_FUNCTION_FAILED;
4842 }
4843 }
4844 return rval;
4845}
4846
4847int
4848qla82xx_md_get_template(scsi_qla_host_t *vha)
4849{
4850 struct qla_hw_data *ha = vha->hw;
4851 mbx_cmd_t mc;
4852 mbx_cmd_t *mcp = &mc;
4853 int rval = QLA_FUNCTION_FAILED;
4854
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004855 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123,
4856 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004857
4858 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4859 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4860 if (!ha->md_tmplt_hdr) {
4861 ql_log(ql_log_warn, vha, 0x1124,
4862 "Unable to allocate memory for Minidump template.\n");
4863 return rval;
4864 }
4865
4866 memset(mcp->mb, 0 , sizeof(mcp->mb));
4867 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4868 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4869 mcp->mb[2] = LSW(RQST_TMPLT);
4870 mcp->mb[3] = MSW(RQST_TMPLT);
4871 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
4872 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
4873 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
4874 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
4875 mcp->mb[8] = LSW(ha->md_template_size);
4876 mcp->mb[9] = MSW(ha->md_template_size);
4877
4878 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4879 mcp->tov = MBX_TOV_SECONDS;
4880 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4881 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4882 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4883 rval = qla2x00_mailbox_command(vha, mcp);
4884
4885 if (rval != QLA_SUCCESS) {
4886 ql_dbg(ql_dbg_mbx, vha, 0x1125,
4887 "mailbox command FAILED=0x%x, subcode=%x.\n",
4888 ((mcp->mb[1] << 16) | mcp->mb[0]),
4889 ((mcp->mb[3] << 16) | mcp->mb[2]));
4890 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004891 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126,
4892 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004893 return rval;
4894}
Saurav Kashyap999916d2011-08-16 11:31:45 -07004895
4896int
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04004897qla8044_md_get_template(scsi_qla_host_t *vha)
4898{
4899 struct qla_hw_data *ha = vha->hw;
4900 mbx_cmd_t mc;
4901 mbx_cmd_t *mcp = &mc;
4902 int rval = QLA_FUNCTION_FAILED;
4903 int offset = 0, size = MINIDUMP_SIZE_36K;
4904 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,
4905 "Entered %s.\n", __func__);
4906
4907 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4908 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4909 if (!ha->md_tmplt_hdr) {
4910 ql_log(ql_log_warn, vha, 0xb11b,
4911 "Unable to allocate memory for Minidump template.\n");
4912 return rval;
4913 }
4914
4915 memset(mcp->mb, 0 , sizeof(mcp->mb));
4916 while (offset < ha->md_template_size) {
4917 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4918 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4919 mcp->mb[2] = LSW(RQST_TMPLT);
4920 mcp->mb[3] = MSW(RQST_TMPLT);
4921 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));
4922 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));
4923 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));
4924 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));
4925 mcp->mb[8] = LSW(size);
4926 mcp->mb[9] = MSW(size);
4927 mcp->mb[10] = offset & 0x0000FFFF;
4928 mcp->mb[11] = offset & 0xFFFF0000;
4929 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4930 mcp->tov = MBX_TOV_SECONDS;
4931 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4932 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4933 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4934 rval = qla2x00_mailbox_command(vha, mcp);
4935
4936 if (rval != QLA_SUCCESS) {
4937 ql_dbg(ql_dbg_mbx, vha, 0xb11c,
4938 "mailbox command FAILED=0x%x, subcode=%x.\n",
4939 ((mcp->mb[1] << 16) | mcp->mb[0]),
4940 ((mcp->mb[3] << 16) | mcp->mb[2]));
4941 return rval;
4942 } else
4943 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,
4944 "Done %s.\n", __func__);
4945 offset = offset + size;
4946 }
4947 return rval;
4948}
4949
4950int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004951qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4952{
4953 int rval;
4954 struct qla_hw_data *ha = vha->hw;
4955 mbx_cmd_t mc;
4956 mbx_cmd_t *mcp = &mc;
4957
4958 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4959 return QLA_FUNCTION_FAILED;
4960
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004961 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133,
4962 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004963
4964 memset(mcp, 0, sizeof(mbx_cmd_t));
4965 mcp->mb[0] = MBC_SET_LED_CONFIG;
4966 mcp->mb[1] = led_cfg[0];
4967 mcp->mb[2] = led_cfg[1];
4968 if (IS_QLA8031(ha)) {
4969 mcp->mb[3] = led_cfg[2];
4970 mcp->mb[4] = led_cfg[3];
4971 mcp->mb[5] = led_cfg[4];
4972 mcp->mb[6] = led_cfg[5];
4973 }
4974
4975 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4976 if (IS_QLA8031(ha))
4977 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4978 mcp->in_mb = MBX_0;
4979 mcp->tov = 30;
4980 mcp->flags = 0;
4981
4982 rval = qla2x00_mailbox_command(vha, mcp);
4983 if (rval != QLA_SUCCESS) {
4984 ql_dbg(ql_dbg_mbx, vha, 0x1134,
4985 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4986 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004987 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135,
4988 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004989 }
4990
4991 return rval;
4992}
4993
4994int
4995qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4996{
4997 int rval;
4998 struct qla_hw_data *ha = vha->hw;
4999 mbx_cmd_t mc;
5000 mbx_cmd_t *mcp = &mc;
5001
5002 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5003 return QLA_FUNCTION_FAILED;
5004
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005005 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136,
5006 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005007
5008 memset(mcp, 0, sizeof(mbx_cmd_t));
5009 mcp->mb[0] = MBC_GET_LED_CONFIG;
5010
5011 mcp->out_mb = MBX_0;
5012 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5013 if (IS_QLA8031(ha))
5014 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5015 mcp->tov = 30;
5016 mcp->flags = 0;
5017
5018 rval = qla2x00_mailbox_command(vha, mcp);
5019 if (rval != QLA_SUCCESS) {
5020 ql_dbg(ql_dbg_mbx, vha, 0x1137,
5021 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5022 } else {
5023 led_cfg[0] = mcp->mb[1];
5024 led_cfg[1] = mcp->mb[2];
5025 if (IS_QLA8031(ha)) {
5026 led_cfg[2] = mcp->mb[3];
5027 led_cfg[3] = mcp->mb[4];
5028 led_cfg[4] = mcp->mb[5];
5029 led_cfg[5] = mcp->mb[6];
5030 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005031 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138,
5032 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005033 }
5034
5035 return rval;
5036}
5037
5038int
Saurav Kashyap999916d2011-08-16 11:31:45 -07005039qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
5040{
5041 int rval;
5042 struct qla_hw_data *ha = vha->hw;
5043 mbx_cmd_t mc;
5044 mbx_cmd_t *mcp = &mc;
5045
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005046 if (!IS_P3P_TYPE(ha))
Saurav Kashyap999916d2011-08-16 11:31:45 -07005047 return QLA_FUNCTION_FAILED;
5048
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005049 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005050 "Entered %s.\n", __func__);
5051
5052 memset(mcp, 0, sizeof(mbx_cmd_t));
5053 mcp->mb[0] = MBC_SET_LED_CONFIG;
5054 if (enable)
5055 mcp->mb[7] = 0xE;
5056 else
5057 mcp->mb[7] = 0xD;
5058
5059 mcp->out_mb = MBX_7|MBX_0;
5060 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005061 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07005062 mcp->flags = 0;
5063
5064 rval = qla2x00_mailbox_command(vha, mcp);
5065 if (rval != QLA_SUCCESS) {
5066 ql_dbg(ql_dbg_mbx, vha, 0x1128,
5067 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5068 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005069 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005070 "Done %s.\n", __func__);
5071 }
5072
5073 return rval;
5074}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005075
5076int
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005077qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005078{
5079 int rval;
5080 struct qla_hw_data *ha = vha->hw;
5081 mbx_cmd_t mc;
5082 mbx_cmd_t *mcp = &mc;
5083
Chad Dupuisf73cb692014-02-26 04:15:06 -05005084 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005085 return QLA_FUNCTION_FAILED;
5086
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005087 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130,
5088 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005089
5090 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
5091 mcp->mb[1] = LSW(reg);
5092 mcp->mb[2] = MSW(reg);
5093 mcp->mb[3] = LSW(data);
5094 mcp->mb[4] = MSW(data);
5095 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5096
5097 mcp->in_mb = MBX_1|MBX_0;
5098 mcp->tov = MBX_TOV_SECONDS;
5099 mcp->flags = 0;
5100 rval = qla2x00_mailbox_command(vha, mcp);
5101
5102 if (rval != QLA_SUCCESS) {
5103 ql_dbg(ql_dbg_mbx, vha, 0x1131,
5104 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5105 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005106 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005107 "Done %s.\n", __func__);
5108 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005109
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005110 return rval;
5111}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005112
5113int
5114qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
5115{
5116 int rval;
5117 struct qla_hw_data *ha = vha->hw;
5118 mbx_cmd_t mc;
5119 mbx_cmd_t *mcp = &mc;
5120
5121 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005122 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b,
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005123 "Implicit LOGO Unsupported.\n");
5124 return QLA_FUNCTION_FAILED;
5125 }
5126
5127
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005128 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c,
5129 "Entering %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005130
5131 /* Perform Implicit LOGO. */
5132 mcp->mb[0] = MBC_PORT_LOGOUT;
5133 mcp->mb[1] = fcport->loop_id;
5134 mcp->mb[10] = BIT_15;
5135 mcp->out_mb = MBX_10|MBX_1|MBX_0;
5136 mcp->in_mb = MBX_0;
5137 mcp->tov = MBX_TOV_SECONDS;
5138 mcp->flags = 0;
5139 rval = qla2x00_mailbox_command(vha, mcp);
5140 if (rval != QLA_SUCCESS)
5141 ql_dbg(ql_dbg_mbx, vha, 0x113d,
5142 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5143 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005144 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e,
5145 "Done %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005146
5147 return rval;
5148}
5149
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005150int
5151qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
5152{
5153 int rval;
5154 mbx_cmd_t mc;
5155 mbx_cmd_t *mcp = &mc;
5156 struct qla_hw_data *ha = vha->hw;
5157 unsigned long retry_max_time = jiffies + (2 * HZ);
5158
Chad Dupuisf73cb692014-02-26 04:15:06 -05005159 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005160 return QLA_FUNCTION_FAILED;
5161
5162 ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
5163
5164retry_rd_reg:
5165 mcp->mb[0] = MBC_READ_REMOTE_REG;
5166 mcp->mb[1] = LSW(reg);
5167 mcp->mb[2] = MSW(reg);
5168 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5169 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5170 mcp->tov = MBX_TOV_SECONDS;
5171 mcp->flags = 0;
5172 rval = qla2x00_mailbox_command(vha, mcp);
5173
5174 if (rval != QLA_SUCCESS) {
5175 ql_dbg(ql_dbg_mbx, vha, 0x114c,
5176 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5177 rval, mcp->mb[0], mcp->mb[1]);
5178 } else {
5179 *data = (mcp->mb[3] | (mcp->mb[4] << 16));
5180 if (*data == QLA8XXX_BAD_VALUE) {
5181 /*
5182 * During soft-reset CAMRAM register reads might
5183 * return 0xbad0bad0. So retry for MAX of 2 sec
5184 * while reading camram registers.
5185 */
5186 if (time_after(jiffies, retry_max_time)) {
5187 ql_dbg(ql_dbg_mbx, vha, 0x1141,
5188 "Failure to read CAMRAM register. "
5189 "data=0x%x.\n", *data);
5190 return QLA_FUNCTION_FAILED;
5191 }
5192 msleep(100);
5193 goto retry_rd_reg;
5194 }
5195 ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
5196 }
5197
5198 return rval;
5199}
5200
5201int
5202qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
5203{
5204 int rval;
5205 mbx_cmd_t mc;
5206 mbx_cmd_t *mcp = &mc;
5207 struct qla_hw_data *ha = vha->hw;
5208
5209 if (!IS_QLA83XX(ha))
5210 return QLA_FUNCTION_FAILED;
5211
5212 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
5213
5214 mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
5215 mcp->out_mb = MBX_0;
5216 mcp->in_mb = MBX_1|MBX_0;
5217 mcp->tov = MBX_TOV_SECONDS;
5218 mcp->flags = 0;
5219 rval = qla2x00_mailbox_command(vha, mcp);
5220
5221 if (rval != QLA_SUCCESS) {
5222 ql_dbg(ql_dbg_mbx, vha, 0x1144,
5223 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5224 rval, mcp->mb[0], mcp->mb[1]);
5225 ha->isp_ops->fw_dump(vha, 0);
5226 } else {
5227 ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
5228 }
5229
5230 return rval;
5231}
5232
5233int
5234qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
5235 uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
5236{
5237 int rval;
5238 mbx_cmd_t mc;
5239 mbx_cmd_t *mcp = &mc;
5240 uint8_t subcode = (uint8_t)options;
5241 struct qla_hw_data *ha = vha->hw;
5242
5243 if (!IS_QLA8031(ha))
5244 return QLA_FUNCTION_FAILED;
5245
5246 ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
5247
5248 mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
5249 mcp->mb[1] = options;
5250 mcp->out_mb = MBX_1|MBX_0;
5251 if (subcode & BIT_2) {
5252 mcp->mb[2] = LSW(start_addr);
5253 mcp->mb[3] = MSW(start_addr);
5254 mcp->mb[4] = LSW(end_addr);
5255 mcp->mb[5] = MSW(end_addr);
5256 mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
5257 }
5258 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5259 if (!(subcode & (BIT_2 | BIT_5)))
5260 mcp->in_mb |= MBX_4|MBX_3;
5261 mcp->tov = MBX_TOV_SECONDS;
5262 mcp->flags = 0;
5263 rval = qla2x00_mailbox_command(vha, mcp);
5264
5265 if (rval != QLA_SUCCESS) {
5266 ql_dbg(ql_dbg_mbx, vha, 0x1147,
5267 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
5268 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
5269 mcp->mb[4]);
5270 ha->isp_ops->fw_dump(vha, 0);
5271 } else {
5272 if (subcode & BIT_5)
5273 *sector_size = mcp->mb[1];
5274 else if (subcode & (BIT_6 | BIT_7)) {
5275 ql_dbg(ql_dbg_mbx, vha, 0x1148,
5276 "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5277 } else if (subcode & (BIT_3 | BIT_4)) {
5278 ql_dbg(ql_dbg_mbx, vha, 0x1149,
5279 "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5280 }
5281 ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
5282 }
5283
5284 return rval;
5285}
Saurav Kashyap81178772012-08-22 14:21:04 -04005286
5287int
5288qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
5289 uint32_t size)
5290{
5291 int rval;
5292 mbx_cmd_t mc;
5293 mbx_cmd_t *mcp = &mc;
5294
5295 if (!IS_MCTP_CAPABLE(vha->hw))
5296 return QLA_FUNCTION_FAILED;
5297
5298 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,
5299 "Entered %s.\n", __func__);
5300
5301 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
5302 mcp->mb[1] = LSW(addr);
5303 mcp->mb[2] = MSW(req_dma);
5304 mcp->mb[3] = LSW(req_dma);
5305 mcp->mb[4] = MSW(size);
5306 mcp->mb[5] = LSW(size);
5307 mcp->mb[6] = MSW(MSD(req_dma));
5308 mcp->mb[7] = LSW(MSD(req_dma));
5309 mcp->mb[8] = MSW(addr);
5310 /* Setting RAM ID to valid */
5311 mcp->mb[10] |= BIT_7;
5312 /* For MCTP RAM ID is 0x40 */
5313 mcp->mb[10] |= 0x40;
5314
5315 mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
5316 MBX_0;
5317
5318 mcp->in_mb = MBX_0;
5319 mcp->tov = MBX_TOV_SECONDS;
5320 mcp->flags = 0;
5321 rval = qla2x00_mailbox_command(vha, mcp);
5322
5323 if (rval != QLA_SUCCESS) {
5324 ql_dbg(ql_dbg_mbx, vha, 0x114e,
5325 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5326 } else {
5327 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,
5328 "Done %s.\n", __func__);
5329 }
5330
5331 return rval;
5332}