blob: a0ae178acf611a9cef0425c37610b9a05b680086 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
Armen Baloyanbd21eaf2014-04-11 16:54:24 -04003 * Copyright (c) 2003-2014 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{
Himanshu Madhanid14e72f2015-04-09 15:00:03 -040036 int rval, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 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;
Himanshu Madhanid14e72f2015-04-09 15:00:03 -040046 uint16_t __iomem *mbx_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -070047 unsigned long wait_time;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080048 struct qla_hw_data *ha = vha->hw;
49 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070050
Himanshu Madhanid14e72f2015-04-09 15:00:03 -040051
Arun Easi5e19ed92012-02-09 11:15:51 -080052 ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -070053
54 if (ha->pdev->error_state > pci_channel_io_frozen) {
Arun Easi5e19ed92012-02-09 11:15:51 -080055 ql_log(ql_log_warn, vha, 0x1001,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070056 "error_state is greater than pci_channel_io_frozen, "
57 "exiting.\n");
Seokmann Jub9b12f72009-03-24 09:08:18 -070058 return QLA_FUNCTION_TIMEOUT;
Saurav Kashyap7c3df132011-07-14 12:00:13 -070059 }
Seokmann Jub9b12f72009-03-24 09:08:18 -070060
Giridhar Malavalia9083012010-04-12 17:59:55 -070061 if (vha->device_flags & DFLG_DEV_FAILED) {
Arun Easi5e19ed92012-02-09 11:15:51 -080062 ql_log(ql_log_warn, vha, 0x1002,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070063 "Device in failed state, exiting.\n");
Giridhar Malavalia9083012010-04-12 17:59:55 -070064 return QLA_FUNCTION_TIMEOUT;
65 }
66
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070067 reg = ha->iobase;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080068 io_lock_on = base_vha->flags.init_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
70 rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080071 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070073
Andrew Vasquez85880802009-12-15 21:29:46 -080074 if (ha->flags.pci_channel_io_perm_failure) {
Arun Easi5e19ed92012-02-09 11:15:51 -080075 ql_log(ql_log_warn, vha, 0x1003,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070076 "Perm failure on EEH timeout MBX, exiting.\n");
Andrew Vasquez85880802009-12-15 21:29:46 -080077 return QLA_FUNCTION_TIMEOUT;
78 }
79
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -040080 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Giridhar Malavali862cd012011-02-23 15:27:11 -080081 /* Setting Link-Down error */
82 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
Arun Easi5e19ed92012-02-09 11:15:51 -080083 ql_log(ql_log_warn, vha, 0x1004,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070084 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Andrew Vasquez1806fcd2011-11-18 09:02:15 -080085 return QLA_FUNCTION_TIMEOUT;
Giridhar Malavali862cd012011-02-23 15:27:11 -080086 }
87
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070089 * Wait for active mailbox commands to finish by waiting at most tov
90 * seconds. This is to serialize actual issuing of mailbox cmds during
91 * non ISP abort time.
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080093 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
94 /* Timeout occurred. Return error. */
Arun Easi5e19ed92012-02-09 11:15:51 -080095 ql_log(ql_log_warn, vha, 0x1005,
Chad Dupuisd8c0d542012-02-09 11:15:46 -080096 "Cmd access timeout, cmd=0x%x, Exiting.\n",
97 mcp->mb[0]);
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080098 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 }
100
101 ha->flags.mbox_busy = 1;
102 /* Save mailbox command for debug */
103 ha->mcp = mcp;
104
Arun Easi5e19ed92012-02-09 11:15:51 -0800105 ql_dbg(ql_dbg_mbx, vha, 0x1006,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700106 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107
108 spin_lock_irqsave(&ha->hardware_lock, flags);
109
110 /* Load mailbox registers. */
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400111 if (IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -0700112 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400113 else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700114 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
115 else
116 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117
118 iptr = mcp->mb;
119 command = mcp->mb[0];
120 mboxes = mcp->out_mb;
121
Joe Carnuccio7b711622014-09-25 05:16:43 -0400122 ql_dbg(ql_dbg_mbx, vha, 0x1111,
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700123 "Mailbox registers (OUT):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
125 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700126 optr =
127 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700128 if (mboxes & BIT_0) {
129 ql_dbg(ql_dbg_mbx, vha, 0x1112,
130 "mbox[%d]<-0x%04x\n", cnt, *iptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131 WRT_REG_WORD(optr, *iptr);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700132 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
134 mboxes >>= 1;
135 optr++;
136 iptr++;
137 }
138
Arun Easi5e19ed92012-02-09 11:15:51 -0800139 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700140 "I/O Address = %p.\n", optr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
142 /* Issue set host interrupt command to send cmd out. */
143 ha->flags.mbox_int = 0;
144 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
145
146 /* Unlock mbx registers and wait for interrupt */
Arun Easi5e19ed92012-02-09 11:15:51 -0800147 ql_dbg(ql_dbg_mbx, vha, 0x100f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700148 "Going to unlock irq & waiting for interrupts. "
149 "jiffies=%lx.\n", jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
151 /* Wait for mbx cmd completion until timeout */
152
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800153 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
155
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400156 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700157 if (RD_REG_DWORD(&reg->isp82.hint) &
158 HINT_MBX_INT_PENDING) {
159 spin_unlock_irqrestore(&ha->hardware_lock,
160 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800161 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800162 ql_dbg(ql_dbg_mbx, vha, 0x1010,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700163 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700164 rval = QLA_FUNCTION_TIMEOUT;
165 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700166 }
167 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
168 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700169 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
170 else
171 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 spin_unlock_irqrestore(&ha->hardware_lock, flags);
173
Giridhar Malavali754d1242013-06-25 11:27:16 -0400174 if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
175 mcp->tov * HZ)) {
176 ql_dbg(ql_dbg_mbx, vha, 0x117a,
177 "cmd=%x Timeout.\n", command);
178 spin_lock_irqsave(&ha->hardware_lock, flags);
179 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
180 spin_unlock_irqrestore(&ha->hardware_lock, flags);
181 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 } else {
Arun Easi5e19ed92012-02-09 11:15:51 -0800183 ql_dbg(ql_dbg_mbx, vha, 0x1011,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700184 "Cmd=%x Polling Mode.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400186 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700187 if (RD_REG_DWORD(&reg->isp82.hint) &
188 HINT_MBX_INT_PENDING) {
189 spin_unlock_irqrestore(&ha->hardware_lock,
190 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800191 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800192 ql_dbg(ql_dbg_mbx, vha, 0x1012,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700193 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700194 rval = QLA_FUNCTION_TIMEOUT;
195 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700196 }
197 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
198 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700199 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
200 else
201 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
205 while (!ha->flags.mbox_int) {
206 if (time_after(jiffies, wait_time))
207 break;
208
209 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800210 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
Andrew Vasquez85880802009-12-15 21:29:46 -0800212 if (!ha->flags.mbox_int &&
213 !(IS_QLA2200(ha) &&
214 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800215 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 } /* while */
Arun Easi5e19ed92012-02-09 11:15:51 -0800217 ql_dbg(ql_dbg_mbx, vha, 0x1013,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700218 "Waited %d sec.\n",
219 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 }
221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 /* Check whether we timed out */
223 if (ha->flags.mbox_int) {
224 uint16_t *iptr2;
225
Arun Easi5e19ed92012-02-09 11:15:51 -0800226 ql_dbg(ql_dbg_mbx, vha, 0x1014,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700227 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
229 /* Got interrupt. Clear the flag. */
230 ha->flags.mbox_int = 0;
231 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
232
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400233 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700234 ha->flags.mbox_busy = 0;
235 /* Setting Link-Down error */
236 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
237 ha->mcp = NULL;
238 rval = QLA_FUNCTION_FAILED;
Arun Easi5e19ed92012-02-09 11:15:51 -0800239 ql_log(ql_log_warn, vha, 0x1015,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700240 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700241 goto premature_exit;
242 }
243
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400244 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
247 /* Load return mailbox registers. */
248 iptr2 = mcp->mb;
249 iptr = (uint16_t *)&ha->mailbox_out[0];
250 mboxes = mcp->in_mb;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700251
252 ql_dbg(ql_dbg_mbx, vha, 0x1113,
253 "Mailbox registers (IN):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700255 if (mboxes & BIT_0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 *iptr2 = *iptr;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700257 ql_dbg(ql_dbg_mbx, vha, 0x1114,
258 "mbox[%d]->0x%04x\n", cnt, *iptr2);
259 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260
261 mboxes >>= 1;
262 iptr2++;
263 iptr++;
264 }
265 } else {
266
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700267 uint16_t mb0;
268 uint32_t ictrl;
269
Andrew Vasqueze4289242007-07-19 15:05:56 -0700270 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700271 mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
272 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
273 } else {
Andrew Vasquezcca53352005-08-26 19:08:30 -0700274 mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700275 ictrl = RD_REG_WORD(&reg->isp.ictrl);
276 }
Arun Easi5e19ed92012-02-09 11:15:51 -0800277 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119,
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400278 "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
279 "mb[0]=0x%x\n", command, ictrl, jiffies, mb0);
Arun Easi5e19ed92012-02-09 11:15:51 -0800280 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800282 /*
283 * Attempt to capture a firmware dump for further analysis
Chad Dupuisb8eb4132013-06-25 11:27:20 -0400284 * of the current firmware state. We do not need to do this
285 * if we are intentionally generating a dump.
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800286 */
Chad Dupuisb8eb4132013-06-25 11:27:20 -0400287 if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR)
288 ha->isp_ops->fw_dump(vha, 0);
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800289
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 rval = QLA_FUNCTION_TIMEOUT;
291 }
292
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 ha->flags.mbox_busy = 0;
294
295 /* Clean up */
296 ha->mcp = NULL;
297
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800298 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800299 ql_dbg(ql_dbg_mbx, vha, 0x101a,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700300 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301
302 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800303 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 }
305
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700306 if (rval == QLA_FUNCTION_TIMEOUT &&
307 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800308 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
309 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 /* not in dpc. schedule it for dpc to take over. */
Arun Easi5e19ed92012-02-09 11:15:51 -0800311 ql_dbg(ql_dbg_mbx, vha, 0x101b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700312 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700313
314 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
315 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
316 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800317 if (IS_QLA82XX(ha)) {
318 ql_dbg(ql_dbg_mbx, vha, 0x112a,
319 "disabling pause transmit on port "
320 "0 & 1.\n");
321 qla82xx_wr_32(ha,
322 QLA82XX_CRB_NIU + 0x98,
323 CRB_NIU_XG_PAUSE_CTL_P0|
324 CRB_NIU_XG_PAUSE_CTL_P1);
325 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700326 ql_log(ql_log_info, base_vha, 0x101c,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400327 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800328 "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "
329 "abort.\n", command, mcp->mb[0],
330 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700331 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
332 qla2xxx_wake_dpc(vha);
333 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 /* call abort directly since we are in the DPC thread */
Arun Easi5e19ed92012-02-09 11:15:51 -0800336 ql_dbg(ql_dbg_mbx, vha, 0x101d,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700337 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700339 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
340 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
341 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800342 if (IS_QLA82XX(ha)) {
343 ql_dbg(ql_dbg_mbx, vha, 0x112b,
344 "disabling pause transmit on port "
345 "0 & 1.\n");
346 qla82xx_wr_32(ha,
347 QLA82XX_CRB_NIU + 0x98,
348 CRB_NIU_XG_PAUSE_CTL_P0|
349 CRB_NIU_XG_PAUSE_CTL_P1);
350 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700351 ql_log(ql_log_info, base_vha, 0x101e,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400352 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800353 "mb[0]=0x%x. Scheduling ISP abort ",
354 command, mcp->mb[0]);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700355 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
356 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
Giridhar Malavalid3360962012-02-09 11:14:10 -0800357 /* Allow next mbx cmd to come in. */
358 complete(&ha->mbx_cmd_comp);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700359 if (ha->isp_ops->abort_isp(vha)) {
360 /* Failed. retry later. */
361 set_bit(ISP_ABORT_NEEDED,
362 &vha->dpc_flags);
363 }
364 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Arun Easi5e19ed92012-02-09 11:15:51 -0800365 ql_dbg(ql_dbg_mbx, vha, 0x101f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700366 "Finished abort_isp.\n");
Giridhar Malavalid3360962012-02-09 11:14:10 -0800367 goto mbx_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 }
370 }
371
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700372premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800374 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Giridhar Malavalid3360962012-02-09 11:14:10 -0800376mbx_done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 if (rval) {
Chad Dupuis34c58012014-08-08 07:38:08 -0400378 ql_dbg(ql_dbg_disc, base_vha, 0x1020,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800379 "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n",
380 mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command);
Himanshu Madhanid14e72f2015-04-09 15:00:03 -0400381
382 ql_dbg(ql_dbg_disc, vha, 0x1115,
383 "host status: 0x%x, flags:0x%lx, intr ctrl reg:0x%x, intr status:0x%x\n",
384 RD_REG_DWORD(&reg->isp24.host_status),
385 ha->fw_dump_cap_flags,
386 RD_REG_DWORD(&reg->isp24.ictrl),
387 RD_REG_DWORD(&reg->isp24.istatus));
388
389 mbx_reg = &reg->isp24.mailbox0;
390 for (i = 0; i < 6; i++)
391 ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x1116,
392 "mbox[%d] 0x%04x\n", i, RD_REG_WORD(mbx_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700394 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 }
396
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 return rval;
398}
399
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800401qla2x00_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 -0800402 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403{
404 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800405 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 mbx_cmd_t mc;
407 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400409 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022,
410 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Andrew Vasqueze4289242007-07-19 15:05:56 -0700412 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800413 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
414 mcp->mb[8] = MSW(risc_addr);
415 mcp->out_mb = MBX_8|MBX_0;
416 } else {
417 mcp->mb[0] = MBC_LOAD_RISC_RAM;
418 mcp->out_mb = MBX_0;
419 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 mcp->mb[1] = LSW(risc_addr);
421 mcp->mb[2] = MSW(req_dma);
422 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 mcp->mb[6] = MSW(MSD(req_dma));
424 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800425 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700426 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700427 mcp->mb[4] = MSW(risc_code_size);
428 mcp->mb[5] = LSW(risc_code_size);
429 mcp->out_mb |= MBX_5|MBX_4;
430 } else {
431 mcp->mb[4] = LSW(risc_code_size);
432 mcp->out_mb |= MBX_4;
433 }
434
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700436 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800438 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700441 ql_dbg(ql_dbg_mbx, vha, 0x1023,
442 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400444 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,
445 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 }
447
448 return rval;
449}
450
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700451#define EXTENDED_BB_CREDITS BIT_0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452/*
453 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700454 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 *
456 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700457 * ha = adapter block pointer.
458 * TARGET_QUEUE_LOCK must be released.
459 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 *
461 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700462 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 *
464 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700465 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 */
467int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800468qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469{
470 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800471 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 mbx_cmd_t mc;
473 mbx_cmd_t *mcp = &mc;
474
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400475 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,
476 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477
478 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700479 mcp->out_mb = MBX_0;
480 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700481 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700482 mcp->mb[1] = MSW(risc_addr);
483 mcp->mb[2] = LSW(risc_addr);
484 mcp->mb[3] = 0;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500485 if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
486 IS_QLA27XX(ha)) {
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700487 struct nvram_81xx *nv = ha->nvram;
488 mcp->mb[4] = (nv->enhanced_features &
489 EXTENDED_BB_CREDITS);
490 } else
491 mcp->mb[4] = 0;
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500492
493 if (ha->flags.exlogins_enabled)
494 mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;
495
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700496 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700497 mcp->in_mb |= MBX_1;
498 } else {
499 mcp->mb[1] = LSW(risc_addr);
500 mcp->out_mb |= MBX_1;
501 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
502 mcp->mb[2] = 0;
503 mcp->out_mb |= MBX_2;
504 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 }
506
Ravi Anandb93480e2008-04-03 13:13:25 -0700507 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800509 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700511 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700512 ql_dbg(ql_dbg_mbx, vha, 0x1026,
513 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700514 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700515 if (IS_FWI2_CAPABLE(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400516 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1027,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700517 "Done exchanges=%x.\n", mcp->mb[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700518 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400519 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
520 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700521 }
522 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523
524 return rval;
525}
526
527/*
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500528 * qla_get_exlogin_status
529 * Get extended login status
530 * uses the memory offload control/status Mailbox
531 *
532 * Input:
533 * ha: adapter state pointer.
534 * fwopt: firmware options
535 *
536 * Returns:
537 * qla2x00 local function status
538 *
539 * Context:
540 * Kernel context.
541 */
542#define FETCH_XLOGINS_STAT 0x8
543int
544qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
545 uint16_t *ex_logins_cnt)
546{
547 int rval;
548 mbx_cmd_t mc;
549 mbx_cmd_t *mcp = &mc;
550
551 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f,
552 "Entered %s\n", __func__);
553
554 memset(mcp->mb, 0 , sizeof(mcp->mb));
555 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
556 mcp->mb[1] = FETCH_XLOGINS_STAT;
557 mcp->out_mb = MBX_1|MBX_0;
558 mcp->in_mb = MBX_10|MBX_4|MBX_0;
559 mcp->tov = MBX_TOV_SECONDS;
560 mcp->flags = 0;
561
562 rval = qla2x00_mailbox_command(vha, mcp);
563 if (rval != QLA_SUCCESS) {
564 ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval);
565 } else {
566 *buf_sz = mcp->mb[4];
567 *ex_logins_cnt = mcp->mb[10];
568
569 ql_log(ql_log_info, vha, 0x1190,
570 "buffer size 0x%x, exchange login count=%d\n",
571 mcp->mb[4], mcp->mb[10]);
572
573 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116,
574 "Done %s.\n", __func__);
575 }
576
577 return rval;
578}
579
580/*
581 * qla_set_exlogin_mem_cfg
582 * set extended login memory configuration
583 * Mbx needs to be issues before init_cb is set
584 *
585 * Input:
586 * ha: adapter state pointer.
587 * buffer: buffer pointer
588 * phys_addr: physical address of buffer
589 * size: size of buffer
590 * TARGET_QUEUE_LOCK must be released
591 * ADAPTER_STATE_LOCK must be release
592 *
593 * Returns:
594 * qla2x00 local funxtion status code.
595 *
596 * Context:
597 * Kernel context.
598 */
599#define CONFIG_XLOGINS_MEM 0x3
600int
601qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
602{
603 int rval;
604 mbx_cmd_t mc;
605 mbx_cmd_t *mcp = &mc;
606 struct qla_hw_data *ha = vha->hw;
607 int configured_count;
608
609 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a,
610 "Entered %s.\n", __func__);
611
612 memset(mcp->mb, 0 , sizeof(mcp->mb));
613 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
614 mcp->mb[1] = CONFIG_XLOGINS_MEM;
615 mcp->mb[2] = MSW(phys_addr);
616 mcp->mb[3] = LSW(phys_addr);
617 mcp->mb[6] = MSW(MSD(phys_addr));
618 mcp->mb[7] = LSW(MSD(phys_addr));
619 mcp->mb[8] = MSW(ha->exlogin_size);
620 mcp->mb[9] = LSW(ha->exlogin_size);
621 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
622 mcp->in_mb = MBX_11|MBX_0;
623 mcp->tov = MBX_TOV_SECONDS;
624 mcp->flags = 0;
625 rval = qla2x00_mailbox_command(vha, mcp);
626 if (rval != QLA_SUCCESS) {
627 /*EMPTY*/
628 ql_dbg(ql_dbg_mbx, vha, 0x111b, "Failed=%x.\n", rval);
629 } else {
630 configured_count = mcp->mb[11];
631 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
632 "Done %s.\n", __func__);
633 }
634
635 return rval;
636}
637
638/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 * qla2x00_get_fw_version
640 * Get firmware version.
641 *
642 * Input:
643 * ha: adapter state pointer.
644 * major: pointer for major number.
645 * minor: pointer for minor number.
646 * subminor: pointer for subminor number.
647 *
648 * Returns:
649 * qla2x00 local function return status code.
650 *
651 * Context:
652 * Kernel context.
653 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700654int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800655qla2x00_get_fw_version(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656{
657 int rval;
658 mbx_cmd_t mc;
659 mbx_cmd_t *mcp = &mc;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800660 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400662 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029,
663 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664
665 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
666 mcp->out_mb = MBX_0;
667 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400668 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha))
Andrew Vasquez55a96152009-03-24 09:08:03 -0700669 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Saurav Kashyapfb0effe2012-08-22 14:21:28 -0400670 if (IS_FWI2_CAPABLE(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800671 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500672 if (IS_QLA27XX(ha))
Sawan Chandak03aa8682015-08-04 13:37:59 -0400673 mcp->in_mb |= MBX_23 | MBX_22 | MBX_21 | MBX_20 | MBX_19 |
674 MBX_18 | MBX_14 | MBX_13 | MBX_11 | MBX_10 | MBX_9 | MBX_8;
675
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700677 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800678 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700679 if (rval != QLA_SUCCESS)
680 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681
682 /* Return mailbox data. */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800683 ha->fw_major_version = mcp->mb[1];
684 ha->fw_minor_version = mcp->mb[2];
685 ha->fw_subminor_version = mcp->mb[3];
686 ha->fw_attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800687 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800688 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 else
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800690 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
Sawan Chandak03aa8682015-08-04 13:37:59 -0400691
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400692 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800693 ha->mpi_version[0] = mcp->mb[10] & 0xff;
694 ha->mpi_version[1] = mcp->mb[11] >> 8;
695 ha->mpi_version[2] = mcp->mb[11] & 0xff;
696 ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
697 ha->phy_version[0] = mcp->mb[8] & 0xff;
698 ha->phy_version[1] = mcp->mb[9] >> 8;
699 ha->phy_version[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800700 }
Sawan Chandak03aa8682015-08-04 13:37:59 -0400701
Saurav Kashyap81178772012-08-22 14:21:04 -0400702 if (IS_FWI2_CAPABLE(ha)) {
703 ha->fw_attributes_h = mcp->mb[15];
704 ha->fw_attributes_ext[0] = mcp->mb[16];
705 ha->fw_attributes_ext[1] = mcp->mb[17];
706 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,
707 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
708 __func__, mcp->mb[15], mcp->mb[6]);
709 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
710 "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
711 __func__, mcp->mb[17], mcp->mb[16]);
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500712 if (ha->fw_attributes_h & 0x4)
713 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d,
714 "%s: Firmware supports Extended Login 0x%x\n",
715 __func__, ha->fw_attributes_h);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800716 }
Sawan Chandak03aa8682015-08-04 13:37:59 -0400717
Chad Dupuisf73cb692014-02-26 04:15:06 -0500718 if (IS_QLA27XX(ha)) {
Sawan Chandak03aa8682015-08-04 13:37:59 -0400719 ha->mpi_version[0] = mcp->mb[10] & 0xff;
720 ha->mpi_version[1] = mcp->mb[11] >> 8;
721 ha->mpi_version[2] = mcp->mb[11] & 0xff;
722 ha->pep_version[0] = mcp->mb[13] & 0xff;
723 ha->pep_version[1] = mcp->mb[14] >> 8;
724 ha->pep_version[2] = mcp->mb[14] & 0xff;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500725 ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18];
726 ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20];
727 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800728
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700729failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 if (rval != QLA_SUCCESS) {
731 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700732 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 } else {
734 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400735 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b,
736 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700738 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739}
740
741/*
742 * qla2x00_get_fw_options
743 * Set firmware options.
744 *
745 * Input:
746 * ha = adapter block pointer.
747 * fwopt = pointer for firmware options.
748 *
749 * Returns:
750 * qla2x00 local function return status code.
751 *
752 * Context:
753 * Kernel context.
754 */
755int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800756qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700757{
758 int rval;
759 mbx_cmd_t mc;
760 mbx_cmd_t *mcp = &mc;
761
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400762 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c,
763 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764
765 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
766 mcp->out_mb = MBX_0;
767 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700768 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800770 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771
772 if (rval != QLA_SUCCESS) {
773 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700774 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700776 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700777 fwopts[1] = mcp->mb[1];
778 fwopts[2] = mcp->mb[2];
779 fwopts[3] = mcp->mb[3];
780
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400781 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e,
782 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 }
784
785 return rval;
786}
787
788
789/*
790 * qla2x00_set_fw_options
791 * Set firmware options.
792 *
793 * Input:
794 * ha = adapter block pointer.
795 * fwopt = pointer for firmware options.
796 *
797 * Returns:
798 * qla2x00 local function return status code.
799 *
800 * Context:
801 * Kernel context.
802 */
803int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800804qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805{
806 int rval;
807 mbx_cmd_t mc;
808 mbx_cmd_t *mcp = &mc;
809
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400810 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f,
811 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812
813 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
814 mcp->mb[1] = fwopts[1];
815 mcp->mb[2] = fwopts[2];
816 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700817 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800819 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700820 mcp->in_mb |= MBX_1;
821 } else {
822 mcp->mb[10] = fwopts[10];
823 mcp->mb[11] = fwopts[11];
824 mcp->mb[12] = 0; /* Undocumented, but used */
825 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
826 }
Ravi Anandb93480e2008-04-03 13:13:25 -0700827 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700828 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800829 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700830
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700831 fwopts[0] = mcp->mb[0];
832
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 if (rval != QLA_SUCCESS) {
834 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700835 ql_dbg(ql_dbg_mbx, vha, 0x1030,
836 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 } else {
838 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400839 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031,
840 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 }
842
843 return rval;
844}
845
846/*
847 * qla2x00_mbx_reg_test
848 * Mailbox register wrap test.
849 *
850 * Input:
851 * ha = adapter block pointer.
852 * TARGET_QUEUE_LOCK must be released.
853 * ADAPTER_STATE_LOCK must be released.
854 *
855 * Returns:
856 * qla2x00 local function return status code.
857 *
858 * Context:
859 * Kernel context.
860 */
861int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800862qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863{
864 int rval;
865 mbx_cmd_t mc;
866 mbx_cmd_t *mcp = &mc;
867
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400868 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032,
869 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700870
871 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
872 mcp->mb[1] = 0xAAAA;
873 mcp->mb[2] = 0x5555;
874 mcp->mb[3] = 0xAA55;
875 mcp->mb[4] = 0x55AA;
876 mcp->mb[5] = 0xA5A5;
877 mcp->mb[6] = 0x5A5A;
878 mcp->mb[7] = 0x2525;
879 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
880 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 -0700881 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800883 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884
885 if (rval == QLA_SUCCESS) {
886 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
887 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
888 rval = QLA_FUNCTION_FAILED;
889 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
890 mcp->mb[7] != 0x2525)
891 rval = QLA_FUNCTION_FAILED;
892 }
893
894 if (rval != QLA_SUCCESS) {
895 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700896 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 } else {
898 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400899 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034,
900 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 }
902
903 return rval;
904}
905
906/*
907 * qla2x00_verify_checksum
908 * Verify firmware checksum.
909 *
910 * Input:
911 * ha = adapter block pointer.
912 * TARGET_QUEUE_LOCK must be released.
913 * ADAPTER_STATE_LOCK must be released.
914 *
915 * Returns:
916 * qla2x00 local function return status code.
917 *
918 * Context:
919 * Kernel context.
920 */
921int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800922qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923{
924 int rval;
925 mbx_cmd_t mc;
926 mbx_cmd_t *mcp = &mc;
927
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400928 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035,
929 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930
931 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700932 mcp->out_mb = MBX_0;
933 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800934 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700935 mcp->mb[1] = MSW(risc_addr);
936 mcp->mb[2] = LSW(risc_addr);
937 mcp->out_mb |= MBX_2|MBX_1;
938 mcp->in_mb |= MBX_2|MBX_1;
939 } else {
940 mcp->mb[1] = LSW(risc_addr);
941 mcp->out_mb |= MBX_1;
942 mcp->in_mb |= MBX_1;
943 }
944
Ravi Anandb93480e2008-04-03 13:13:25 -0700945 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800947 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700948
949 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700950 ql_dbg(ql_dbg_mbx, vha, 0x1036,
951 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
952 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400954 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037,
955 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 }
957
958 return rval;
959}
960
961/*
962 * qla2x00_issue_iocb
963 * Issue IOCB using mailbox command
964 *
965 * Input:
966 * ha = adapter state pointer.
967 * buffer = buffer pointer.
968 * phys_addr = physical address of buffer.
969 * size = size of buffer.
970 * TARGET_QUEUE_LOCK must be released.
971 * ADAPTER_STATE_LOCK must be released.
972 *
973 * Returns:
974 * qla2x00 local function return status code.
975 *
976 * Context:
977 * Kernel context.
978 */
Giridhar Malavali6e980162010-03-19 17:03:58 -0700979int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800980qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700981 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982{
983 int rval;
984 mbx_cmd_t mc;
985 mbx_cmd_t *mcp = &mc;
986
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400987 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038,
988 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700989
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
991 mcp->mb[1] = 0;
992 mcp->mb[2] = MSW(phys_addr);
993 mcp->mb[3] = LSW(phys_addr);
994 mcp->mb[6] = MSW(MSD(phys_addr));
995 mcp->mb[7] = LSW(MSD(phys_addr));
996 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
997 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700998 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700999 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001000 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001
1002 if (rval != QLA_SUCCESS) {
1003 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001004 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -07001006 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
1007
1008 /* Mask reserved bits. */
1009 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001010 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001011 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a,
1012 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 }
1014
1015 return rval;
1016}
1017
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001018int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001019qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001020 size_t size)
1021{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001022 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001023 MBX_TOV_SECONDS);
1024}
1025
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026/*
1027 * qla2x00_abort_command
1028 * Abort command aborts a specified IOCB.
1029 *
1030 * Input:
1031 * ha = adapter block pointer.
1032 * sp = SB structure pointer.
1033 *
1034 * Returns:
1035 * qla2x00 local function return status code.
1036 *
1037 * Context:
1038 * Kernel context.
1039 */
1040int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001041qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042{
1043 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001044 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001045 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046 mbx_cmd_t mc;
1047 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001048 fc_port_t *fcport = sp->fcport;
1049 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001050 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001051 struct req_que *req = vha->req;
Giridhar Malavali9ba56b92012-02-09 11:15:36 -08001052 struct scsi_cmnd *cmd = GET_CMD_SP(sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001054 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b,
1055 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -07001057 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05001058 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001059 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 break;
1061 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -07001062 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063
Chad Dupuis8d93f552013-01-30 03:34:37 -05001064 if (handle == req->num_outstanding_cmds) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 /* command not found */
1066 return QLA_FUNCTION_FAILED;
1067 }
1068
1069 mcp->mb[0] = MBC_ABORT_COMMAND;
1070 if (HAS_EXTENDED_IDS(ha))
1071 mcp->mb[1] = fcport->loop_id;
1072 else
1073 mcp->mb[1] = fcport->loop_id << 8;
1074 mcp->mb[2] = (uint16_t)handle;
1075 mcp->mb[3] = (uint16_t)(handle >> 16);
Giridhar Malavali9ba56b92012-02-09 11:15:36 -08001076 mcp->mb[6] = (uint16_t)cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1078 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001079 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001081 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082
1083 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001084 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001086 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d,
1087 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088 }
1089
1090 return rval;
1091}
1092
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001094qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095{
Andrew Vasquez523ec772008-04-03 13:13:24 -07001096 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001097 mbx_cmd_t mc;
1098 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001099 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001100 struct req_que *req;
1101 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102
Andrew Vasquez523ec772008-04-03 13:13:24 -07001103 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001104 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001105
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001106 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e,
1107 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001108
Giridhar Malavali7e2b8952010-05-28 15:08:17 -07001109 req = vha->hw->req_q_map[0];
1110 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001112 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001113 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 mcp->mb[1] = fcport->loop_id;
1115 mcp->mb[10] = 0;
1116 mcp->out_mb |= MBX_10;
1117 } else {
1118 mcp->mb[1] = fcport->loop_id << 8;
1119 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001120 mcp->mb[2] = vha->hw->loop_reset_delay;
1121 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122
1123 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001124 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001125 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001126 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001128 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f,
1129 "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001130 }
1131
1132 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001133 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
1134 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001135 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001136 ql_dbg(ql_dbg_mbx, vha, 0x1040,
1137 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001139 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041,
1140 "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001141 }
1142
1143 return rval;
1144}
1145
1146int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001147qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07001148{
1149 int rval, rval2;
1150 mbx_cmd_t mc;
1151 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001152 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001153 struct req_que *req;
1154 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001155
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001156 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001157
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001158 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042,
1159 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001160
Giridhar Malavali7e2b8952010-05-28 15:08:17 -07001161 req = vha->hw->req_q_map[0];
1162 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001163 mcp->mb[0] = MBC_LUN_RESET;
1164 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001165 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -07001166 mcp->mb[1] = fcport->loop_id;
1167 else
1168 mcp->mb[1] = fcport->loop_id << 8;
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001169 mcp->mb[2] = (u32)l;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001170 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001171 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001172
1173 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001174 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001175 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001176 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001177 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001178 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001179 }
1180
1181 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001182 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1183 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001184 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001185 ql_dbg(ql_dbg_mbx, vha, 0x1044,
1186 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001187 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001188 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045,
1189 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 }
1191
1192 return rval;
1193}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194
1195/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 * qla2x00_get_adapter_id
1197 * Get adapter ID and topology.
1198 *
1199 * Input:
1200 * ha = adapter block pointer.
1201 * id = pointer for loop ID.
1202 * al_pa = pointer for AL_PA.
1203 * area = pointer for area.
1204 * domain = pointer for domain.
1205 * top = pointer for topology.
1206 * TARGET_QUEUE_LOCK must be released.
1207 * ADAPTER_STATE_LOCK must be released.
1208 *
1209 * Returns:
1210 * qla2x00 local function return status code.
1211 *
1212 * Context:
1213 * Kernel context.
1214 */
1215int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001216qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001217 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218{
1219 int rval;
1220 mbx_cmd_t mc;
1221 mbx_cmd_t *mcp = &mc;
1222
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001223 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046,
1224 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225
1226 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001227 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001228 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001229 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001230 if (IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001231 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001232 if (IS_FWI2_CAPABLE(vha->hw))
1233 mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16;
Ravi Anandb93480e2008-04-03 13:13:25 -07001234 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001236 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001237 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1238 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001239 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1240 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241
1242 /* Return data. */
1243 *id = mcp->mb[1];
1244 *al_pa = LSB(mcp->mb[2]);
1245 *area = MSB(mcp->mb[2]);
1246 *domain = LSB(mcp->mb[3]);
1247 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001248 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249
1250 if (rval != QLA_SUCCESS) {
1251 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001252 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001254 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048,
1255 "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001256
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001257 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001258 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1259 vha->fcoe_fcf_idx = mcp->mb[10];
1260 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1261 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1262 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1263 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1264 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1265 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1266 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001267 /* If FA-WWN supported */
Saurav Kashyapd6b9b422015-08-04 13:37:55 -04001268 if (IS_FAWWN_CAPABLE(vha->hw)) {
1269 if (mcp->mb[7] & BIT_14) {
1270 vha->port_name[0] = MSB(mcp->mb[16]);
1271 vha->port_name[1] = LSB(mcp->mb[16]);
1272 vha->port_name[2] = MSB(mcp->mb[17]);
1273 vha->port_name[3] = LSB(mcp->mb[17]);
1274 vha->port_name[4] = MSB(mcp->mb[18]);
1275 vha->port_name[5] = LSB(mcp->mb[18]);
1276 vha->port_name[6] = MSB(mcp->mb[19]);
1277 vha->port_name[7] = LSB(mcp->mb[19]);
1278 fc_host_port_name(vha->host) =
1279 wwn_to_u64(vha->port_name);
1280 ql_dbg(ql_dbg_mbx, vha, 0x10ca,
1281 "FA-WWN acquired %016llx\n",
1282 wwn_to_u64(vha->port_name));
1283 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001284 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 }
1286
1287 return rval;
1288}
1289
1290/*
1291 * qla2x00_get_retry_cnt
1292 * Get current firmware login retry count and delay.
1293 *
1294 * Input:
1295 * ha = adapter block pointer.
1296 * retry_cnt = pointer to login retry count.
1297 * tov = pointer to login timeout value.
1298 *
1299 * Returns:
1300 * qla2x00 local function return status code.
1301 *
1302 * Context:
1303 * Kernel context.
1304 */
1305int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001306qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 uint16_t *r_a_tov)
1308{
1309 int rval;
1310 uint16_t ratov;
1311 mbx_cmd_t mc;
1312 mbx_cmd_t *mcp = &mc;
1313
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001314 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049,
1315 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316
1317 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1318 mcp->out_mb = MBX_0;
1319 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001320 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001322 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323
1324 if (rval != QLA_SUCCESS) {
1325 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001326 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1327 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 } else {
1329 /* Convert returned data and check our values. */
1330 *r_a_tov = mcp->mb[3] / 2;
1331 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1332 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1333 /* Update to the larger values */
1334 *retry_cnt = (uint8_t)mcp->mb[1];
1335 *tov = ratov;
1336 }
1337
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001338 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001339 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 }
1341
1342 return rval;
1343}
1344
1345/*
1346 * qla2x00_init_firmware
1347 * Initialize adapter firmware.
1348 *
1349 * Input:
1350 * ha = adapter block pointer.
1351 * dptr = Initialization control block pointer.
1352 * size = size of initialization control block.
1353 * TARGET_QUEUE_LOCK must be released.
1354 * ADAPTER_STATE_LOCK must be released.
1355 *
1356 * Returns:
1357 * qla2x00 local function return status code.
1358 *
1359 * Context:
1360 * Kernel context.
1361 */
1362int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001363qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364{
1365 int rval;
1366 mbx_cmd_t mc;
1367 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001368 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001370 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,
1371 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001373 if (IS_P3P_TYPE(ha) && ql2xdbwr)
Bart Van Assche8dfa4b5a2015-07-09 07:24:50 -07001374 qla82xx_wr_32(ha, (uintptr_t __force)ha->nxdb_wr_ptr,
Giridhar Malavalia9083012010-04-12 17:59:55 -07001375 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1376
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001377 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001378 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1379 else
1380 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1381
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001382 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383 mcp->mb[2] = MSW(ha->init_cb_dma);
1384 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1386 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001387 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Joe Carnuccio4ef21bd2013-10-30 03:38:11 -04001388 if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001389 mcp->mb[1] = BIT_0;
1390 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1391 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1392 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1393 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1394 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1395 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1396 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001397 /* 1 and 2 should normally be captured. */
1398 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001399 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001400 /* mb3 is additional info about the installed SFP. */
1401 mcp->in_mb |= MBX_3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 mcp->buf_size = size;
1403 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001404 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001405 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406
1407 if (rval != QLA_SUCCESS) {
1408 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001409 ql_dbg(ql_dbg_mbx, vha, 0x104d,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001410 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1411 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 } else {
1413 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001414 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,
1415 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416 }
1417
1418 return rval;
1419}
1420
1421/*
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001422 * qla2x00_get_node_name_list
1423 * Issue get node name list mailbox command, kmalloc()
1424 * and return the resulting list. Caller must kfree() it!
1425 *
1426 * Input:
1427 * ha = adapter state pointer.
1428 * out_data = resulting list
1429 * out_len = length of the resulting list
1430 *
1431 * Returns:
1432 * qla2x00 local function return status code.
1433 *
1434 * Context:
1435 * Kernel context.
1436 */
1437int
1438qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len)
1439{
1440 struct qla_hw_data *ha = vha->hw;
1441 struct qla_port_24xx_data *list = NULL;
1442 void *pmap;
1443 mbx_cmd_t mc;
1444 dma_addr_t pmap_dma;
1445 ulong dma_size;
1446 int rval, left;
1447
1448 left = 1;
1449 while (left > 0) {
1450 dma_size = left * sizeof(*list);
1451 pmap = dma_alloc_coherent(&ha->pdev->dev, dma_size,
1452 &pmap_dma, GFP_KERNEL);
1453 if (!pmap) {
1454 ql_log(ql_log_warn, vha, 0x113f,
1455 "%s(%ld): DMA Alloc failed of %ld\n",
1456 __func__, vha->host_no, dma_size);
1457 rval = QLA_MEMORY_ALLOC_FAILED;
1458 goto out;
1459 }
1460
1461 mc.mb[0] = MBC_PORT_NODE_NAME_LIST;
1462 mc.mb[1] = BIT_1 | BIT_3;
1463 mc.mb[2] = MSW(pmap_dma);
1464 mc.mb[3] = LSW(pmap_dma);
1465 mc.mb[6] = MSW(MSD(pmap_dma));
1466 mc.mb[7] = LSW(MSD(pmap_dma));
1467 mc.mb[8] = dma_size;
1468 mc.out_mb = MBX_0|MBX_1|MBX_2|MBX_3|MBX_6|MBX_7|MBX_8;
1469 mc.in_mb = MBX_0|MBX_1;
1470 mc.tov = 30;
1471 mc.flags = MBX_DMA_IN;
1472
1473 rval = qla2x00_mailbox_command(vha, &mc);
1474 if (rval != QLA_SUCCESS) {
1475 if ((mc.mb[0] == MBS_COMMAND_ERROR) &&
1476 (mc.mb[1] == 0xA)) {
1477 left += le16_to_cpu(mc.mb[2]) /
1478 sizeof(struct qla_port_24xx_data);
1479 goto restart;
1480 }
1481 goto out_free;
1482 }
1483
1484 left = 0;
1485
Benoit Tainec1818f12014-05-26 17:21:16 +02001486 list = kmemdup(pmap, dma_size, GFP_KERNEL);
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001487 if (!list) {
1488 ql_log(ql_log_warn, vha, 0x1140,
1489 "%s(%ld): failed to allocate node names list "
1490 "structure.\n", __func__, vha->host_no);
1491 rval = QLA_MEMORY_ALLOC_FAILED;
1492 goto out_free;
1493 }
1494
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001495restart:
1496 dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
1497 }
1498
1499 *out_data = list;
1500 *out_len = dma_size;
1501
1502out:
1503 return rval;
1504
1505out_free:
1506 dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
1507 return rval;
1508}
1509
1510/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 * qla2x00_get_port_database
1512 * Issue normal/enhanced get port database mailbox command
1513 * and copy device name as necessary.
1514 *
1515 * Input:
1516 * ha = adapter state pointer.
1517 * dev = structure pointer.
1518 * opt = enhanced cmd option byte.
1519 *
1520 * Returns:
1521 * qla2x00 local function return status code.
1522 *
1523 * Context:
1524 * Kernel context.
1525 */
1526int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001527qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528{
1529 int rval;
1530 mbx_cmd_t mc;
1531 mbx_cmd_t *mcp = &mc;
1532 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001533 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001535 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001537 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f,
1538 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001540 pd24 = NULL;
1541 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001543 ql_log(ql_log_warn, vha, 0x1050,
1544 "Failed to allocate port database structure.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 return QLA_MEMORY_ALLOC_FAILED;
1546 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001547 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001549 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001550 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 mcp->mb[2] = MSW(pd_dma);
1553 mcp->mb[3] = LSW(pd_dma);
1554 mcp->mb[6] = MSW(MSD(pd_dma));
1555 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001556 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001557 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001559 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001560 mcp->mb[1] = fcport->loop_id;
1561 mcp->mb[10] = opt;
1562 mcp->out_mb |= MBX_10|MBX_1;
1563 mcp->in_mb |= MBX_1;
1564 } else if (HAS_EXTENDED_IDS(ha)) {
1565 mcp->mb[1] = fcport->loop_id;
1566 mcp->mb[10] = opt;
1567 mcp->out_mb |= MBX_10|MBX_1;
1568 } else {
1569 mcp->mb[1] = fcport->loop_id << 8 | opt;
1570 mcp->out_mb |= MBX_1;
1571 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001572 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1573 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 mcp->flags = MBX_DMA_IN;
1575 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001576 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 if (rval != QLA_SUCCESS)
1578 goto gpd_error_out;
1579
Andrew Vasqueze4289242007-07-19 15:05:56 -07001580 if (IS_FWI2_CAPABLE(ha)) {
Arun Easi0eba25d2012-02-09 11:15:58 -08001581 uint64_t zero = 0;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001582 pd24 = (struct port_database_24xx *) pd;
1583
1584 /* Check for logged in state. */
1585 if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1586 pd24->last_login_state != PDS_PRLI_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001587 ql_dbg(ql_dbg_mbx, vha, 0x1051,
1588 "Unable to verify login-state (%x/%x) for "
1589 "loop_id %x.\n", pd24->current_login_state,
1590 pd24->last_login_state, fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001591 rval = QLA_FUNCTION_FAILED;
1592 goto gpd_error_out;
1593 }
1594
Arun Easi0eba25d2012-02-09 11:15:58 -08001595 if (fcport->loop_id == FC_NO_LOOP_ID ||
1596 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1597 memcmp(fcport->port_name, pd24->port_name, 8))) {
1598 /* We lost the device mid way. */
1599 rval = QLA_NOT_LOGGED_IN;
1600 goto gpd_error_out;
1601 }
1602
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001603 /* Names are little-endian. */
1604 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1605 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1606
1607 /* Get port_id of device. */
1608 fcport->d_id.b.domain = pd24->port_id[0];
1609 fcport->d_id.b.area = pd24->port_id[1];
1610 fcport->d_id.b.al_pa = pd24->port_id[2];
1611 fcport->d_id.b.rsvd_1 = 0;
1612
1613 /* If not target must be initiator or unknown type. */
1614 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1615 fcport->port_type = FCT_INITIATOR;
1616 else
1617 fcport->port_type = FCT_TARGET;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001618
1619 /* Passback COS information. */
1620 fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ?
1621 FC_COS_CLASS2 : FC_COS_CLASS3;
1622
1623 if (pd24->prli_svc_param_word_3[0] & BIT_7)
1624 fcport->flags |= FCF_CONF_COMP_SUPPORTED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001625 } else {
Arun Easi0eba25d2012-02-09 11:15:58 -08001626 uint64_t zero = 0;
1627
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001628 /* Check for logged in state. */
1629 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1630 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001631 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1632 "Unable to verify login-state (%x/%x) - "
1633 "portid=%02x%02x%02x.\n", pd->master_state,
1634 pd->slave_state, fcport->d_id.b.domain,
1635 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001636 rval = QLA_FUNCTION_FAILED;
1637 goto gpd_error_out;
1638 }
1639
Arun Easi0eba25d2012-02-09 11:15:58 -08001640 if (fcport->loop_id == FC_NO_LOOP_ID ||
1641 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1642 memcmp(fcport->port_name, pd->port_name, 8))) {
1643 /* We lost the device mid way. */
1644 rval = QLA_NOT_LOGGED_IN;
1645 goto gpd_error_out;
1646 }
1647
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001648 /* Names are little-endian. */
1649 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1650 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1651
1652 /* Get port_id of device. */
1653 fcport->d_id.b.domain = pd->port_id[0];
1654 fcport->d_id.b.area = pd->port_id[3];
1655 fcport->d_id.b.al_pa = pd->port_id[2];
1656 fcport->d_id.b.rsvd_1 = 0;
1657
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001658 /* If not target must be initiator or unknown type. */
1659 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1660 fcport->port_type = FCT_INITIATOR;
1661 else
1662 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001663
1664 /* Passback COS information. */
1665 fcport->supported_classes = (pd->options & BIT_4) ?
1666 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667 }
1668
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669gpd_error_out:
1670 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1671
1672 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001673 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1674 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1675 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001677 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053,
1678 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 }
1680
1681 return rval;
1682}
1683
1684/*
1685 * qla2x00_get_firmware_state
1686 * Get adapter firmware state.
1687 *
1688 * Input:
1689 * ha = adapter block pointer.
1690 * dptr = pointer for firmware state.
1691 * TARGET_QUEUE_LOCK must be released.
1692 * ADAPTER_STATE_LOCK must be released.
1693 *
1694 * Returns:
1695 * qla2x00 local function return status code.
1696 *
1697 * Context:
1698 * Kernel context.
1699 */
1700int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001701qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702{
1703 int rval;
1704 mbx_cmd_t mc;
1705 mbx_cmd_t *mcp = &mc;
1706
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001707 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
1708 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709
1710 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1711 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001712 if (IS_FWI2_CAPABLE(vha->hw))
Joe Carnucciob5a340d2014-09-25 05:16:48 -04001713 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001714 else
1715 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001716 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001718 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001720 /* Return firmware states. */
1721 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001722 if (IS_FWI2_CAPABLE(vha->hw)) {
1723 states[1] = mcp->mb[2];
1724 states[2] = mcp->mb[3];
1725 states[3] = mcp->mb[4];
1726 states[4] = mcp->mb[5];
Joe Carnucciob5a340d2014-09-25 05:16:48 -04001727 states[5] = mcp->mb[6]; /* DPORT status */
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001728 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729
1730 if (rval != QLA_SUCCESS) {
1731 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001732 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 } else {
1734 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001735 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,
1736 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 }
1738
1739 return rval;
1740}
1741
1742/*
1743 * qla2x00_get_port_name
1744 * Issue get port name mailbox command.
1745 * Returned name is in big endian format.
1746 *
1747 * Input:
1748 * ha = adapter block pointer.
1749 * loop_id = loop ID of device.
1750 * name = pointer for name.
1751 * TARGET_QUEUE_LOCK must be released.
1752 * ADAPTER_STATE_LOCK must be released.
1753 *
1754 * Returns:
1755 * qla2x00 local function return status code.
1756 *
1757 * Context:
1758 * Kernel context.
1759 */
1760int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001761qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 uint8_t opt)
1763{
1764 int rval;
1765 mbx_cmd_t mc;
1766 mbx_cmd_t *mcp = &mc;
1767
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001768 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057,
1769 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770
1771 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001772 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001773 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001774 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 mcp->mb[1] = loop_id;
1776 mcp->mb[10] = opt;
1777 mcp->out_mb |= MBX_10;
1778 } else {
1779 mcp->mb[1] = loop_id << 8 | opt;
1780 }
1781
1782 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001783 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001785 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786
1787 if (rval != QLA_SUCCESS) {
1788 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001789 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 } else {
1791 if (name != NULL) {
1792 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05001793 name[0] = MSB(mcp->mb[2]);
1794 name[1] = LSB(mcp->mb[2]);
1795 name[2] = MSB(mcp->mb[3]);
1796 name[3] = LSB(mcp->mb[3]);
1797 name[4] = MSB(mcp->mb[6]);
1798 name[5] = LSB(mcp->mb[6]);
1799 name[6] = MSB(mcp->mb[7]);
1800 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 }
1802
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001803 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059,
1804 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 }
1806
1807 return rval;
1808}
1809
1810/*
Joe Carnuccio61e1b262013-02-08 01:57:48 -05001811 * qla24xx_link_initialization
1812 * Issue link initialization mailbox command.
1813 *
1814 * Input:
1815 * ha = adapter block pointer.
1816 * TARGET_QUEUE_LOCK must be released.
1817 * ADAPTER_STATE_LOCK must be released.
1818 *
1819 * Returns:
1820 * qla2x00 local function return status code.
1821 *
1822 * Context:
1823 * Kernel context.
1824 */
1825int
1826qla24xx_link_initialize(scsi_qla_host_t *vha)
1827{
1828 int rval;
1829 mbx_cmd_t mc;
1830 mbx_cmd_t *mcp = &mc;
1831
1832 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152,
1833 "Entered %s.\n", __func__);
1834
1835 if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw))
1836 return QLA_FUNCTION_FAILED;
1837
1838 mcp->mb[0] = MBC_LINK_INITIALIZATION;
Joe Carnuccio5a5c27b2013-08-27 01:37:49 -04001839 mcp->mb[1] = BIT_4;
1840 if (vha->hw->operating_mode == LOOP)
1841 mcp->mb[1] |= BIT_6;
1842 else
1843 mcp->mb[1] |= BIT_5;
Joe Carnuccio61e1b262013-02-08 01:57:48 -05001844 mcp->mb[2] = 0;
1845 mcp->mb[3] = 0;
1846 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1847 mcp->in_mb = MBX_0;
1848 mcp->tov = MBX_TOV_SECONDS;
1849 mcp->flags = 0;
1850 rval = qla2x00_mailbox_command(vha, mcp);
1851
1852 if (rval != QLA_SUCCESS) {
1853 ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval);
1854 } else {
1855 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154,
1856 "Done %s.\n", __func__);
1857 }
1858
1859 return rval;
1860}
1861
1862/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001863 * qla2x00_lip_reset
1864 * Issue LIP reset mailbox command.
1865 *
1866 * Input:
1867 * ha = adapter block pointer.
1868 * TARGET_QUEUE_LOCK must be released.
1869 * ADAPTER_STATE_LOCK must be released.
1870 *
1871 * Returns:
1872 * qla2x00 local function return status code.
1873 *
1874 * Context:
1875 * Kernel context.
1876 */
1877int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001878qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879{
1880 int rval;
1881 mbx_cmd_t mc;
1882 mbx_cmd_t *mcp = &mc;
1883
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001884 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a,
1885 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001887 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001888 /* Logout across all FCFs. */
1889 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1890 mcp->mb[1] = BIT_1;
1891 mcp->mb[2] = 0;
1892 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1893 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001894 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001895 mcp->mb[1] = BIT_6;
1896 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001897 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001898 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001900 mcp->mb[0] = MBC_LIP_RESET;
1901 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001902 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001903 mcp->mb[1] = 0x00ff;
1904 mcp->mb[10] = 0;
1905 mcp->out_mb |= MBX_10;
1906 } else {
1907 mcp->mb[1] = 0xff00;
1908 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001909 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001910 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001913 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001915 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916
1917 if (rval != QLA_SUCCESS) {
1918 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001919 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 } else {
1921 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001922 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c,
1923 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 }
1925
1926 return rval;
1927}
1928
1929/*
1930 * qla2x00_send_sns
1931 * Send SNS command.
1932 *
1933 * Input:
1934 * ha = adapter block pointer.
1935 * sns = pointer for command.
1936 * cmd_size = command size.
1937 * buf_size = response/command size.
1938 * TARGET_QUEUE_LOCK must be released.
1939 * ADAPTER_STATE_LOCK must be released.
1940 *
1941 * Returns:
1942 * qla2x00 local function return status code.
1943 *
1944 * Context:
1945 * Kernel context.
1946 */
1947int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001948qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949 uint16_t cmd_size, size_t buf_size)
1950{
1951 int rval;
1952 mbx_cmd_t mc;
1953 mbx_cmd_t *mcp = &mc;
1954
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001955 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d,
1956 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001958 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001959 "Retry cnt=%d ratov=%d total tov=%d.\n",
1960 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961
1962 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1963 mcp->mb[1] = cmd_size;
1964 mcp->mb[2] = MSW(sns_phys_address);
1965 mcp->mb[3] = LSW(sns_phys_address);
1966 mcp->mb[6] = MSW(MSD(sns_phys_address));
1967 mcp->mb[7] = LSW(MSD(sns_phys_address));
1968 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1969 mcp->in_mb = MBX_0|MBX_1;
1970 mcp->buf_size = buf_size;
1971 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001972 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1973 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001974
1975 if (rval != QLA_SUCCESS) {
1976 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001977 ql_dbg(ql_dbg_mbx, vha, 0x105f,
1978 "Failed=%x mb[0]=%x mb[1]=%x.\n",
1979 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980 } else {
1981 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001982 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060,
1983 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 }
1985
1986 return rval;
1987}
1988
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001989int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001990qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001991 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1992{
1993 int rval;
1994
1995 struct logio_entry_24xx *lg;
1996 dma_addr_t lg_dma;
1997 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001998 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001999 struct req_que *req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002000
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002001 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061,
2002 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002003
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002004 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002005 req = ha->req_q_map[0];
2006 else
2007 req = vha->req;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002008
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002009 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
2010 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002011 ql_log(ql_log_warn, vha, 0x1062,
2012 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002013 return QLA_MEMORY_ALLOC_FAILED;
2014 }
2015 memset(lg, 0, sizeof(struct logio_entry_24xx));
2016
2017 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2018 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002019 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002020 lg->nport_handle = cpu_to_le16(loop_id);
Bart Van Asschead950362015-07-09 07:24:08 -07002021 lg->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002022 if (opt & BIT_0)
Bart Van Asschead950362015-07-09 07:24:08 -07002023 lg->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07002024 if (opt & BIT_1)
Bart Van Asschead950362015-07-09 07:24:08 -07002025 lg->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002026 lg->port_id[0] = al_pa;
2027 lg->port_id[1] = area;
2028 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002029 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08002030 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2031 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002032 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002033 ql_dbg(ql_dbg_mbx, vha, 0x1063,
2034 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002035 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002036 ql_dbg(ql_dbg_mbx, vha, 0x1064,
2037 "Failed to complete IOCB -- error status (%x).\n",
2038 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002039 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002040 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002041 iop[0] = le32_to_cpu(lg->io_parameter[0]);
2042 iop[1] = le32_to_cpu(lg->io_parameter[1]);
2043
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002044 ql_dbg(ql_dbg_mbx, vha, 0x1065,
2045 "Failed to complete IOCB -- completion status (%x) "
2046 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
2047 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002048
2049 switch (iop[0]) {
2050 case LSC_SCODE_PORTID_USED:
2051 mb[0] = MBS_PORT_ID_USED;
2052 mb[1] = LSW(iop[1]);
2053 break;
2054 case LSC_SCODE_NPORT_USED:
2055 mb[0] = MBS_LOOP_ID_USED;
2056 break;
2057 case LSC_SCODE_NOLINK:
2058 case LSC_SCODE_NOIOCB:
2059 case LSC_SCODE_NOXCB:
2060 case LSC_SCODE_CMD_FAILED:
2061 case LSC_SCODE_NOFABRIC:
2062 case LSC_SCODE_FW_NOT_READY:
2063 case LSC_SCODE_NOT_LOGGED_IN:
2064 case LSC_SCODE_NOPCB:
2065 case LSC_SCODE_ELS_REJECT:
2066 case LSC_SCODE_CMD_PARAM_ERR:
2067 case LSC_SCODE_NONPORT:
2068 case LSC_SCODE_LOGGED_IN:
2069 case LSC_SCODE_NOFLOGI_ACC:
2070 default:
2071 mb[0] = MBS_COMMAND_ERROR;
2072 break;
2073 }
2074 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002075 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066,
2076 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002077
2078 iop[0] = le32_to_cpu(lg->io_parameter[0]);
2079
2080 mb[0] = MBS_COMMAND_COMPLETE;
2081 mb[1] = 0;
2082 if (iop[0] & BIT_4) {
2083 if (iop[0] & BIT_8)
2084 mb[1] |= BIT_1;
2085 } else
2086 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07002087
2088 /* Passback COS information. */
2089 mb[10] = 0;
2090 if (lg->io_parameter[7] || lg->io_parameter[8])
2091 mb[10] |= BIT_0; /* Class 2. */
2092 if (lg->io_parameter[9] || lg->io_parameter[10])
2093 mb[10] |= BIT_1; /* Class 3. */
Bart Van Asschead950362015-07-09 07:24:08 -07002094 if (lg->io_parameter[0] & cpu_to_le32(BIT_7))
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04002095 mb[10] |= BIT_7; /* Confirmed Completion
2096 * Allowed
2097 */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002098 }
2099
2100 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2101
2102 return rval;
2103}
2104
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105/*
2106 * qla2x00_login_fabric
2107 * Issue login fabric port mailbox command.
2108 *
2109 * Input:
2110 * ha = adapter block pointer.
2111 * loop_id = device loop ID.
2112 * domain = device domain.
2113 * area = device area.
2114 * al_pa = device AL_PA.
2115 * status = pointer for return status.
2116 * opt = command options.
2117 * TARGET_QUEUE_LOCK must be released.
2118 * ADAPTER_STATE_LOCK must be released.
2119 *
2120 * Returns:
2121 * qla2x00 local function return status code.
2122 *
2123 * Context:
2124 * Kernel context.
2125 */
2126int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002127qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
2129{
2130 int rval;
2131 mbx_cmd_t mc;
2132 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002133 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002134
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002135 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067,
2136 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137
2138 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
2139 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2140 if (HAS_EXTENDED_IDS(ha)) {
2141 mcp->mb[1] = loop_id;
2142 mcp->mb[10] = opt;
2143 mcp->out_mb |= MBX_10;
2144 } else {
2145 mcp->mb[1] = (loop_id << 8) | opt;
2146 }
2147 mcp->mb[2] = domain;
2148 mcp->mb[3] = area << 8 | al_pa;
2149
2150 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
2151 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2152 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002153 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154
2155 /* Return mailbox statuses. */
2156 if (mb != NULL) {
2157 mb[0] = mcp->mb[0];
2158 mb[1] = mcp->mb[1];
2159 mb[2] = mcp->mb[2];
2160 mb[6] = mcp->mb[6];
2161 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07002162 /* COS retrieved from Get-Port-Database mailbox command. */
2163 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002164 }
2165
2166 if (rval != QLA_SUCCESS) {
2167 /* RLU tmp code: need to change main mailbox_command function to
2168 * return ok even when the mailbox completion value is not
2169 * SUCCESS. The caller needs to be responsible to interpret
2170 * the return values of this mailbox command if we're not
2171 * to change too much of the existing code.
2172 */
2173 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
2174 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
2175 mcp->mb[0] == 0x4006)
2176 rval = QLA_SUCCESS;
2177
2178 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002179 ql_dbg(ql_dbg_mbx, vha, 0x1068,
2180 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
2181 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182 } else {
2183 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002184 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069,
2185 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186 }
2187
2188 return rval;
2189}
2190
2191/*
2192 * qla2x00_login_local_device
2193 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002194 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002195 * Input:
2196 * ha = adapter block pointer.
2197 * loop_id = device loop ID.
2198 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002199 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002200 * Returns:
2201 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002202 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002203 * Context:
2204 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002205 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002206 */
2207int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002208qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002209 uint16_t *mb_ret, uint8_t opt)
2210{
2211 int rval;
2212 mbx_cmd_t mc;
2213 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002214 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002215
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002216 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a,
2217 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002218
Andrew Vasqueze4289242007-07-19 15:05:56 -07002219 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002220 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002221 fcport->d_id.b.domain, fcport->d_id.b.area,
2222 fcport->d_id.b.al_pa, mb_ret, opt);
2223
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
2225 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002226 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 else
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002228 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002229 mcp->mb[2] = opt;
2230 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2231 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
2232 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2233 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002234 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002235
2236 /* Return mailbox statuses. */
2237 if (mb_ret != NULL) {
2238 mb_ret[0] = mcp->mb[0];
2239 mb_ret[1] = mcp->mb[1];
2240 mb_ret[6] = mcp->mb[6];
2241 mb_ret[7] = mcp->mb[7];
2242 }
2243
2244 if (rval != QLA_SUCCESS) {
2245 /* AV tmp code: need to change main mailbox_command function to
2246 * return ok even when the mailbox completion value is not
2247 * SUCCESS. The caller needs to be responsible to interpret
2248 * the return values of this mailbox command if we're not
2249 * to change too much of the existing code.
2250 */
2251 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
2252 rval = QLA_SUCCESS;
2253
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002254 ql_dbg(ql_dbg_mbx, vha, 0x106b,
2255 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
2256 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 } else {
2258 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002259 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c,
2260 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002261 }
2262
2263 return (rval);
2264}
2265
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002266int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002267qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002268 uint8_t area, uint8_t al_pa)
2269{
2270 int rval;
2271 struct logio_entry_24xx *lg;
2272 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002273 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002274 struct req_que *req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002275
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002276 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d,
2277 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002278
2279 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
2280 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002281 ql_log(ql_log_warn, vha, 0x106e,
2282 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002283 return QLA_MEMORY_ALLOC_FAILED;
2284 }
2285 memset(lg, 0, sizeof(struct logio_entry_24xx));
2286
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002287 if (ql2xmaxqueues > 1)
2288 req = ha->req_q_map[0];
2289 else
2290 req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002291 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2292 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002293 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002294 lg->nport_handle = cpu_to_le16(loop_id);
2295 lg->control_flags =
Bart Van Asschead950362015-07-09 07:24:08 -07002296 cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
Andrew Vasquezc8d66912011-03-30 11:46:21 -07002297 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002298 lg->port_id[0] = al_pa;
2299 lg->port_id[1] = area;
2300 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002301 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08002302 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2303 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002304 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002305 ql_dbg(ql_dbg_mbx, vha, 0x106f,
2306 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002307 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002308 ql_dbg(ql_dbg_mbx, vha, 0x1070,
2309 "Failed to complete IOCB -- error status (%x).\n",
2310 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002311 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002312 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002313 ql_dbg(ql_dbg_mbx, vha, 0x1071,
2314 "Failed to complete IOCB -- completion status (%x) "
2315 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002316 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002317 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002318 } else {
2319 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002320 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072,
2321 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002322 }
2323
2324 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2325
2326 return rval;
2327}
2328
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329/*
2330 * qla2x00_fabric_logout
2331 * Issue logout fabric port mailbox command.
2332 *
2333 * Input:
2334 * ha = adapter block pointer.
2335 * loop_id = device loop ID.
2336 * TARGET_QUEUE_LOCK must be released.
2337 * ADAPTER_STATE_LOCK must be released.
2338 *
2339 * Returns:
2340 * qla2x00 local function return status code.
2341 *
2342 * Context:
2343 * Kernel context.
2344 */
2345int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002346qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002347 uint8_t area, uint8_t al_pa)
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, 0x1073,
2354 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355
2356 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
2357 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002358 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359 mcp->mb[1] = loop_id;
2360 mcp->mb[10] = 0;
2361 mcp->out_mb |= MBX_10;
2362 } else {
2363 mcp->mb[1] = loop_id << 8;
2364 }
2365
2366 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002367 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002368 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002369 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370
2371 if (rval != QLA_SUCCESS) {
2372 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002373 ql_dbg(ql_dbg_mbx, vha, 0x1074,
2374 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375 } else {
2376 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002377 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075,
2378 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379 }
2380
2381 return rval;
2382}
2383
2384/*
2385 * qla2x00_full_login_lip
2386 * Issue full login LIP mailbox command.
2387 *
2388 * Input:
2389 * ha = adapter block pointer.
2390 * TARGET_QUEUE_LOCK must be released.
2391 * ADAPTER_STATE_LOCK must be released.
2392 *
2393 * Returns:
2394 * qla2x00 local function return status code.
2395 *
2396 * Context:
2397 * Kernel context.
2398 */
2399int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002400qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401{
2402 int rval;
2403 mbx_cmd_t mc;
2404 mbx_cmd_t *mcp = &mc;
2405
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002406 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076,
2407 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408
2409 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002410 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002411 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002412 mcp->mb[3] = 0;
2413 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2414 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002415 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002417 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418
2419 if (rval != QLA_SUCCESS) {
2420 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002421 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422 } else {
2423 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002424 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078,
2425 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002426 }
2427
2428 return rval;
2429}
2430
2431/*
2432 * qla2x00_get_id_list
2433 *
2434 * Input:
2435 * ha = adapter block pointer.
2436 *
2437 * Returns:
2438 * qla2x00 local function return status code.
2439 *
2440 * Context:
2441 * Kernel context.
2442 */
2443int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002444qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445 uint16_t *entries)
2446{
2447 int rval;
2448 mbx_cmd_t mc;
2449 mbx_cmd_t *mcp = &mc;
2450
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002451 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079,
2452 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002453
2454 if (id_list == NULL)
2455 return QLA_FUNCTION_FAILED;
2456
2457 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002458 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002459 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002460 mcp->mb[2] = MSW(id_list_dma);
2461 mcp->mb[3] = LSW(id_list_dma);
2462 mcp->mb[6] = MSW(MSD(id_list_dma));
2463 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002464 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002465 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002466 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002467 } else {
2468 mcp->mb[1] = MSW(id_list_dma);
2469 mcp->mb[2] = LSW(id_list_dma);
2470 mcp->mb[3] = MSW(MSD(id_list_dma));
2471 mcp->mb[6] = LSW(MSD(id_list_dma));
2472 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2473 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002474 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002475 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002476 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002477 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002478
2479 if (rval != QLA_SUCCESS) {
2480 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002481 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482 } else {
2483 *entries = mcp->mb[1];
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002484 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b,
2485 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486 }
2487
2488 return rval;
2489}
2490
2491/*
2492 * qla2x00_get_resource_cnts
2493 * Get current firmware resource counts.
2494 *
2495 * Input:
2496 * ha = adapter block pointer.
2497 *
2498 * Returns:
2499 * qla2x00 local function return status code.
2500 *
2501 * Context:
2502 * Kernel context.
2503 */
2504int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002505qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002506 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002507 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508{
2509 int rval;
2510 mbx_cmd_t mc;
2511 mbx_cmd_t *mcp = &mc;
2512
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002513 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c,
2514 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515
2516 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2517 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002518 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 -05002519 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) || IS_QLA27XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002520 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002521 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002523 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524
2525 if (rval != QLA_SUCCESS) {
2526 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002527 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2528 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002530 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002531 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2532 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2533 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2534 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002535
2536 if (cur_xchg_cnt)
2537 *cur_xchg_cnt = mcp->mb[3];
2538 if (orig_xchg_cnt)
2539 *orig_xchg_cnt = mcp->mb[6];
2540 if (cur_iocb_cnt)
2541 *cur_iocb_cnt = mcp->mb[7];
2542 if (orig_iocb_cnt)
2543 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002544 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002545 *max_npiv_vports = mcp->mb[11];
Himanshu Madhanib20f02e2015-06-10 11:05:18 -04002546 if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) ||
2547 IS_QLA27XX(vha->hw)) && max_fcfs)
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002548 *max_fcfs = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 }
2550
2551 return (rval);
2552}
2553
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554/*
2555 * qla2x00_get_fcal_position_map
2556 * Get FCAL (LILP) position map using mailbox command
2557 *
2558 * Input:
2559 * ha = adapter state pointer.
2560 * pos_map = buffer pointer (can be NULL).
2561 *
2562 * Returns:
2563 * qla2x00 local function return status code.
2564 *
2565 * Context:
2566 * Kernel context.
2567 */
2568int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002569qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570{
2571 int rval;
2572 mbx_cmd_t mc;
2573 mbx_cmd_t *mcp = &mc;
2574 char *pmap;
2575 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002576 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002578 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f,
2579 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002580
Andrew Vasquez4b892582008-09-11 21:22:48 -07002581 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002583 ql_log(ql_log_warn, vha, 0x1080,
2584 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002585 return QLA_MEMORY_ALLOC_FAILED;
2586 }
2587 memset(pmap, 0, FCAL_MAP_SIZE);
2588
2589 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2590 mcp->mb[2] = MSW(pmap_dma);
2591 mcp->mb[3] = LSW(pmap_dma);
2592 mcp->mb[6] = MSW(MSD(pmap_dma));
2593 mcp->mb[7] = LSW(MSD(pmap_dma));
2594 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2595 mcp->in_mb = MBX_1|MBX_0;
2596 mcp->buf_size = FCAL_MAP_SIZE;
2597 mcp->flags = MBX_DMA_IN;
2598 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002599 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600
2601 if (rval == QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002602 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002603 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2604 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2605 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2606 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607
2608 if (pos_map)
2609 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2610 }
2611 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2612
2613 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002614 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002616 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083,
2617 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618 }
2619
2620 return rval;
2621}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002622
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002623/*
2624 * qla2x00_get_link_status
2625 *
2626 * Input:
2627 * ha = adapter block pointer.
2628 * loop_id = device loop ID.
2629 * ret_buf = pointer to link status return buffer.
2630 *
2631 * Returns:
2632 * 0 = success.
2633 * BIT_0 = mem alloc error.
2634 * BIT_1 = mailbox error.
2635 */
2636int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002637qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002638 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002639{
2640 int rval;
2641 mbx_cmd_t mc;
2642 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002643 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002644 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002645
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002646 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084,
2647 "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002648
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002649 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002650 mcp->mb[2] = MSW(stats_dma);
2651 mcp->mb[3] = LSW(stats_dma);
2652 mcp->mb[6] = MSW(MSD(stats_dma));
2653 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002654 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2655 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002656 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002657 mcp->mb[1] = loop_id;
2658 mcp->mb[4] = 0;
2659 mcp->mb[10] = 0;
2660 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2661 mcp->in_mb |= MBX_1;
2662 } else if (HAS_EXTENDED_IDS(ha)) {
2663 mcp->mb[1] = loop_id;
2664 mcp->mb[10] = 0;
2665 mcp->out_mb |= MBX_10|MBX_1;
2666 } else {
2667 mcp->mb[1] = loop_id << 8;
2668 mcp->out_mb |= MBX_1;
2669 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002670 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002671 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002672 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002673
2674 if (rval == QLA_SUCCESS) {
2675 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002676 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2677 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002678 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002679 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002680 /* Copy over data -- firmware data is LE. */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002681 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086,
2682 "Done %s.\n", __func__);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002683 dwords = offsetof(struct link_statistics, unused1) / 4;
2684 siter = diter = &stats->link_fail_cnt;
2685 while (dwords--)
2686 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002687 }
2688 } else {
2689 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002690 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002691 }
2692
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002693 return rval;
2694}
2695
2696int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002697qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002698 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002699{
2700 int rval;
2701 mbx_cmd_t mc;
2702 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002703 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002704
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002705 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,
2706 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002707
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002708 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002709 mcp->mb[2] = MSW(stats_dma);
2710 mcp->mb[3] = LSW(stats_dma);
2711 mcp->mb[6] = MSW(MSD(stats_dma));
2712 mcp->mb[7] = LSW(MSD(stats_dma));
2713 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002714 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002715 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002716 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 -07002717 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002718 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002719 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002720 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002721
2722 if (rval == QLA_SUCCESS) {
2723 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002724 ql_dbg(ql_dbg_mbx, vha, 0x1089,
2725 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002726 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002727 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002728 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a,
2729 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002730 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002731 dwords = sizeof(struct link_statistics) / 4;
2732 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002733 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002734 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002735 }
2736 } else {
2737 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002738 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002739 }
2740
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002741 return rval;
2742}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002743
2744int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002745qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002746{
2747 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002748 unsigned long flags = 0;
2749
2750 struct abort_entry_24xx *abt;
2751 dma_addr_t abt_dma;
2752 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002753 fc_port_t *fcport = sp->fcport;
2754 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002755 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07002756 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002757
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002758 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,
2759 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002760
Armen Baloyan4440e462014-02-26 04:15:18 -05002761 if (ql2xasynctmfenable)
2762 return qla24xx_async_abort_command(sp);
2763
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002764 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05002765 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002766 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002767 break;
2768 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002769 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05002770 if (handle == req->num_outstanding_cmds) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002771 /* Command not found. */
2772 return QLA_FUNCTION_FAILED;
2773 }
2774
2775 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2776 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002777 ql_log(ql_log_warn, vha, 0x108d,
2778 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002779 return QLA_MEMORY_ALLOC_FAILED;
2780 }
2781 memset(abt, 0, sizeof(struct abort_entry_24xx));
2782
2783 abt->entry_type = ABORT_IOCB_TYPE;
2784 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002785 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002786 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07002787 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002788 abt->port_id[0] = fcport->d_id.b.al_pa;
2789 abt->port_id[1] = fcport->d_id.b.area;
2790 abt->port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04002791 abt->vp_index = fcport->vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002792
2793 abt->req_que_no = cpu_to_le16(req->id);
2794
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002795 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002796 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002797 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2798 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002799 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002800 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2801 "Failed to complete IOCB -- error status (%x).\n",
2802 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002803 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002804 } else if (abt->nport_handle != cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002805 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2806 "Failed to complete IOCB -- completion status (%x).\n",
2807 le16_to_cpu(abt->nport_handle));
Chad Dupuisf934c9d2014-04-11 16:54:31 -04002808 if (abt->nport_handle == CS_IOCB_ERROR)
2809 rval = QLA_FUNCTION_PARAMETER_ERROR;
2810 else
2811 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002812 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002813 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
2814 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002815 }
2816
2817 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2818
2819 return rval;
2820}
2821
2822struct tsk_mgmt_cmd {
2823 union {
2824 struct tsk_mgmt_entry tsk;
2825 struct sts_entry_24xx sts;
2826 } p;
2827};
2828
Andrew Vasquez523ec772008-04-03 13:13:24 -07002829static int
2830__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02002831 uint64_t l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002832{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002833 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002834 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002835 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002836 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002837 scsi_qla_host_t *vha;
2838 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002839 struct req_que *req;
2840 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002841
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002842 vha = fcport->vha;
2843 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002844 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002845
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002846 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092,
2847 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002848
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002849 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002850 rsp = ha->rsp_q_map[tag + 1];
2851 else
2852 rsp = req->rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002853 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002854 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002855 ql_log(ql_log_warn, vha, 0x1093,
2856 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002857 return QLA_MEMORY_ALLOC_FAILED;
2858 }
2859 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2860
2861 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2862 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002863 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002864 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002865 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002866 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002867 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2868 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2869 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04002870 tsk->p.tsk.vp_index = fcport->vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002871 if (type == TCF_LUN_RESET) {
2872 int_to_scsilun(l, &tsk->p.tsk.lun);
2873 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2874 sizeof(tsk->p.tsk.lun));
2875 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002876
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002877 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002878 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002879 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002880 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2881 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002882 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002883 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2884 "Failed to complete IOCB -- error status (%x).\n",
2885 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002886 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002887 } else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002888 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2889 "Failed to complete IOCB -- completion status (%x).\n",
2890 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002891 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08002892 } else if (le16_to_cpu(sts->scsi_status) &
2893 SS_RESPONSE_INFO_LEN_VALID) {
2894 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002895 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002896 "Ignoring inconsistent data length -- not enough "
2897 "response info (%d).\n",
2898 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08002899 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002900 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2901 "Failed to complete IOCB -- response (%x).\n",
2902 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08002903 rval = QLA_FUNCTION_FAILED;
2904 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002905 }
2906
2907 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002908 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002909 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2910 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002911 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2912 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002913 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002914 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a,
2915 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002916 }
2917
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002918 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002919
2920 return rval;
2921}
2922
Andrew Vasquez523ec772008-04-03 13:13:24 -07002923int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02002924qla24xx_abort_target(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002925{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002926 struct qla_hw_data *ha = fcport->vha->hw;
2927
2928 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2929 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2930
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002931 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002932}
2933
2934int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02002935qla24xx_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002936{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002937 struct qla_hw_data *ha = fcport->vha->hw;
2938
2939 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2940 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2941
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002942 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002943}
2944
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002945int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002946qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002947{
2948 int rval;
2949 mbx_cmd_t mc;
2950 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002951 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002952
Andrew Vasquez68af0812008-05-12 22:21:13 -07002953 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002954 return QLA_FUNCTION_FAILED;
2955
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002956 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b,
2957 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002958
2959 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2960 mcp->out_mb = MBX_0;
2961 mcp->in_mb = MBX_0;
2962 mcp->tov = 5;
2963 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002964 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002965
2966 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002967 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002968 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002969 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d,
2970 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002971 }
2972
2973 return rval;
2974}
2975
Joe Carnucciodb64e932013-10-30 03:38:18 -04002976int
2977qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data)
2978{
2979 int rval;
2980 mbx_cmd_t mc;
2981 mbx_cmd_t *mcp = &mc;
2982
Joe Carnucciof299c7c2015-08-04 13:37:51 -04002983 if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
2984 !IS_QLA27XX(vha->hw))
Joe Carnucciodb64e932013-10-30 03:38:18 -04002985 return QLA_FUNCTION_FAILED;
2986
2987 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182,
2988 "Entered %s.\n", __func__);
2989
2990 mcp->mb[0] = MBC_WRITE_SERDES;
2991 mcp->mb[1] = addr;
Andrew Vasquez064135e2015-04-09 15:00:02 -04002992 if (IS_QLA2031(vha->hw))
2993 mcp->mb[2] = data & 0xff;
2994 else
2995 mcp->mb[2] = data;
2996
Joe Carnucciodb64e932013-10-30 03:38:18 -04002997 mcp->mb[3] = 0;
2998 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2999 mcp->in_mb = MBX_0;
3000 mcp->tov = MBX_TOV_SECONDS;
3001 mcp->flags = 0;
3002 rval = qla2x00_mailbox_command(vha, mcp);
3003
3004 if (rval != QLA_SUCCESS) {
3005 ql_dbg(ql_dbg_mbx, vha, 0x1183,
3006 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3007 } else {
3008 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184,
3009 "Done %s.\n", __func__);
3010 }
3011
3012 return rval;
3013}
3014
3015int
3016qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)
3017{
3018 int rval;
3019 mbx_cmd_t mc;
3020 mbx_cmd_t *mcp = &mc;
3021
Joe Carnucciof299c7c2015-08-04 13:37:51 -04003022 if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
3023 !IS_QLA27XX(vha->hw))
Joe Carnucciodb64e932013-10-30 03:38:18 -04003024 return QLA_FUNCTION_FAILED;
3025
3026 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185,
3027 "Entered %s.\n", __func__);
3028
3029 mcp->mb[0] = MBC_READ_SERDES;
3030 mcp->mb[1] = addr;
3031 mcp->mb[3] = 0;
3032 mcp->out_mb = MBX_3|MBX_1|MBX_0;
3033 mcp->in_mb = MBX_1|MBX_0;
3034 mcp->tov = MBX_TOV_SECONDS;
3035 mcp->flags = 0;
3036 rval = qla2x00_mailbox_command(vha, mcp);
3037
Andrew Vasquez064135e2015-04-09 15:00:02 -04003038 if (IS_QLA2031(vha->hw))
3039 *data = mcp->mb[1] & 0xff;
3040 else
3041 *data = mcp->mb[1];
Joe Carnucciodb64e932013-10-30 03:38:18 -04003042
3043 if (rval != QLA_SUCCESS) {
3044 ql_dbg(ql_dbg_mbx, vha, 0x1186,
3045 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3046 } else {
3047 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187,
3048 "Done %s.\n", __func__);
3049 }
3050
3051 return rval;
3052}
3053
Joe Carnuccioe8887c52014-04-11 16:54:17 -04003054int
3055qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)
3056{
3057 int rval;
3058 mbx_cmd_t mc;
3059 mbx_cmd_t *mcp = &mc;
3060
3061 if (!IS_QLA8044(vha->hw))
3062 return QLA_FUNCTION_FAILED;
3063
3064 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1186,
3065 "Entered %s.\n", __func__);
3066
3067 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3068 mcp->mb[1] = HCS_WRITE_SERDES;
3069 mcp->mb[3] = LSW(addr);
3070 mcp->mb[4] = MSW(addr);
3071 mcp->mb[5] = LSW(data);
3072 mcp->mb[6] = MSW(data);
3073 mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
3074 mcp->in_mb = MBX_0;
3075 mcp->tov = MBX_TOV_SECONDS;
3076 mcp->flags = 0;
3077 rval = qla2x00_mailbox_command(vha, mcp);
3078
3079 if (rval != QLA_SUCCESS) {
3080 ql_dbg(ql_dbg_mbx, vha, 0x1187,
3081 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3082 } else {
3083 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188,
3084 "Done %s.\n", __func__);
3085 }
3086
3087 return rval;
3088}
3089
3090int
3091qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
3092{
3093 int rval;
3094 mbx_cmd_t mc;
3095 mbx_cmd_t *mcp = &mc;
3096
3097 if (!IS_QLA8044(vha->hw))
3098 return QLA_FUNCTION_FAILED;
3099
3100 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189,
3101 "Entered %s.\n", __func__);
3102
3103 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3104 mcp->mb[1] = HCS_READ_SERDES;
3105 mcp->mb[3] = LSW(addr);
3106 mcp->mb[4] = MSW(addr);
3107 mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0;
3108 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3109 mcp->tov = MBX_TOV_SECONDS;
3110 mcp->flags = 0;
3111 rval = qla2x00_mailbox_command(vha, mcp);
3112
3113 *data = mcp->mb[2] << 16 | mcp->mb[1];
3114
3115 if (rval != QLA_SUCCESS) {
3116 ql_dbg(ql_dbg_mbx, vha, 0x118a,
3117 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3118 } else {
3119 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b,
3120 "Done %s.\n", __func__);
3121 }
3122
3123 return rval;
3124}
3125
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003126/**
3127 * qla2x00_set_serdes_params() -
3128 * @ha: HA context
3129 *
3130 * Returns
3131 */
3132int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003133qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003134 uint16_t sw_em_2g, uint16_t sw_em_4g)
3135{
3136 int rval;
3137 mbx_cmd_t mc;
3138 mbx_cmd_t *mcp = &mc;
3139
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003140 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e,
3141 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003142
3143 mcp->mb[0] = MBC_SERDES_PARAMS;
3144 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08003145 mcp->mb[2] = sw_em_1g | BIT_15;
3146 mcp->mb[3] = sw_em_2g | BIT_15;
3147 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003148 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3149 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003150 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003151 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003152 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003153
3154 if (rval != QLA_SUCCESS) {
3155 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003156 ql_dbg(ql_dbg_mbx, vha, 0x109f,
3157 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003158 } else {
3159 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003160 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0,
3161 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003162 }
3163
3164 return rval;
3165}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003166
3167int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003168qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003169{
3170 int rval;
3171 mbx_cmd_t mc;
3172 mbx_cmd_t *mcp = &mc;
3173
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003174 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003175 return QLA_FUNCTION_FAILED;
3176
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003177 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1,
3178 "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003179
3180 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08003181 mcp->mb[1] = 0;
3182 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003183 mcp->in_mb = MBX_0;
3184 mcp->tov = 5;
3185 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003186 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003187
3188 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003189 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07003190 if (mcp->mb[0] == MBS_INVALID_COMMAND)
3191 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003192 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003193 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3,
3194 "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003195 }
3196
3197 return rval;
3198}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003199
3200int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003201qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003202 uint16_t buffers)
3203{
3204 int rval;
3205 mbx_cmd_t mc;
3206 mbx_cmd_t *mcp = &mc;
3207
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003208 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4,
3209 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003210
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003211 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003212 return QLA_FUNCTION_FAILED;
3213
Andrew Vasquez85880802009-12-15 21:29:46 -08003214 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3215 return QLA_FUNCTION_FAILED;
3216
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003217 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003218 mcp->mb[1] = TC_EFT_ENABLE;
3219 mcp->mb[2] = LSW(eft_dma);
3220 mcp->mb[3] = MSW(eft_dma);
3221 mcp->mb[4] = LSW(MSD(eft_dma));
3222 mcp->mb[5] = MSW(MSD(eft_dma));
3223 mcp->mb[6] = buffers;
3224 mcp->mb[7] = TC_AEN_DISABLE;
3225 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 -07003226 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003227 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003228 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003229 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003230 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003231 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
3232 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3233 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003234 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003235 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6,
3236 "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003237 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003238
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003239 return rval;
3240}
3241
3242int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003243qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003244{
3245 int rval;
3246 mbx_cmd_t mc;
3247 mbx_cmd_t *mcp = &mc;
3248
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003249 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7,
3250 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003251
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003252 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003253 return QLA_FUNCTION_FAILED;
3254
Andrew Vasquez85880802009-12-15 21:29:46 -08003255 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3256 return QLA_FUNCTION_FAILED;
3257
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003258 mcp->mb[0] = MBC_TRACE_CONTROL;
3259 mcp->mb[1] = TC_EFT_DISABLE;
3260 mcp->out_mb = MBX_1|MBX_0;
3261 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003262 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003263 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003264 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003265 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003266 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
3267 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3268 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003269 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003270 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9,
3271 "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003272 }
3273
3274 return rval;
3275}
3276
Andrew Vasquez88729e52006-06-23 16:10:50 -07003277int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003278qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003279 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
3280{
3281 int rval;
3282 mbx_cmd_t mc;
3283 mbx_cmd_t *mcp = &mc;
3284
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003285 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa,
3286 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003287
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003288 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
Chad Dupuisf73cb692014-02-26 04:15:06 -05003289 !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003290 return QLA_FUNCTION_FAILED;
3291
Andrew Vasquez85880802009-12-15 21:29:46 -08003292 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3293 return QLA_FUNCTION_FAILED;
3294
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003295 mcp->mb[0] = MBC_TRACE_CONTROL;
3296 mcp->mb[1] = TC_FCE_ENABLE;
3297 mcp->mb[2] = LSW(fce_dma);
3298 mcp->mb[3] = MSW(fce_dma);
3299 mcp->mb[4] = LSW(MSD(fce_dma));
3300 mcp->mb[5] = MSW(MSD(fce_dma));
3301 mcp->mb[6] = buffers;
3302 mcp->mb[7] = TC_AEN_DISABLE;
3303 mcp->mb[8] = 0;
3304 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
3305 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
3306 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3307 MBX_1|MBX_0;
3308 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003309 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003310 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003311 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003312 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003313 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
3314 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3315 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003316 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003317 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac,
3318 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003319
3320 if (mb)
3321 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
3322 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07003323 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003324 }
3325
3326 return rval;
3327}
3328
3329int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003330qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003331{
3332 int rval;
3333 mbx_cmd_t mc;
3334 mbx_cmd_t *mcp = &mc;
3335
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003336 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad,
3337 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003338
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003339 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003340 return QLA_FUNCTION_FAILED;
3341
Andrew Vasquez85880802009-12-15 21:29:46 -08003342 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3343 return QLA_FUNCTION_FAILED;
3344
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003345 mcp->mb[0] = MBC_TRACE_CONTROL;
3346 mcp->mb[1] = TC_FCE_DISABLE;
3347 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
3348 mcp->out_mb = MBX_2|MBX_1|MBX_0;
3349 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3350 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003351 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003352 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003353 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003354 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003355 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
3356 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3357 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003358 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003359 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af,
3360 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003361
3362 if (wr)
3363 *wr = (uint64_t) mcp->mb[5] << 48 |
3364 (uint64_t) mcp->mb[4] << 32 |
3365 (uint64_t) mcp->mb[3] << 16 |
3366 (uint64_t) mcp->mb[2];
3367 if (rd)
3368 *rd = (uint64_t) mcp->mb[9] << 48 |
3369 (uint64_t) mcp->mb[8] << 32 |
3370 (uint64_t) mcp->mb[7] << 16 |
3371 (uint64_t) mcp->mb[6];
3372 }
3373
3374 return rval;
3375}
3376
3377int
Giridhar Malavali6e980162010-03-19 17:03:58 -07003378qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
3379 uint16_t *port_speed, uint16_t *mb)
3380{
3381 int rval;
3382 mbx_cmd_t mc;
3383 mbx_cmd_t *mcp = &mc;
3384
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003385 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0,
3386 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003387
Giridhar Malavali6e980162010-03-19 17:03:58 -07003388 if (!IS_IIDMA_CAPABLE(vha->hw))
3389 return QLA_FUNCTION_FAILED;
3390
Giridhar Malavali6e980162010-03-19 17:03:58 -07003391 mcp->mb[0] = MBC_PORT_PARAMS;
3392 mcp->mb[1] = loop_id;
3393 mcp->mb[2] = mcp->mb[3] = 0;
3394 mcp->mb[9] = vha->vp_idx;
3395 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3396 mcp->in_mb = MBX_3|MBX_1|MBX_0;
3397 mcp->tov = MBX_TOV_SECONDS;
3398 mcp->flags = 0;
3399 rval = qla2x00_mailbox_command(vha, mcp);
3400
3401 /* Return mailbox statuses. */
3402 if (mb != NULL) {
3403 mb[0] = mcp->mb[0];
3404 mb[1] = mcp->mb[1];
3405 mb[3] = mcp->mb[3];
3406 }
3407
3408 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003409 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003410 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003411 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2,
3412 "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003413 if (port_speed)
3414 *port_speed = mcp->mb[3];
3415 }
3416
3417 return rval;
3418}
3419
3420int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003421qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003422 uint16_t port_speed, uint16_t *mb)
3423{
3424 int rval;
3425 mbx_cmd_t mc;
3426 mbx_cmd_t *mcp = &mc;
3427
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003428 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3,
3429 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003430
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003431 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003432 return QLA_FUNCTION_FAILED;
3433
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003434 mcp->mb[0] = MBC_PORT_PARAMS;
3435 mcp->mb[1] = loop_id;
3436 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003437 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07003438 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
3439 else
3440 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
3441 mcp->mb[9] = vha->vp_idx;
3442 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3443 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003444 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003445 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003446 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003447
3448 /* Return mailbox statuses. */
3449 if (mb != NULL) {
3450 mb[0] = mcp->mb[0];
3451 mb[1] = mcp->mb[1];
3452 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003453 }
3454
3455 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003456 ql_dbg(ql_dbg_mbx, vha, 0x10b4,
3457 "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003458 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003459 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5,
3460 "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003461 }
3462
3463 return rval;
3464}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003465
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003466void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003467qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003468 struct vp_rpt_id_entry_24xx *rptid_entry)
3469{
3470 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07003471 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003472 struct qla_hw_data *ha = vha->hw;
3473 scsi_qla_host_t *vp;
Arun Easifeafb7b2010-09-03 14:57:00 -07003474 unsigned long flags;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003475 int found;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003476
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003477 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
3478 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003479
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003480 if (rptid_entry->entry_status != 0)
3481 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003482
3483 if (rptid_entry->format == 0) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003484 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003485 "Format 0 : Number of VPs setup %d, number of "
3486 "VPs acquired %d.\n",
3487 MSB(le16_to_cpu(rptid_entry->vp_count)),
3488 LSB(le16_to_cpu(rptid_entry->vp_count)));
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003489 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b8,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003490 "Primary port id %02x%02x%02x.\n",
3491 rptid_entry->port_id[2], rptid_entry->port_id[1],
3492 rptid_entry->port_id[0]);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003493 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07003494 vp_idx = LSB(stat);
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003495 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b9,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003496 "Format 1: VP[%d] enabled - status %d - with "
3497 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003498 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003499 rptid_entry->port_id[0]);
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003500
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04003501 /* FA-WWN is only for physical port */
3502 if (!vp_idx) {
3503 void *wwpn = ha->init_cb->port_name;
3504
3505 if (!MSB(stat)) {
3506 if (rptid_entry->vp_idx_map[1] & BIT_6)
3507 wwpn = rptid_entry->reserved_4 + 8;
3508 }
3509 memcpy(vha->port_name, wwpn, WWN_SIZE);
3510 fc_host_port_name(vha->host) =
3511 wwn_to_u64(vha->port_name);
3512 ql_dbg(ql_dbg_mbx, vha, 0x1018,
3513 "FA-WWN portname %016llx (%x)\n",
3514 fc_host_port_name(vha->host), MSB(stat));
3515 }
3516
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003517 vp = vha;
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04003518 if (vp_idx == 0)
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003519 goto reg_needed;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003520
Saurav Kashyap681e0142012-11-21 02:40:28 -05003521 if (MSB(stat) != 0 && MSB(stat) != 2) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003522 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
3523 "Could not acquire ID for VP[%d].\n", vp_idx);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003524 return;
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07003525 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003526
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003527 found = 0;
Arun Easifeafb7b2010-09-03 14:57:00 -07003528 spin_lock_irqsave(&ha->vport_slock, flags);
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003529 list_for_each_entry(vp, &ha->vp_list, list) {
3530 if (vp_idx == vp->vp_idx) {
3531 found = 1;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003532 break;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003533 }
3534 }
Arun Easifeafb7b2010-09-03 14:57:00 -07003535 spin_unlock_irqrestore(&ha->vport_slock, flags);
3536
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003537 if (!found)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003538 return;
3539
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003540 vp->d_id.b.domain = rptid_entry->port_id[2];
3541 vp->d_id.b.area = rptid_entry->port_id[1];
3542 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003543
3544 /*
3545 * Cannot configure here as we are still sitting on the
3546 * response queue. Handle it in dpc context.
3547 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003548 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003549
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003550reg_needed:
3551 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
3552 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
3553 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003554 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003555 }
3556}
3557
3558/*
3559 * qla24xx_modify_vp_config
3560 * Change VP configuration for vha
3561 *
3562 * Input:
3563 * vha = adapter block pointer.
3564 *
3565 * Returns:
3566 * qla2xxx local function return status code.
3567 *
3568 * Context:
3569 * Kernel context.
3570 */
3571int
3572qla24xx_modify_vp_config(scsi_qla_host_t *vha)
3573{
3574 int rval;
3575 struct vp_config_entry_24xx *vpmod;
3576 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003577 struct qla_hw_data *ha = vha->hw;
3578 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003579
3580 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003581
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003582 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb,
3583 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003584
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003585 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003586 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003587 ql_log(ql_log_warn, vha, 0x10bc,
3588 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003589 return QLA_MEMORY_ALLOC_FAILED;
3590 }
3591
3592 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
3593 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
3594 vpmod->entry_count = 1;
3595 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
3596 vpmod->vp_count = 1;
3597 vpmod->vp_index1 = vha->vp_idx;
3598 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04003599
3600 qlt_modify_vp_config(vha, vpmod);
3601
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003602 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
3603 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
3604 vpmod->entry_count = 1;
3605
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003606 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003607 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003608 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
3609 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003610 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003611 ql_dbg(ql_dbg_mbx, vha, 0x10be,
3612 "Failed to complete IOCB -- error status (%x).\n",
3613 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003614 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07003615 } else if (vpmod->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003616 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3617 "Failed to complete IOCB -- completion status (%x).\n",
3618 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003619 rval = QLA_FUNCTION_FAILED;
3620 } else {
3621 /* EMPTY */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003622 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0,
3623 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003624 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3625 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003626 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003627
3628 return rval;
3629}
3630
3631/*
3632 * qla24xx_control_vp
3633 * Enable a virtual port for given host
3634 *
3635 * Input:
3636 * ha = adapter block pointer.
3637 * vhba = virtual adapter (unused)
3638 * index = index number for enabled VP
3639 *
3640 * Returns:
3641 * qla2xxx local function return status code.
3642 *
3643 * Context:
3644 * Kernel context.
3645 */
3646int
3647qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
3648{
3649 int rval;
3650 int map, pos;
3651 struct vp_ctrl_entry_24xx *vce;
3652 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003653 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003654 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003655 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003656
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003657 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c1,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003658 "Entered %s enabling index %d.\n", __func__, vp_index);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003659
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08003660 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003661 return QLA_PARAMETER_ERROR;
3662
3663 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3664 if (!vce) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003665 ql_log(ql_log_warn, vha, 0x10c2,
3666 "Failed to allocate VP control IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003667 return QLA_MEMORY_ALLOC_FAILED;
3668 }
3669 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3670
3671 vce->entry_type = VP_CTRL_IOCB_TYPE;
3672 vce->entry_count = 1;
3673 vce->command = cpu_to_le16(cmd);
Bart Van Asschead950362015-07-09 07:24:08 -07003674 vce->vp_count = cpu_to_le16(1);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003675
3676 /* index map in firmware starts with 1; decrement index
3677 * this is ok as we never use index 0
3678 */
3679 map = (vp_index - 1) / 8;
3680 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003681 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003682 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003683 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003684
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003685 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003686 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003687 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3688 "Failed to issue VP control IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003689 } else if (vce->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003690 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3691 "Failed to complete IOCB -- error status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003692 vce->entry_status);
3693 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07003694 } else if (vce->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003695 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3696 "Failed to complet IOCB -- completion status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003697 le16_to_cpu(vce->comp_status));
3698 rval = QLA_FUNCTION_FAILED;
3699 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003700 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c6,
3701 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003702 }
3703
3704 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3705
3706 return rval;
3707}
3708
3709/*
3710 * qla2x00_send_change_request
3711 * Receive or disable RSCN request from fabric controller
3712 *
3713 * Input:
3714 * ha = adapter block pointer
3715 * format = registration format:
3716 * 0 - Reserved
3717 * 1 - Fabric detected registration
3718 * 2 - N_port detected registration
3719 * 3 - Full registration
3720 * FF - clear registration
3721 * vp_idx = Virtual port index
3722 *
3723 * Returns:
3724 * qla2x00 local function return status code.
3725 *
3726 * Context:
3727 * Kernel Context
3728 */
3729
3730int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003731qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003732 uint16_t vp_idx)
3733{
3734 int rval;
3735 mbx_cmd_t mc;
3736 mbx_cmd_t *mcp = &mc;
3737
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003738 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7,
3739 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003740
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003741 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3742 mcp->mb[1] = format;
3743 mcp->mb[9] = vp_idx;
3744 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3745 mcp->in_mb = MBX_0|MBX_1;
3746 mcp->tov = MBX_TOV_SECONDS;
3747 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003748 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003749
3750 if (rval == QLA_SUCCESS) {
3751 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3752 rval = BIT_1;
3753 }
3754 } else
3755 rval = BIT_1;
3756
3757 return rval;
3758}
Andrew Vasquez338c9162007-09-20 14:07:33 -07003759
3760int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003761qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07003762 uint32_t size)
3763{
3764 int rval;
3765 mbx_cmd_t mc;
3766 mbx_cmd_t *mcp = &mc;
3767
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003768 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009,
3769 "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003770
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003771 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003772 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3773 mcp->mb[8] = MSW(addr);
3774 mcp->out_mb = MBX_8|MBX_0;
3775 } else {
3776 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3777 mcp->out_mb = MBX_0;
3778 }
3779 mcp->mb[1] = LSW(addr);
3780 mcp->mb[2] = MSW(req_dma);
3781 mcp->mb[3] = LSW(req_dma);
3782 mcp->mb[6] = MSW(MSD(req_dma));
3783 mcp->mb[7] = LSW(MSD(req_dma));
3784 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003785 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003786 mcp->mb[4] = MSW(size);
3787 mcp->mb[5] = LSW(size);
3788 mcp->out_mb |= MBX_5|MBX_4;
3789 } else {
3790 mcp->mb[4] = LSW(size);
3791 mcp->out_mb |= MBX_4;
3792 }
3793
3794 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003795 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07003796 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003797 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003798
3799 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003800 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3801 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003802 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003803 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007,
3804 "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003805 }
3806
3807 return rval;
3808}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003809/* 84XX Support **************************************************************/
3810
3811struct cs84xx_mgmt_cmd {
3812 union {
3813 struct verify_chip_entry_84xx req;
3814 struct verify_chip_rsp_84xx rsp;
3815 } p;
3816};
3817
3818int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003819qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003820{
3821 int rval, retry;
3822 struct cs84xx_mgmt_cmd *mn;
3823 dma_addr_t mn_dma;
3824 uint16_t options;
3825 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003826 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003827
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003828 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8,
3829 "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003830
3831 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3832 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003833 return QLA_MEMORY_ALLOC_FAILED;
3834 }
3835
3836 /* Force Update? */
3837 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3838 /* Diagnostic firmware? */
3839 /* options |= MENLO_DIAG_FW; */
3840 /* We update the firmware with only one data sequence. */
3841 options |= VCO_END_OF_DATA;
3842
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003843 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003844 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003845 memset(mn, 0, sizeof(*mn));
3846 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3847 mn->p.req.entry_count = 1;
3848 mn->p.req.options = cpu_to_le16(options);
3849
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003850 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3851 "Dump of Verify Request.\n");
3852 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3853 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003854
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003855 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003856 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003857 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3858 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003859 goto verify_done;
3860 }
3861
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003862 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3863 "Dump of Verify Response.\n");
3864 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3865 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003866
3867 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3868 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3869 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003870 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003871 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003872
3873 if (status[0] != CS_COMPLETE) {
3874 rval = QLA_FUNCTION_FAILED;
3875 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003876 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3877 "Firmware update failed. Retrying "
3878 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003879 options |= VCO_DONT_UPDATE_FW;
3880 options &= ~VCO_FORCE_UPDATE;
3881 retry = 1;
3882 }
3883 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003884 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003885 "Firmware updated to %x.\n",
3886 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003887
3888 /* NOTE: we only update OP firmware. */
3889 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3890 ha->cs84xx->op_fw_version =
3891 le32_to_cpu(mn->p.rsp.fw_ver);
3892 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3893 flags);
3894 }
3895 } while (retry);
3896
3897verify_done:
3898 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3899
3900 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003901 ql_dbg(ql_dbg_mbx, vha, 0x10d1,
3902 "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003903 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003904 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2,
3905 "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003906 }
3907
3908 return rval;
3909}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003910
3911int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003912qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003913{
3914 int rval;
3915 unsigned long flags;
3916 mbx_cmd_t mc;
3917 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003918 struct qla_hw_data *ha = vha->hw;
3919
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003920 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
3921 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003922
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04003923 if (IS_SHADOW_REG_CAPABLE(ha))
3924 req->options |= BIT_13;
3925
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003926 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003927 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003928 mcp->mb[2] = MSW(LSD(req->dma));
3929 mcp->mb[3] = LSW(LSD(req->dma));
3930 mcp->mb[6] = MSW(MSD(req->dma));
3931 mcp->mb[7] = LSW(MSD(req->dma));
3932 mcp->mb[5] = req->length;
3933 if (req->rsp)
3934 mcp->mb[10] = req->rsp->id;
3935 mcp->mb[12] = req->qos;
3936 mcp->mb[11] = req->vp_idx;
3937 mcp->mb[13] = req->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003938 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003939 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003940
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003941 mcp->mb[4] = req->id;
3942 /* que in ptr index */
3943 mcp->mb[8] = 0;
3944 /* que out ptr index */
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04003945 mcp->mb[9] = *req->out_ptr = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003946 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3947 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3948 mcp->in_mb = MBX_0;
3949 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003950 mcp->tov = MBX_TOV_SECONDS * 2;
3951
Chad Dupuisf73cb692014-02-26 04:15:06 -05003952 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003953 mcp->in_mb |= MBX_1;
Joe Carnuccioba4828b2014-04-11 16:54:10 -04003954 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003955 mcp->out_mb |= MBX_15;
3956 /* debug q create issue in SR-IOV */
3957 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3958 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003959
3960 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003961 if (!(req->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003962 WRT_REG_DWORD(req->req_q_in, 0);
Joe Carnuccio29db41c2014-04-11 16:54:09 -04003963 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003964 WRT_REG_DWORD(req->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003965 }
3966 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3967
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003968 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003969 if (rval != QLA_SUCCESS) {
3970 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3971 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3972 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003973 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5,
3974 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003975 }
3976
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003977 return rval;
3978}
3979
3980int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003981qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003982{
3983 int rval;
3984 unsigned long flags;
3985 mbx_cmd_t mc;
3986 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003987 struct qla_hw_data *ha = vha->hw;
3988
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003989 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
3990 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003991
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04003992 if (IS_SHADOW_REG_CAPABLE(ha))
3993 rsp->options |= BIT_13;
3994
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003995 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003996 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003997 mcp->mb[2] = MSW(LSD(rsp->dma));
3998 mcp->mb[3] = LSW(LSD(rsp->dma));
3999 mcp->mb[6] = MSW(MSD(rsp->dma));
4000 mcp->mb[7] = LSW(MSD(rsp->dma));
4001 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08004002 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004003 mcp->mb[13] = rsp->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004004 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004005 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004006
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004007 mcp->mb[4] = rsp->id;
4008 /* que in ptr index */
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004009 mcp->mb[8] = *rsp->in_ptr = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004010 /* que out ptr index */
4011 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07004012 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004013 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4014 mcp->in_mb = MBX_0;
4015 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004016 mcp->tov = MBX_TOV_SECONDS * 2;
4017
4018 if (IS_QLA81XX(ha)) {
4019 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
4020 mcp->in_mb |= MBX_1;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004021 } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004022 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
4023 mcp->in_mb |= MBX_1;
4024 /* debug q create issue in SR-IOV */
4025 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
4026 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004027
4028 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004029 if (!(rsp->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004030 WRT_REG_DWORD(rsp->rsp_q_out, 0);
Himanshu Madhanib20f02e2015-06-10 11:05:18 -04004031 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004032 WRT_REG_DWORD(rsp->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004033 }
4034
4035 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4036
Anirban Chakraborty17d98632008-12-18 10:06:15 -08004037 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004038 if (rval != QLA_SUCCESS) {
4039 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
4040 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4041 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004042 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8,
4043 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004044 }
4045
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004046 return rval;
4047}
4048
Andrew Vasquez8a659572009-02-08 20:50:12 -08004049int
4050qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
4051{
4052 int rval;
4053 mbx_cmd_t mc;
4054 mbx_cmd_t *mcp = &mc;
4055
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004056 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9,
4057 "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004058
4059 mcp->mb[0] = MBC_IDC_ACK;
4060 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
4061 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4062 mcp->in_mb = MBX_0;
4063 mcp->tov = MBX_TOV_SECONDS;
4064 mcp->flags = 0;
4065 rval = qla2x00_mailbox_command(vha, mcp);
4066
4067 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004068 ql_dbg(ql_dbg_mbx, vha, 0x10da,
4069 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004070 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004071 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db,
4072 "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004073 }
4074
4075 return rval;
4076}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004077
4078int
4079qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
4080{
4081 int rval;
4082 mbx_cmd_t mc;
4083 mbx_cmd_t *mcp = &mc;
4084
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004085 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc,
4086 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004087
Chad Dupuisf73cb692014-02-26 04:15:06 -05004088 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4089 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004090 return QLA_FUNCTION_FAILED;
4091
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004092 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4093 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
4094 mcp->out_mb = MBX_1|MBX_0;
4095 mcp->in_mb = MBX_1|MBX_0;
4096 mcp->tov = MBX_TOV_SECONDS;
4097 mcp->flags = 0;
4098 rval = qla2x00_mailbox_command(vha, mcp);
4099
4100 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004101 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
4102 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4103 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004104 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004105 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de,
4106 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004107 *sector_size = mcp->mb[1];
4108 }
4109
4110 return rval;
4111}
4112
4113int
4114qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
4115{
4116 int rval;
4117 mbx_cmd_t mc;
4118 mbx_cmd_t *mcp = &mc;
4119
Chad Dupuisf73cb692014-02-26 04:15:06 -05004120 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4121 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004122 return QLA_FUNCTION_FAILED;
4123
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004124 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df,
4125 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004126
4127 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4128 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
4129 FAC_OPT_CMD_WRITE_PROTECT;
4130 mcp->out_mb = MBX_1|MBX_0;
4131 mcp->in_mb = MBX_1|MBX_0;
4132 mcp->tov = MBX_TOV_SECONDS;
4133 mcp->flags = 0;
4134 rval = qla2x00_mailbox_command(vha, mcp);
4135
4136 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004137 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
4138 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4139 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004140 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004141 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1,
4142 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004143 }
4144
4145 return rval;
4146}
4147
4148int
4149qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
4150{
4151 int rval;
4152 mbx_cmd_t mc;
4153 mbx_cmd_t *mcp = &mc;
4154
Chad Dupuisf73cb692014-02-26 04:15:06 -05004155 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4156 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004157 return QLA_FUNCTION_FAILED;
4158
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004159 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,
4160 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004161
4162 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4163 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
4164 mcp->mb[2] = LSW(start);
4165 mcp->mb[3] = MSW(start);
4166 mcp->mb[4] = LSW(finish);
4167 mcp->mb[5] = MSW(finish);
4168 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4169 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4170 mcp->tov = MBX_TOV_SECONDS;
4171 mcp->flags = 0;
4172 rval = qla2x00_mailbox_command(vha, mcp);
4173
4174 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004175 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
4176 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4177 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004178 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004179 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,
4180 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004181 }
4182
4183 return rval;
4184}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004185
4186int
4187qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
4188{
4189 int rval = 0;
4190 mbx_cmd_t mc;
4191 mbx_cmd_t *mcp = &mc;
4192
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004193 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5,
4194 "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004195
4196 mcp->mb[0] = MBC_RESTART_MPI_FW;
4197 mcp->out_mb = MBX_0;
4198 mcp->in_mb = MBX_0|MBX_1;
4199 mcp->tov = MBX_TOV_SECONDS;
4200 mcp->flags = 0;
4201 rval = qla2x00_mailbox_command(vha, mcp);
4202
4203 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004204 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
4205 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4206 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004207 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004208 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7,
4209 "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004210 }
4211
4212 return rval;
4213}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004214
Joe Carnuccioc46e65c2013-08-27 01:37:35 -04004215int
4216qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4217{
4218 int rval;
4219 mbx_cmd_t mc;
4220 mbx_cmd_t *mcp = &mc;
4221 int i;
4222 int len;
4223 uint16_t *str;
4224 struct qla_hw_data *ha = vha->hw;
4225
4226 if (!IS_P3P_TYPE(ha))
4227 return QLA_FUNCTION_FAILED;
4228
4229 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b,
4230 "Entered %s.\n", __func__);
4231
4232 str = (void *)version;
4233 len = strlen(version);
4234
4235 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4236 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8;
4237 mcp->out_mb = MBX_1|MBX_0;
4238 for (i = 4; i < 16 && len; i++, str++, len -= 2) {
4239 mcp->mb[i] = cpu_to_le16p(str);
4240 mcp->out_mb |= 1<<i;
4241 }
4242 for (; i < 16; i++) {
4243 mcp->mb[i] = 0;
4244 mcp->out_mb |= 1<<i;
4245 }
4246 mcp->in_mb = MBX_1|MBX_0;
4247 mcp->tov = MBX_TOV_SECONDS;
4248 mcp->flags = 0;
4249 rval = qla2x00_mailbox_command(vha, mcp);
4250
4251 if (rval != QLA_SUCCESS) {
4252 ql_dbg(ql_dbg_mbx, vha, 0x117c,
4253 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4254 } else {
4255 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d,
4256 "Done %s.\n", __func__);
4257 }
4258
4259 return rval;
4260}
4261
4262int
4263qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4264{
4265 int rval;
4266 mbx_cmd_t mc;
4267 mbx_cmd_t *mcp = &mc;
4268 int len;
4269 uint16_t dwlen;
4270 uint8_t *str;
4271 dma_addr_t str_dma;
4272 struct qla_hw_data *ha = vha->hw;
4273
4274 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) ||
4275 IS_P3P_TYPE(ha))
4276 return QLA_FUNCTION_FAILED;
4277
4278 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e,
4279 "Entered %s.\n", __func__);
4280
4281 str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);
4282 if (!str) {
4283 ql_log(ql_log_warn, vha, 0x117f,
4284 "Failed to allocate driver version param.\n");
4285 return QLA_MEMORY_ALLOC_FAILED;
4286 }
4287
4288 memcpy(str, "\x7\x3\x11\x0", 4);
4289 dwlen = str[0];
4290 len = dwlen * 4 - 4;
4291 memset(str + 4, 0, len);
4292 if (len > strlen(version))
4293 len = strlen(version);
4294 memcpy(str + 4, version, len);
4295
4296 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4297 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;
4298 mcp->mb[2] = MSW(LSD(str_dma));
4299 mcp->mb[3] = LSW(LSD(str_dma));
4300 mcp->mb[6] = MSW(MSD(str_dma));
4301 mcp->mb[7] = LSW(MSD(str_dma));
4302 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4303 mcp->in_mb = MBX_1|MBX_0;
4304 mcp->tov = MBX_TOV_SECONDS;
4305 mcp->flags = 0;
4306 rval = qla2x00_mailbox_command(vha, mcp);
4307
4308 if (rval != QLA_SUCCESS) {
4309 ql_dbg(ql_dbg_mbx, vha, 0x1180,
4310 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4311 } else {
4312 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181,
4313 "Done %s.\n", __func__);
4314 }
4315
4316 dma_pool_free(ha->s_dma_pool, str, str_dma);
4317
4318 return rval;
4319}
4320
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004321static int
4322qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
4323{
4324 int rval;
4325 mbx_cmd_t mc;
4326 mbx_cmd_t *mcp = &mc;
4327
4328 if (!IS_FWI2_CAPABLE(vha->hw))
4329 return QLA_FUNCTION_FAILED;
4330
4331 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4332 "Entered %s.\n", __func__);
4333
4334 mcp->mb[0] = MBC_GET_RNID_PARAMS;
4335 mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8;
4336 mcp->out_mb = MBX_1|MBX_0;
4337 mcp->in_mb = MBX_1|MBX_0;
4338 mcp->tov = MBX_TOV_SECONDS;
4339 mcp->flags = 0;
4340 rval = qla2x00_mailbox_command(vha, mcp);
4341 *temp = mcp->mb[1];
4342
4343 if (rval != QLA_SUCCESS) {
4344 ql_dbg(ql_dbg_mbx, vha, 0x115a,
4345 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4346 } else {
4347 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4348 "Done %s.\n", __func__);
4349 }
4350
4351 return rval;
4352}
4353
Joe Carnuccio3a117112013-02-08 01:58:00 -05004354int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004355qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4356 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004357{
4358 int rval;
4359 mbx_cmd_t mc;
4360 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004361 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, 0x10e8,
4364 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004365
Joe Carnuccio6766df92011-05-10 11:30:15 -07004366 if (!IS_FWI2_CAPABLE(ha))
4367 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004368
Joe Carnuccio6766df92011-05-10 11:30:15 -07004369 if (len == 1)
4370 opt |= BIT_0;
4371
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004372 mcp->mb[0] = MBC_READ_SFP;
4373 mcp->mb[1] = dev;
4374 mcp->mb[2] = MSW(sfp_dma);
4375 mcp->mb[3] = LSW(sfp_dma);
4376 mcp->mb[6] = MSW(MSD(sfp_dma));
4377 mcp->mb[7] = LSW(MSD(sfp_dma));
4378 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004379 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004380 mcp->mb[10] = opt;
4381 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 -07004382 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004383 mcp->tov = MBX_TOV_SECONDS;
4384 mcp->flags = 0;
4385 rval = qla2x00_mailbox_command(vha, mcp);
4386
4387 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004388 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004389
4390 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004391 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
4392 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004393 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004394 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
4395 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004396 }
4397
4398 return rval;
4399}
4400
4401int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004402qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4403 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004404{
4405 int rval;
4406 mbx_cmd_t mc;
4407 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004408 struct qla_hw_data *ha = vha->hw;
4409
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004410 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb,
4411 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004412
Joe Carnuccio6766df92011-05-10 11:30:15 -07004413 if (!IS_FWI2_CAPABLE(ha))
4414 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004415
Joe Carnuccio6766df92011-05-10 11:30:15 -07004416 if (len == 1)
4417 opt |= BIT_0;
4418
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004419 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004420 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004421
4422 mcp->mb[0] = MBC_WRITE_SFP;
4423 mcp->mb[1] = dev;
4424 mcp->mb[2] = MSW(sfp_dma);
4425 mcp->mb[3] = LSW(sfp_dma);
4426 mcp->mb[6] = MSW(MSD(sfp_dma));
4427 mcp->mb[7] = LSW(MSD(sfp_dma));
4428 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004429 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004430 mcp->mb[10] = opt;
4431 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 -07004432 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004433 mcp->tov = MBX_TOV_SECONDS;
4434 mcp->flags = 0;
4435 rval = qla2x00_mailbox_command(vha, mcp);
4436
4437 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004438 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
4439 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004440 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004441 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed,
4442 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004443 }
4444
4445 return rval;
4446}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004447
4448int
4449qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
4450 uint16_t size_in_bytes, uint16_t *actual_size)
4451{
4452 int rval;
4453 mbx_cmd_t mc;
4454 mbx_cmd_t *mcp = &mc;
4455
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004456 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee,
4457 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004458
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004459 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004460 return QLA_FUNCTION_FAILED;
4461
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004462 mcp->mb[0] = MBC_GET_XGMAC_STATS;
4463 mcp->mb[2] = MSW(stats_dma);
4464 mcp->mb[3] = LSW(stats_dma);
4465 mcp->mb[6] = MSW(MSD(stats_dma));
4466 mcp->mb[7] = LSW(MSD(stats_dma));
4467 mcp->mb[8] = size_in_bytes >> 2;
4468 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4469 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4470 mcp->tov = MBX_TOV_SECONDS;
4471 mcp->flags = 0;
4472 rval = qla2x00_mailbox_command(vha, mcp);
4473
4474 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004475 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
4476 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4477 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004478 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004479 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0,
4480 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004481
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004482
4483 *actual_size = mcp->mb[2] << 2;
4484 }
4485
4486 return rval;
4487}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004488
4489int
4490qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
4491 uint16_t size)
4492{
4493 int rval;
4494 mbx_cmd_t mc;
4495 mbx_cmd_t *mcp = &mc;
4496
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004497 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1,
4498 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004499
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004500 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004501 return QLA_FUNCTION_FAILED;
4502
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004503 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4504 mcp->mb[1] = 0;
4505 mcp->mb[2] = MSW(tlv_dma);
4506 mcp->mb[3] = LSW(tlv_dma);
4507 mcp->mb[6] = MSW(MSD(tlv_dma));
4508 mcp->mb[7] = LSW(MSD(tlv_dma));
4509 mcp->mb[8] = size;
4510 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4511 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4512 mcp->tov = MBX_TOV_SECONDS;
4513 mcp->flags = 0;
4514 rval = qla2x00_mailbox_command(vha, mcp);
4515
4516 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004517 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
4518 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4519 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004520 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004521 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3,
4522 "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004523 }
4524
4525 return rval;
4526}
Andrew Vasquez18e75552009-06-03 09:55:30 -07004527
4528int
4529qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
4530{
4531 int rval;
4532 mbx_cmd_t mc;
4533 mbx_cmd_t *mcp = &mc;
4534
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004535 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4,
4536 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004537
Andrew Vasquez18e75552009-06-03 09:55:30 -07004538 if (!IS_FWI2_CAPABLE(vha->hw))
4539 return QLA_FUNCTION_FAILED;
4540
Andrew Vasquez18e75552009-06-03 09:55:30 -07004541 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
4542 mcp->mb[1] = LSW(risc_addr);
4543 mcp->mb[8] = MSW(risc_addr);
4544 mcp->out_mb = MBX_8|MBX_1|MBX_0;
4545 mcp->in_mb = MBX_3|MBX_2|MBX_0;
4546 mcp->tov = 30;
4547 mcp->flags = 0;
4548 rval = qla2x00_mailbox_command(vha, mcp);
4549 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004550 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
4551 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004552 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004553 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6,
4554 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004555 *data = mcp->mb[3] << 16 | mcp->mb[2];
4556 }
4557
4558 return rval;
4559}
4560
4561int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004562qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4563 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004564{
4565 int rval;
4566 mbx_cmd_t mc;
4567 mbx_cmd_t *mcp = &mc;
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004568
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004569 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7,
4570 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004571
4572 memset(mcp->mb, 0 , sizeof(mcp->mb));
4573 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
4574 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
4575
4576 /* transfer count */
4577 mcp->mb[10] = LSW(mreq->transfer_size);
4578 mcp->mb[11] = MSW(mreq->transfer_size);
4579
4580 /* send data address */
4581 mcp->mb[14] = LSW(mreq->send_dma);
4582 mcp->mb[15] = MSW(mreq->send_dma);
4583 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4584 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4585
Lucas De Marchi25985ed2011-03-30 22:57:33 -03004586 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004587 mcp->mb[16] = LSW(mreq->rcv_dma);
4588 mcp->mb[17] = MSW(mreq->rcv_dma);
4589 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4590 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4591
4592 /* Iteration count */
Joe Carnuccio1b98b422013-03-28 08:21:26 -04004593 mcp->mb[18] = LSW(mreq->iteration_count);
4594 mcp->mb[19] = MSW(mreq->iteration_count);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004595
4596 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
4597 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 -08004598 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004599 mcp->out_mb |= MBX_2;
4600 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
4601
4602 mcp->buf_size = mreq->transfer_size;
4603 mcp->tov = MBX_TOV_SECONDS;
4604 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4605
4606 rval = qla2x00_mailbox_command(vha, mcp);
4607
4608 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004609 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
4610 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
4611 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
4612 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004613 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004614 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9,
4615 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004616 }
4617
4618 /* Copy mailbox information */
4619 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004620 return rval;
4621}
4622
4623int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004624qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4625 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004626{
4627 int rval;
4628 mbx_cmd_t mc;
4629 mbx_cmd_t *mcp = &mc;
4630 struct qla_hw_data *ha = vha->hw;
4631
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004632 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa,
4633 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004634
4635 memset(mcp->mb, 0 , sizeof(mcp->mb));
4636 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
4637 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004638 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004639 mcp->mb[1] |= BIT_15;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004640 mcp->mb[2] = vha->fcoe_fcf_idx;
4641 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004642 mcp->mb[16] = LSW(mreq->rcv_dma);
4643 mcp->mb[17] = MSW(mreq->rcv_dma);
4644 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4645 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4646
4647 mcp->mb[10] = LSW(mreq->transfer_size);
4648
4649 mcp->mb[14] = LSW(mreq->send_dma);
4650 mcp->mb[15] = MSW(mreq->send_dma);
4651 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4652 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4653
4654 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
4655 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004656 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004657 mcp->out_mb |= MBX_2;
4658
4659 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004660 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
4661 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004662 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004663 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004664 mcp->in_mb |= MBX_3;
4665
4666 mcp->tov = MBX_TOV_SECONDS;
4667 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4668 mcp->buf_size = mreq->transfer_size;
4669
4670 rval = qla2x00_mailbox_command(vha, mcp);
4671
4672 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004673 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
4674 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4675 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004676 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004677 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc,
4678 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004679 }
4680
4681 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07004682 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004683 return rval;
4684}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07004685
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004686int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004687qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004688{
4689 int rval;
4690 mbx_cmd_t mc;
4691 mbx_cmd_t *mcp = &mc;
4692
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004693 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004694 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004695
4696 mcp->mb[0] = MBC_ISP84XX_RESET;
4697 mcp->mb[1] = enable_diagnostic;
4698 mcp->out_mb = MBX_1|MBX_0;
4699 mcp->in_mb = MBX_1|MBX_0;
4700 mcp->tov = MBX_TOV_SECONDS;
4701 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004702 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004703
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004704 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004705 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004706 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004707 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff,
4708 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004709
4710 return rval;
4711}
4712
4713int
Andrew Vasquez18e75552009-06-03 09:55:30 -07004714qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
4715{
4716 int rval;
4717 mbx_cmd_t mc;
4718 mbx_cmd_t *mcp = &mc;
4719
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004720 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100,
4721 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004722
Andrew Vasquez18e75552009-06-03 09:55:30 -07004723 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07004724 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07004725
Andrew Vasquez18e75552009-06-03 09:55:30 -07004726 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
4727 mcp->mb[1] = LSW(risc_addr);
4728 mcp->mb[2] = LSW(data);
4729 mcp->mb[3] = MSW(data);
4730 mcp->mb[8] = MSW(risc_addr);
4731 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
4732 mcp->in_mb = MBX_0;
4733 mcp->tov = 30;
4734 mcp->flags = 0;
4735 rval = qla2x00_mailbox_command(vha, mcp);
4736 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004737 ql_dbg(ql_dbg_mbx, vha, 0x1101,
4738 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004739 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004740 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
4741 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004742 }
4743
4744 return rval;
4745}
Michael Hernandez3064ff32009-12-15 21:29:44 -08004746
4747int
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004748qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
4749{
4750 int rval;
4751 uint32_t stat, timer;
4752 uint16_t mb0 = 0;
4753 struct qla_hw_data *ha = vha->hw;
4754 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
4755
4756 rval = QLA_SUCCESS;
4757
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004758 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103,
4759 "Entered %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004760
4761 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
4762
4763 /* Write the MBC data to the registers */
4764 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
4765 WRT_REG_WORD(&reg->mailbox1, mb[0]);
4766 WRT_REG_WORD(&reg->mailbox2, mb[1]);
4767 WRT_REG_WORD(&reg->mailbox3, mb[2]);
4768 WRT_REG_WORD(&reg->mailbox4, mb[3]);
4769
4770 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
4771
4772 /* Poll for MBC interrupt */
4773 for (timer = 6000000; timer; timer--) {
4774 /* Check for pending interrupts. */
4775 stat = RD_REG_DWORD(&reg->host_status);
4776 if (stat & HSRX_RISC_INT) {
4777 stat &= 0xff;
4778
4779 if (stat == 0x1 || stat == 0x2 ||
4780 stat == 0x10 || stat == 0x11) {
4781 set_bit(MBX_INTERRUPT,
4782 &ha->mbx_cmd_flags);
4783 mb0 = RD_REG_WORD(&reg->mailbox0);
4784 WRT_REG_DWORD(&reg->hccr,
4785 HCCRX_CLR_RISC_INT);
4786 RD_REG_DWORD(&reg->hccr);
4787 break;
4788 }
4789 }
4790 udelay(5);
4791 }
4792
4793 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
4794 rval = mb0 & MBS_MASK;
4795 else
4796 rval = QLA_FUNCTION_FAILED;
4797
4798 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004799 ql_dbg(ql_dbg_mbx, vha, 0x1104,
4800 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004801 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004802 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105,
4803 "Done %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004804 }
4805
4806 return rval;
4807}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004808
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004809int
Michael Hernandez3064ff32009-12-15 21:29:44 -08004810qla2x00_get_data_rate(scsi_qla_host_t *vha)
4811{
4812 int rval;
4813 mbx_cmd_t mc;
4814 mbx_cmd_t *mcp = &mc;
4815 struct qla_hw_data *ha = vha->hw;
4816
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004817 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
4818 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004819
Michael Hernandez3064ff32009-12-15 21:29:44 -08004820 if (!IS_FWI2_CAPABLE(ha))
4821 return QLA_FUNCTION_FAILED;
4822
Michael Hernandez3064ff32009-12-15 21:29:44 -08004823 mcp->mb[0] = MBC_DATA_RATE;
4824 mcp->mb[1] = 0;
4825 mcp->out_mb = MBX_1|MBX_0;
4826 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004827 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004828 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08004829 mcp->tov = MBX_TOV_SECONDS;
4830 mcp->flags = 0;
4831 rval = qla2x00_mailbox_command(vha, mcp);
4832 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004833 ql_dbg(ql_dbg_mbx, vha, 0x1107,
4834 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004835 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004836 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
4837 "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004838 if (mcp->mb[1] != 0x7)
4839 ha->link_data_rate = mcp->mb[1];
4840 }
4841
4842 return rval;
4843}
Sarang Radke09ff7012010-03-19 17:03:59 -07004844
4845int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004846qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4847{
4848 int rval;
4849 mbx_cmd_t mc;
4850 mbx_cmd_t *mcp = &mc;
4851 struct qla_hw_data *ha = vha->hw;
4852
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004853 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
4854 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004855
Chad Dupuisf73cb692014-02-26 04:15:06 -05004856 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) &&
4857 !IS_QLA27XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004858 return QLA_FUNCTION_FAILED;
4859 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4860 mcp->out_mb = MBX_0;
4861 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4862 mcp->tov = MBX_TOV_SECONDS;
4863 mcp->flags = 0;
4864
4865 rval = qla2x00_mailbox_command(vha, mcp);
4866
4867 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004868 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4869 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004870 } else {
4871 /* Copy all bits to preserve original value */
4872 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4873
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004874 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b,
4875 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004876 }
4877 return rval;
4878}
4879
4880int
4881qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4882{
4883 int rval;
4884 mbx_cmd_t mc;
4885 mbx_cmd_t *mcp = &mc;
4886
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004887 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c,
4888 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004889
4890 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4891 /* Copy all bits to preserve original setting */
4892 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4893 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4894 mcp->in_mb = MBX_0;
4895 mcp->tov = MBX_TOV_SECONDS;
4896 mcp->flags = 0;
4897 rval = qla2x00_mailbox_command(vha, mcp);
4898
4899 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004900 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4901 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004902 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004903 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e,
4904 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004905
4906 return rval;
4907}
4908
4909
4910int
Sarang Radke09ff7012010-03-19 17:03:59 -07004911qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4912 uint16_t *mb)
4913{
4914 int rval;
4915 mbx_cmd_t mc;
4916 mbx_cmd_t *mcp = &mc;
4917 struct qla_hw_data *ha = vha->hw;
4918
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004919 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f,
4920 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004921
Sarang Radke09ff7012010-03-19 17:03:59 -07004922 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4923 return QLA_FUNCTION_FAILED;
4924
Sarang Radke09ff7012010-03-19 17:03:59 -07004925 mcp->mb[0] = MBC_PORT_PARAMS;
4926 mcp->mb[1] = loop_id;
4927 if (ha->flags.fcp_prio_enabled)
4928 mcp->mb[2] = BIT_1;
4929 else
4930 mcp->mb[2] = BIT_2;
4931 mcp->mb[4] = priority & 0xf;
4932 mcp->mb[9] = vha->vp_idx;
4933 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4934 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4935 mcp->tov = 30;
4936 mcp->flags = 0;
4937 rval = qla2x00_mailbox_command(vha, mcp);
4938 if (mb != NULL) {
4939 mb[0] = mcp->mb[0];
4940 mb[1] = mcp->mb[1];
4941 mb[3] = mcp->mb[3];
4942 mb[4] = mcp->mb[4];
4943 }
4944
4945 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004946 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07004947 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004948 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc,
4949 "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07004950 }
4951
4952 return rval;
4953}
Giridhar Malavalia9083012010-04-12 17:59:55 -07004954
4955int
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004956qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)
Andrew Vasquez794a5692010-12-21 16:00:21 -08004957{
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004958 int rval = QLA_FUNCTION_FAILED;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004959 struct qla_hw_data *ha = vha->hw;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004960 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004961
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004962 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) {
4963 ql_dbg(ql_dbg_mbx, vha, 0x1150,
4964 "Thermal not supported by this card.\n");
4965 return rval;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004966 }
Andrew Vasquez794a5692010-12-21 16:00:21 -08004967
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004968 if (IS_QLA25XX(ha)) {
4969 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
4970 ha->pdev->subsystem_device == 0x0175) {
4971 rval = qla2x00_read_sfp(vha, 0, &byte,
4972 0x98, 0x1, 1, BIT_13|BIT_0);
4973 *temp = byte;
4974 return rval;
4975 }
4976 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
4977 ha->pdev->subsystem_device == 0x338e) {
4978 rval = qla2x00_read_sfp(vha, 0, &byte,
4979 0x98, 0x1, 1, BIT_15|BIT_14|BIT_0);
4980 *temp = byte;
4981 return rval;
4982 }
4983 ql_dbg(ql_dbg_mbx, vha, 0x10c9,
4984 "Thermal not supported by this card.\n");
4985 return rval;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004986 }
4987
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004988 if (IS_QLA82XX(ha)) {
4989 *temp = qla82xx_read_temperature(vha);
4990 rval = QLA_SUCCESS;
4991 return rval;
4992 } else if (IS_QLA8044(ha)) {
4993 *temp = qla8044_read_temperature(vha);
4994 rval = QLA_SUCCESS;
4995 return rval;
4996 }
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004997
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004998 rval = qla2x00_read_asic_temperature(vha, temp);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004999 return rval;
5000}
5001
5002int
Giridhar Malavalia9083012010-04-12 17:59:55 -07005003qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
5004{
5005 int rval;
5006 struct qla_hw_data *ha = vha->hw;
5007 mbx_cmd_t mc;
5008 mbx_cmd_t *mcp = &mc;
5009
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005010 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017,
5011 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005012
Giridhar Malavalia9083012010-04-12 17:59:55 -07005013 if (!IS_FWI2_CAPABLE(ha))
5014 return QLA_FUNCTION_FAILED;
5015
Giridhar Malavalia9083012010-04-12 17:59:55 -07005016 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05005017 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07005018 mcp->mb[1] = 1;
5019
5020 mcp->out_mb = MBX_1|MBX_0;
5021 mcp->in_mb = MBX_0;
5022 mcp->tov = 30;
5023 mcp->flags = 0;
5024
5025 rval = qla2x00_mailbox_command(vha, mcp);
5026 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005027 ql_dbg(ql_dbg_mbx, vha, 0x1016,
5028 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005029 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005030 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e,
5031 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005032 }
5033
5034 return rval;
5035}
5036
5037int
5038qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
5039{
5040 int rval;
5041 struct qla_hw_data *ha = vha->hw;
5042 mbx_cmd_t mc;
5043 mbx_cmd_t *mcp = &mc;
5044
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005045 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
5046 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005047
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005048 if (!IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -07005049 return QLA_FUNCTION_FAILED;
5050
Giridhar Malavalia9083012010-04-12 17:59:55 -07005051 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05005052 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07005053 mcp->mb[1] = 0;
5054
5055 mcp->out_mb = MBX_1|MBX_0;
5056 mcp->in_mb = MBX_0;
5057 mcp->tov = 30;
5058 mcp->flags = 0;
5059
5060 rval = qla2x00_mailbox_command(vha, mcp);
5061 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005062 ql_dbg(ql_dbg_mbx, vha, 0x100c,
5063 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005064 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005065 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b,
5066 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005067 }
5068
5069 return rval;
5070}
Giridhar Malavali08de2842011-08-16 11:31:44 -07005071
5072int
5073qla82xx_md_get_template_size(scsi_qla_host_t *vha)
5074{
5075 struct qla_hw_data *ha = vha->hw;
5076 mbx_cmd_t mc;
5077 mbx_cmd_t *mcp = &mc;
5078 int rval = QLA_FUNCTION_FAILED;
5079
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005080 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f,
5081 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005082
5083 memset(mcp->mb, 0 , sizeof(mcp->mb));
5084 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5085 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5086 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
5087 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
5088
5089 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5090 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
5091 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5092
5093 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5094 mcp->tov = MBX_TOV_SECONDS;
5095 rval = qla2x00_mailbox_command(vha, mcp);
5096
5097 /* Always copy back return mailbox values. */
5098 if (rval != QLA_SUCCESS) {
5099 ql_dbg(ql_dbg_mbx, vha, 0x1120,
5100 "mailbox command FAILED=0x%x, subcode=%x.\n",
5101 (mcp->mb[1] << 16) | mcp->mb[0],
5102 (mcp->mb[3] << 16) | mcp->mb[2]);
5103 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005104 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121,
5105 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005106 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
5107 if (!ha->md_template_size) {
5108 ql_dbg(ql_dbg_mbx, vha, 0x1122,
5109 "Null template size obtained.\n");
5110 rval = QLA_FUNCTION_FAILED;
5111 }
5112 }
5113 return rval;
5114}
5115
5116int
5117qla82xx_md_get_template(scsi_qla_host_t *vha)
5118{
5119 struct qla_hw_data *ha = vha->hw;
5120 mbx_cmd_t mc;
5121 mbx_cmd_t *mcp = &mc;
5122 int rval = QLA_FUNCTION_FAILED;
5123
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005124 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123,
5125 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005126
5127 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
5128 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
5129 if (!ha->md_tmplt_hdr) {
5130 ql_log(ql_log_warn, vha, 0x1124,
5131 "Unable to allocate memory for Minidump template.\n");
5132 return rval;
5133 }
5134
5135 memset(mcp->mb, 0 , sizeof(mcp->mb));
5136 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5137 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5138 mcp->mb[2] = LSW(RQST_TMPLT);
5139 mcp->mb[3] = MSW(RQST_TMPLT);
5140 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
5141 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
5142 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
5143 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
5144 mcp->mb[8] = LSW(ha->md_template_size);
5145 mcp->mb[9] = MSW(ha->md_template_size);
5146
5147 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5148 mcp->tov = MBX_TOV_SECONDS;
5149 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5150 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5151 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5152 rval = qla2x00_mailbox_command(vha, mcp);
5153
5154 if (rval != QLA_SUCCESS) {
5155 ql_dbg(ql_dbg_mbx, vha, 0x1125,
5156 "mailbox command FAILED=0x%x, subcode=%x.\n",
5157 ((mcp->mb[1] << 16) | mcp->mb[0]),
5158 ((mcp->mb[3] << 16) | mcp->mb[2]));
5159 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005160 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126,
5161 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005162 return rval;
5163}
Saurav Kashyap999916d2011-08-16 11:31:45 -07005164
5165int
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005166qla8044_md_get_template(scsi_qla_host_t *vha)
5167{
5168 struct qla_hw_data *ha = vha->hw;
5169 mbx_cmd_t mc;
5170 mbx_cmd_t *mcp = &mc;
5171 int rval = QLA_FUNCTION_FAILED;
5172 int offset = 0, size = MINIDUMP_SIZE_36K;
5173 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,
5174 "Entered %s.\n", __func__);
5175
5176 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
5177 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
5178 if (!ha->md_tmplt_hdr) {
5179 ql_log(ql_log_warn, vha, 0xb11b,
5180 "Unable to allocate memory for Minidump template.\n");
5181 return rval;
5182 }
5183
5184 memset(mcp->mb, 0 , sizeof(mcp->mb));
5185 while (offset < ha->md_template_size) {
5186 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5187 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5188 mcp->mb[2] = LSW(RQST_TMPLT);
5189 mcp->mb[3] = MSW(RQST_TMPLT);
5190 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));
5191 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));
5192 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));
5193 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));
5194 mcp->mb[8] = LSW(size);
5195 mcp->mb[9] = MSW(size);
5196 mcp->mb[10] = offset & 0x0000FFFF;
5197 mcp->mb[11] = offset & 0xFFFF0000;
5198 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5199 mcp->tov = MBX_TOV_SECONDS;
5200 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5201 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5202 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5203 rval = qla2x00_mailbox_command(vha, mcp);
5204
5205 if (rval != QLA_SUCCESS) {
5206 ql_dbg(ql_dbg_mbx, vha, 0xb11c,
5207 "mailbox command FAILED=0x%x, subcode=%x.\n",
5208 ((mcp->mb[1] << 16) | mcp->mb[0]),
5209 ((mcp->mb[3] << 16) | mcp->mb[2]));
5210 return rval;
5211 } else
5212 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,
5213 "Done %s.\n", __func__);
5214 offset = offset + size;
5215 }
5216 return rval;
5217}
5218
5219int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005220qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5221{
5222 int rval;
5223 struct qla_hw_data *ha = vha->hw;
5224 mbx_cmd_t mc;
5225 mbx_cmd_t *mcp = &mc;
5226
5227 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5228 return QLA_FUNCTION_FAILED;
5229
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005230 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133,
5231 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005232
5233 memset(mcp, 0, sizeof(mbx_cmd_t));
5234 mcp->mb[0] = MBC_SET_LED_CONFIG;
5235 mcp->mb[1] = led_cfg[0];
5236 mcp->mb[2] = led_cfg[1];
5237 if (IS_QLA8031(ha)) {
5238 mcp->mb[3] = led_cfg[2];
5239 mcp->mb[4] = led_cfg[3];
5240 mcp->mb[5] = led_cfg[4];
5241 mcp->mb[6] = led_cfg[5];
5242 }
5243
5244 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5245 if (IS_QLA8031(ha))
5246 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5247 mcp->in_mb = MBX_0;
5248 mcp->tov = 30;
5249 mcp->flags = 0;
5250
5251 rval = qla2x00_mailbox_command(vha, mcp);
5252 if (rval != QLA_SUCCESS) {
5253 ql_dbg(ql_dbg_mbx, vha, 0x1134,
5254 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5255 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005256 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135,
5257 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005258 }
5259
5260 return rval;
5261}
5262
5263int
5264qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5265{
5266 int rval;
5267 struct qla_hw_data *ha = vha->hw;
5268 mbx_cmd_t mc;
5269 mbx_cmd_t *mcp = &mc;
5270
5271 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5272 return QLA_FUNCTION_FAILED;
5273
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005274 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136,
5275 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005276
5277 memset(mcp, 0, sizeof(mbx_cmd_t));
5278 mcp->mb[0] = MBC_GET_LED_CONFIG;
5279
5280 mcp->out_mb = MBX_0;
5281 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5282 if (IS_QLA8031(ha))
5283 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5284 mcp->tov = 30;
5285 mcp->flags = 0;
5286
5287 rval = qla2x00_mailbox_command(vha, mcp);
5288 if (rval != QLA_SUCCESS) {
5289 ql_dbg(ql_dbg_mbx, vha, 0x1137,
5290 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5291 } else {
5292 led_cfg[0] = mcp->mb[1];
5293 led_cfg[1] = mcp->mb[2];
5294 if (IS_QLA8031(ha)) {
5295 led_cfg[2] = mcp->mb[3];
5296 led_cfg[3] = mcp->mb[4];
5297 led_cfg[4] = mcp->mb[5];
5298 led_cfg[5] = mcp->mb[6];
5299 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005300 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138,
5301 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005302 }
5303
5304 return rval;
5305}
5306
5307int
Saurav Kashyap999916d2011-08-16 11:31:45 -07005308qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
5309{
5310 int rval;
5311 struct qla_hw_data *ha = vha->hw;
5312 mbx_cmd_t mc;
5313 mbx_cmd_t *mcp = &mc;
5314
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005315 if (!IS_P3P_TYPE(ha))
Saurav Kashyap999916d2011-08-16 11:31:45 -07005316 return QLA_FUNCTION_FAILED;
5317
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005318 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005319 "Entered %s.\n", __func__);
5320
5321 memset(mcp, 0, sizeof(mbx_cmd_t));
5322 mcp->mb[0] = MBC_SET_LED_CONFIG;
5323 if (enable)
5324 mcp->mb[7] = 0xE;
5325 else
5326 mcp->mb[7] = 0xD;
5327
5328 mcp->out_mb = MBX_7|MBX_0;
5329 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005330 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07005331 mcp->flags = 0;
5332
5333 rval = qla2x00_mailbox_command(vha, mcp);
5334 if (rval != QLA_SUCCESS) {
5335 ql_dbg(ql_dbg_mbx, vha, 0x1128,
5336 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5337 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005338 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005339 "Done %s.\n", __func__);
5340 }
5341
5342 return rval;
5343}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005344
5345int
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005346qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005347{
5348 int rval;
5349 struct qla_hw_data *ha = vha->hw;
5350 mbx_cmd_t mc;
5351 mbx_cmd_t *mcp = &mc;
5352
Chad Dupuisf73cb692014-02-26 04:15:06 -05005353 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005354 return QLA_FUNCTION_FAILED;
5355
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005356 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130,
5357 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005358
5359 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
5360 mcp->mb[1] = LSW(reg);
5361 mcp->mb[2] = MSW(reg);
5362 mcp->mb[3] = LSW(data);
5363 mcp->mb[4] = MSW(data);
5364 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5365
5366 mcp->in_mb = MBX_1|MBX_0;
5367 mcp->tov = MBX_TOV_SECONDS;
5368 mcp->flags = 0;
5369 rval = qla2x00_mailbox_command(vha, mcp);
5370
5371 if (rval != QLA_SUCCESS) {
5372 ql_dbg(ql_dbg_mbx, vha, 0x1131,
5373 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5374 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005375 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005376 "Done %s.\n", __func__);
5377 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005378
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005379 return rval;
5380}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005381
5382int
5383qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
5384{
5385 int rval;
5386 struct qla_hw_data *ha = vha->hw;
5387 mbx_cmd_t mc;
5388 mbx_cmd_t *mcp = &mc;
5389
5390 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005391 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b,
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005392 "Implicit LOGO Unsupported.\n");
5393 return QLA_FUNCTION_FAILED;
5394 }
5395
5396
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005397 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c,
5398 "Entering %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005399
5400 /* Perform Implicit LOGO. */
5401 mcp->mb[0] = MBC_PORT_LOGOUT;
5402 mcp->mb[1] = fcport->loop_id;
5403 mcp->mb[10] = BIT_15;
5404 mcp->out_mb = MBX_10|MBX_1|MBX_0;
5405 mcp->in_mb = MBX_0;
5406 mcp->tov = MBX_TOV_SECONDS;
5407 mcp->flags = 0;
5408 rval = qla2x00_mailbox_command(vha, mcp);
5409 if (rval != QLA_SUCCESS)
5410 ql_dbg(ql_dbg_mbx, vha, 0x113d,
5411 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5412 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005413 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e,
5414 "Done %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005415
5416 return rval;
5417}
5418
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005419int
5420qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
5421{
5422 int rval;
5423 mbx_cmd_t mc;
5424 mbx_cmd_t *mcp = &mc;
5425 struct qla_hw_data *ha = vha->hw;
5426 unsigned long retry_max_time = jiffies + (2 * HZ);
5427
Chad Dupuisf73cb692014-02-26 04:15:06 -05005428 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005429 return QLA_FUNCTION_FAILED;
5430
5431 ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
5432
5433retry_rd_reg:
5434 mcp->mb[0] = MBC_READ_REMOTE_REG;
5435 mcp->mb[1] = LSW(reg);
5436 mcp->mb[2] = MSW(reg);
5437 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5438 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5439 mcp->tov = MBX_TOV_SECONDS;
5440 mcp->flags = 0;
5441 rval = qla2x00_mailbox_command(vha, mcp);
5442
5443 if (rval != QLA_SUCCESS) {
5444 ql_dbg(ql_dbg_mbx, vha, 0x114c,
5445 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5446 rval, mcp->mb[0], mcp->mb[1]);
5447 } else {
5448 *data = (mcp->mb[3] | (mcp->mb[4] << 16));
5449 if (*data == QLA8XXX_BAD_VALUE) {
5450 /*
5451 * During soft-reset CAMRAM register reads might
5452 * return 0xbad0bad0. So retry for MAX of 2 sec
5453 * while reading camram registers.
5454 */
5455 if (time_after(jiffies, retry_max_time)) {
5456 ql_dbg(ql_dbg_mbx, vha, 0x1141,
5457 "Failure to read CAMRAM register. "
5458 "data=0x%x.\n", *data);
5459 return QLA_FUNCTION_FAILED;
5460 }
5461 msleep(100);
5462 goto retry_rd_reg;
5463 }
5464 ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
5465 }
5466
5467 return rval;
5468}
5469
5470int
5471qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
5472{
5473 int rval;
5474 mbx_cmd_t mc;
5475 mbx_cmd_t *mcp = &mc;
5476 struct qla_hw_data *ha = vha->hw;
5477
Himanshu Madhanib20f02e2015-06-10 11:05:18 -04005478 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005479 return QLA_FUNCTION_FAILED;
5480
5481 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
5482
5483 mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
5484 mcp->out_mb = MBX_0;
5485 mcp->in_mb = MBX_1|MBX_0;
5486 mcp->tov = MBX_TOV_SECONDS;
5487 mcp->flags = 0;
5488 rval = qla2x00_mailbox_command(vha, mcp);
5489
5490 if (rval != QLA_SUCCESS) {
5491 ql_dbg(ql_dbg_mbx, vha, 0x1144,
5492 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5493 rval, mcp->mb[0], mcp->mb[1]);
5494 ha->isp_ops->fw_dump(vha, 0);
5495 } else {
5496 ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
5497 }
5498
5499 return rval;
5500}
5501
5502int
5503qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
5504 uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
5505{
5506 int rval;
5507 mbx_cmd_t mc;
5508 mbx_cmd_t *mcp = &mc;
5509 uint8_t subcode = (uint8_t)options;
5510 struct qla_hw_data *ha = vha->hw;
5511
5512 if (!IS_QLA8031(ha))
5513 return QLA_FUNCTION_FAILED;
5514
5515 ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
5516
5517 mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
5518 mcp->mb[1] = options;
5519 mcp->out_mb = MBX_1|MBX_0;
5520 if (subcode & BIT_2) {
5521 mcp->mb[2] = LSW(start_addr);
5522 mcp->mb[3] = MSW(start_addr);
5523 mcp->mb[4] = LSW(end_addr);
5524 mcp->mb[5] = MSW(end_addr);
5525 mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
5526 }
5527 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5528 if (!(subcode & (BIT_2 | BIT_5)))
5529 mcp->in_mb |= MBX_4|MBX_3;
5530 mcp->tov = MBX_TOV_SECONDS;
5531 mcp->flags = 0;
5532 rval = qla2x00_mailbox_command(vha, mcp);
5533
5534 if (rval != QLA_SUCCESS) {
5535 ql_dbg(ql_dbg_mbx, vha, 0x1147,
5536 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
5537 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
5538 mcp->mb[4]);
5539 ha->isp_ops->fw_dump(vha, 0);
5540 } else {
5541 if (subcode & BIT_5)
5542 *sector_size = mcp->mb[1];
5543 else if (subcode & (BIT_6 | BIT_7)) {
5544 ql_dbg(ql_dbg_mbx, vha, 0x1148,
5545 "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5546 } else if (subcode & (BIT_3 | BIT_4)) {
5547 ql_dbg(ql_dbg_mbx, vha, 0x1149,
5548 "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5549 }
5550 ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
5551 }
5552
5553 return rval;
5554}
Saurav Kashyap81178772012-08-22 14:21:04 -04005555
5556int
5557qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
5558 uint32_t size)
5559{
5560 int rval;
5561 mbx_cmd_t mc;
5562 mbx_cmd_t *mcp = &mc;
5563
5564 if (!IS_MCTP_CAPABLE(vha->hw))
5565 return QLA_FUNCTION_FAILED;
5566
5567 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,
5568 "Entered %s.\n", __func__);
5569
5570 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
5571 mcp->mb[1] = LSW(addr);
5572 mcp->mb[2] = MSW(req_dma);
5573 mcp->mb[3] = LSW(req_dma);
5574 mcp->mb[4] = MSW(size);
5575 mcp->mb[5] = LSW(size);
5576 mcp->mb[6] = MSW(MSD(req_dma));
5577 mcp->mb[7] = LSW(MSD(req_dma));
5578 mcp->mb[8] = MSW(addr);
5579 /* Setting RAM ID to valid */
5580 mcp->mb[10] |= BIT_7;
5581 /* For MCTP RAM ID is 0x40 */
5582 mcp->mb[10] |= 0x40;
5583
5584 mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
5585 MBX_0;
5586
5587 mcp->in_mb = MBX_0;
5588 mcp->tov = MBX_TOV_SECONDS;
5589 mcp->flags = 0;
5590 rval = qla2x00_mailbox_command(vha, mcp);
5591
5592 if (rval != QLA_SUCCESS) {
5593 ql_dbg(ql_dbg_mbx, vha, 0x114e,
5594 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5595 } else {
5596 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,
5597 "Done %s.\n", __func__);
5598 }
5599
5600 return rval;
5601}