blob: 17537f0b3b54d17ab7e4c5e7c79835b07e6d8243 [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
Quinn Tran15f30a52017-03-15 09:48:52 -070013static struct mb_cmd_name {
14 uint16_t cmd;
15 const char *str;
16} mb_str[] = {
17 {MBC_GET_PORT_DATABASE, "GPDB"},
18 {MBC_GET_ID_LIST, "GIDList"},
19 {MBC_GET_LINK_PRIV_STATS, "Stats"},
Quinn Tran94d83e32017-12-28 12:33:23 -080020 {MBC_GET_RESOURCE_COUNTS, "ResCnt"},
Quinn Tran15f30a52017-03-15 09:48:52 -070021};
22
23static const char *mb_to_str(uint16_t cmd)
24{
25 int i;
26 struct mb_cmd_name *e;
27
28 for (i = 0; i < ARRAY_SIZE(mb_str); i++) {
29 e = mb_str + i;
30 if (cmd == e->cmd)
31 return e->str;
32 }
33 return "unknown";
34}
35
Bart Van Asscheca825822017-01-17 09:34:14 -080036static struct rom_cmd {
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -080037 uint16_t cmd;
38} rom_cmds[] = {
39 { MBC_LOAD_RAM },
40 { MBC_EXECUTE_FIRMWARE },
41 { MBC_READ_RAM_WORD },
42 { MBC_MAILBOX_REGISTER_TEST },
43 { MBC_VERIFY_CHECKSUM },
44 { MBC_GET_FIRMWARE_VERSION },
45 { MBC_LOAD_RISC_RAM },
46 { MBC_DUMP_RISC_RAM },
47 { MBC_LOAD_RISC_RAM_EXTENDED },
48 { MBC_DUMP_RISC_RAM_EXTENDED },
49 { MBC_WRITE_RAM_WORD_EXTENDED },
50 { MBC_READ_RAM_EXTENDED },
51 { MBC_GET_RESOURCE_COUNTS },
52 { MBC_SET_FIRMWARE_OPTION },
53 { MBC_MID_INITIALIZE_FIRMWARE },
54 { MBC_GET_FIRMWARE_STATE },
55 { MBC_GET_MEM_OFFLOAD_CNTRL_STAT },
56 { MBC_GET_RETRY_COUNT },
57 { MBC_TRACE_CONTROL },
Michael Hernandezb7edfa22017-08-23 15:04:56 -070058 { MBC_INITIALIZE_MULTIQ },
Quinn Tran1608cc42017-08-23 15:05:03 -070059 { MBC_IOCB_COMMAND_A64 },
60 { MBC_GET_ADAPTER_LOOP_ID },
Quinn Trane4e3a2c2017-08-23 15:05:07 -070061 { MBC_READ_SFP },
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -080062};
63
64static int is_rom_cmd(uint16_t cmd)
65{
66 int i;
67 struct rom_cmd *wc;
68
69 for (i = 0; i < ARRAY_SIZE(rom_cmds); i++) {
70 wc = rom_cmds + i;
71 if (wc->cmd == cmd)
72 return 1;
73 }
74
75 return 0;
76}
Linus Torvalds1da177e2005-04-16 15:20:36 -070077
78/*
79 * qla2x00_mailbox_command
80 * Issue mailbox command and waits for completion.
81 *
82 * Input:
83 * ha = adapter block pointer.
84 * mcp = driver internal mbx struct pointer.
85 *
86 * Output:
87 * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
88 *
89 * Returns:
90 * 0 : QLA_SUCCESS = cmd performed success
91 * 1 : QLA_FUNCTION_FAILED (error encountered)
92 * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
93 *
94 * Context:
95 * Kernel context.
96 */
97static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080098qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070099{
Himanshu Madhanid14e72f2015-04-09 15:00:03 -0400100 int rval, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 unsigned long flags = 0;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500102 device_reg_t *reg;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700103 uint8_t abort_active;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700104 uint8_t io_lock_on;
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700105 uint16_t command = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 uint16_t *iptr;
107 uint16_t __iomem *optr;
108 uint32_t cnt;
109 uint32_t mboxes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 unsigned long wait_time;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800111 struct qla_hw_data *ha = vha->hw;
112 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700113
Himanshu Madhanid14e72f2015-04-09 15:00:03 -0400114
Arun Easi5e19ed92012-02-09 11:15:51 -0800115 ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700116
117 if (ha->pdev->error_state > pci_channel_io_frozen) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800118 ql_log(ql_log_warn, vha, 0x1001,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700119 "error_state is greater than pci_channel_io_frozen, "
120 "exiting.\n");
Seokmann Jub9b12f72009-03-24 09:08:18 -0700121 return QLA_FUNCTION_TIMEOUT;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700122 }
Seokmann Jub9b12f72009-03-24 09:08:18 -0700123
Giridhar Malavalia9083012010-04-12 17:59:55 -0700124 if (vha->device_flags & DFLG_DEV_FAILED) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800125 ql_log(ql_log_warn, vha, 0x1002,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700126 "Device in failed state, exiting.\n");
Giridhar Malavalia9083012010-04-12 17:59:55 -0700127 return QLA_FUNCTION_TIMEOUT;
128 }
129
Bart Van Asschec2a5d942017-01-11 15:58:58 -0800130 /* if PCI error, then avoid mbx processing.*/
Sawan Chandakba175892017-06-02 09:11:58 -0700131 if (test_bit(PFLG_DISCONNECTED, &base_vha->dpc_flags) &&
132 test_bit(UNLOADING, &base_vha->dpc_flags)) {
Quinn Tran83548fe2017-06-02 09:12:01 -0700133 ql_log(ql_log_warn, vha, 0xd04e,
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400134 "PCI error, exiting.\n");
135 return QLA_FUNCTION_TIMEOUT;
Bart Van Asschec2a5d942017-01-11 15:58:58 -0800136 }
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400137
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700138 reg = ha->iobase;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800139 io_lock_on = base_vha->flags.init_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140
141 rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800142 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700144
Andrew Vasquez85880802009-12-15 21:29:46 -0800145 if (ha->flags.pci_channel_io_perm_failure) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800146 ql_log(ql_log_warn, vha, 0x1003,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700147 "Perm failure on EEH timeout MBX, exiting.\n");
Andrew Vasquez85880802009-12-15 21:29:46 -0800148 return QLA_FUNCTION_TIMEOUT;
149 }
150
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400151 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Giridhar Malavali862cd012011-02-23 15:27:11 -0800152 /* Setting Link-Down error */
153 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
Arun Easi5e19ed92012-02-09 11:15:51 -0800154 ql_log(ql_log_warn, vha, 0x1004,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700155 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Andrew Vasquez1806fcd2011-11-18 09:02:15 -0800156 return QLA_FUNCTION_TIMEOUT;
Giridhar Malavali862cd012011-02-23 15:27:11 -0800157 }
158
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -0800159 /* check if ISP abort is active and return cmd with timeout */
160 if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
161 test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
162 test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) &&
163 !is_rom_cmd(mcp->mb[0])) {
164 ql_log(ql_log_info, vha, 0x1005,
165 "Cmd 0x%x aborted with timeout since ISP Abort is pending\n",
166 mcp->mb[0]);
167 return QLA_FUNCTION_TIMEOUT;
168 }
169
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700171 * Wait for active mailbox commands to finish by waiting at most tov
172 * seconds. This is to serialize actual issuing of mailbox cmds during
173 * non ISP abort time.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800175 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
176 /* Timeout occurred. Return error. */
Quinn Tran83548fe2017-06-02 09:12:01 -0700177 ql_log(ql_log_warn, vha, 0xd035,
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800178 "Cmd access timeout, cmd=0x%x, Exiting.\n",
179 mcp->mb[0]);
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800180 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 }
182
183 ha->flags.mbox_busy = 1;
184 /* Save mailbox command for debug */
185 ha->mcp = mcp;
186
Arun Easi5e19ed92012-02-09 11:15:51 -0800187 ql_dbg(ql_dbg_mbx, vha, 0x1006,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700188 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189
190 spin_lock_irqsave(&ha->hardware_lock, flags);
191
192 /* Load mailbox registers. */
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400193 if (IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -0700194 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400195 else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700196 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
197 else
198 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
200 iptr = mcp->mb;
201 command = mcp->mb[0];
202 mboxes = mcp->out_mb;
203
Joe Carnuccio7b711622014-09-25 05:16:43 -0400204 ql_dbg(ql_dbg_mbx, vha, 0x1111,
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700205 "Mailbox registers (OUT):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
207 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700208 optr =
209 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700210 if (mboxes & BIT_0) {
211 ql_dbg(ql_dbg_mbx, vha, 0x1112,
212 "mbox[%d]<-0x%04x\n", cnt, *iptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 WRT_REG_WORD(optr, *iptr);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700214 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
216 mboxes >>= 1;
217 optr++;
218 iptr++;
219 }
220
Arun Easi5e19ed92012-02-09 11:15:51 -0800221 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700222 "I/O Address = %p.\n", optr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223
224 /* Issue set host interrupt command to send cmd out. */
225 ha->flags.mbox_int = 0;
226 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
227
228 /* Unlock mbx registers and wait for interrupt */
Arun Easi5e19ed92012-02-09 11:15:51 -0800229 ql_dbg(ql_dbg_mbx, vha, 0x100f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700230 "Going to unlock irq & waiting for interrupts. "
231 "jiffies=%lx.\n", jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232
233 /* Wait for mbx cmd completion until timeout */
234
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800235 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
237
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400238 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700239 if (RD_REG_DWORD(&reg->isp82.hint) &
240 HINT_MBX_INT_PENDING) {
241 spin_unlock_irqrestore(&ha->hardware_lock,
242 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800243 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800244 ql_dbg(ql_dbg_mbx, vha, 0x1010,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700245 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700246 rval = QLA_FUNCTION_TIMEOUT;
247 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700248 }
249 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
250 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700251 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
252 else
253 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 spin_unlock_irqrestore(&ha->hardware_lock, flags);
255
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -0800256 wait_time = jiffies;
Giridhar Malavali754d1242013-06-25 11:27:16 -0400257 if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
258 mcp->tov * HZ)) {
259 ql_dbg(ql_dbg_mbx, vha, 0x117a,
260 "cmd=%x Timeout.\n", command);
261 spin_lock_irqsave(&ha->hardware_lock, flags);
262 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
263 spin_unlock_irqrestore(&ha->hardware_lock, flags);
264 }
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -0800265 if (time_after(jiffies, wait_time + 5 * HZ))
266 ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",
267 command, jiffies_to_msecs(jiffies - wait_time));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268 } else {
Arun Easi5e19ed92012-02-09 11:15:51 -0800269 ql_dbg(ql_dbg_mbx, vha, 0x1011,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700270 "Cmd=%x Polling Mode.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400272 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700273 if (RD_REG_DWORD(&reg->isp82.hint) &
274 HINT_MBX_INT_PENDING) {
275 spin_unlock_irqrestore(&ha->hardware_lock,
276 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800277 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800278 ql_dbg(ql_dbg_mbx, vha, 0x1012,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700279 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700280 rval = QLA_FUNCTION_TIMEOUT;
281 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700282 }
283 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
284 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700285 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
286 else
287 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289
290 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
291 while (!ha->flags.mbox_int) {
292 if (time_after(jiffies, wait_time))
293 break;
294
Rodrigo R. Galvao3cb182b2018-05-28 14:58:44 -0300295 /*
296 * Check if it's UNLOADING, cause we cannot poll in
297 * this case, or else a NULL pointer dereference
298 * is triggered.
299 */
300 if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags)))
301 return QLA_FUNCTION_TIMEOUT;
302
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800304 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305
Andrew Vasquez85880802009-12-15 21:29:46 -0800306 if (!ha->flags.mbox_int &&
307 !(IS_QLA2200(ha) &&
308 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800309 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 } /* while */
Arun Easi5e19ed92012-02-09 11:15:51 -0800311 ql_dbg(ql_dbg_mbx, vha, 0x1013,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700312 "Waited %d sec.\n",
313 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 }
315
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 /* Check whether we timed out */
317 if (ha->flags.mbox_int) {
318 uint16_t *iptr2;
319
Arun Easi5e19ed92012-02-09 11:15:51 -0800320 ql_dbg(ql_dbg_mbx, vha, 0x1014,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700321 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322
323 /* Got interrupt. Clear the flag. */
324 ha->flags.mbox_int = 0;
325 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
326
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400327 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700328 ha->flags.mbox_busy = 0;
329 /* Setting Link-Down error */
330 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
331 ha->mcp = NULL;
332 rval = QLA_FUNCTION_FAILED;
Quinn Tran83548fe2017-06-02 09:12:01 -0700333 ql_log(ql_log_warn, vha, 0xd048,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700334 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700335 goto premature_exit;
336 }
337
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400338 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340
341 /* Load return mailbox registers. */
342 iptr2 = mcp->mb;
343 iptr = (uint16_t *)&ha->mailbox_out[0];
344 mboxes = mcp->in_mb;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700345
346 ql_dbg(ql_dbg_mbx, vha, 0x1113,
347 "Mailbox registers (IN):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700349 if (mboxes & BIT_0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350 *iptr2 = *iptr;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700351 ql_dbg(ql_dbg_mbx, vha, 0x1114,
352 "mbox[%d]->0x%04x\n", cnt, *iptr2);
353 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
355 mboxes >>= 1;
356 iptr2++;
357 iptr++;
358 }
359 } else {
360
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800361 uint16_t mb[8];
362 uint32_t ictrl, host_status, hccr;
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400363 uint16_t w;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700364
Andrew Vasqueze4289242007-07-19 15:05:56 -0700365 if (IS_FWI2_CAPABLE(ha)) {
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800366 mb[0] = RD_REG_WORD(&reg->isp24.mailbox0);
367 mb[1] = RD_REG_WORD(&reg->isp24.mailbox1);
368 mb[2] = RD_REG_WORD(&reg->isp24.mailbox2);
369 mb[3] = RD_REG_WORD(&reg->isp24.mailbox3);
370 mb[7] = RD_REG_WORD(&reg->isp24.mailbox7);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700371 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800372 host_status = RD_REG_DWORD(&reg->isp24.host_status);
373 hccr = RD_REG_DWORD(&reg->isp24.hccr);
374
Quinn Tran83548fe2017-06-02 09:12:01 -0700375 ql_log(ql_log_warn, vha, 0xd04c,
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800376 "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
377 "mb[0-3]=[0x%x 0x%x 0x%x 0x%x] mb7 0x%x host_status 0x%x hccr 0x%x\n",
378 command, ictrl, jiffies, mb[0], mb[1], mb[2], mb[3],
379 mb[7], host_status, hccr);
380
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700381 } else {
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800382 mb[0] = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700383 ictrl = RD_REG_WORD(&reg->isp.ictrl);
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800384 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119,
385 "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
386 "mb[0]=0x%x\n", command, ictrl, jiffies, mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700387 }
Arun Easi5e19ed92012-02-09 11:15:51 -0800388 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400390 /* Capture FW dump only, if PCI device active */
391 if (!pci_channel_offline(vha->hw->pdev)) {
392 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
393 if (w == 0xffff || ictrl == 0xffffffff) {
394 /* This is special case if there is unload
395 * of driver happening and if PCI device go
396 * into bad state due to PCI error condition
397 * then only PCI ERR flag would be set.
398 * we will do premature exit for above case.
399 */
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400400 ha->flags.mbox_busy = 0;
401 rval = QLA_FUNCTION_TIMEOUT;
402 goto premature_exit;
403 }
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800404
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400405 /* Attempt to capture firmware dump for further
406 * anallysis of the current formware state. we do not
407 * need to do this if we are intentionally generating
408 * a dump
409 */
410 if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR)
411 ha->isp_ops->fw_dump(vha, 0);
412 rval = QLA_FUNCTION_TIMEOUT;
413 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414 }
415
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 ha->flags.mbox_busy = 0;
417
418 /* Clean up */
419 ha->mcp = NULL;
420
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800421 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800422 ql_dbg(ql_dbg_mbx, vha, 0x101a,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700423 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
425 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800426 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 }
428
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700429 if (rval == QLA_FUNCTION_TIMEOUT &&
430 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800431 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
432 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 /* not in dpc. schedule it for dpc to take over. */
Arun Easi5e19ed92012-02-09 11:15:51 -0800434 ql_dbg(ql_dbg_mbx, vha, 0x101b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700435 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700436
437 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
438 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
439 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800440 if (IS_QLA82XX(ha)) {
441 ql_dbg(ql_dbg_mbx, vha, 0x112a,
442 "disabling pause transmit on port "
443 "0 & 1.\n");
444 qla82xx_wr_32(ha,
445 QLA82XX_CRB_NIU + 0x98,
446 CRB_NIU_XG_PAUSE_CTL_P0|
447 CRB_NIU_XG_PAUSE_CTL_P1);
448 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700449 ql_log(ql_log_info, base_vha, 0x101c,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400450 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800451 "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "
452 "abort.\n", command, mcp->mb[0],
453 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700454 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
455 qla2xxx_wake_dpc(vha);
456 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 /* call abort directly since we are in the DPC thread */
Arun Easi5e19ed92012-02-09 11:15:51 -0800459 ql_dbg(ql_dbg_mbx, vha, 0x101d,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700460 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700462 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
463 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
464 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800465 if (IS_QLA82XX(ha)) {
466 ql_dbg(ql_dbg_mbx, vha, 0x112b,
467 "disabling pause transmit on port "
468 "0 & 1.\n");
469 qla82xx_wr_32(ha,
470 QLA82XX_CRB_NIU + 0x98,
471 CRB_NIU_XG_PAUSE_CTL_P0|
472 CRB_NIU_XG_PAUSE_CTL_P1);
473 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700474 ql_log(ql_log_info, base_vha, 0x101e,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400475 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800476 "mb[0]=0x%x. Scheduling ISP abort ",
477 command, mcp->mb[0]);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700478 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
479 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
Giridhar Malavalid3360962012-02-09 11:14:10 -0800480 /* Allow next mbx cmd to come in. */
481 complete(&ha->mbx_cmd_comp);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700482 if (ha->isp_ops->abort_isp(vha)) {
483 /* Failed. retry later. */
484 set_bit(ISP_ABORT_NEEDED,
485 &vha->dpc_flags);
486 }
487 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Arun Easi5e19ed92012-02-09 11:15:51 -0800488 ql_dbg(ql_dbg_mbx, vha, 0x101f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700489 "Finished abort_isp.\n");
Giridhar Malavalid3360962012-02-09 11:14:10 -0800490 goto mbx_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 }
493 }
494
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700495premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800497 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700498
Giridhar Malavalid3360962012-02-09 11:14:10 -0800499mbx_done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 if (rval) {
Joe Carnuccio050dc762017-08-23 15:05:14 -0700501 if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) {
502 pr_warn("%s [%s]-%04x:%ld: **** Failed", QL_MSGHDR,
503 dev_name(&ha->pdev->dev), 0x1020+0x800,
504 vha->host_no);
505 mboxes = mcp->in_mb;
506 cnt = 4;
507 for (i = 0; i < ha->mbx_count && cnt; i++, mboxes >>= 1)
508 if (mboxes & BIT_0) {
509 printk(" mb[%u]=%x", i, mcp->mb[i]);
510 cnt--;
511 }
512 pr_warn(" cmd=%x ****\n", command);
513 }
Meelis Roosf7e59e92018-03-08 15:44:07 +0200514 if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) {
515 ql_dbg(ql_dbg_mbx, vha, 0x1198,
516 "host_status=%#x intr_ctrl=%#x intr_status=%#x\n",
517 RD_REG_DWORD(&reg->isp24.host_status),
518 RD_REG_DWORD(&reg->isp24.ictrl),
519 RD_REG_DWORD(&reg->isp24.istatus));
520 } else {
521 ql_dbg(ql_dbg_mbx, vha, 0x1206,
522 "ctrl_status=%#x ictrl=%#x istatus=%#x\n",
523 RD_REG_WORD(&reg->isp.ctrl_status),
524 RD_REG_WORD(&reg->isp.ictrl),
525 RD_REG_WORD(&reg->isp.istatus));
526 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700528 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 }
530
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 return rval;
532}
533
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800535qla2x00_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 -0800536 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537{
538 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800539 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 mbx_cmd_t mc;
541 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400543 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022,
544 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545
Andrew Vasqueze4289242007-07-19 15:05:56 -0700546 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800547 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
548 mcp->mb[8] = MSW(risc_addr);
549 mcp->out_mb = MBX_8|MBX_0;
550 } else {
551 mcp->mb[0] = MBC_LOAD_RISC_RAM;
552 mcp->out_mb = MBX_0;
553 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554 mcp->mb[1] = LSW(risc_addr);
555 mcp->mb[2] = MSW(req_dma);
556 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 mcp->mb[6] = MSW(MSD(req_dma));
558 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800559 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700560 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700561 mcp->mb[4] = MSW(risc_code_size);
562 mcp->mb[5] = LSW(risc_code_size);
563 mcp->out_mb |= MBX_5|MBX_4;
564 } else {
565 mcp->mb[4] = LSW(risc_code_size);
566 mcp->out_mb |= MBX_4;
567 }
568
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700570 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800572 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700575 ql_dbg(ql_dbg_mbx, vha, 0x1023,
576 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400578 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,
579 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 }
581
582 return rval;
583}
584
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700585#define EXTENDED_BB_CREDITS BIT_0
Duane Grigsbye84067d2017-06-21 13:48:43 -0700586#define NVME_ENABLE_FLAG BIT_3
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700587static inline uint16_t qla25xx_set_sfp_lr_dist(struct qla_hw_data *ha)
588{
589 uint16_t mb4 = BIT_0;
590
591 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
592 mb4 |= ha->long_range_distance << LR_DIST_FW_POS;
593
594 return mb4;
595}
596
597static inline uint16_t qla25xx_set_nvr_lr_dist(struct qla_hw_data *ha)
598{
599 uint16_t mb4 = BIT_0;
600
601 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
602 struct nvram_81xx *nv = ha->nvram;
603
604 mb4 |= LR_DIST_FW_FIELD(nv->enhanced_features);
605 }
606
607 return mb4;
608}
Duane Grigsbye84067d2017-06-21 13:48:43 -0700609
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610/*
611 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700612 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 *
614 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700615 * ha = adapter block pointer.
616 * TARGET_QUEUE_LOCK must be released.
617 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 *
619 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700620 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 *
622 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700623 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 */
625int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800626qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627{
628 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800629 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630 mbx_cmd_t mc;
631 mbx_cmd_t *mcp = &mc;
632
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400633 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,
634 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635
636 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700637 mcp->out_mb = MBX_0;
638 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700639 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700640 mcp->mb[1] = MSW(risc_addr);
641 mcp->mb[2] = LSW(risc_addr);
642 mcp->mb[3] = 0;
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700643 mcp->mb[4] = 0;
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700644 ha->flags.using_lr_setting = 0;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500645 if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
646 IS_QLA27XX(ha)) {
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700647 if (ql2xautodetectsfp) {
648 if (ha->flags.detected_lr_sfp) {
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700649 mcp->mb[4] |=
650 qla25xx_set_sfp_lr_dist(ha);
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700651 ha->flags.using_lr_setting = 1;
652 }
653 } else {
654 struct nvram_81xx *nv = ha->nvram;
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700655 /* set LR distance if specified in nvram */
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700656 if (nv->enhanced_features &
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700657 NEF_LR_DIST_ENABLE) {
658 mcp->mb[4] |=
659 qla25xx_set_nvr_lr_dist(ha);
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700660 ha->flags.using_lr_setting = 1;
661 }
662 }
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700663 }
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500664
Duane Grigsbye84067d2017-06-21 13:48:43 -0700665 if (ql2xnvmeenable && IS_QLA27XX(ha))
666 mcp->mb[4] |= NVME_ENABLE_FLAG;
667
Sawan Chandak92d44082017-08-23 15:05:16 -0700668 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
669 struct nvram_81xx *nv = ha->nvram;
670 /* set minimum speed if specified in nvram */
671 if (nv->min_link_speed >= 2 &&
672 nv->min_link_speed <= 5) {
673 mcp->mb[4] |= BIT_4;
674 mcp->mb[11] = nv->min_link_speed;
675 mcp->out_mb |= MBX_11;
676 mcp->in_mb |= BIT_5;
677 vha->min_link_speed_feat = nv->min_link_speed;
678 }
679 }
680
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500681 if (ha->flags.exlogins_enabled)
682 mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;
683
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -0500684 if (ha->flags.exchoffld_enabled)
685 mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
686
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700687 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700688 mcp->in_mb |= MBX_3 | MBX_2 | MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700689 } else {
690 mcp->mb[1] = LSW(risc_addr);
691 mcp->out_mb |= MBX_1;
692 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
693 mcp->mb[2] = 0;
694 mcp->out_mb |= MBX_2;
695 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 }
697
Ravi Anandb93480e2008-04-03 13:13:25 -0700698 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800700 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700702 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700703 ql_dbg(ql_dbg_mbx, vha, 0x1026,
704 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700705 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700706 if (IS_FWI2_CAPABLE(ha)) {
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700707 ha->fw_ability_mask = mcp->mb[3] << 16 | mcp->mb[2];
708 ql_dbg(ql_dbg_mbx, vha, 0x119a,
709 "fw_ability_mask=%x.\n", ha->fw_ability_mask);
Sawan Chandak92d44082017-08-23 15:05:16 -0700710 ql_dbg(ql_dbg_mbx, vha, 0x1027,
711 "exchanges=%x.\n", mcp->mb[1]);
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700712 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
713 ha->max_speed_sup = mcp->mb[2] & BIT_0;
Sawan Chandak92d44082017-08-23 15:05:16 -0700714 ql_dbg(ql_dbg_mbx, vha, 0x119b,
715 "Maximum speed supported=%s.\n",
716 ha->max_speed_sup ? "32Gps" : "16Gps");
717 if (vha->min_link_speed_feat) {
718 ha->min_link_speed = mcp->mb[5];
719 ql_dbg(ql_dbg_mbx, vha, 0x119c,
720 "Minimum speed set=%s.\n",
721 mcp->mb[5] == 5 ? "32Gps" :
722 mcp->mb[5] == 4 ? "16Gps" :
723 mcp->mb[5] == 3 ? "8Gps" :
724 mcp->mb[5] == 2 ? "4Gps" :
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700725 "unknown");
Sawan Chandak92d44082017-08-23 15:05:16 -0700726 }
727 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700728 }
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700729 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
730 "Done.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700731 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732
733 return rval;
734}
735
736/*
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500737 * qla_get_exlogin_status
738 * Get extended login status
739 * uses the memory offload control/status Mailbox
740 *
741 * Input:
742 * ha: adapter state pointer.
743 * fwopt: firmware options
744 *
745 * Returns:
746 * qla2x00 local function status
747 *
748 * Context:
749 * Kernel context.
750 */
751#define FETCH_XLOGINS_STAT 0x8
752int
753qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
754 uint16_t *ex_logins_cnt)
755{
756 int rval;
757 mbx_cmd_t mc;
758 mbx_cmd_t *mcp = &mc;
759
760 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f,
761 "Entered %s\n", __func__);
762
763 memset(mcp->mb, 0 , sizeof(mcp->mb));
764 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
765 mcp->mb[1] = FETCH_XLOGINS_STAT;
766 mcp->out_mb = MBX_1|MBX_0;
767 mcp->in_mb = MBX_10|MBX_4|MBX_0;
768 mcp->tov = MBX_TOV_SECONDS;
769 mcp->flags = 0;
770
771 rval = qla2x00_mailbox_command(vha, mcp);
772 if (rval != QLA_SUCCESS) {
773 ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval);
774 } else {
775 *buf_sz = mcp->mb[4];
776 *ex_logins_cnt = mcp->mb[10];
777
778 ql_log(ql_log_info, vha, 0x1190,
779 "buffer size 0x%x, exchange login count=%d\n",
780 mcp->mb[4], mcp->mb[10]);
781
782 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116,
783 "Done %s.\n", __func__);
784 }
785
786 return rval;
787}
788
789/*
790 * qla_set_exlogin_mem_cfg
791 * set extended login memory configuration
792 * Mbx needs to be issues before init_cb is set
793 *
794 * Input:
795 * ha: adapter state pointer.
796 * buffer: buffer pointer
797 * phys_addr: physical address of buffer
798 * size: size of buffer
799 * TARGET_QUEUE_LOCK must be released
800 * ADAPTER_STATE_LOCK must be release
801 *
802 * Returns:
803 * qla2x00 local funxtion status code.
804 *
805 * Context:
806 * Kernel context.
807 */
808#define CONFIG_XLOGINS_MEM 0x3
809int
810qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
811{
812 int rval;
813 mbx_cmd_t mc;
814 mbx_cmd_t *mcp = &mc;
815 struct qla_hw_data *ha = vha->hw;
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500816
817 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a,
818 "Entered %s.\n", __func__);
819
820 memset(mcp->mb, 0 , sizeof(mcp->mb));
821 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
822 mcp->mb[1] = CONFIG_XLOGINS_MEM;
823 mcp->mb[2] = MSW(phys_addr);
824 mcp->mb[3] = LSW(phys_addr);
825 mcp->mb[6] = MSW(MSD(phys_addr));
826 mcp->mb[7] = LSW(MSD(phys_addr));
827 mcp->mb[8] = MSW(ha->exlogin_size);
828 mcp->mb[9] = LSW(ha->exlogin_size);
829 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
830 mcp->in_mb = MBX_11|MBX_0;
831 mcp->tov = MBX_TOV_SECONDS;
832 mcp->flags = 0;
833 rval = qla2x00_mailbox_command(vha, mcp);
834 if (rval != QLA_SUCCESS) {
835 /*EMPTY*/
836 ql_dbg(ql_dbg_mbx, vha, 0x111b, "Failed=%x.\n", rval);
837 } else {
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500838 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
839 "Done %s.\n", __func__);
840 }
841
842 return rval;
843}
844
845/*
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -0500846 * qla_get_exchoffld_status
847 * Get exchange offload status
848 * uses the memory offload control/status Mailbox
849 *
850 * Input:
851 * ha: adapter state pointer.
852 * fwopt: firmware options
853 *
854 * Returns:
855 * qla2x00 local function status
856 *
857 * Context:
858 * Kernel context.
859 */
860#define FETCH_XCHOFFLD_STAT 0x2
861int
862qla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
863 uint16_t *ex_logins_cnt)
864{
865 int rval;
866 mbx_cmd_t mc;
867 mbx_cmd_t *mcp = &mc;
868
869 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1019,
870 "Entered %s\n", __func__);
871
872 memset(mcp->mb, 0 , sizeof(mcp->mb));
873 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
874 mcp->mb[1] = FETCH_XCHOFFLD_STAT;
875 mcp->out_mb = MBX_1|MBX_0;
876 mcp->in_mb = MBX_10|MBX_4|MBX_0;
877 mcp->tov = MBX_TOV_SECONDS;
878 mcp->flags = 0;
879
880 rval = qla2x00_mailbox_command(vha, mcp);
881 if (rval != QLA_SUCCESS) {
882 ql_dbg(ql_dbg_mbx, vha, 0x1155, "Failed=%x.\n", rval);
883 } else {
884 *buf_sz = mcp->mb[4];
885 *ex_logins_cnt = mcp->mb[10];
886
887 ql_log(ql_log_info, vha, 0x118e,
888 "buffer size 0x%x, exchange offload count=%d\n",
889 mcp->mb[4], mcp->mb[10]);
890
891 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1156,
892 "Done %s.\n", __func__);
893 }
894
895 return rval;
896}
897
898/*
899 * qla_set_exchoffld_mem_cfg
900 * Set exchange offload memory configuration
901 * Mbx needs to be issues before init_cb is set
902 *
903 * Input:
904 * ha: adapter state pointer.
905 * buffer: buffer pointer
906 * phys_addr: physical address of buffer
907 * size: size of buffer
908 * TARGET_QUEUE_LOCK must be released
909 * ADAPTER_STATE_LOCK must be release
910 *
911 * Returns:
912 * qla2x00 local funxtion status code.
913 *
914 * Context:
915 * Kernel context.
916 */
917#define CONFIG_XCHOFFLD_MEM 0x3
918int
Quinn Tran99e1b682017-06-02 09:12:03 -0700919qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha)
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -0500920{
921 int rval;
922 mbx_cmd_t mc;
923 mbx_cmd_t *mcp = &mc;
924 struct qla_hw_data *ha = vha->hw;
925
926 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1157,
927 "Entered %s.\n", __func__);
928
929 memset(mcp->mb, 0 , sizeof(mcp->mb));
930 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
931 mcp->mb[1] = CONFIG_XCHOFFLD_MEM;
Quinn Tran99e1b682017-06-02 09:12:03 -0700932 mcp->mb[2] = MSW(ha->exchoffld_buf_dma);
933 mcp->mb[3] = LSW(ha->exchoffld_buf_dma);
934 mcp->mb[6] = MSW(MSD(ha->exchoffld_buf_dma));
935 mcp->mb[7] = LSW(MSD(ha->exchoffld_buf_dma));
936 mcp->mb[8] = MSW(ha->exchoffld_size);
937 mcp->mb[9] = LSW(ha->exchoffld_size);
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -0500938 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
939 mcp->in_mb = MBX_11|MBX_0;
940 mcp->tov = MBX_TOV_SECONDS;
941 mcp->flags = 0;
942 rval = qla2x00_mailbox_command(vha, mcp);
943 if (rval != QLA_SUCCESS) {
944 /*EMPTY*/
945 ql_dbg(ql_dbg_mbx, vha, 0x1158, "Failed=%x.\n", rval);
946 } else {
947 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192,
948 "Done %s.\n", __func__);
949 }
950
951 return rval;
952}
953
954/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 * qla2x00_get_fw_version
956 * Get firmware version.
957 *
958 * Input:
959 * ha: adapter state pointer.
960 * major: pointer for major number.
961 * minor: pointer for minor number.
962 * subminor: pointer for subminor number.
963 *
964 * Returns:
965 * qla2x00 local function return status code.
966 *
967 * Context:
968 * Kernel context.
969 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700970int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800971qla2x00_get_fw_version(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972{
973 int rval;
974 mbx_cmd_t mc;
975 mbx_cmd_t *mcp = &mc;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800976 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400978 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029,
979 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980
981 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
982 mcp->out_mb = MBX_0;
983 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400984 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha))
Andrew Vasquez55a96152009-03-24 09:08:03 -0700985 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Saurav Kashyapfb0effe2012-08-22 14:21:28 -0400986 if (IS_FWI2_CAPABLE(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800987 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500988 if (IS_QLA27XX(ha))
Joe Carnuccioad1ef172016-07-06 11:14:18 -0400989 mcp->in_mb |=
990 MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18|
991 MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8;
Sawan Chandak03aa8682015-08-04 13:37:59 -0400992
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700994 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800995 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700996 if (rval != QLA_SUCCESS)
997 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998
999 /* Return mailbox data. */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001000 ha->fw_major_version = mcp->mb[1];
1001 ha->fw_minor_version = mcp->mb[2];
1002 ha->fw_subminor_version = mcp->mb[3];
1003 ha->fw_attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001004 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001005 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001006 else
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001007 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
Sawan Chandak03aa8682015-08-04 13:37:59 -04001008
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001009 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001010 ha->mpi_version[0] = mcp->mb[10] & 0xff;
1011 ha->mpi_version[1] = mcp->mb[11] >> 8;
1012 ha->mpi_version[2] = mcp->mb[11] & 0xff;
1013 ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
1014 ha->phy_version[0] = mcp->mb[8] & 0xff;
1015 ha->phy_version[1] = mcp->mb[9] >> 8;
1016 ha->phy_version[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001017 }
Sawan Chandak03aa8682015-08-04 13:37:59 -04001018
Saurav Kashyap81178772012-08-22 14:21:04 -04001019 if (IS_FWI2_CAPABLE(ha)) {
1020 ha->fw_attributes_h = mcp->mb[15];
1021 ha->fw_attributes_ext[0] = mcp->mb[16];
1022 ha->fw_attributes_ext[1] = mcp->mb[17];
1023 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,
1024 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
1025 __func__, mcp->mb[15], mcp->mb[6]);
1026 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
1027 "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
1028 __func__, mcp->mb[17], mcp->mb[16]);
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -05001029
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -05001030 if (ha->fw_attributes_h & 0x4)
1031 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d,
1032 "%s: Firmware supports Extended Login 0x%x\n",
1033 __func__, ha->fw_attributes_h);
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -05001034
1035 if (ha->fw_attributes_h & 0x8)
1036 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191,
1037 "%s: Firmware supports Exchange Offload 0x%x\n",
1038 __func__, ha->fw_attributes_h);
Duane Grigsbye84067d2017-06-21 13:48:43 -07001039
Duane Grigsbydeeae7a2017-07-21 09:32:25 -07001040 /*
1041 * FW supports nvme and driver load parameter requested nvme.
1042 * BIT 26 of fw_attributes indicates NVMe support.
1043 */
Darren Trapp1cbc0ef2018-03-20 23:09:37 -07001044 if ((ha->fw_attributes_h & 0x400) && ql2xnvmeenable) {
Duane Grigsbye84067d2017-06-21 13:48:43 -07001045 vha->flags.nvme_enabled = 1;
Darren Trapp1cbc0ef2018-03-20 23:09:37 -07001046 ql_log(ql_log_info, vha, 0xd302,
1047 "%s: FC-NVMe is Enabled (0x%x)\n",
1048 __func__, ha->fw_attributes_h);
1049 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001050 }
Sawan Chandak03aa8682015-08-04 13:37:59 -04001051
Chad Dupuisf73cb692014-02-26 04:15:06 -05001052 if (IS_QLA27XX(ha)) {
Sawan Chandak03aa8682015-08-04 13:37:59 -04001053 ha->mpi_version[0] = mcp->mb[10] & 0xff;
1054 ha->mpi_version[1] = mcp->mb[11] >> 8;
1055 ha->mpi_version[2] = mcp->mb[11] & 0xff;
1056 ha->pep_version[0] = mcp->mb[13] & 0xff;
1057 ha->pep_version[1] = mcp->mb[14] >> 8;
1058 ha->pep_version[2] = mcp->mb[14] & 0xff;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001059 ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18];
1060 ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20];
Joe Carnuccioad1ef172016-07-06 11:14:18 -04001061 ha->fw_ddr_ram_start = (mcp->mb[23] << 16) | mcp->mb[22];
1062 ha->fw_ddr_ram_end = (mcp->mb[25] << 16) | mcp->mb[24];
Chad Dupuisf73cb692014-02-26 04:15:06 -05001063 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001064
Andrew Vasquezca9e9c32009-06-03 09:55:20 -07001065failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 if (rval != QLA_SUCCESS) {
1067 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001068 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 } else {
1070 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001071 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b,
1072 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001073 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -07001074 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075}
1076
1077/*
1078 * qla2x00_get_fw_options
1079 * Set firmware options.
1080 *
1081 * Input:
1082 * ha = adapter block pointer.
1083 * fwopt = pointer for firmware options.
1084 *
1085 * Returns:
1086 * qla2x00 local function return status code.
1087 *
1088 * Context:
1089 * Kernel context.
1090 */
1091int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001092qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001093{
1094 int rval;
1095 mbx_cmd_t mc;
1096 mbx_cmd_t *mcp = &mc;
1097
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001098 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c,
1099 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
1101 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
1102 mcp->out_mb = MBX_0;
1103 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001104 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001106 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107
1108 if (rval != QLA_SUCCESS) {
1109 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001110 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001112 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 fwopts[1] = mcp->mb[1];
1114 fwopts[2] = mcp->mb[2];
1115 fwopts[3] = mcp->mb[3];
1116
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001117 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e,
1118 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119 }
1120
1121 return rval;
1122}
1123
1124
1125/*
1126 * qla2x00_set_fw_options
1127 * Set firmware options.
1128 *
1129 * Input:
1130 * ha = adapter block pointer.
1131 * fwopt = pointer for firmware options.
1132 *
1133 * Returns:
1134 * qla2x00 local function return status code.
1135 *
1136 * Context:
1137 * Kernel context.
1138 */
1139int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001140qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141{
1142 int rval;
1143 mbx_cmd_t mc;
1144 mbx_cmd_t *mcp = &mc;
1145
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001146 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f,
1147 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148
1149 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
1150 mcp->mb[1] = fwopts[1];
1151 mcp->mb[2] = fwopts[2];
1152 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001153 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001155 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001156 mcp->in_mb |= MBX_1;
Quinn Tran2da52732017-06-02 09:12:05 -07001157 mcp->mb[10] = fwopts[10];
1158 mcp->out_mb |= MBX_10;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001159 } else {
1160 mcp->mb[10] = fwopts[10];
1161 mcp->mb[11] = fwopts[11];
1162 mcp->mb[12] = 0; /* Undocumented, but used */
1163 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
1164 }
Ravi Anandb93480e2008-04-03 13:13:25 -07001165 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001167 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001169 fwopts[0] = mcp->mb[0];
1170
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 if (rval != QLA_SUCCESS) {
1172 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001173 ql_dbg(ql_dbg_mbx, vha, 0x1030,
1174 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 } else {
1176 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001177 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031,
1178 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 }
1180
1181 return rval;
1182}
1183
1184/*
1185 * qla2x00_mbx_reg_test
1186 * Mailbox register wrap test.
1187 *
1188 * Input:
1189 * ha = adapter block pointer.
1190 * TARGET_QUEUE_LOCK must be released.
1191 * ADAPTER_STATE_LOCK must be released.
1192 *
1193 * Returns:
1194 * qla2x00 local function return status code.
1195 *
1196 * Context:
1197 * Kernel context.
1198 */
1199int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001200qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201{
1202 int rval;
1203 mbx_cmd_t mc;
1204 mbx_cmd_t *mcp = &mc;
1205
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001206 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032,
1207 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208
1209 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
1210 mcp->mb[1] = 0xAAAA;
1211 mcp->mb[2] = 0x5555;
1212 mcp->mb[3] = 0xAA55;
1213 mcp->mb[4] = 0x55AA;
1214 mcp->mb[5] = 0xA5A5;
1215 mcp->mb[6] = 0x5A5A;
1216 mcp->mb[7] = 0x2525;
1217 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1218 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 -07001219 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001221 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222
1223 if (rval == QLA_SUCCESS) {
1224 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
1225 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
1226 rval = QLA_FUNCTION_FAILED;
1227 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
1228 mcp->mb[7] != 0x2525)
1229 rval = QLA_FUNCTION_FAILED;
1230 }
1231
1232 if (rval != QLA_SUCCESS) {
1233 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001234 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235 } else {
1236 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001237 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034,
1238 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239 }
1240
1241 return rval;
1242}
1243
1244/*
1245 * qla2x00_verify_checksum
1246 * Verify firmware checksum.
1247 *
1248 * Input:
1249 * ha = adapter block pointer.
1250 * TARGET_QUEUE_LOCK must be released.
1251 * ADAPTER_STATE_LOCK must be released.
1252 *
1253 * Returns:
1254 * qla2x00 local function return status code.
1255 *
1256 * Context:
1257 * Kernel context.
1258 */
1259int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001260qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261{
1262 int rval;
1263 mbx_cmd_t mc;
1264 mbx_cmd_t *mcp = &mc;
1265
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001266 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035,
1267 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268
1269 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001270 mcp->out_mb = MBX_0;
1271 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001272 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001273 mcp->mb[1] = MSW(risc_addr);
1274 mcp->mb[2] = LSW(risc_addr);
1275 mcp->out_mb |= MBX_2|MBX_1;
1276 mcp->in_mb |= MBX_2|MBX_1;
1277 } else {
1278 mcp->mb[1] = LSW(risc_addr);
1279 mcp->out_mb |= MBX_1;
1280 mcp->in_mb |= MBX_1;
1281 }
1282
Ravi Anandb93480e2008-04-03 13:13:25 -07001283 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001285 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286
1287 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001288 ql_dbg(ql_dbg_mbx, vha, 0x1036,
1289 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
1290 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001292 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037,
1293 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 }
1295
1296 return rval;
1297}
1298
1299/*
1300 * qla2x00_issue_iocb
1301 * Issue IOCB using mailbox command
1302 *
1303 * Input:
1304 * ha = adapter state pointer.
1305 * buffer = buffer pointer.
1306 * phys_addr = physical address of buffer.
1307 * size = size of buffer.
1308 * TARGET_QUEUE_LOCK must be released.
1309 * ADAPTER_STATE_LOCK must be released.
1310 *
1311 * Returns:
1312 * qla2x00 local function return status code.
1313 *
1314 * Context:
1315 * Kernel context.
1316 */
Giridhar Malavali6e980162010-03-19 17:03:58 -07001317int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001318qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001319 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320{
1321 int rval;
1322 mbx_cmd_t mc;
1323 mbx_cmd_t *mcp = &mc;
1324
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001325 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038,
1326 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001327
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
1329 mcp->mb[1] = 0;
1330 mcp->mb[2] = MSW(phys_addr);
1331 mcp->mb[3] = LSW(phys_addr);
1332 mcp->mb[6] = MSW(MSD(phys_addr));
1333 mcp->mb[7] = LSW(MSD(phys_addr));
1334 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1335 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001336 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001338 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339
1340 if (rval != QLA_SUCCESS) {
1341 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001342 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -07001344 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
1345
1346 /* Mask reserved bits. */
1347 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001348 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001349 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a,
1350 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 }
1352
1353 return rval;
1354}
1355
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001356int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001357qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001358 size_t size)
1359{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001360 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001361 MBX_TOV_SECONDS);
1362}
1363
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364/*
1365 * qla2x00_abort_command
1366 * Abort command aborts a specified IOCB.
1367 *
1368 * Input:
1369 * ha = adapter block pointer.
1370 * sp = SB structure pointer.
1371 *
1372 * Returns:
1373 * qla2x00 local function return status code.
1374 *
1375 * Context:
1376 * Kernel context.
1377 */
1378int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001379qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380{
1381 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001383 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384 mbx_cmd_t mc;
1385 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001386 fc_port_t *fcport = sp->fcport;
1387 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001388 struct qla_hw_data *ha = vha->hw;
Michael Hernandezd7459522016-12-12 14:40:07 -08001389 struct req_que *req;
Giridhar Malavali9ba56b92012-02-09 11:15:36 -08001390 struct scsi_cmnd *cmd = GET_CMD_SP(sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001392 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b,
1393 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394
Michael Hernandezd7459522016-12-12 14:40:07 -08001395 if (vha->flags.qpairs_available && sp->qpair)
1396 req = sp->qpair->req;
1397 else
1398 req = vha->req;
1399
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -07001400 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05001401 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001402 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403 break;
1404 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -07001405 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406
Chad Dupuis8d93f552013-01-30 03:34:37 -05001407 if (handle == req->num_outstanding_cmds) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408 /* command not found */
1409 return QLA_FUNCTION_FAILED;
1410 }
1411
1412 mcp->mb[0] = MBC_ABORT_COMMAND;
1413 if (HAS_EXTENDED_IDS(ha))
1414 mcp->mb[1] = fcport->loop_id;
1415 else
1416 mcp->mb[1] = fcport->loop_id << 8;
1417 mcp->mb[2] = (uint16_t)handle;
1418 mcp->mb[3] = (uint16_t)(handle >> 16);
Giridhar Malavali9ba56b92012-02-09 11:15:36 -08001419 mcp->mb[6] = (uint16_t)cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1421 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001422 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001424 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425
1426 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001427 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001429 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d,
1430 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 }
1432
1433 return rval;
1434}
1435
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001437qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438{
Andrew Vasquez523ec772008-04-03 13:13:24 -07001439 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440 mbx_cmd_t mc;
1441 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001442 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001443 struct req_que *req;
1444 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445
Andrew Vasquez523ec772008-04-03 13:13:24 -07001446 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001447 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001448
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001449 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e,
1450 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001451
Giridhar Malavali7e2b8952010-05-28 15:08:17 -07001452 req = vha->hw->req_q_map[0];
1453 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001455 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001456 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457 mcp->mb[1] = fcport->loop_id;
1458 mcp->mb[10] = 0;
1459 mcp->out_mb |= MBX_10;
1460 } else {
1461 mcp->mb[1] = fcport->loop_id << 8;
1462 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001463 mcp->mb[2] = vha->hw->loop_reset_delay;
1464 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465
1466 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001467 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001469 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001471 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f,
1472 "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001473 }
1474
1475 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001476 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
1477 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001478 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001479 ql_dbg(ql_dbg_mbx, vha, 0x1040,
1480 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001482 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041,
1483 "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001484 }
1485
1486 return rval;
1487}
1488
1489int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001490qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07001491{
1492 int rval, rval2;
1493 mbx_cmd_t mc;
1494 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001495 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001496 struct req_que *req;
1497 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001498
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001499 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001500
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001501 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042,
1502 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001503
Giridhar Malavali7e2b8952010-05-28 15:08:17 -07001504 req = vha->hw->req_q_map[0];
1505 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001506 mcp->mb[0] = MBC_LUN_RESET;
1507 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001508 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -07001509 mcp->mb[1] = fcport->loop_id;
1510 else
1511 mcp->mb[1] = fcport->loop_id << 8;
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001512 mcp->mb[2] = (u32)l;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001513 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001514 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001515
1516 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001517 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001518 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001519 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001520 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001521 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001522 }
1523
1524 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001525 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1526 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001527 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001528 ql_dbg(ql_dbg_mbx, vha, 0x1044,
1529 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001530 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001531 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045,
1532 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533 }
1534
1535 return rval;
1536}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537
1538/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 * qla2x00_get_adapter_id
1540 * Get adapter ID and topology.
1541 *
1542 * Input:
1543 * ha = adapter block pointer.
1544 * id = pointer for loop ID.
1545 * al_pa = pointer for AL_PA.
1546 * area = pointer for area.
1547 * domain = pointer for domain.
1548 * top = pointer for topology.
1549 * TARGET_QUEUE_LOCK must be released.
1550 * ADAPTER_STATE_LOCK must be released.
1551 *
1552 * Returns:
1553 * qla2x00 local function return status code.
1554 *
1555 * Context:
1556 * Kernel context.
1557 */
1558int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001559qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001560 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561{
1562 int rval;
1563 mbx_cmd_t mc;
1564 mbx_cmd_t *mcp = &mc;
1565
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001566 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046,
1567 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568
1569 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001570 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001571 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001572 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001573 if (IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001574 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001575 if (IS_FWI2_CAPABLE(vha->hw))
1576 mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16;
Sawan Chandak969a6192016-01-27 12:03:32 -05001577 if (IS_QLA27XX(vha->hw))
1578 mcp->in_mb |= MBX_15;
Ravi Anandb93480e2008-04-03 13:13:25 -07001579 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001581 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001582 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1583 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001584 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1585 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586
1587 /* Return data. */
1588 *id = mcp->mb[1];
1589 *al_pa = LSB(mcp->mb[2]);
1590 *area = MSB(mcp->mb[2]);
1591 *domain = LSB(mcp->mb[3]);
1592 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001593 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594
1595 if (rval != QLA_SUCCESS) {
1596 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001597 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001599 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048,
1600 "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001601
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001602 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001603 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1604 vha->fcoe_fcf_idx = mcp->mb[10];
1605 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1606 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1607 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1608 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1609 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1610 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1611 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001612 /* If FA-WWN supported */
Saurav Kashyapd6b9b422015-08-04 13:37:55 -04001613 if (IS_FAWWN_CAPABLE(vha->hw)) {
1614 if (mcp->mb[7] & BIT_14) {
1615 vha->port_name[0] = MSB(mcp->mb[16]);
1616 vha->port_name[1] = LSB(mcp->mb[16]);
1617 vha->port_name[2] = MSB(mcp->mb[17]);
1618 vha->port_name[3] = LSB(mcp->mb[17]);
1619 vha->port_name[4] = MSB(mcp->mb[18]);
1620 vha->port_name[5] = LSB(mcp->mb[18]);
1621 vha->port_name[6] = MSB(mcp->mb[19]);
1622 vha->port_name[7] = LSB(mcp->mb[19]);
1623 fc_host_port_name(vha->host) =
1624 wwn_to_u64(vha->port_name);
1625 ql_dbg(ql_dbg_mbx, vha, 0x10ca,
1626 "FA-WWN acquired %016llx\n",
1627 wwn_to_u64(vha->port_name));
1628 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001629 }
Sawan Chandak969a6192016-01-27 12:03:32 -05001630
1631 if (IS_QLA27XX(vha->hw))
1632 vha->bbcr = mcp->mb[15];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633 }
1634
1635 return rval;
1636}
1637
1638/*
1639 * qla2x00_get_retry_cnt
1640 * Get current firmware login retry count and delay.
1641 *
1642 * Input:
1643 * ha = adapter block pointer.
1644 * retry_cnt = pointer to login retry count.
1645 * tov = pointer to login timeout value.
1646 *
1647 * Returns:
1648 * qla2x00 local function return status code.
1649 *
1650 * Context:
1651 * Kernel context.
1652 */
1653int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001654qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 uint16_t *r_a_tov)
1656{
1657 int rval;
1658 uint16_t ratov;
1659 mbx_cmd_t mc;
1660 mbx_cmd_t *mcp = &mc;
1661
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001662 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049,
1663 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664
1665 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1666 mcp->out_mb = MBX_0;
1667 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001668 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001670 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671
1672 if (rval != QLA_SUCCESS) {
1673 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001674 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1675 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 } else {
1677 /* Convert returned data and check our values. */
1678 *r_a_tov = mcp->mb[3] / 2;
1679 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1680 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1681 /* Update to the larger values */
1682 *retry_cnt = (uint8_t)mcp->mb[1];
1683 *tov = ratov;
1684 }
1685
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001686 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001687 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 }
1689
1690 return rval;
1691}
1692
1693/*
1694 * qla2x00_init_firmware
1695 * Initialize adapter firmware.
1696 *
1697 * Input:
1698 * ha = adapter block pointer.
1699 * dptr = Initialization control block pointer.
1700 * size = size of initialization control block.
1701 * TARGET_QUEUE_LOCK must be released.
1702 * ADAPTER_STATE_LOCK must be released.
1703 *
1704 * Returns:
1705 * qla2x00 local function return status code.
1706 *
1707 * Context:
1708 * Kernel context.
1709 */
1710int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001711qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712{
1713 int rval;
1714 mbx_cmd_t mc;
1715 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001716 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001718 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,
1719 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001721 if (IS_P3P_TYPE(ha) && ql2xdbwr)
Bart Van Assche8dfa4b5a2015-07-09 07:24:50 -07001722 qla82xx_wr_32(ha, (uintptr_t __force)ha->nxdb_wr_ptr,
Giridhar Malavalia9083012010-04-12 17:59:55 -07001723 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1724
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001725 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001726 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1727 else
1728 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1729
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001730 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 mcp->mb[2] = MSW(ha->init_cb_dma);
1732 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1734 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001735 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Joe Carnuccio4ef21bd2013-10-30 03:38:11 -04001736 if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001737 mcp->mb[1] = BIT_0;
1738 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1739 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1740 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1741 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1742 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1743 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1744 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001745 /* 1 and 2 should normally be captured. */
1746 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001747 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001748 /* mb3 is additional info about the installed SFP. */
1749 mcp->in_mb |= MBX_3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 mcp->buf_size = size;
1751 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001752 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001753 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754
1755 if (rval != QLA_SUCCESS) {
1756 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001757 ql_dbg(ql_dbg_mbx, vha, 0x104d,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001758 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1759 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 } else {
Sawan Chandak92d44082017-08-23 15:05:16 -07001761 if (IS_QLA27XX(ha)) {
1762 if (mcp->mb[2] == 6 || mcp->mb[3] == 2)
1763 ql_dbg(ql_dbg_mbx, vha, 0x119d,
1764 "Invalid SFP/Validation Failed\n");
1765 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001766 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,
1767 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 }
1769
1770 return rval;
1771}
1772
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001773
1774/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 * qla2x00_get_port_database
1776 * Issue normal/enhanced get port database mailbox command
1777 * and copy device name as necessary.
1778 *
1779 * Input:
1780 * ha = adapter state pointer.
1781 * dev = structure pointer.
1782 * opt = enhanced cmd option byte.
1783 *
1784 * Returns:
1785 * qla2x00 local function return status code.
1786 *
1787 * Context:
1788 * Kernel context.
1789 */
1790int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001791qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792{
1793 int rval;
1794 mbx_cmd_t mc;
1795 mbx_cmd_t *mcp = &mc;
1796 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001797 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001799 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001800
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001801 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f,
1802 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001804 pd24 = NULL;
Thomas Meyer08eb7f42017-09-21 08:15:26 +02001805 pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001807 ql_log(ql_log_warn, vha, 0x1050,
1808 "Failed to allocate port database structure.\n");
Duane Grigsbyedd05de2017-10-13 09:34:06 -07001809 fcport->query = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 return QLA_MEMORY_ALLOC_FAILED;
1811 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001813 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001814 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001815 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816 mcp->mb[2] = MSW(pd_dma);
1817 mcp->mb[3] = LSW(pd_dma);
1818 mcp->mb[6] = MSW(MSD(pd_dma));
1819 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001820 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001821 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001823 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001824 mcp->mb[1] = fcport->loop_id;
1825 mcp->mb[10] = opt;
1826 mcp->out_mb |= MBX_10|MBX_1;
1827 mcp->in_mb |= MBX_1;
1828 } else if (HAS_EXTENDED_IDS(ha)) {
1829 mcp->mb[1] = fcport->loop_id;
1830 mcp->mb[10] = opt;
1831 mcp->out_mb |= MBX_10|MBX_1;
1832 } else {
1833 mcp->mb[1] = fcport->loop_id << 8 | opt;
1834 mcp->out_mb |= MBX_1;
1835 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001836 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1837 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 mcp->flags = MBX_DMA_IN;
1839 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001840 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 if (rval != QLA_SUCCESS)
1842 goto gpd_error_out;
1843
Andrew Vasqueze4289242007-07-19 15:05:56 -07001844 if (IS_FWI2_CAPABLE(ha)) {
Arun Easi0eba25d2012-02-09 11:15:58 -08001845 uint64_t zero = 0;
Duane Grigsbyc0c462c2017-10-13 09:34:05 -07001846 u8 current_login_state, last_login_state;
1847
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001848 pd24 = (struct port_database_24xx *) pd;
1849
1850 /* Check for logged in state. */
Duane Grigsbyc0c462c2017-10-13 09:34:05 -07001851 if (fcport->fc4f_nvme) {
1852 current_login_state = pd24->current_login_state >> 4;
1853 last_login_state = pd24->last_login_state >> 4;
1854 } else {
1855 current_login_state = pd24->current_login_state & 0xf;
1856 last_login_state = pd24->last_login_state & 0xf;
1857 }
1858 fcport->current_login_state = pd24->current_login_state;
1859 fcport->last_login_state = pd24->last_login_state;
1860
1861 /* Check for logged in state. */
1862 if (current_login_state != PDS_PRLI_COMPLETE &&
1863 last_login_state != PDS_PRLI_COMPLETE) {
1864 ql_dbg(ql_dbg_mbx, vha, 0x119a,
1865 "Unable to verify login-state (%x/%x) for loop_id %x.\n",
1866 current_login_state, last_login_state,
1867 fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001868 rval = QLA_FUNCTION_FAILED;
Duane Grigsbyc0c462c2017-10-13 09:34:05 -07001869
1870 if (!fcport->query)
1871 goto gpd_error_out;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001872 }
1873
Arun Easi0eba25d2012-02-09 11:15:58 -08001874 if (fcport->loop_id == FC_NO_LOOP_ID ||
1875 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1876 memcmp(fcport->port_name, pd24->port_name, 8))) {
1877 /* We lost the device mid way. */
1878 rval = QLA_NOT_LOGGED_IN;
1879 goto gpd_error_out;
1880 }
1881
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001882 /* Names are little-endian. */
1883 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1884 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1885
1886 /* Get port_id of device. */
1887 fcport->d_id.b.domain = pd24->port_id[0];
1888 fcport->d_id.b.area = pd24->port_id[1];
1889 fcport->d_id.b.al_pa = pd24->port_id[2];
1890 fcport->d_id.b.rsvd_1 = 0;
1891
1892 /* If not target must be initiator or unknown type. */
1893 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1894 fcport->port_type = FCT_INITIATOR;
1895 else
1896 fcport->port_type = FCT_TARGET;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001897
1898 /* Passback COS information. */
1899 fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ?
1900 FC_COS_CLASS2 : FC_COS_CLASS3;
1901
1902 if (pd24->prli_svc_param_word_3[0] & BIT_7)
1903 fcport->flags |= FCF_CONF_COMP_SUPPORTED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001904 } else {
Arun Easi0eba25d2012-02-09 11:15:58 -08001905 uint64_t zero = 0;
1906
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001907 /* Check for logged in state. */
1908 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1909 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001910 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1911 "Unable to verify login-state (%x/%x) - "
1912 "portid=%02x%02x%02x.\n", pd->master_state,
1913 pd->slave_state, fcport->d_id.b.domain,
1914 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001915 rval = QLA_FUNCTION_FAILED;
1916 goto gpd_error_out;
1917 }
1918
Arun Easi0eba25d2012-02-09 11:15:58 -08001919 if (fcport->loop_id == FC_NO_LOOP_ID ||
1920 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1921 memcmp(fcport->port_name, pd->port_name, 8))) {
1922 /* We lost the device mid way. */
1923 rval = QLA_NOT_LOGGED_IN;
1924 goto gpd_error_out;
1925 }
1926
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001927 /* Names are little-endian. */
1928 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1929 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1930
1931 /* Get port_id of device. */
1932 fcport->d_id.b.domain = pd->port_id[0];
1933 fcport->d_id.b.area = pd->port_id[3];
1934 fcport->d_id.b.al_pa = pd->port_id[2];
1935 fcport->d_id.b.rsvd_1 = 0;
1936
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001937 /* If not target must be initiator or unknown type. */
1938 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1939 fcport->port_type = FCT_INITIATOR;
1940 else
1941 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001942
1943 /* Passback COS information. */
1944 fcport->supported_classes = (pd->options & BIT_4) ?
1945 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 }
1947
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948gpd_error_out:
1949 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
Duane Grigsbyedd05de2017-10-13 09:34:06 -07001950 fcport->query = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951
1952 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001953 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1954 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1955 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001957 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053,
1958 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 }
1960
1961 return rval;
1962}
1963
1964/*
1965 * qla2x00_get_firmware_state
1966 * Get adapter firmware state.
1967 *
1968 * Input:
1969 * ha = adapter block pointer.
1970 * dptr = pointer for firmware state.
1971 * TARGET_QUEUE_LOCK must be released.
1972 * ADAPTER_STATE_LOCK must be released.
1973 *
1974 * Returns:
1975 * qla2x00 local function return status code.
1976 *
1977 * Context:
1978 * Kernel context.
1979 */
1980int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001981qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982{
1983 int rval;
1984 mbx_cmd_t mc;
1985 mbx_cmd_t *mcp = &mc;
Sawan Chandak92d44082017-08-23 15:05:16 -07001986 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001988 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
1989 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001990
1991 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1992 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001993 if (IS_FWI2_CAPABLE(vha->hw))
Joe Carnucciob5a340d2014-09-25 05:16:48 -04001994 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001995 else
1996 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001997 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001998 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001999 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000
Harihara Kadayam4d4df192008-04-03 13:13:26 -07002001 /* Return firmware states. */
2002 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002003 if (IS_FWI2_CAPABLE(vha->hw)) {
2004 states[1] = mcp->mb[2];
Joe Carnuccioec891462016-07-06 11:14:26 -04002005 states[2] = mcp->mb[3]; /* SFP info */
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002006 states[3] = mcp->mb[4];
2007 states[4] = mcp->mb[5];
Joe Carnucciob5a340d2014-09-25 05:16:48 -04002008 states[5] = mcp->mb[6]; /* DPORT status */
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002009 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010
2011 if (rval != QLA_SUCCESS) {
2012 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002013 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014 } else {
Sawan Chandak92d44082017-08-23 15:05:16 -07002015 if (IS_QLA27XX(ha)) {
2016 if (mcp->mb[2] == 6 || mcp->mb[3] == 2)
2017 ql_dbg(ql_dbg_mbx, vha, 0x119e,
2018 "Invalid SFP/Validation Failed\n");
2019 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002020 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,
2021 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022 }
2023
2024 return rval;
2025}
2026
2027/*
2028 * qla2x00_get_port_name
2029 * Issue get port name mailbox command.
2030 * Returned name is in big endian format.
2031 *
2032 * Input:
2033 * ha = adapter block pointer.
2034 * loop_id = loop ID of device.
2035 * name = pointer for name.
2036 * TARGET_QUEUE_LOCK must be released.
2037 * ADAPTER_STATE_LOCK must be released.
2038 *
2039 * Returns:
2040 * qla2x00 local function return status code.
2041 *
2042 * Context:
2043 * Kernel context.
2044 */
2045int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002046qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002047 uint8_t opt)
2048{
2049 int rval;
2050 mbx_cmd_t mc;
2051 mbx_cmd_t *mcp = &mc;
2052
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002053 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057,
2054 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002055
2056 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002057 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002058 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002059 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002060 mcp->mb[1] = loop_id;
2061 mcp->mb[10] = opt;
2062 mcp->out_mb |= MBX_10;
2063 } else {
2064 mcp->mb[1] = loop_id << 8 | opt;
2065 }
2066
2067 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002068 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002069 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002070 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071
2072 if (rval != QLA_SUCCESS) {
2073 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002074 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075 } else {
2076 if (name != NULL) {
2077 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05002078 name[0] = MSB(mcp->mb[2]);
2079 name[1] = LSB(mcp->mb[2]);
2080 name[2] = MSB(mcp->mb[3]);
2081 name[3] = LSB(mcp->mb[3]);
2082 name[4] = MSB(mcp->mb[6]);
2083 name[5] = LSB(mcp->mb[6]);
2084 name[6] = MSB(mcp->mb[7]);
2085 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002086 }
2087
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002088 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059,
2089 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 }
2091
2092 return rval;
2093}
2094
2095/*
Joe Carnuccio61e1b262013-02-08 01:57:48 -05002096 * qla24xx_link_initialization
2097 * Issue link initialization mailbox command.
2098 *
2099 * Input:
2100 * ha = adapter block pointer.
2101 * TARGET_QUEUE_LOCK must be released.
2102 * ADAPTER_STATE_LOCK must be released.
2103 *
2104 * Returns:
2105 * qla2x00 local function return status code.
2106 *
2107 * Context:
2108 * Kernel context.
2109 */
2110int
2111qla24xx_link_initialize(scsi_qla_host_t *vha)
2112{
2113 int rval;
2114 mbx_cmd_t mc;
2115 mbx_cmd_t *mcp = &mc;
2116
2117 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152,
2118 "Entered %s.\n", __func__);
2119
2120 if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw))
2121 return QLA_FUNCTION_FAILED;
2122
2123 mcp->mb[0] = MBC_LINK_INITIALIZATION;
Joe Carnuccio5a5c27b2013-08-27 01:37:49 -04002124 mcp->mb[1] = BIT_4;
2125 if (vha->hw->operating_mode == LOOP)
2126 mcp->mb[1] |= BIT_6;
2127 else
2128 mcp->mb[1] |= BIT_5;
Joe Carnuccio61e1b262013-02-08 01:57:48 -05002129 mcp->mb[2] = 0;
2130 mcp->mb[3] = 0;
2131 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2132 mcp->in_mb = MBX_0;
2133 mcp->tov = MBX_TOV_SECONDS;
2134 mcp->flags = 0;
2135 rval = qla2x00_mailbox_command(vha, mcp);
2136
2137 if (rval != QLA_SUCCESS) {
2138 ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval);
2139 } else {
2140 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154,
2141 "Done %s.\n", __func__);
2142 }
2143
2144 return rval;
2145}
2146
2147/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 * qla2x00_lip_reset
2149 * Issue LIP reset mailbox command.
2150 *
2151 * Input:
2152 * ha = adapter block pointer.
2153 * TARGET_QUEUE_LOCK must be released.
2154 * ADAPTER_STATE_LOCK must be released.
2155 *
2156 * Returns:
2157 * qla2x00 local function return status code.
2158 *
2159 * Context:
2160 * Kernel context.
2161 */
2162int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002163qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002164{
2165 int rval;
2166 mbx_cmd_t mc;
2167 mbx_cmd_t *mcp = &mc;
2168
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002169 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a,
2170 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002172 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08002173 /* Logout across all FCFs. */
2174 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2175 mcp->mb[1] = BIT_1;
2176 mcp->mb[2] = 0;
2177 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2178 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002179 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Quinn Tran48acad02018-08-02 13:16:44 -07002180 if (N2N_TOPO(vha->hw))
2181 mcp->mb[1] = BIT_4; /* re-init */
2182 else
2183 mcp->mb[1] = BIT_6; /* LIP */
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002184 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002185 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002186 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002187 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002188 mcp->mb[0] = MBC_LIP_RESET;
2189 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002190 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002191 mcp->mb[1] = 0x00ff;
2192 mcp->mb[10] = 0;
2193 mcp->out_mb |= MBX_10;
2194 } else {
2195 mcp->mb[1] = 0xff00;
2196 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002197 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002198 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002200 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002201 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002203 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002204
2205 if (rval != QLA_SUCCESS) {
2206 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002207 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208 } else {
2209 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002210 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c,
2211 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212 }
2213
2214 return rval;
2215}
2216
2217/*
2218 * qla2x00_send_sns
2219 * Send SNS command.
2220 *
2221 * Input:
2222 * ha = adapter block pointer.
2223 * sns = pointer for command.
2224 * cmd_size = command size.
2225 * buf_size = response/command size.
2226 * TARGET_QUEUE_LOCK must be released.
2227 * ADAPTER_STATE_LOCK must be released.
2228 *
2229 * Returns:
2230 * qla2x00 local function return status code.
2231 *
2232 * Context:
2233 * Kernel context.
2234 */
2235int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002236qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237 uint16_t cmd_size, size_t buf_size)
2238{
2239 int rval;
2240 mbx_cmd_t mc;
2241 mbx_cmd_t *mcp = &mc;
2242
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002243 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d,
2244 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002246 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002247 "Retry cnt=%d ratov=%d total tov=%d.\n",
2248 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002249
2250 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
2251 mcp->mb[1] = cmd_size;
2252 mcp->mb[2] = MSW(sns_phys_address);
2253 mcp->mb[3] = LSW(sns_phys_address);
2254 mcp->mb[6] = MSW(MSD(sns_phys_address));
2255 mcp->mb[7] = LSW(MSD(sns_phys_address));
2256 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2257 mcp->in_mb = MBX_0|MBX_1;
2258 mcp->buf_size = buf_size;
2259 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002260 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
2261 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262
2263 if (rval != QLA_SUCCESS) {
2264 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002265 ql_dbg(ql_dbg_mbx, vha, 0x105f,
2266 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2267 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268 } else {
2269 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002270 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060,
2271 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272 }
2273
2274 return rval;
2275}
2276
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002277int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002278qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002279 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
2280{
2281 int rval;
2282
2283 struct logio_entry_24xx *lg;
2284 dma_addr_t lg_dma;
2285 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002286 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002287 struct req_que *req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002288
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002289 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061,
2290 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002291
Michael Hernandezd7459522016-12-12 14:40:07 -08002292 if (vha->vp_idx && vha->qpair)
2293 req = vha->qpair->req;
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002294 else
Michael Hernandezd7459522016-12-12 14:40:07 -08002295 req = ha->req_q_map[0];
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002296
Thomas Meyer08eb7f42017-09-21 08:15:26 +02002297 lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002298 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002299 ql_log(ql_log_warn, vha, 0x1062,
2300 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002301 return QLA_MEMORY_ALLOC_FAILED;
2302 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002303
2304 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2305 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002306 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002307 lg->nport_handle = cpu_to_le16(loop_id);
Bart Van Asschead950362015-07-09 07:24:08 -07002308 lg->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002309 if (opt & BIT_0)
Bart Van Asschead950362015-07-09 07:24:08 -07002310 lg->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07002311 if (opt & BIT_1)
Bart Van Asschead950362015-07-09 07:24:08 -07002312 lg->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002313 lg->port_id[0] = al_pa;
2314 lg->port_id[1] = area;
2315 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002316 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08002317 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2318 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002319 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002320 ql_dbg(ql_dbg_mbx, vha, 0x1063,
2321 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002322 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002323 ql_dbg(ql_dbg_mbx, vha, 0x1064,
2324 "Failed to complete IOCB -- error status (%x).\n",
2325 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002326 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002327 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002328 iop[0] = le32_to_cpu(lg->io_parameter[0]);
2329 iop[1] = le32_to_cpu(lg->io_parameter[1]);
2330
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002331 ql_dbg(ql_dbg_mbx, vha, 0x1065,
2332 "Failed to complete IOCB -- completion status (%x) "
2333 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
2334 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002335
2336 switch (iop[0]) {
2337 case LSC_SCODE_PORTID_USED:
2338 mb[0] = MBS_PORT_ID_USED;
2339 mb[1] = LSW(iop[1]);
2340 break;
2341 case LSC_SCODE_NPORT_USED:
2342 mb[0] = MBS_LOOP_ID_USED;
2343 break;
2344 case LSC_SCODE_NOLINK:
2345 case LSC_SCODE_NOIOCB:
2346 case LSC_SCODE_NOXCB:
2347 case LSC_SCODE_CMD_FAILED:
2348 case LSC_SCODE_NOFABRIC:
2349 case LSC_SCODE_FW_NOT_READY:
2350 case LSC_SCODE_NOT_LOGGED_IN:
2351 case LSC_SCODE_NOPCB:
2352 case LSC_SCODE_ELS_REJECT:
2353 case LSC_SCODE_CMD_PARAM_ERR:
2354 case LSC_SCODE_NONPORT:
2355 case LSC_SCODE_LOGGED_IN:
2356 case LSC_SCODE_NOFLOGI_ACC:
2357 default:
2358 mb[0] = MBS_COMMAND_ERROR;
2359 break;
2360 }
2361 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002362 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066,
2363 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002364
2365 iop[0] = le32_to_cpu(lg->io_parameter[0]);
2366
2367 mb[0] = MBS_COMMAND_COMPLETE;
2368 mb[1] = 0;
2369 if (iop[0] & BIT_4) {
2370 if (iop[0] & BIT_8)
2371 mb[1] |= BIT_1;
2372 } else
2373 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07002374
2375 /* Passback COS information. */
2376 mb[10] = 0;
2377 if (lg->io_parameter[7] || lg->io_parameter[8])
2378 mb[10] |= BIT_0; /* Class 2. */
2379 if (lg->io_parameter[9] || lg->io_parameter[10])
2380 mb[10] |= BIT_1; /* Class 3. */
Bart Van Asschead950362015-07-09 07:24:08 -07002381 if (lg->io_parameter[0] & cpu_to_le32(BIT_7))
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04002382 mb[10] |= BIT_7; /* Confirmed Completion
2383 * Allowed
2384 */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002385 }
2386
2387 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2388
2389 return rval;
2390}
2391
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392/*
2393 * qla2x00_login_fabric
2394 * Issue login fabric port mailbox command.
2395 *
2396 * Input:
2397 * ha = adapter block pointer.
2398 * loop_id = device loop ID.
2399 * domain = device domain.
2400 * area = device area.
2401 * al_pa = device AL_PA.
2402 * status = pointer for return status.
2403 * opt = command options.
2404 * TARGET_QUEUE_LOCK must be released.
2405 * ADAPTER_STATE_LOCK must be released.
2406 *
2407 * Returns:
2408 * qla2x00 local function return status code.
2409 *
2410 * Context:
2411 * Kernel context.
2412 */
2413int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002414qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002415 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
2416{
2417 int rval;
2418 mbx_cmd_t mc;
2419 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002420 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002422 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067,
2423 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424
2425 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
2426 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2427 if (HAS_EXTENDED_IDS(ha)) {
2428 mcp->mb[1] = loop_id;
2429 mcp->mb[10] = opt;
2430 mcp->out_mb |= MBX_10;
2431 } else {
2432 mcp->mb[1] = (loop_id << 8) | opt;
2433 }
2434 mcp->mb[2] = domain;
2435 mcp->mb[3] = area << 8 | al_pa;
2436
2437 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
2438 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2439 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002440 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441
2442 /* Return mailbox statuses. */
2443 if (mb != NULL) {
2444 mb[0] = mcp->mb[0];
2445 mb[1] = mcp->mb[1];
2446 mb[2] = mcp->mb[2];
2447 mb[6] = mcp->mb[6];
2448 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07002449 /* COS retrieved from Get-Port-Database mailbox command. */
2450 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451 }
2452
2453 if (rval != QLA_SUCCESS) {
2454 /* RLU tmp code: need to change main mailbox_command function to
2455 * return ok even when the mailbox completion value is not
2456 * SUCCESS. The caller needs to be responsible to interpret
2457 * the return values of this mailbox command if we're not
2458 * to change too much of the existing code.
2459 */
2460 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
2461 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
2462 mcp->mb[0] == 0x4006)
2463 rval = QLA_SUCCESS;
2464
2465 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002466 ql_dbg(ql_dbg_mbx, vha, 0x1068,
2467 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
2468 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002469 } else {
2470 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002471 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069,
2472 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473 }
2474
2475 return rval;
2476}
2477
2478/*
2479 * qla2x00_login_local_device
2480 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002481 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482 * Input:
2483 * ha = adapter block pointer.
2484 * loop_id = device loop ID.
2485 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002486 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487 * Returns:
2488 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002489 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490 * Context:
2491 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002492 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493 */
2494int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002495qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496 uint16_t *mb_ret, uint8_t opt)
2497{
2498 int rval;
2499 mbx_cmd_t mc;
2500 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002501 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002503 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a,
2504 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002505
Andrew Vasqueze4289242007-07-19 15:05:56 -07002506 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002507 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002508 fcport->d_id.b.domain, fcport->d_id.b.area,
2509 fcport->d_id.b.al_pa, mb_ret, opt);
2510
Linus Torvalds1da177e2005-04-16 15:20:36 -07002511 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
2512 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002513 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514 else
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002515 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516 mcp->mb[2] = opt;
2517 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2518 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
2519 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2520 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002521 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522
2523 /* Return mailbox statuses. */
2524 if (mb_ret != NULL) {
2525 mb_ret[0] = mcp->mb[0];
2526 mb_ret[1] = mcp->mb[1];
2527 mb_ret[6] = mcp->mb[6];
2528 mb_ret[7] = mcp->mb[7];
2529 }
2530
2531 if (rval != QLA_SUCCESS) {
2532 /* AV tmp code: need to change main mailbox_command function to
2533 * return ok even when the mailbox completion value is not
2534 * SUCCESS. The caller needs to be responsible to interpret
2535 * the return values of this mailbox command if we're not
2536 * to change too much of the existing code.
2537 */
2538 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
2539 rval = QLA_SUCCESS;
2540
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002541 ql_dbg(ql_dbg_mbx, vha, 0x106b,
2542 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
2543 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002544 } else {
2545 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002546 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c,
2547 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002548 }
2549
2550 return (rval);
2551}
2552
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002553int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002554qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002555 uint8_t area, uint8_t al_pa)
2556{
2557 int rval;
2558 struct logio_entry_24xx *lg;
2559 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002560 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002561 struct req_que *req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002562
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002563 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d,
2564 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002565
Thomas Meyer08eb7f42017-09-21 08:15:26 +02002566 lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002567 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002568 ql_log(ql_log_warn, vha, 0x106e,
2569 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002570 return QLA_MEMORY_ALLOC_FAILED;
2571 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002572
Michael Hernandezd7459522016-12-12 14:40:07 -08002573 req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002574 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2575 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002576 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002577 lg->nport_handle = cpu_to_le16(loop_id);
2578 lg->control_flags =
Bart Van Asschead950362015-07-09 07:24:08 -07002579 cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
Andrew Vasquezc8d66912011-03-30 11:46:21 -07002580 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002581 lg->port_id[0] = al_pa;
2582 lg->port_id[1] = area;
2583 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002584 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08002585 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2586 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002587 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002588 ql_dbg(ql_dbg_mbx, vha, 0x106f,
2589 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002590 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002591 ql_dbg(ql_dbg_mbx, vha, 0x1070,
2592 "Failed to complete IOCB -- error status (%x).\n",
2593 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002594 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002595 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002596 ql_dbg(ql_dbg_mbx, vha, 0x1071,
2597 "Failed to complete IOCB -- completion status (%x) "
2598 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002599 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002600 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002601 } else {
2602 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002603 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072,
2604 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002605 }
2606
2607 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2608
2609 return rval;
2610}
2611
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612/*
2613 * qla2x00_fabric_logout
2614 * Issue logout fabric port mailbox command.
2615 *
2616 * Input:
2617 * ha = adapter block pointer.
2618 * loop_id = device loop ID.
2619 * TARGET_QUEUE_LOCK must be released.
2620 * ADAPTER_STATE_LOCK must be released.
2621 *
2622 * Returns:
2623 * qla2x00 local function return status code.
2624 *
2625 * Context:
2626 * Kernel context.
2627 */
2628int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002629qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002630 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631{
2632 int rval;
2633 mbx_cmd_t mc;
2634 mbx_cmd_t *mcp = &mc;
2635
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002636 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073,
2637 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638
2639 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
2640 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002641 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002642 mcp->mb[1] = loop_id;
2643 mcp->mb[10] = 0;
2644 mcp->out_mb |= MBX_10;
2645 } else {
2646 mcp->mb[1] = loop_id << 8;
2647 }
2648
2649 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002650 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002651 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002652 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002653
2654 if (rval != QLA_SUCCESS) {
2655 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002656 ql_dbg(ql_dbg_mbx, vha, 0x1074,
2657 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658 } else {
2659 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002660 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075,
2661 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 }
2663
2664 return rval;
2665}
2666
2667/*
2668 * qla2x00_full_login_lip
2669 * Issue full login LIP mailbox command.
2670 *
2671 * Input:
2672 * ha = adapter block pointer.
2673 * TARGET_QUEUE_LOCK must be released.
2674 * ADAPTER_STATE_LOCK must be released.
2675 *
2676 * Returns:
2677 * qla2x00 local function return status code.
2678 *
2679 * Context:
2680 * Kernel context.
2681 */
2682int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002683qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002684{
2685 int rval;
2686 mbx_cmd_t mc;
2687 mbx_cmd_t *mcp = &mc;
2688
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002689 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076,
2690 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691
2692 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002693 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002694 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002695 mcp->mb[3] = 0;
2696 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2697 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002698 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002700 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701
2702 if (rval != QLA_SUCCESS) {
2703 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002704 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705 } else {
2706 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002707 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078,
2708 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709 }
2710
2711 return rval;
2712}
2713
2714/*
2715 * qla2x00_get_id_list
2716 *
2717 * Input:
2718 * ha = adapter block pointer.
2719 *
2720 * Returns:
2721 * qla2x00 local function return status code.
2722 *
2723 * Context:
2724 * Kernel context.
2725 */
2726int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002727qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 uint16_t *entries)
2729{
2730 int rval;
2731 mbx_cmd_t mc;
2732 mbx_cmd_t *mcp = &mc;
2733
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002734 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079,
2735 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002736
2737 if (id_list == NULL)
2738 return QLA_FUNCTION_FAILED;
2739
2740 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002741 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002742 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002743 mcp->mb[2] = MSW(id_list_dma);
2744 mcp->mb[3] = LSW(id_list_dma);
2745 mcp->mb[6] = MSW(MSD(id_list_dma));
2746 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002747 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002748 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002749 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002750 } else {
2751 mcp->mb[1] = MSW(id_list_dma);
2752 mcp->mb[2] = LSW(id_list_dma);
2753 mcp->mb[3] = MSW(MSD(id_list_dma));
2754 mcp->mb[6] = LSW(MSD(id_list_dma));
2755 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2756 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002757 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002758 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002760 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002761
2762 if (rval != QLA_SUCCESS) {
2763 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002764 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002765 } else {
2766 *entries = mcp->mb[1];
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002767 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b,
2768 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002769 }
2770
2771 return rval;
2772}
2773
2774/*
2775 * qla2x00_get_resource_cnts
2776 * Get current firmware resource counts.
2777 *
2778 * Input:
2779 * ha = adapter block pointer.
2780 *
2781 * Returns:
2782 * qla2x00 local function return status code.
2783 *
2784 * Context:
2785 * Kernel context.
2786 */
2787int
Quinn Tran03e8c682015-12-17 14:56:59 -05002788qla2x00_get_resource_cnts(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002789{
Quinn Tran03e8c682015-12-17 14:56:59 -05002790 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002791 int rval;
2792 mbx_cmd_t mc;
2793 mbx_cmd_t *mcp = &mc;
2794
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002795 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c,
2796 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797
2798 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2799 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002800 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 -05002801 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) || IS_QLA27XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002802 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002803 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002804 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002805 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002806
2807 if (rval != QLA_SUCCESS) {
2808 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002809 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2810 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002812 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002813 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2814 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2815 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2816 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817
Quinn Tran03e8c682015-12-17 14:56:59 -05002818 ha->orig_fw_tgt_xcb_count = mcp->mb[1];
2819 ha->cur_fw_tgt_xcb_count = mcp->mb[2];
2820 ha->cur_fw_xcb_count = mcp->mb[3];
2821 ha->orig_fw_xcb_count = mcp->mb[6];
2822 ha->cur_fw_iocb_count = mcp->mb[7];
2823 ha->orig_fw_iocb_count = mcp->mb[10];
2824 if (ha->flags.npiv_supported)
2825 ha->max_npiv_vports = mcp->mb[11];
2826 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
2827 ha->fw_max_fcf_count = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002828 }
2829
2830 return (rval);
2831}
2832
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833/*
2834 * qla2x00_get_fcal_position_map
2835 * Get FCAL (LILP) position map using mailbox command
2836 *
2837 * Input:
2838 * ha = adapter state pointer.
2839 * pos_map = buffer pointer (can be NULL).
2840 *
2841 * Returns:
2842 * qla2x00 local function return status code.
2843 *
2844 * Context:
2845 * Kernel context.
2846 */
2847int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002848qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849{
2850 int rval;
2851 mbx_cmd_t mc;
2852 mbx_cmd_t *mcp = &mc;
2853 char *pmap;
2854 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002855 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002857 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f,
2858 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002859
Thomas Meyer08eb7f42017-09-21 08:15:26 +02002860 pmap = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002862 ql_log(ql_log_warn, vha, 0x1080,
2863 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002864 return QLA_MEMORY_ALLOC_FAILED;
2865 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866
2867 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2868 mcp->mb[2] = MSW(pmap_dma);
2869 mcp->mb[3] = LSW(pmap_dma);
2870 mcp->mb[6] = MSW(MSD(pmap_dma));
2871 mcp->mb[7] = LSW(MSD(pmap_dma));
2872 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2873 mcp->in_mb = MBX_1|MBX_0;
2874 mcp->buf_size = FCAL_MAP_SIZE;
2875 mcp->flags = MBX_DMA_IN;
2876 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002877 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002878
2879 if (rval == QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002880 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002881 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2882 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2883 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2884 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885
2886 if (pos_map)
2887 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2888 }
2889 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2890
2891 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002892 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002893 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002894 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083,
2895 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896 }
2897
2898 return rval;
2899}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002900
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002901/*
2902 * qla2x00_get_link_status
2903 *
2904 * Input:
2905 * ha = adapter block pointer.
2906 * loop_id = device loop ID.
2907 * ret_buf = pointer to link status return buffer.
2908 *
2909 * Returns:
2910 * 0 = success.
2911 * BIT_0 = mem alloc error.
2912 * BIT_1 = mailbox error.
2913 */
2914int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002915qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002916 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002917{
2918 int rval;
2919 mbx_cmd_t mc;
2920 mbx_cmd_t *mcp = &mc;
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04002921 uint32_t *iter = (void *)stats;
2922 ushort dwords = offsetof(typeof(*stats), link_up_cnt)/sizeof(*iter);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002923 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002924
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002925 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084,
2926 "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002927
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002928 mcp->mb[0] = MBC_GET_LINK_STATUS;
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04002929 mcp->mb[2] = MSW(LSD(stats_dma));
2930 mcp->mb[3] = LSW(LSD(stats_dma));
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002931 mcp->mb[6] = MSW(MSD(stats_dma));
2932 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002933 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2934 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002935 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002936 mcp->mb[1] = loop_id;
2937 mcp->mb[4] = 0;
2938 mcp->mb[10] = 0;
2939 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2940 mcp->in_mb |= MBX_1;
2941 } else if (HAS_EXTENDED_IDS(ha)) {
2942 mcp->mb[1] = loop_id;
2943 mcp->mb[10] = 0;
2944 mcp->out_mb |= MBX_10|MBX_1;
2945 } else {
2946 mcp->mb[1] = loop_id << 8;
2947 mcp->out_mb |= MBX_1;
2948 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002949 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002950 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002951 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002952
2953 if (rval == QLA_SUCCESS) {
2954 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002955 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2956 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002957 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002958 } else {
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04002959 /* Re-endianize - firmware data is le32. */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002960 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086,
2961 "Done %s.\n", __func__);
Joe Carnuccioda08ef52016-01-27 12:03:34 -05002962 for ( ; dwords--; iter++)
2963 le32_to_cpus(iter);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002964 }
2965 } else {
2966 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002967 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002968 }
2969
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002970 return rval;
2971}
2972
2973int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002974qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Quinn Tran15f30a52017-03-15 09:48:52 -07002975 dma_addr_t stats_dma, uint16_t options)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002976{
2977 int rval;
2978 mbx_cmd_t mc;
2979 mbx_cmd_t *mcp = &mc;
Joe Carnuccioda08ef52016-01-27 12:03:34 -05002980 uint32_t *iter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002981
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002982 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,
2983 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002984
Quinn Tran15f30a52017-03-15 09:48:52 -07002985 memset(&mc, 0, sizeof(mc));
2986 mc.mb[0] = MBC_GET_LINK_PRIV_STATS;
2987 mc.mb[2] = MSW(stats_dma);
2988 mc.mb[3] = LSW(stats_dma);
2989 mc.mb[6] = MSW(MSD(stats_dma));
2990 mc.mb[7] = LSW(MSD(stats_dma));
2991 mc.mb[8] = sizeof(struct link_statistics) / 4;
2992 mc.mb[9] = cpu_to_le16(vha->vp_idx);
2993 mc.mb[10] = cpu_to_le16(options);
2994
2995 rval = qla24xx_send_mb_cmd(vha, &mc);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002996
2997 if (rval == QLA_SUCCESS) {
2998 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002999 ql_dbg(ql_dbg_mbx, vha, 0x1089,
3000 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08003001 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003002 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003003 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a,
3004 "Done %s.\n", __func__);
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04003005 /* Re-endianize - firmware data is le32. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08003006 dwords = sizeof(struct link_statistics) / 4;
Joe Carnuccioda08ef52016-01-27 12:03:34 -05003007 iter = &stats->link_fail_cnt;
3008 for ( ; dwords--; iter++)
3009 le32_to_cpus(iter);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003010 }
3011 } else {
3012 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003013 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003014 }
3015
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003016 return rval;
3017}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003018
3019int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003020qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003021{
3022 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003023 unsigned long flags = 0;
3024
3025 struct abort_entry_24xx *abt;
3026 dma_addr_t abt_dma;
3027 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003028 fc_port_t *fcport = sp->fcport;
3029 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003030 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07003031 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003032
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003033 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,
3034 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003035
Michael Hernandezd7459522016-12-12 14:40:07 -08003036 if (vha->flags.qpairs_available && sp->qpair)
3037 req = sp->qpair->req;
3038
Armen Baloyan4440e462014-02-26 04:15:18 -05003039 if (ql2xasynctmfenable)
3040 return qla24xx_async_abort_command(sp);
3041
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003042 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05003043 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003044 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003045 break;
3046 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003047 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05003048 if (handle == req->num_outstanding_cmds) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003049 /* Command not found. */
3050 return QLA_FUNCTION_FAILED;
3051 }
3052
Thomas Meyer08eb7f42017-09-21 08:15:26 +02003053 abt = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003054 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003055 ql_log(ql_log_warn, vha, 0x108d,
3056 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003057 return QLA_MEMORY_ALLOC_FAILED;
3058 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003059
3060 abt->entry_type = ABORT_IOCB_TYPE;
3061 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003062 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003063 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07003064 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003065 abt->port_id[0] = fcport->d_id.b.al_pa;
3066 abt->port_id[1] = fcport->d_id.b.area;
3067 abt->port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04003068 abt->vp_index = fcport->vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003069
3070 abt->req_que_no = cpu_to_le16(req->id);
3071
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003072 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003073 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003074 ql_dbg(ql_dbg_mbx, vha, 0x108e,
3075 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003076 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003077 ql_dbg(ql_dbg_mbx, vha, 0x108f,
3078 "Failed to complete IOCB -- error status (%x).\n",
3079 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003080 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07003081 } else if (abt->nport_handle != cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003082 ql_dbg(ql_dbg_mbx, vha, 0x1090,
3083 "Failed to complete IOCB -- completion status (%x).\n",
3084 le16_to_cpu(abt->nport_handle));
Chad Dupuisf934c9d2014-04-11 16:54:31 -04003085 if (abt->nport_handle == CS_IOCB_ERROR)
3086 rval = QLA_FUNCTION_PARAMETER_ERROR;
3087 else
3088 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003089 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003090 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
3091 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003092 }
3093
3094 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
3095
3096 return rval;
3097}
3098
3099struct tsk_mgmt_cmd {
3100 union {
3101 struct tsk_mgmt_entry tsk;
3102 struct sts_entry_24xx sts;
3103 } p;
3104};
3105
Andrew Vasquez523ec772008-04-03 13:13:24 -07003106static int
3107__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02003108 uint64_t l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003109{
Andrew Vasquez523ec772008-04-03 13:13:24 -07003110 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003111 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003112 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003113 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003114 scsi_qla_host_t *vha;
3115 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003116 struct req_que *req;
3117 struct rsp_que *rsp;
Michael Hernandezd7459522016-12-12 14:40:07 -08003118 struct qla_qpair *qpair;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003119
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003120 vha = fcport->vha;
3121 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003122 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003123
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003124 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092,
3125 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003126
Michael Hernandezd7459522016-12-12 14:40:07 -08003127 if (vha->vp_idx && vha->qpair) {
3128 /* NPIV port */
3129 qpair = vha->qpair;
3130 rsp = qpair->rsp;
3131 req = qpair->req;
3132 } else {
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07003133 rsp = req->rsp;
Michael Hernandezd7459522016-12-12 14:40:07 -08003134 }
3135
Thomas Meyer08eb7f42017-09-21 08:15:26 +02003136 tsk = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003137 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003138 ql_log(ql_log_warn, vha, 0x1093,
3139 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003140 return QLA_MEMORY_ALLOC_FAILED;
3141 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003142
3143 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
3144 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003145 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003146 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08003147 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07003148 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003149 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
3150 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
3151 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04003152 tsk->p.tsk.vp_index = fcport->vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07003153 if (type == TCF_LUN_RESET) {
3154 int_to_scsilun(l, &tsk->p.tsk.lun);
3155 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
3156 sizeof(tsk->p.tsk.lun));
3157 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003158
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003159 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003160 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003161 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003162 ql_dbg(ql_dbg_mbx, vha, 0x1094,
3163 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003164 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003165 ql_dbg(ql_dbg_mbx, vha, 0x1095,
3166 "Failed to complete IOCB -- error status (%x).\n",
3167 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003168 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07003169 } else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003170 ql_dbg(ql_dbg_mbx, vha, 0x1096,
3171 "Failed to complete IOCB -- completion status (%x).\n",
3172 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003173 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08003174 } else if (le16_to_cpu(sts->scsi_status) &
3175 SS_RESPONSE_INFO_LEN_VALID) {
3176 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003177 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003178 "Ignoring inconsistent data length -- not enough "
3179 "response info (%d).\n",
3180 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08003181 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003182 ql_dbg(ql_dbg_mbx, vha, 0x1098,
3183 "Failed to complete IOCB -- response (%x).\n",
3184 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08003185 rval = QLA_FUNCTION_FAILED;
3186 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003187 }
3188
3189 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003190 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07003191 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
3192 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003193 ql_dbg(ql_dbg_mbx, vha, 0x1099,
3194 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003195 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003196 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a,
3197 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003198 }
3199
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003200 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003201
3202 return rval;
3203}
3204
Andrew Vasquez523ec772008-04-03 13:13:24 -07003205int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02003206qla24xx_abort_target(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07003207{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07003208 struct qla_hw_data *ha = fcport->vha->hw;
3209
3210 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
3211 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
3212
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003213 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07003214}
3215
3216int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02003217qla24xx_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07003218{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07003219 struct qla_hw_data *ha = fcport->vha->hw;
3220
3221 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
3222 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
3223
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003224 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07003225}
3226
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003227int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003228qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003229{
3230 int rval;
3231 mbx_cmd_t mc;
3232 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003233 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003234
Andrew Vasquez68af0812008-05-12 22:21:13 -07003235 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003236 return QLA_FUNCTION_FAILED;
3237
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003238 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b,
3239 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003240
3241 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
3242 mcp->out_mb = MBX_0;
3243 mcp->in_mb = MBX_0;
3244 mcp->tov = 5;
3245 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003246 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003247
3248 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003249 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003250 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003251 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d,
3252 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003253 }
3254
3255 return rval;
3256}
3257
Joe Carnucciodb64e932013-10-30 03:38:18 -04003258int
3259qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data)
3260{
3261 int rval;
3262 mbx_cmd_t mc;
3263 mbx_cmd_t *mcp = &mc;
3264
Joe Carnucciof299c7c2015-08-04 13:37:51 -04003265 if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
3266 !IS_QLA27XX(vha->hw))
Joe Carnucciodb64e932013-10-30 03:38:18 -04003267 return QLA_FUNCTION_FAILED;
3268
3269 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182,
3270 "Entered %s.\n", __func__);
3271
3272 mcp->mb[0] = MBC_WRITE_SERDES;
3273 mcp->mb[1] = addr;
Andrew Vasquez064135e2015-04-09 15:00:02 -04003274 if (IS_QLA2031(vha->hw))
3275 mcp->mb[2] = data & 0xff;
3276 else
3277 mcp->mb[2] = data;
3278
Joe Carnucciodb64e932013-10-30 03:38:18 -04003279 mcp->mb[3] = 0;
3280 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3281 mcp->in_mb = MBX_0;
3282 mcp->tov = MBX_TOV_SECONDS;
3283 mcp->flags = 0;
3284 rval = qla2x00_mailbox_command(vha, mcp);
3285
3286 if (rval != QLA_SUCCESS) {
3287 ql_dbg(ql_dbg_mbx, vha, 0x1183,
3288 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3289 } else {
3290 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184,
3291 "Done %s.\n", __func__);
3292 }
3293
3294 return rval;
3295}
3296
3297int
3298qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)
3299{
3300 int rval;
3301 mbx_cmd_t mc;
3302 mbx_cmd_t *mcp = &mc;
3303
Joe Carnucciof299c7c2015-08-04 13:37:51 -04003304 if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
3305 !IS_QLA27XX(vha->hw))
Joe Carnucciodb64e932013-10-30 03:38:18 -04003306 return QLA_FUNCTION_FAILED;
3307
3308 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185,
3309 "Entered %s.\n", __func__);
3310
3311 mcp->mb[0] = MBC_READ_SERDES;
3312 mcp->mb[1] = addr;
3313 mcp->mb[3] = 0;
3314 mcp->out_mb = MBX_3|MBX_1|MBX_0;
3315 mcp->in_mb = MBX_1|MBX_0;
3316 mcp->tov = MBX_TOV_SECONDS;
3317 mcp->flags = 0;
3318 rval = qla2x00_mailbox_command(vha, mcp);
3319
Andrew Vasquez064135e2015-04-09 15:00:02 -04003320 if (IS_QLA2031(vha->hw))
3321 *data = mcp->mb[1] & 0xff;
3322 else
3323 *data = mcp->mb[1];
Joe Carnucciodb64e932013-10-30 03:38:18 -04003324
3325 if (rval != QLA_SUCCESS) {
3326 ql_dbg(ql_dbg_mbx, vha, 0x1186,
3327 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3328 } else {
3329 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187,
3330 "Done %s.\n", __func__);
3331 }
3332
3333 return rval;
3334}
3335
Joe Carnuccioe8887c52014-04-11 16:54:17 -04003336int
3337qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)
3338{
3339 int rval;
3340 mbx_cmd_t mc;
3341 mbx_cmd_t *mcp = &mc;
3342
3343 if (!IS_QLA8044(vha->hw))
3344 return QLA_FUNCTION_FAILED;
3345
Quinn Tran83548fe2017-06-02 09:12:01 -07003346 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x11a0,
Joe Carnuccioe8887c52014-04-11 16:54:17 -04003347 "Entered %s.\n", __func__);
3348
3349 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3350 mcp->mb[1] = HCS_WRITE_SERDES;
3351 mcp->mb[3] = LSW(addr);
3352 mcp->mb[4] = MSW(addr);
3353 mcp->mb[5] = LSW(data);
3354 mcp->mb[6] = MSW(data);
3355 mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
3356 mcp->in_mb = MBX_0;
3357 mcp->tov = MBX_TOV_SECONDS;
3358 mcp->flags = 0;
3359 rval = qla2x00_mailbox_command(vha, mcp);
3360
3361 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07003362 ql_dbg(ql_dbg_mbx, vha, 0x11a1,
Joe Carnuccioe8887c52014-04-11 16:54:17 -04003363 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3364 } else {
3365 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188,
3366 "Done %s.\n", __func__);
3367 }
3368
3369 return rval;
3370}
3371
3372int
3373qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
3374{
3375 int rval;
3376 mbx_cmd_t mc;
3377 mbx_cmd_t *mcp = &mc;
3378
3379 if (!IS_QLA8044(vha->hw))
3380 return QLA_FUNCTION_FAILED;
3381
3382 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189,
3383 "Entered %s.\n", __func__);
3384
3385 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3386 mcp->mb[1] = HCS_READ_SERDES;
3387 mcp->mb[3] = LSW(addr);
3388 mcp->mb[4] = MSW(addr);
3389 mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0;
3390 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3391 mcp->tov = MBX_TOV_SECONDS;
3392 mcp->flags = 0;
3393 rval = qla2x00_mailbox_command(vha, mcp);
3394
3395 *data = mcp->mb[2] << 16 | mcp->mb[1];
3396
3397 if (rval != QLA_SUCCESS) {
3398 ql_dbg(ql_dbg_mbx, vha, 0x118a,
3399 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3400 } else {
3401 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b,
3402 "Done %s.\n", __func__);
3403 }
3404
3405 return rval;
3406}
3407
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003408/**
3409 * qla2x00_set_serdes_params() -
Bart Van Assche2db62282018-01-23 16:33:51 -08003410 * @vha: HA context
3411 * @sw_em_1g:
3412 * @sw_em_2g:
3413 * @sw_em_4g:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003414 *
3415 * Returns
3416 */
3417int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003418qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003419 uint16_t sw_em_2g, uint16_t sw_em_4g)
3420{
3421 int rval;
3422 mbx_cmd_t mc;
3423 mbx_cmd_t *mcp = &mc;
3424
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003425 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e,
3426 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003427
3428 mcp->mb[0] = MBC_SERDES_PARAMS;
3429 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08003430 mcp->mb[2] = sw_em_1g | BIT_15;
3431 mcp->mb[3] = sw_em_2g | BIT_15;
3432 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003433 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3434 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003435 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003436 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003437 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003438
3439 if (rval != QLA_SUCCESS) {
3440 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003441 ql_dbg(ql_dbg_mbx, vha, 0x109f,
3442 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003443 } else {
3444 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003445 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0,
3446 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003447 }
3448
3449 return rval;
3450}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003451
3452int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003453qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003454{
3455 int rval;
3456 mbx_cmd_t mc;
3457 mbx_cmd_t *mcp = &mc;
3458
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003459 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003460 return QLA_FUNCTION_FAILED;
3461
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003462 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1,
3463 "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003464
3465 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08003466 mcp->mb[1] = 0;
3467 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003468 mcp->in_mb = MBX_0;
3469 mcp->tov = 5;
3470 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003471 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003472
3473 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003474 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07003475 if (mcp->mb[0] == MBS_INVALID_COMMAND)
3476 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003477 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003478 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3,
3479 "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003480 }
3481
3482 return rval;
3483}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003484
3485int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003486qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003487 uint16_t buffers)
3488{
3489 int rval;
3490 mbx_cmd_t mc;
3491 mbx_cmd_t *mcp = &mc;
3492
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003493 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4,
3494 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003495
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003496 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003497 return QLA_FUNCTION_FAILED;
3498
Andrew Vasquez85880802009-12-15 21:29:46 -08003499 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3500 return QLA_FUNCTION_FAILED;
3501
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003502 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003503 mcp->mb[1] = TC_EFT_ENABLE;
3504 mcp->mb[2] = LSW(eft_dma);
3505 mcp->mb[3] = MSW(eft_dma);
3506 mcp->mb[4] = LSW(MSD(eft_dma));
3507 mcp->mb[5] = MSW(MSD(eft_dma));
3508 mcp->mb[6] = buffers;
3509 mcp->mb[7] = TC_AEN_DISABLE;
3510 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 -07003511 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003512 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003513 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003514 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003515 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003516 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
3517 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3518 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003519 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003520 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6,
3521 "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003522 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003523
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003524 return rval;
3525}
3526
3527int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003528qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003529{
3530 int rval;
3531 mbx_cmd_t mc;
3532 mbx_cmd_t *mcp = &mc;
3533
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003534 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7,
3535 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003536
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003537 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003538 return QLA_FUNCTION_FAILED;
3539
Andrew Vasquez85880802009-12-15 21:29:46 -08003540 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3541 return QLA_FUNCTION_FAILED;
3542
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003543 mcp->mb[0] = MBC_TRACE_CONTROL;
3544 mcp->mb[1] = TC_EFT_DISABLE;
3545 mcp->out_mb = MBX_1|MBX_0;
3546 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003547 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003548 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003549 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003550 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003551 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
3552 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3553 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003554 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003555 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9,
3556 "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003557 }
3558
3559 return rval;
3560}
3561
Andrew Vasquez88729e52006-06-23 16:10:50 -07003562int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003563qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003564 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
3565{
3566 int rval;
3567 mbx_cmd_t mc;
3568 mbx_cmd_t *mcp = &mc;
3569
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003570 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa,
3571 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003572
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003573 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
Chad Dupuisf73cb692014-02-26 04:15:06 -05003574 !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003575 return QLA_FUNCTION_FAILED;
3576
Andrew Vasquez85880802009-12-15 21:29:46 -08003577 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3578 return QLA_FUNCTION_FAILED;
3579
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003580 mcp->mb[0] = MBC_TRACE_CONTROL;
3581 mcp->mb[1] = TC_FCE_ENABLE;
3582 mcp->mb[2] = LSW(fce_dma);
3583 mcp->mb[3] = MSW(fce_dma);
3584 mcp->mb[4] = LSW(MSD(fce_dma));
3585 mcp->mb[5] = MSW(MSD(fce_dma));
3586 mcp->mb[6] = buffers;
3587 mcp->mb[7] = TC_AEN_DISABLE;
3588 mcp->mb[8] = 0;
3589 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
3590 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
3591 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3592 MBX_1|MBX_0;
3593 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003594 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003595 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003596 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003597 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003598 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
3599 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3600 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003601 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003602 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac,
3603 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003604
3605 if (mb)
3606 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
3607 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07003608 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003609 }
3610
3611 return rval;
3612}
3613
3614int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003615qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003616{
3617 int rval;
3618 mbx_cmd_t mc;
3619 mbx_cmd_t *mcp = &mc;
3620
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003621 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad,
3622 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003623
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003624 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003625 return QLA_FUNCTION_FAILED;
3626
Andrew Vasquez85880802009-12-15 21:29:46 -08003627 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3628 return QLA_FUNCTION_FAILED;
3629
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003630 mcp->mb[0] = MBC_TRACE_CONTROL;
3631 mcp->mb[1] = TC_FCE_DISABLE;
3632 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
3633 mcp->out_mb = MBX_2|MBX_1|MBX_0;
3634 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3635 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003636 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003637 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003638 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003639 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003640 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
3641 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3642 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003643 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003644 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af,
3645 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003646
3647 if (wr)
3648 *wr = (uint64_t) mcp->mb[5] << 48 |
3649 (uint64_t) mcp->mb[4] << 32 |
3650 (uint64_t) mcp->mb[3] << 16 |
3651 (uint64_t) mcp->mb[2];
3652 if (rd)
3653 *rd = (uint64_t) mcp->mb[9] << 48 |
3654 (uint64_t) mcp->mb[8] << 32 |
3655 (uint64_t) mcp->mb[7] << 16 |
3656 (uint64_t) mcp->mb[6];
3657 }
3658
3659 return rval;
3660}
3661
3662int
Giridhar Malavali6e980162010-03-19 17:03:58 -07003663qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
3664 uint16_t *port_speed, uint16_t *mb)
3665{
3666 int rval;
3667 mbx_cmd_t mc;
3668 mbx_cmd_t *mcp = &mc;
3669
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003670 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0,
3671 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003672
Giridhar Malavali6e980162010-03-19 17:03:58 -07003673 if (!IS_IIDMA_CAPABLE(vha->hw))
3674 return QLA_FUNCTION_FAILED;
3675
Giridhar Malavali6e980162010-03-19 17:03:58 -07003676 mcp->mb[0] = MBC_PORT_PARAMS;
3677 mcp->mb[1] = loop_id;
3678 mcp->mb[2] = mcp->mb[3] = 0;
3679 mcp->mb[9] = vha->vp_idx;
3680 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3681 mcp->in_mb = MBX_3|MBX_1|MBX_0;
3682 mcp->tov = MBX_TOV_SECONDS;
3683 mcp->flags = 0;
3684 rval = qla2x00_mailbox_command(vha, mcp);
3685
3686 /* Return mailbox statuses. */
3687 if (mb != NULL) {
3688 mb[0] = mcp->mb[0];
3689 mb[1] = mcp->mb[1];
3690 mb[3] = mcp->mb[3];
3691 }
3692
3693 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003694 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003695 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003696 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2,
3697 "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003698 if (port_speed)
3699 *port_speed = mcp->mb[3];
3700 }
3701
3702 return rval;
3703}
3704
3705int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003706qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003707 uint16_t port_speed, uint16_t *mb)
3708{
3709 int rval;
3710 mbx_cmd_t mc;
3711 mbx_cmd_t *mcp = &mc;
3712
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003713 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3,
3714 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003715
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003716 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003717 return QLA_FUNCTION_FAILED;
3718
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003719 mcp->mb[0] = MBC_PORT_PARAMS;
3720 mcp->mb[1] = loop_id;
3721 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003722 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07003723 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
3724 else
3725 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
3726 mcp->mb[9] = vha->vp_idx;
3727 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3728 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003729 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003730 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003731 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003732
3733 /* Return mailbox statuses. */
3734 if (mb != NULL) {
3735 mb[0] = mcp->mb[0];
3736 mb[1] = mcp->mb[1];
3737 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003738 }
3739
3740 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003741 ql_dbg(ql_dbg_mbx, vha, 0x10b4,
3742 "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003743 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003744 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5,
3745 "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003746 }
3747
3748 return rval;
3749}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003750
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003751void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003752qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003753 struct vp_rpt_id_entry_24xx *rptid_entry)
3754{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003755 struct qla_hw_data *ha = vha->hw;
Quinn Tran41dc5292017-01-19 22:28:03 -08003756 scsi_qla_host_t *vp = NULL;
Arun Easifeafb7b2010-09-03 14:57:00 -07003757 unsigned long flags;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003758 int found;
Quinn Tran482c9dc2017-03-15 09:48:54 -07003759 port_id_t id;
Quinn Tran9cd883f2017-12-28 12:33:24 -08003760 struct fc_port *fcport;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003761
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003762 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
3763 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003764
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003765 if (rptid_entry->entry_status != 0)
3766 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003767
Quinn Tran482c9dc2017-03-15 09:48:54 -07003768 id.b.domain = rptid_entry->port_id[2];
3769 id.b.area = rptid_entry->port_id[1];
3770 id.b.al_pa = rptid_entry->port_id[0];
3771 id.b.rsvd_1 = 0;
Darren Trapp1763c1f2018-03-20 23:09:34 -07003772 ha->flags.n2n_ae = 0;
Quinn Tran482c9dc2017-03-15 09:48:54 -07003773
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003774 if (rptid_entry->format == 0) {
Quinn Tran41dc5292017-01-19 22:28:03 -08003775 /* loop */
Quinn Tranec7193e2017-03-15 09:48:55 -07003776 ql_dbg(ql_dbg_async, vha, 0x10b7,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003777 "Format 0 : Number of VPs setup %d, number of "
Quinn Tran41dc5292017-01-19 22:28:03 -08003778 "VPs acquired %d.\n", rptid_entry->vp_setup,
3779 rptid_entry->vp_acquired);
Quinn Tranec7193e2017-03-15 09:48:55 -07003780 ql_dbg(ql_dbg_async, vha, 0x10b8,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003781 "Primary port id %02x%02x%02x.\n",
3782 rptid_entry->port_id[2], rptid_entry->port_id[1],
3783 rptid_entry->port_id[0]);
Quinn Tran9cd883f2017-12-28 12:33:24 -08003784 ha->current_topology = ISP_CFG_NL;
Quinn Tran482c9dc2017-03-15 09:48:54 -07003785 qlt_update_host_map(vha, id);
Quinn Tran41dc5292017-01-19 22:28:03 -08003786
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003787 } else if (rptid_entry->format == 1) {
Quinn Tran41dc5292017-01-19 22:28:03 -08003788 /* fabric */
Quinn Tranec7193e2017-03-15 09:48:55 -07003789 ql_dbg(ql_dbg_async, vha, 0x10b9,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003790 "Format 1: VP[%d] enabled - status %d - with "
Quinn Tran41dc5292017-01-19 22:28:03 -08003791 "port id %02x%02x%02x.\n", rptid_entry->vp_idx,
3792 rptid_entry->vp_status,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003793 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003794 rptid_entry->port_id[0]);
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003795 ql_dbg(ql_dbg_async, vha, 0x5075,
3796 "Format 1: Remote WWPN %8phC.\n",
3797 rptid_entry->u.f1.port_name);
3798
3799 ql_dbg(ql_dbg_async, vha, 0x5075,
3800 "Format 1: WWPN %8phC.\n",
3801 vha->port_name);
3802
3803 /* N2N. direct connect */
3804 if (IS_QLA27XX(ha) &&
3805 ((rptid_entry->u.f1.flags>>1) & 0x7) == 2) {
3806 /* if our portname is higher then initiate N2N login */
3807 if (wwn_to_u64(vha->port_name) >
3808 wwn_to_u64(rptid_entry->u.f1.port_name)) {
3809 // ??? qlt_update_host_map(vha, id);
3810 vha->n2n_id = 0x1;
3811 ql_dbg(ql_dbg_async, vha, 0x5075,
3812 "Format 1: Setting n2n_update_needed for id %d\n",
3813 vha->n2n_id);
3814 } else {
3815 ql_dbg(ql_dbg_async, vha, 0x5075,
3816 "Format 1: Remote login - Waiting for WWPN %8phC.\n",
3817 rptid_entry->u.f1.port_name);
3818 }
3819
3820 memcpy(vha->n2n_port_name, rptid_entry->u.f1.port_name,
3821 WWN_SIZE);
3822 set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
3823 set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
3824 set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
Darren Trapp1763c1f2018-03-20 23:09:34 -07003825 ha->flags.n2n_ae = 1;
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003826 return;
3827 }
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003828
Quinn Tran9cd883f2017-12-28 12:33:24 -08003829 ha->flags.gpsc_supported = 1;
3830 ha->current_topology = ISP_CFG_F;
Sawan Chandak969a6192016-01-27 12:03:32 -05003831 /* buffer to buffer credit flag */
Quinn Tran41dc5292017-01-19 22:28:03 -08003832 vha->flags.bbcr_enable = (rptid_entry->u.f1.bbcr & 0xf) != 0;
Sawan Chandak969a6192016-01-27 12:03:32 -05003833
Quinn Tran41dc5292017-01-19 22:28:03 -08003834 if (rptid_entry->vp_idx == 0) {
3835 if (rptid_entry->vp_status == VP_STAT_COMPL) {
3836 /* FA-WWN is only for physical port */
3837 if (qla_ini_mode_enabled(vha) &&
3838 ha->flags.fawwpn_enabled &&
3839 (rptid_entry->u.f1.flags &
Sawan Chandakfcc5b5c2017-08-23 15:05:02 -07003840 BIT_6)) {
Quinn Tran41dc5292017-01-19 22:28:03 -08003841 memcpy(vha->port_name,
3842 rptid_entry->u.f1.port_name,
3843 WWN_SIZE);
3844 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04003845
Quinn Tran482c9dc2017-03-15 09:48:54 -07003846 qlt_update_host_map(vha, id);
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04003847 }
Quinn Tran41dc5292017-01-19 22:28:03 -08003848
Quinn Tran41dc5292017-01-19 22:28:03 -08003849 set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
3850 set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
3851 } else {
3852 if (rptid_entry->vp_status != VP_STAT_COMPL &&
3853 rptid_entry->vp_status != VP_STAT_ID_CHG) {
3854 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
3855 "Could not acquire ID for VP[%d].\n",
3856 rptid_entry->vp_idx);
3857 return;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003858 }
Quinn Tran41dc5292017-01-19 22:28:03 -08003859
3860 found = 0;
3861 spin_lock_irqsave(&ha->vport_slock, flags);
3862 list_for_each_entry(vp, &ha->vp_list, list) {
3863 if (rptid_entry->vp_idx == vp->vp_idx) {
3864 found = 1;
3865 break;
3866 }
3867 }
3868 spin_unlock_irqrestore(&ha->vport_slock, flags);
3869
3870 if (!found)
3871 return;
3872
Quinn Tran482c9dc2017-03-15 09:48:54 -07003873 qlt_update_host_map(vp, id);
Quinn Tran41dc5292017-01-19 22:28:03 -08003874
3875 /*
3876 * Cannot configure here as we are still sitting on the
3877 * response queue. Handle it in dpc context.
3878 */
3879 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
3880 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
3881 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003882 }
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003883 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003884 qla2xxx_wake_dpc(vha);
Quinn Tran41dc5292017-01-19 22:28:03 -08003885 } else if (rptid_entry->format == 2) {
Quinn Tran83548fe2017-06-02 09:12:01 -07003886 ql_dbg(ql_dbg_async, vha, 0x505f,
Quinn Tran41dc5292017-01-19 22:28:03 -08003887 "RIDA: format 2/N2N Primary port id %02x%02x%02x.\n",
3888 rptid_entry->port_id[2], rptid_entry->port_id[1],
3889 rptid_entry->port_id[0]);
3890
Quinn Tran83548fe2017-06-02 09:12:01 -07003891 ql_dbg(ql_dbg_async, vha, 0x5075,
Quinn Tran41dc5292017-01-19 22:28:03 -08003892 "N2N: Remote WWPN %8phC.\n",
3893 rptid_entry->u.f2.port_name);
3894
3895 /* N2N. direct connect */
Quinn Tran9cd883f2017-12-28 12:33:24 -08003896 ha->current_topology = ISP_CFG_N;
3897 ha->flags.rida_fmt2 = 1;
Quinn Tran41dc5292017-01-19 22:28:03 -08003898 vha->d_id.b.domain = rptid_entry->port_id[2];
3899 vha->d_id.b.area = rptid_entry->port_id[1];
3900 vha->d_id.b.al_pa = rptid_entry->port_id[0];
3901
Darren Trapp1763c1f2018-03-20 23:09:34 -07003902 ha->flags.n2n_ae = 1;
Quinn Tran41dc5292017-01-19 22:28:03 -08003903 spin_lock_irqsave(&ha->vport_slock, flags);
3904 qlt_update_vp_map(vha, SET_AL_PA);
3905 spin_unlock_irqrestore(&ha->vport_slock, flags);
Quinn Tran9cd883f2017-12-28 12:33:24 -08003906
3907 list_for_each_entry(fcport, &vha->vp_fcports, list) {
3908 fcport->scan_state = QLA_FCPORT_SCAN;
3909 }
3910
3911 fcport = qla2x00_find_fcport_by_wwpn(vha,
3912 rptid_entry->u.f2.port_name, 1);
3913
3914 if (fcport) {
Quinn Tran23dd98a2018-08-02 13:16:45 -07003915 fcport->login_retry = vha->hw->login_retry_count;
Quinn Tran9cd883f2017-12-28 12:33:24 -08003916 fcport->plogi_nack_done_deadline = jiffies + HZ;
3917 fcport->scan_state = QLA_FCPORT_FOUND;
Quinn Tran9cd883f2017-12-28 12:33:24 -08003918 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003919 }
3920}
3921
3922/*
3923 * qla24xx_modify_vp_config
3924 * Change VP configuration for vha
3925 *
3926 * Input:
3927 * vha = adapter block pointer.
3928 *
3929 * Returns:
3930 * qla2xxx local function return status code.
3931 *
3932 * Context:
3933 * Kernel context.
3934 */
3935int
3936qla24xx_modify_vp_config(scsi_qla_host_t *vha)
3937{
3938 int rval;
3939 struct vp_config_entry_24xx *vpmod;
3940 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003941 struct qla_hw_data *ha = vha->hw;
3942 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003943
3944 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003945
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003946 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb,
3947 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003948
Thomas Meyer08eb7f42017-09-21 08:15:26 +02003949 vpmod = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003950 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003951 ql_log(ql_log_warn, vha, 0x10bc,
3952 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003953 return QLA_MEMORY_ALLOC_FAILED;
3954 }
3955
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003956 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
3957 vpmod->entry_count = 1;
3958 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
3959 vpmod->vp_count = 1;
3960 vpmod->vp_index1 = vha->vp_idx;
3961 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04003962
3963 qlt_modify_vp_config(vha, vpmod);
3964
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003965 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
3966 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
3967 vpmod->entry_count = 1;
3968
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003969 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003970 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003971 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
3972 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003973 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003974 ql_dbg(ql_dbg_mbx, vha, 0x10be,
3975 "Failed to complete IOCB -- error status (%x).\n",
3976 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003977 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07003978 } else if (vpmod->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003979 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3980 "Failed to complete IOCB -- completion status (%x).\n",
3981 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003982 rval = QLA_FUNCTION_FAILED;
3983 } else {
3984 /* EMPTY */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003985 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0,
3986 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003987 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3988 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003989 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003990
3991 return rval;
3992}
3993
3994/*
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003995 * qla2x00_send_change_request
3996 * Receive or disable RSCN request from fabric controller
3997 *
3998 * Input:
3999 * ha = adapter block pointer
4000 * format = registration format:
4001 * 0 - Reserved
4002 * 1 - Fabric detected registration
4003 * 2 - N_port detected registration
4004 * 3 - Full registration
4005 * FF - clear registration
4006 * vp_idx = Virtual port index
4007 *
4008 * Returns:
4009 * qla2x00 local function return status code.
4010 *
4011 * Context:
4012 * Kernel Context
4013 */
4014
4015int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004016qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004017 uint16_t vp_idx)
4018{
4019 int rval;
4020 mbx_cmd_t mc;
4021 mbx_cmd_t *mcp = &mc;
4022
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004023 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7,
4024 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004025
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004026 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
4027 mcp->mb[1] = format;
4028 mcp->mb[9] = vp_idx;
4029 mcp->out_mb = MBX_9|MBX_1|MBX_0;
4030 mcp->in_mb = MBX_0|MBX_1;
4031 mcp->tov = MBX_TOV_SECONDS;
4032 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004033 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004034
4035 if (rval == QLA_SUCCESS) {
4036 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
4037 rval = BIT_1;
4038 }
4039 } else
4040 rval = BIT_1;
4041
4042 return rval;
4043}
Andrew Vasquez338c9162007-09-20 14:07:33 -07004044
4045int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004046qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07004047 uint32_t size)
4048{
4049 int rval;
4050 mbx_cmd_t mc;
4051 mbx_cmd_t *mcp = &mc;
4052
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004053 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009,
4054 "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004055
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004056 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07004057 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
4058 mcp->mb[8] = MSW(addr);
4059 mcp->out_mb = MBX_8|MBX_0;
4060 } else {
4061 mcp->mb[0] = MBC_DUMP_RISC_RAM;
4062 mcp->out_mb = MBX_0;
4063 }
4064 mcp->mb[1] = LSW(addr);
4065 mcp->mb[2] = MSW(req_dma);
4066 mcp->mb[3] = LSW(req_dma);
4067 mcp->mb[6] = MSW(MSD(req_dma));
4068 mcp->mb[7] = LSW(MSD(req_dma));
4069 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004070 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07004071 mcp->mb[4] = MSW(size);
4072 mcp->mb[5] = LSW(size);
4073 mcp->out_mb |= MBX_5|MBX_4;
4074 } else {
4075 mcp->mb[4] = LSW(size);
4076 mcp->out_mb |= MBX_4;
4077 }
4078
4079 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07004080 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07004081 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004082 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004083
4084 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004085 ql_dbg(ql_dbg_mbx, vha, 0x1008,
4086 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004087 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004088 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007,
4089 "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004090 }
4091
4092 return rval;
4093}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004094/* 84XX Support **************************************************************/
4095
4096struct cs84xx_mgmt_cmd {
4097 union {
4098 struct verify_chip_entry_84xx req;
4099 struct verify_chip_rsp_84xx rsp;
4100 } p;
4101};
4102
4103int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004104qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004105{
4106 int rval, retry;
4107 struct cs84xx_mgmt_cmd *mn;
4108 dma_addr_t mn_dma;
4109 uint16_t options;
4110 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004111 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004112
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004113 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8,
4114 "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004115
4116 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
4117 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004118 return QLA_MEMORY_ALLOC_FAILED;
4119 }
4120
4121 /* Force Update? */
4122 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
4123 /* Diagnostic firmware? */
4124 /* options |= MENLO_DIAG_FW; */
4125 /* We update the firmware with only one data sequence. */
4126 options |= VCO_END_OF_DATA;
4127
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004128 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07004129 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004130 memset(mn, 0, sizeof(*mn));
4131 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
4132 mn->p.req.entry_count = 1;
4133 mn->p.req.options = cpu_to_le16(options);
4134
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004135 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
4136 "Dump of Verify Request.\n");
4137 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
4138 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004139
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004140 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004141 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004142 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
4143 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004144 goto verify_done;
4145 }
4146
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004147 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
4148 "Dump of Verify Response.\n");
4149 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
4150 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004151
4152 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
4153 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
4154 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004155 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004156 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004157
4158 if (status[0] != CS_COMPLETE) {
4159 rval = QLA_FUNCTION_FAILED;
4160 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004161 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
4162 "Firmware update failed. Retrying "
4163 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004164 options |= VCO_DONT_UPDATE_FW;
4165 options &= ~VCO_FORCE_UPDATE;
4166 retry = 1;
4167 }
4168 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004169 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004170 "Firmware updated to %x.\n",
4171 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004172
4173 /* NOTE: we only update OP firmware. */
4174 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
4175 ha->cs84xx->op_fw_version =
4176 le32_to_cpu(mn->p.rsp.fw_ver);
4177 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
4178 flags);
4179 }
4180 } while (retry);
4181
4182verify_done:
4183 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
4184
4185 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004186 ql_dbg(ql_dbg_mbx, vha, 0x10d1,
4187 "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004188 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004189 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2,
4190 "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004191 }
4192
4193 return rval;
4194}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004195
4196int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004197qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004198{
4199 int rval;
4200 unsigned long flags;
4201 mbx_cmd_t mc;
4202 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004203 struct qla_hw_data *ha = vha->hw;
4204
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004205 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
4206 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004207
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004208 if (IS_SHADOW_REG_CAPABLE(ha))
4209 req->options |= BIT_13;
4210
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004211 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004212 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004213 mcp->mb[2] = MSW(LSD(req->dma));
4214 mcp->mb[3] = LSW(LSD(req->dma));
4215 mcp->mb[6] = MSW(MSD(req->dma));
4216 mcp->mb[7] = LSW(MSD(req->dma));
4217 mcp->mb[5] = req->length;
4218 if (req->rsp)
4219 mcp->mb[10] = req->rsp->id;
4220 mcp->mb[12] = req->qos;
4221 mcp->mb[11] = req->vp_idx;
4222 mcp->mb[13] = req->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004223 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004224 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004225
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004226 mcp->mb[4] = req->id;
4227 /* que in ptr index */
4228 mcp->mb[8] = 0;
4229 /* que out ptr index */
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004230 mcp->mb[9] = *req->out_ptr = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004231 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
4232 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4233 mcp->in_mb = MBX_0;
4234 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004235 mcp->tov = MBX_TOV_SECONDS * 2;
4236
Chad Dupuisf73cb692014-02-26 04:15:06 -05004237 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004238 mcp->in_mb |= MBX_1;
Joe Carnuccioba4828b2014-04-11 16:54:10 -04004239 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004240 mcp->out_mb |= MBX_15;
4241 /* debug q create issue in SR-IOV */
4242 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
4243 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004244
4245 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004246 if (!(req->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004247 WRT_REG_DWORD(req->req_q_in, 0);
Joe Carnuccio29db41c2014-04-11 16:54:09 -04004248 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004249 WRT_REG_DWORD(req->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004250 }
4251 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4252
Anirban Chakraborty17d98632008-12-18 10:06:15 -08004253 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004254 if (rval != QLA_SUCCESS) {
4255 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
4256 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4257 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004258 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5,
4259 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004260 }
4261
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004262 return rval;
4263}
4264
4265int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004266qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004267{
4268 int rval;
4269 unsigned long flags;
4270 mbx_cmd_t mc;
4271 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004272 struct qla_hw_data *ha = vha->hw;
4273
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004274 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
4275 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004276
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004277 if (IS_SHADOW_REG_CAPABLE(ha))
4278 rsp->options |= BIT_13;
4279
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004280 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004281 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004282 mcp->mb[2] = MSW(LSD(rsp->dma));
4283 mcp->mb[3] = LSW(LSD(rsp->dma));
4284 mcp->mb[6] = MSW(MSD(rsp->dma));
4285 mcp->mb[7] = LSW(MSD(rsp->dma));
4286 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08004287 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004288 mcp->mb[13] = rsp->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004289 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004290 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004291
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004292 mcp->mb[4] = rsp->id;
4293 /* que in ptr index */
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004294 mcp->mb[8] = *rsp->in_ptr = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004295 /* que out ptr index */
4296 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07004297 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004298 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4299 mcp->in_mb = MBX_0;
4300 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004301 mcp->tov = MBX_TOV_SECONDS * 2;
4302
4303 if (IS_QLA81XX(ha)) {
4304 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
4305 mcp->in_mb |= MBX_1;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004306 } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004307 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
4308 mcp->in_mb |= MBX_1;
4309 /* debug q create issue in SR-IOV */
4310 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
4311 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004312
4313 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004314 if (!(rsp->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004315 WRT_REG_DWORD(rsp->rsp_q_out, 0);
Himanshu Madhanib20f02e2015-06-10 11:05:18 -04004316 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004317 WRT_REG_DWORD(rsp->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004318 }
4319
4320 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4321
Anirban Chakraborty17d98632008-12-18 10:06:15 -08004322 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004323 if (rval != QLA_SUCCESS) {
4324 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
4325 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4326 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004327 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8,
4328 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004329 }
4330
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004331 return rval;
4332}
4333
Andrew Vasquez8a659572009-02-08 20:50:12 -08004334int
4335qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
4336{
4337 int rval;
4338 mbx_cmd_t mc;
4339 mbx_cmd_t *mcp = &mc;
4340
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004341 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9,
4342 "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004343
4344 mcp->mb[0] = MBC_IDC_ACK;
4345 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
4346 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4347 mcp->in_mb = MBX_0;
4348 mcp->tov = MBX_TOV_SECONDS;
4349 mcp->flags = 0;
4350 rval = qla2x00_mailbox_command(vha, mcp);
4351
4352 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004353 ql_dbg(ql_dbg_mbx, vha, 0x10da,
4354 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004355 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004356 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db,
4357 "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004358 }
4359
4360 return rval;
4361}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004362
4363int
4364qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
4365{
4366 int rval;
4367 mbx_cmd_t mc;
4368 mbx_cmd_t *mcp = &mc;
4369
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004370 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc,
4371 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004372
Chad Dupuisf73cb692014-02-26 04:15:06 -05004373 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4374 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004375 return QLA_FUNCTION_FAILED;
4376
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004377 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4378 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
4379 mcp->out_mb = MBX_1|MBX_0;
4380 mcp->in_mb = MBX_1|MBX_0;
4381 mcp->tov = MBX_TOV_SECONDS;
4382 mcp->flags = 0;
4383 rval = qla2x00_mailbox_command(vha, mcp);
4384
4385 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004386 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
4387 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4388 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004389 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004390 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de,
4391 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004392 *sector_size = mcp->mb[1];
4393 }
4394
4395 return rval;
4396}
4397
4398int
4399qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
4400{
4401 int rval;
4402 mbx_cmd_t mc;
4403 mbx_cmd_t *mcp = &mc;
4404
Chad Dupuisf73cb692014-02-26 04:15:06 -05004405 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4406 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004407 return QLA_FUNCTION_FAILED;
4408
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004409 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df,
4410 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004411
4412 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4413 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
4414 FAC_OPT_CMD_WRITE_PROTECT;
4415 mcp->out_mb = MBX_1|MBX_0;
4416 mcp->in_mb = MBX_1|MBX_0;
4417 mcp->tov = MBX_TOV_SECONDS;
4418 mcp->flags = 0;
4419 rval = qla2x00_mailbox_command(vha, mcp);
4420
4421 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004422 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
4423 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4424 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004425 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004426 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1,
4427 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004428 }
4429
4430 return rval;
4431}
4432
4433int
4434qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
4435{
4436 int rval;
4437 mbx_cmd_t mc;
4438 mbx_cmd_t *mcp = &mc;
4439
Chad Dupuisf73cb692014-02-26 04:15:06 -05004440 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4441 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004442 return QLA_FUNCTION_FAILED;
4443
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004444 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,
4445 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004446
4447 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4448 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
4449 mcp->mb[2] = LSW(start);
4450 mcp->mb[3] = MSW(start);
4451 mcp->mb[4] = LSW(finish);
4452 mcp->mb[5] = MSW(finish);
4453 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4454 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4455 mcp->tov = MBX_TOV_SECONDS;
4456 mcp->flags = 0;
4457 rval = qla2x00_mailbox_command(vha, mcp);
4458
4459 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004460 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
4461 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4462 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004463 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004464 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,
4465 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004466 }
4467
4468 return rval;
4469}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004470
4471int
4472qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
4473{
4474 int rval = 0;
4475 mbx_cmd_t mc;
4476 mbx_cmd_t *mcp = &mc;
4477
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004478 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5,
4479 "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004480
4481 mcp->mb[0] = MBC_RESTART_MPI_FW;
4482 mcp->out_mb = MBX_0;
4483 mcp->in_mb = MBX_0|MBX_1;
4484 mcp->tov = MBX_TOV_SECONDS;
4485 mcp->flags = 0;
4486 rval = qla2x00_mailbox_command(vha, mcp);
4487
4488 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004489 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
4490 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4491 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004492 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004493 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7,
4494 "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004495 }
4496
4497 return rval;
4498}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004499
Joe Carnuccioc46e65c2013-08-27 01:37:35 -04004500int
4501qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4502{
4503 int rval;
4504 mbx_cmd_t mc;
4505 mbx_cmd_t *mcp = &mc;
4506 int i;
4507 int len;
4508 uint16_t *str;
4509 struct qla_hw_data *ha = vha->hw;
4510
4511 if (!IS_P3P_TYPE(ha))
4512 return QLA_FUNCTION_FAILED;
4513
4514 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b,
4515 "Entered %s.\n", __func__);
4516
4517 str = (void *)version;
4518 len = strlen(version);
4519
4520 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4521 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8;
4522 mcp->out_mb = MBX_1|MBX_0;
4523 for (i = 4; i < 16 && len; i++, str++, len -= 2) {
4524 mcp->mb[i] = cpu_to_le16p(str);
4525 mcp->out_mb |= 1<<i;
4526 }
4527 for (; i < 16; i++) {
4528 mcp->mb[i] = 0;
4529 mcp->out_mb |= 1<<i;
4530 }
4531 mcp->in_mb = MBX_1|MBX_0;
4532 mcp->tov = MBX_TOV_SECONDS;
4533 mcp->flags = 0;
4534 rval = qla2x00_mailbox_command(vha, mcp);
4535
4536 if (rval != QLA_SUCCESS) {
4537 ql_dbg(ql_dbg_mbx, vha, 0x117c,
4538 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4539 } else {
4540 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d,
4541 "Done %s.\n", __func__);
4542 }
4543
4544 return rval;
4545}
4546
4547int
4548qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4549{
4550 int rval;
4551 mbx_cmd_t mc;
4552 mbx_cmd_t *mcp = &mc;
4553 int len;
4554 uint16_t dwlen;
4555 uint8_t *str;
4556 dma_addr_t str_dma;
4557 struct qla_hw_data *ha = vha->hw;
4558
4559 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) ||
4560 IS_P3P_TYPE(ha))
4561 return QLA_FUNCTION_FAILED;
4562
4563 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e,
4564 "Entered %s.\n", __func__);
4565
4566 str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);
4567 if (!str) {
4568 ql_log(ql_log_warn, vha, 0x117f,
4569 "Failed to allocate driver version param.\n");
4570 return QLA_MEMORY_ALLOC_FAILED;
4571 }
4572
4573 memcpy(str, "\x7\x3\x11\x0", 4);
4574 dwlen = str[0];
4575 len = dwlen * 4 - 4;
4576 memset(str + 4, 0, len);
4577 if (len > strlen(version))
4578 len = strlen(version);
4579 memcpy(str + 4, version, len);
4580
4581 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4582 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;
4583 mcp->mb[2] = MSW(LSD(str_dma));
4584 mcp->mb[3] = LSW(LSD(str_dma));
4585 mcp->mb[6] = MSW(MSD(str_dma));
4586 mcp->mb[7] = LSW(MSD(str_dma));
4587 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4588 mcp->in_mb = MBX_1|MBX_0;
4589 mcp->tov = MBX_TOV_SECONDS;
4590 mcp->flags = 0;
4591 rval = qla2x00_mailbox_command(vha, mcp);
4592
4593 if (rval != QLA_SUCCESS) {
4594 ql_dbg(ql_dbg_mbx, vha, 0x1180,
4595 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4596 } else {
4597 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181,
4598 "Done %s.\n", __func__);
4599 }
4600
4601 dma_pool_free(ha->s_dma_pool, str, str_dma);
4602
4603 return rval;
4604}
4605
Duane Grigsbyedd05de2017-10-13 09:34:06 -07004606int
4607qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
4608 void *buf, uint16_t bufsiz)
4609{
4610 int rval, i;
4611 mbx_cmd_t mc;
4612 mbx_cmd_t *mcp = &mc;
4613 uint32_t *bp;
4614
4615 if (!IS_FWI2_CAPABLE(vha->hw))
4616 return QLA_FUNCTION_FAILED;
4617
4618 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4619 "Entered %s.\n", __func__);
4620
4621 mcp->mb[0] = MBC_GET_RNID_PARAMS;
4622 mcp->mb[1] = RNID_TYPE_PORT_LOGIN << 8;
4623 mcp->mb[2] = MSW(buf_dma);
4624 mcp->mb[3] = LSW(buf_dma);
4625 mcp->mb[6] = MSW(MSD(buf_dma));
4626 mcp->mb[7] = LSW(MSD(buf_dma));
4627 mcp->mb[8] = bufsiz/4;
4628 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4629 mcp->in_mb = MBX_1|MBX_0;
4630 mcp->tov = MBX_TOV_SECONDS;
4631 mcp->flags = 0;
4632 rval = qla2x00_mailbox_command(vha, mcp);
4633
4634 if (rval != QLA_SUCCESS) {
4635 ql_dbg(ql_dbg_mbx, vha, 0x115a,
4636 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4637 } else {
4638 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4639 "Done %s.\n", __func__);
4640 bp = (uint32_t *) buf;
4641 for (i = 0; i < (bufsiz-4)/4; i++, bp++)
4642 *bp = cpu_to_be32(*bp);
4643 }
4644
4645 return rval;
4646}
4647
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004648static int
4649qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
4650{
4651 int rval;
4652 mbx_cmd_t mc;
4653 mbx_cmd_t *mcp = &mc;
4654
4655 if (!IS_FWI2_CAPABLE(vha->hw))
4656 return QLA_FUNCTION_FAILED;
4657
4658 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4659 "Entered %s.\n", __func__);
4660
4661 mcp->mb[0] = MBC_GET_RNID_PARAMS;
4662 mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8;
4663 mcp->out_mb = MBX_1|MBX_0;
4664 mcp->in_mb = MBX_1|MBX_0;
4665 mcp->tov = MBX_TOV_SECONDS;
4666 mcp->flags = 0;
4667 rval = qla2x00_mailbox_command(vha, mcp);
4668 *temp = mcp->mb[1];
4669
4670 if (rval != QLA_SUCCESS) {
4671 ql_dbg(ql_dbg_mbx, vha, 0x115a,
4672 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4673 } else {
4674 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4675 "Done %s.\n", __func__);
4676 }
4677
4678 return rval;
4679}
4680
Joe Carnuccio3a117112013-02-08 01:58:00 -05004681int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004682qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4683 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004684{
4685 int rval;
4686 mbx_cmd_t mc;
4687 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004688 struct qla_hw_data *ha = vha->hw;
4689
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004690 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,
4691 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004692
Joe Carnuccio6766df92011-05-10 11:30:15 -07004693 if (!IS_FWI2_CAPABLE(ha))
4694 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004695
Joe Carnuccio6766df92011-05-10 11:30:15 -07004696 if (len == 1)
4697 opt |= BIT_0;
4698
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004699 mcp->mb[0] = MBC_READ_SFP;
4700 mcp->mb[1] = dev;
4701 mcp->mb[2] = MSW(sfp_dma);
4702 mcp->mb[3] = LSW(sfp_dma);
4703 mcp->mb[6] = MSW(MSD(sfp_dma));
4704 mcp->mb[7] = LSW(MSD(sfp_dma));
4705 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004706 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004707 mcp->mb[10] = opt;
4708 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 -07004709 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004710 mcp->tov = MBX_TOV_SECONDS;
4711 mcp->flags = 0;
4712 rval = qla2x00_mailbox_command(vha, mcp);
4713
4714 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004715 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004716
4717 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004718 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
4719 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Quinn Trane4e3a2c2017-08-23 15:05:07 -07004720 if (mcp->mb[0] == MBS_COMMAND_ERROR &&
4721 mcp->mb[1] == 0x22)
4722 /* sfp is not there */
4723 rval = QLA_INTERFACE_ERROR;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004724 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004725 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
4726 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004727 }
4728
4729 return rval;
4730}
4731
4732int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004733qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4734 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004735{
4736 int rval;
4737 mbx_cmd_t mc;
4738 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004739 struct qla_hw_data *ha = vha->hw;
4740
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004741 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb,
4742 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004743
Joe Carnuccio6766df92011-05-10 11:30:15 -07004744 if (!IS_FWI2_CAPABLE(ha))
4745 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004746
Joe Carnuccio6766df92011-05-10 11:30:15 -07004747 if (len == 1)
4748 opt |= BIT_0;
4749
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004750 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004751 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004752
4753 mcp->mb[0] = MBC_WRITE_SFP;
4754 mcp->mb[1] = dev;
4755 mcp->mb[2] = MSW(sfp_dma);
4756 mcp->mb[3] = LSW(sfp_dma);
4757 mcp->mb[6] = MSW(MSD(sfp_dma));
4758 mcp->mb[7] = LSW(MSD(sfp_dma));
4759 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004760 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004761 mcp->mb[10] = opt;
4762 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 -07004763 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004764 mcp->tov = MBX_TOV_SECONDS;
4765 mcp->flags = 0;
4766 rval = qla2x00_mailbox_command(vha, mcp);
4767
4768 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004769 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
4770 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004771 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004772 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed,
4773 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004774 }
4775
4776 return rval;
4777}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004778
4779int
4780qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
4781 uint16_t size_in_bytes, uint16_t *actual_size)
4782{
4783 int rval;
4784 mbx_cmd_t mc;
4785 mbx_cmd_t *mcp = &mc;
4786
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004787 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee,
4788 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004789
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004790 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004791 return QLA_FUNCTION_FAILED;
4792
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004793 mcp->mb[0] = MBC_GET_XGMAC_STATS;
4794 mcp->mb[2] = MSW(stats_dma);
4795 mcp->mb[3] = LSW(stats_dma);
4796 mcp->mb[6] = MSW(MSD(stats_dma));
4797 mcp->mb[7] = LSW(MSD(stats_dma));
4798 mcp->mb[8] = size_in_bytes >> 2;
4799 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4800 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4801 mcp->tov = MBX_TOV_SECONDS;
4802 mcp->flags = 0;
4803 rval = qla2x00_mailbox_command(vha, mcp);
4804
4805 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004806 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
4807 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4808 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004809 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004810 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0,
4811 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004812
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004813
4814 *actual_size = mcp->mb[2] << 2;
4815 }
4816
4817 return rval;
4818}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004819
4820int
4821qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
4822 uint16_t size)
4823{
4824 int rval;
4825 mbx_cmd_t mc;
4826 mbx_cmd_t *mcp = &mc;
4827
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004828 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1,
4829 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004830
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004831 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004832 return QLA_FUNCTION_FAILED;
4833
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004834 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4835 mcp->mb[1] = 0;
4836 mcp->mb[2] = MSW(tlv_dma);
4837 mcp->mb[3] = LSW(tlv_dma);
4838 mcp->mb[6] = MSW(MSD(tlv_dma));
4839 mcp->mb[7] = LSW(MSD(tlv_dma));
4840 mcp->mb[8] = size;
4841 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4842 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4843 mcp->tov = MBX_TOV_SECONDS;
4844 mcp->flags = 0;
4845 rval = qla2x00_mailbox_command(vha, mcp);
4846
4847 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004848 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
4849 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4850 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004851 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004852 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3,
4853 "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004854 }
4855
4856 return rval;
4857}
Andrew Vasquez18e75552009-06-03 09:55:30 -07004858
4859int
4860qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
4861{
4862 int rval;
4863 mbx_cmd_t mc;
4864 mbx_cmd_t *mcp = &mc;
4865
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004866 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4,
4867 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004868
Andrew Vasquez18e75552009-06-03 09:55:30 -07004869 if (!IS_FWI2_CAPABLE(vha->hw))
4870 return QLA_FUNCTION_FAILED;
4871
Andrew Vasquez18e75552009-06-03 09:55:30 -07004872 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
4873 mcp->mb[1] = LSW(risc_addr);
4874 mcp->mb[8] = MSW(risc_addr);
4875 mcp->out_mb = MBX_8|MBX_1|MBX_0;
4876 mcp->in_mb = MBX_3|MBX_2|MBX_0;
4877 mcp->tov = 30;
4878 mcp->flags = 0;
4879 rval = qla2x00_mailbox_command(vha, mcp);
4880 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004881 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
4882 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004883 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004884 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6,
4885 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004886 *data = mcp->mb[3] << 16 | mcp->mb[2];
4887 }
4888
4889 return rval;
4890}
4891
4892int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004893qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4894 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004895{
4896 int rval;
4897 mbx_cmd_t mc;
4898 mbx_cmd_t *mcp = &mc;
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004899
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004900 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7,
4901 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004902
4903 memset(mcp->mb, 0 , sizeof(mcp->mb));
4904 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
4905 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
4906
4907 /* transfer count */
4908 mcp->mb[10] = LSW(mreq->transfer_size);
4909 mcp->mb[11] = MSW(mreq->transfer_size);
4910
4911 /* send data address */
4912 mcp->mb[14] = LSW(mreq->send_dma);
4913 mcp->mb[15] = MSW(mreq->send_dma);
4914 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4915 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4916
Lucas De Marchi25985ed2011-03-30 22:57:33 -03004917 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004918 mcp->mb[16] = LSW(mreq->rcv_dma);
4919 mcp->mb[17] = MSW(mreq->rcv_dma);
4920 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4921 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4922
4923 /* Iteration count */
Joe Carnuccio1b98b422013-03-28 08:21:26 -04004924 mcp->mb[18] = LSW(mreq->iteration_count);
4925 mcp->mb[19] = MSW(mreq->iteration_count);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004926
4927 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
4928 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 -08004929 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004930 mcp->out_mb |= MBX_2;
4931 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
4932
4933 mcp->buf_size = mreq->transfer_size;
4934 mcp->tov = MBX_TOV_SECONDS;
4935 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4936
4937 rval = qla2x00_mailbox_command(vha, mcp);
4938
4939 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004940 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
4941 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
4942 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
4943 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004944 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004945 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9,
4946 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004947 }
4948
4949 /* Copy mailbox information */
4950 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004951 return rval;
4952}
4953
4954int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004955qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4956 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004957{
4958 int rval;
4959 mbx_cmd_t mc;
4960 mbx_cmd_t *mcp = &mc;
4961 struct qla_hw_data *ha = vha->hw;
4962
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004963 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa,
4964 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004965
4966 memset(mcp->mb, 0 , sizeof(mcp->mb));
4967 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
Joe Carnuccio1d634962017-05-24 18:06:22 -07004968 /* BIT_6 specifies 64bit address */
4969 mcp->mb[1] = mreq->options | BIT_15 | BIT_6;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004970 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -07004971 mcp->mb[2] = vha->fcoe_fcf_idx;
4972 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004973 mcp->mb[16] = LSW(mreq->rcv_dma);
4974 mcp->mb[17] = MSW(mreq->rcv_dma);
4975 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4976 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4977
4978 mcp->mb[10] = LSW(mreq->transfer_size);
4979
4980 mcp->mb[14] = LSW(mreq->send_dma);
4981 mcp->mb[15] = MSW(mreq->send_dma);
4982 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4983 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4984
4985 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
4986 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004987 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004988 mcp->out_mb |= MBX_2;
4989
4990 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004991 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
4992 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004993 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004994 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004995 mcp->in_mb |= MBX_3;
4996
4997 mcp->tov = MBX_TOV_SECONDS;
4998 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4999 mcp->buf_size = mreq->transfer_size;
5000
5001 rval = qla2x00_mailbox_command(vha, mcp);
5002
5003 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005004 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
5005 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5006 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005007 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005008 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc,
5009 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005010 }
5011
5012 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07005013 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005014 return rval;
5015}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07005016
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005017int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005018qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005019{
5020 int rval;
5021 mbx_cmd_t mc;
5022 mbx_cmd_t *mcp = &mc;
5023
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005024 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005025 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005026
5027 mcp->mb[0] = MBC_ISP84XX_RESET;
5028 mcp->mb[1] = enable_diagnostic;
5029 mcp->out_mb = MBX_1|MBX_0;
5030 mcp->in_mb = MBX_1|MBX_0;
5031 mcp->tov = MBX_TOV_SECONDS;
5032 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005033 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005034
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005035 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005036 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005037 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005038 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff,
5039 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005040
5041 return rval;
5042}
5043
5044int
Andrew Vasquez18e75552009-06-03 09:55:30 -07005045qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
5046{
5047 int rval;
5048 mbx_cmd_t mc;
5049 mbx_cmd_t *mcp = &mc;
5050
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005051 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100,
5052 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005053
Andrew Vasquez18e75552009-06-03 09:55:30 -07005054 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07005055 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07005056
Andrew Vasquez18e75552009-06-03 09:55:30 -07005057 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
5058 mcp->mb[1] = LSW(risc_addr);
5059 mcp->mb[2] = LSW(data);
5060 mcp->mb[3] = MSW(data);
5061 mcp->mb[8] = MSW(risc_addr);
5062 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
5063 mcp->in_mb = MBX_0;
5064 mcp->tov = 30;
5065 mcp->flags = 0;
5066 rval = qla2x00_mailbox_command(vha, mcp);
5067 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005068 ql_dbg(ql_dbg_mbx, vha, 0x1101,
5069 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07005070 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005071 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
5072 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07005073 }
5074
5075 return rval;
5076}
Michael Hernandez3064ff32009-12-15 21:29:44 -08005077
5078int
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005079qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
5080{
5081 int rval;
5082 uint32_t stat, timer;
5083 uint16_t mb0 = 0;
5084 struct qla_hw_data *ha = vha->hw;
5085 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
5086
5087 rval = QLA_SUCCESS;
5088
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005089 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103,
5090 "Entered %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005091
5092 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
5093
5094 /* Write the MBC data to the registers */
5095 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
5096 WRT_REG_WORD(&reg->mailbox1, mb[0]);
5097 WRT_REG_WORD(&reg->mailbox2, mb[1]);
5098 WRT_REG_WORD(&reg->mailbox3, mb[2]);
5099 WRT_REG_WORD(&reg->mailbox4, mb[3]);
5100
5101 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
5102
5103 /* Poll for MBC interrupt */
5104 for (timer = 6000000; timer; timer--) {
5105 /* Check for pending interrupts. */
5106 stat = RD_REG_DWORD(&reg->host_status);
5107 if (stat & HSRX_RISC_INT) {
5108 stat &= 0xff;
5109
5110 if (stat == 0x1 || stat == 0x2 ||
5111 stat == 0x10 || stat == 0x11) {
5112 set_bit(MBX_INTERRUPT,
5113 &ha->mbx_cmd_flags);
5114 mb0 = RD_REG_WORD(&reg->mailbox0);
5115 WRT_REG_DWORD(&reg->hccr,
5116 HCCRX_CLR_RISC_INT);
5117 RD_REG_DWORD(&reg->hccr);
5118 break;
5119 }
5120 }
5121 udelay(5);
5122 }
5123
5124 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
5125 rval = mb0 & MBS_MASK;
5126 else
5127 rval = QLA_FUNCTION_FAILED;
5128
5129 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005130 ql_dbg(ql_dbg_mbx, vha, 0x1104,
5131 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005132 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005133 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105,
5134 "Done %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005135 }
5136
5137 return rval;
5138}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005139
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005140int
Michael Hernandez3064ff32009-12-15 21:29:44 -08005141qla2x00_get_data_rate(scsi_qla_host_t *vha)
5142{
5143 int rval;
5144 mbx_cmd_t mc;
5145 mbx_cmd_t *mcp = &mc;
5146 struct qla_hw_data *ha = vha->hw;
5147
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005148 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
5149 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005150
Michael Hernandez3064ff32009-12-15 21:29:44 -08005151 if (!IS_FWI2_CAPABLE(ha))
5152 return QLA_FUNCTION_FAILED;
5153
Michael Hernandez3064ff32009-12-15 21:29:44 -08005154 mcp->mb[0] = MBC_DATA_RATE;
5155 mcp->mb[1] = 0;
5156 mcp->out_mb = MBX_1|MBX_0;
5157 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05005158 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005159 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08005160 mcp->tov = MBX_TOV_SECONDS;
5161 mcp->flags = 0;
5162 rval = qla2x00_mailbox_command(vha, mcp);
5163 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005164 ql_dbg(ql_dbg_mbx, vha, 0x1107,
5165 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08005166 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005167 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
5168 "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08005169 if (mcp->mb[1] != 0x7)
5170 ha->link_data_rate = mcp->mb[1];
5171 }
5172
5173 return rval;
5174}
Sarang Radke09ff7012010-03-19 17:03:59 -07005175
5176int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005177qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
5178{
5179 int rval;
5180 mbx_cmd_t mc;
5181 mbx_cmd_t *mcp = &mc;
5182 struct qla_hw_data *ha = vha->hw;
5183
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005184 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
5185 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005186
Chad Dupuisf73cb692014-02-26 04:15:06 -05005187 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) &&
5188 !IS_QLA27XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005189 return QLA_FUNCTION_FAILED;
5190 mcp->mb[0] = MBC_GET_PORT_CONFIG;
5191 mcp->out_mb = MBX_0;
5192 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5193 mcp->tov = MBX_TOV_SECONDS;
5194 mcp->flags = 0;
5195
5196 rval = qla2x00_mailbox_command(vha, mcp);
5197
5198 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005199 ql_dbg(ql_dbg_mbx, vha, 0x110a,
5200 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005201 } else {
5202 /* Copy all bits to preserve original value */
5203 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
5204
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005205 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b,
5206 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005207 }
5208 return rval;
5209}
5210
5211int
5212qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
5213{
5214 int rval;
5215 mbx_cmd_t mc;
5216 mbx_cmd_t *mcp = &mc;
5217
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005218 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c,
5219 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005220
5221 mcp->mb[0] = MBC_SET_PORT_CONFIG;
5222 /* Copy all bits to preserve original setting */
5223 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
5224 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5225 mcp->in_mb = MBX_0;
5226 mcp->tov = MBX_TOV_SECONDS;
5227 mcp->flags = 0;
5228 rval = qla2x00_mailbox_command(vha, mcp);
5229
5230 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005231 ql_dbg(ql_dbg_mbx, vha, 0x110d,
5232 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005233 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005234 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e,
5235 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005236
5237 return rval;
5238}
5239
5240
5241int
Sarang Radke09ff7012010-03-19 17:03:59 -07005242qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
5243 uint16_t *mb)
5244{
5245 int rval;
5246 mbx_cmd_t mc;
5247 mbx_cmd_t *mcp = &mc;
5248 struct qla_hw_data *ha = vha->hw;
5249
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005250 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f,
5251 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005252
Sarang Radke09ff7012010-03-19 17:03:59 -07005253 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
5254 return QLA_FUNCTION_FAILED;
5255
Sarang Radke09ff7012010-03-19 17:03:59 -07005256 mcp->mb[0] = MBC_PORT_PARAMS;
5257 mcp->mb[1] = loop_id;
5258 if (ha->flags.fcp_prio_enabled)
5259 mcp->mb[2] = BIT_1;
5260 else
5261 mcp->mb[2] = BIT_2;
5262 mcp->mb[4] = priority & 0xf;
5263 mcp->mb[9] = vha->vp_idx;
5264 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5265 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5266 mcp->tov = 30;
5267 mcp->flags = 0;
5268 rval = qla2x00_mailbox_command(vha, mcp);
5269 if (mb != NULL) {
5270 mb[0] = mcp->mb[0];
5271 mb[1] = mcp->mb[1];
5272 mb[3] = mcp->mb[3];
5273 mb[4] = mcp->mb[4];
5274 }
5275
5276 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005277 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07005278 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005279 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc,
5280 "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07005281 }
5282
5283 return rval;
5284}
Giridhar Malavalia9083012010-04-12 17:59:55 -07005285
5286int
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005287qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)
Andrew Vasquez794a5692010-12-21 16:00:21 -08005288{
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005289 int rval = QLA_FUNCTION_FAILED;
Andrew Vasquez794a5692010-12-21 16:00:21 -08005290 struct qla_hw_data *ha = vha->hw;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005291 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08005292
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005293 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) {
5294 ql_dbg(ql_dbg_mbx, vha, 0x1150,
5295 "Thermal not supported by this card.\n");
5296 return rval;
Andrew Vasquez794a5692010-12-21 16:00:21 -08005297 }
Andrew Vasquez794a5692010-12-21 16:00:21 -08005298
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005299 if (IS_QLA25XX(ha)) {
5300 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
5301 ha->pdev->subsystem_device == 0x0175) {
5302 rval = qla2x00_read_sfp(vha, 0, &byte,
5303 0x98, 0x1, 1, BIT_13|BIT_0);
5304 *temp = byte;
5305 return rval;
5306 }
5307 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
5308 ha->pdev->subsystem_device == 0x338e) {
5309 rval = qla2x00_read_sfp(vha, 0, &byte,
5310 0x98, 0x1, 1, BIT_15|BIT_14|BIT_0);
5311 *temp = byte;
5312 return rval;
5313 }
5314 ql_dbg(ql_dbg_mbx, vha, 0x10c9,
5315 "Thermal not supported by this card.\n");
5316 return rval;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005317 }
5318
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005319 if (IS_QLA82XX(ha)) {
5320 *temp = qla82xx_read_temperature(vha);
5321 rval = QLA_SUCCESS;
5322 return rval;
5323 } else if (IS_QLA8044(ha)) {
5324 *temp = qla8044_read_temperature(vha);
5325 rval = QLA_SUCCESS;
5326 return rval;
5327 }
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005328
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005329 rval = qla2x00_read_asic_temperature(vha, temp);
Andrew Vasquez794a5692010-12-21 16:00:21 -08005330 return rval;
5331}
5332
5333int
Giridhar Malavalia9083012010-04-12 17:59:55 -07005334qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
5335{
5336 int rval;
5337 struct qla_hw_data *ha = vha->hw;
5338 mbx_cmd_t mc;
5339 mbx_cmd_t *mcp = &mc;
5340
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005341 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017,
5342 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005343
Giridhar Malavalia9083012010-04-12 17:59:55 -07005344 if (!IS_FWI2_CAPABLE(ha))
5345 return QLA_FUNCTION_FAILED;
5346
Giridhar Malavalia9083012010-04-12 17:59:55 -07005347 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05005348 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07005349 mcp->mb[1] = 1;
5350
5351 mcp->out_mb = MBX_1|MBX_0;
5352 mcp->in_mb = MBX_0;
5353 mcp->tov = 30;
5354 mcp->flags = 0;
5355
5356 rval = qla2x00_mailbox_command(vha, mcp);
5357 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005358 ql_dbg(ql_dbg_mbx, vha, 0x1016,
5359 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005360 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005361 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e,
5362 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005363 }
5364
5365 return rval;
5366}
5367
5368int
5369qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
5370{
5371 int rval;
5372 struct qla_hw_data *ha = vha->hw;
5373 mbx_cmd_t mc;
5374 mbx_cmd_t *mcp = &mc;
5375
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005376 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
5377 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005378
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005379 if (!IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -07005380 return QLA_FUNCTION_FAILED;
5381
Giridhar Malavalia9083012010-04-12 17:59:55 -07005382 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05005383 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07005384 mcp->mb[1] = 0;
5385
5386 mcp->out_mb = MBX_1|MBX_0;
5387 mcp->in_mb = MBX_0;
5388 mcp->tov = 30;
5389 mcp->flags = 0;
5390
5391 rval = qla2x00_mailbox_command(vha, mcp);
5392 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005393 ql_dbg(ql_dbg_mbx, vha, 0x100c,
5394 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005395 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005396 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b,
5397 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005398 }
5399
5400 return rval;
5401}
Giridhar Malavali08de2842011-08-16 11:31:44 -07005402
5403int
5404qla82xx_md_get_template_size(scsi_qla_host_t *vha)
5405{
5406 struct qla_hw_data *ha = vha->hw;
5407 mbx_cmd_t mc;
5408 mbx_cmd_t *mcp = &mc;
5409 int rval = QLA_FUNCTION_FAILED;
5410
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005411 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f,
5412 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005413
5414 memset(mcp->mb, 0 , sizeof(mcp->mb));
5415 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5416 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5417 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
5418 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
5419
5420 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5421 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
5422 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5423
5424 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5425 mcp->tov = MBX_TOV_SECONDS;
5426 rval = qla2x00_mailbox_command(vha, mcp);
5427
5428 /* Always copy back return mailbox values. */
5429 if (rval != QLA_SUCCESS) {
5430 ql_dbg(ql_dbg_mbx, vha, 0x1120,
5431 "mailbox command FAILED=0x%x, subcode=%x.\n",
5432 (mcp->mb[1] << 16) | mcp->mb[0],
5433 (mcp->mb[3] << 16) | mcp->mb[2]);
5434 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005435 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121,
5436 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005437 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
5438 if (!ha->md_template_size) {
5439 ql_dbg(ql_dbg_mbx, vha, 0x1122,
5440 "Null template size obtained.\n");
5441 rval = QLA_FUNCTION_FAILED;
5442 }
5443 }
5444 return rval;
5445}
5446
5447int
5448qla82xx_md_get_template(scsi_qla_host_t *vha)
5449{
5450 struct qla_hw_data *ha = vha->hw;
5451 mbx_cmd_t mc;
5452 mbx_cmd_t *mcp = &mc;
5453 int rval = QLA_FUNCTION_FAILED;
5454
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005455 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123,
5456 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005457
5458 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
5459 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
5460 if (!ha->md_tmplt_hdr) {
5461 ql_log(ql_log_warn, vha, 0x1124,
5462 "Unable to allocate memory for Minidump template.\n");
5463 return rval;
5464 }
5465
5466 memset(mcp->mb, 0 , sizeof(mcp->mb));
5467 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5468 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5469 mcp->mb[2] = LSW(RQST_TMPLT);
5470 mcp->mb[3] = MSW(RQST_TMPLT);
5471 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
5472 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
5473 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
5474 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
5475 mcp->mb[8] = LSW(ha->md_template_size);
5476 mcp->mb[9] = MSW(ha->md_template_size);
5477
5478 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5479 mcp->tov = MBX_TOV_SECONDS;
5480 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5481 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5482 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5483 rval = qla2x00_mailbox_command(vha, mcp);
5484
5485 if (rval != QLA_SUCCESS) {
5486 ql_dbg(ql_dbg_mbx, vha, 0x1125,
5487 "mailbox command FAILED=0x%x, subcode=%x.\n",
5488 ((mcp->mb[1] << 16) | mcp->mb[0]),
5489 ((mcp->mb[3] << 16) | mcp->mb[2]));
5490 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005491 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126,
5492 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005493 return rval;
5494}
Saurav Kashyap999916d2011-08-16 11:31:45 -07005495
5496int
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005497qla8044_md_get_template(scsi_qla_host_t *vha)
5498{
5499 struct qla_hw_data *ha = vha->hw;
5500 mbx_cmd_t mc;
5501 mbx_cmd_t *mcp = &mc;
5502 int rval = QLA_FUNCTION_FAILED;
5503 int offset = 0, size = MINIDUMP_SIZE_36K;
5504 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,
5505 "Entered %s.\n", __func__);
5506
5507 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
5508 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
5509 if (!ha->md_tmplt_hdr) {
5510 ql_log(ql_log_warn, vha, 0xb11b,
5511 "Unable to allocate memory for Minidump template.\n");
5512 return rval;
5513 }
5514
5515 memset(mcp->mb, 0 , sizeof(mcp->mb));
5516 while (offset < ha->md_template_size) {
5517 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5518 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5519 mcp->mb[2] = LSW(RQST_TMPLT);
5520 mcp->mb[3] = MSW(RQST_TMPLT);
5521 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));
5522 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));
5523 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));
5524 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));
5525 mcp->mb[8] = LSW(size);
5526 mcp->mb[9] = MSW(size);
5527 mcp->mb[10] = offset & 0x0000FFFF;
5528 mcp->mb[11] = offset & 0xFFFF0000;
5529 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5530 mcp->tov = MBX_TOV_SECONDS;
5531 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5532 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5533 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5534 rval = qla2x00_mailbox_command(vha, mcp);
5535
5536 if (rval != QLA_SUCCESS) {
5537 ql_dbg(ql_dbg_mbx, vha, 0xb11c,
5538 "mailbox command FAILED=0x%x, subcode=%x.\n",
5539 ((mcp->mb[1] << 16) | mcp->mb[0]),
5540 ((mcp->mb[3] << 16) | mcp->mb[2]));
5541 return rval;
5542 } else
5543 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,
5544 "Done %s.\n", __func__);
5545 offset = offset + size;
5546 }
5547 return rval;
5548}
5549
5550int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005551qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5552{
5553 int rval;
5554 struct qla_hw_data *ha = vha->hw;
5555 mbx_cmd_t mc;
5556 mbx_cmd_t *mcp = &mc;
5557
5558 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5559 return QLA_FUNCTION_FAILED;
5560
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005561 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133,
5562 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005563
5564 memset(mcp, 0, sizeof(mbx_cmd_t));
5565 mcp->mb[0] = MBC_SET_LED_CONFIG;
5566 mcp->mb[1] = led_cfg[0];
5567 mcp->mb[2] = led_cfg[1];
5568 if (IS_QLA8031(ha)) {
5569 mcp->mb[3] = led_cfg[2];
5570 mcp->mb[4] = led_cfg[3];
5571 mcp->mb[5] = led_cfg[4];
5572 mcp->mb[6] = led_cfg[5];
5573 }
5574
5575 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5576 if (IS_QLA8031(ha))
5577 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5578 mcp->in_mb = MBX_0;
5579 mcp->tov = 30;
5580 mcp->flags = 0;
5581
5582 rval = qla2x00_mailbox_command(vha, mcp);
5583 if (rval != QLA_SUCCESS) {
5584 ql_dbg(ql_dbg_mbx, vha, 0x1134,
5585 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5586 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005587 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135,
5588 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005589 }
5590
5591 return rval;
5592}
5593
5594int
5595qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5596{
5597 int rval;
5598 struct qla_hw_data *ha = vha->hw;
5599 mbx_cmd_t mc;
5600 mbx_cmd_t *mcp = &mc;
5601
5602 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5603 return QLA_FUNCTION_FAILED;
5604
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005605 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136,
5606 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005607
5608 memset(mcp, 0, sizeof(mbx_cmd_t));
5609 mcp->mb[0] = MBC_GET_LED_CONFIG;
5610
5611 mcp->out_mb = MBX_0;
5612 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5613 if (IS_QLA8031(ha))
5614 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5615 mcp->tov = 30;
5616 mcp->flags = 0;
5617
5618 rval = qla2x00_mailbox_command(vha, mcp);
5619 if (rval != QLA_SUCCESS) {
5620 ql_dbg(ql_dbg_mbx, vha, 0x1137,
5621 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5622 } else {
5623 led_cfg[0] = mcp->mb[1];
5624 led_cfg[1] = mcp->mb[2];
5625 if (IS_QLA8031(ha)) {
5626 led_cfg[2] = mcp->mb[3];
5627 led_cfg[3] = mcp->mb[4];
5628 led_cfg[4] = mcp->mb[5];
5629 led_cfg[5] = mcp->mb[6];
5630 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005631 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138,
5632 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005633 }
5634
5635 return rval;
5636}
5637
5638int
Saurav Kashyap999916d2011-08-16 11:31:45 -07005639qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
5640{
5641 int rval;
5642 struct qla_hw_data *ha = vha->hw;
5643 mbx_cmd_t mc;
5644 mbx_cmd_t *mcp = &mc;
5645
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005646 if (!IS_P3P_TYPE(ha))
Saurav Kashyap999916d2011-08-16 11:31:45 -07005647 return QLA_FUNCTION_FAILED;
5648
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005649 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005650 "Entered %s.\n", __func__);
5651
5652 memset(mcp, 0, sizeof(mbx_cmd_t));
5653 mcp->mb[0] = MBC_SET_LED_CONFIG;
5654 if (enable)
5655 mcp->mb[7] = 0xE;
5656 else
5657 mcp->mb[7] = 0xD;
5658
5659 mcp->out_mb = MBX_7|MBX_0;
5660 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005661 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07005662 mcp->flags = 0;
5663
5664 rval = qla2x00_mailbox_command(vha, mcp);
5665 if (rval != QLA_SUCCESS) {
5666 ql_dbg(ql_dbg_mbx, vha, 0x1128,
5667 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5668 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005669 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005670 "Done %s.\n", __func__);
5671 }
5672
5673 return rval;
5674}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005675
5676int
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005677qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005678{
5679 int rval;
5680 struct qla_hw_data *ha = vha->hw;
5681 mbx_cmd_t mc;
5682 mbx_cmd_t *mcp = &mc;
5683
Chad Dupuisf73cb692014-02-26 04:15:06 -05005684 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005685 return QLA_FUNCTION_FAILED;
5686
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005687 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130,
5688 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005689
5690 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
5691 mcp->mb[1] = LSW(reg);
5692 mcp->mb[2] = MSW(reg);
5693 mcp->mb[3] = LSW(data);
5694 mcp->mb[4] = MSW(data);
5695 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5696
5697 mcp->in_mb = MBX_1|MBX_0;
5698 mcp->tov = MBX_TOV_SECONDS;
5699 mcp->flags = 0;
5700 rval = qla2x00_mailbox_command(vha, mcp);
5701
5702 if (rval != QLA_SUCCESS) {
5703 ql_dbg(ql_dbg_mbx, vha, 0x1131,
5704 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5705 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005706 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005707 "Done %s.\n", __func__);
5708 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005709
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005710 return rval;
5711}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005712
5713int
5714qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
5715{
5716 int rval;
5717 struct qla_hw_data *ha = vha->hw;
5718 mbx_cmd_t mc;
5719 mbx_cmd_t *mcp = &mc;
5720
5721 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005722 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b,
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005723 "Implicit LOGO Unsupported.\n");
5724 return QLA_FUNCTION_FAILED;
5725 }
5726
5727
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005728 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c,
5729 "Entering %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005730
5731 /* Perform Implicit LOGO. */
5732 mcp->mb[0] = MBC_PORT_LOGOUT;
5733 mcp->mb[1] = fcport->loop_id;
5734 mcp->mb[10] = BIT_15;
5735 mcp->out_mb = MBX_10|MBX_1|MBX_0;
5736 mcp->in_mb = MBX_0;
5737 mcp->tov = MBX_TOV_SECONDS;
5738 mcp->flags = 0;
5739 rval = qla2x00_mailbox_command(vha, mcp);
5740 if (rval != QLA_SUCCESS)
5741 ql_dbg(ql_dbg_mbx, vha, 0x113d,
5742 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5743 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005744 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e,
5745 "Done %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005746
5747 return rval;
5748}
5749
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005750int
5751qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
5752{
5753 int rval;
5754 mbx_cmd_t mc;
5755 mbx_cmd_t *mcp = &mc;
5756 struct qla_hw_data *ha = vha->hw;
5757 unsigned long retry_max_time = jiffies + (2 * HZ);
5758
Chad Dupuisf73cb692014-02-26 04:15:06 -05005759 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005760 return QLA_FUNCTION_FAILED;
5761
5762 ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
5763
5764retry_rd_reg:
5765 mcp->mb[0] = MBC_READ_REMOTE_REG;
5766 mcp->mb[1] = LSW(reg);
5767 mcp->mb[2] = MSW(reg);
5768 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5769 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5770 mcp->tov = MBX_TOV_SECONDS;
5771 mcp->flags = 0;
5772 rval = qla2x00_mailbox_command(vha, mcp);
5773
5774 if (rval != QLA_SUCCESS) {
5775 ql_dbg(ql_dbg_mbx, vha, 0x114c,
5776 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5777 rval, mcp->mb[0], mcp->mb[1]);
5778 } else {
5779 *data = (mcp->mb[3] | (mcp->mb[4] << 16));
5780 if (*data == QLA8XXX_BAD_VALUE) {
5781 /*
5782 * During soft-reset CAMRAM register reads might
5783 * return 0xbad0bad0. So retry for MAX of 2 sec
5784 * while reading camram registers.
5785 */
5786 if (time_after(jiffies, retry_max_time)) {
5787 ql_dbg(ql_dbg_mbx, vha, 0x1141,
5788 "Failure to read CAMRAM register. "
5789 "data=0x%x.\n", *data);
5790 return QLA_FUNCTION_FAILED;
5791 }
5792 msleep(100);
5793 goto retry_rd_reg;
5794 }
5795 ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
5796 }
5797
5798 return rval;
5799}
5800
5801int
5802qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
5803{
5804 int rval;
5805 mbx_cmd_t mc;
5806 mbx_cmd_t *mcp = &mc;
5807 struct qla_hw_data *ha = vha->hw;
5808
Himanshu Madhanib20f02e2015-06-10 11:05:18 -04005809 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005810 return QLA_FUNCTION_FAILED;
5811
5812 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
5813
5814 mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
5815 mcp->out_mb = MBX_0;
5816 mcp->in_mb = MBX_1|MBX_0;
5817 mcp->tov = MBX_TOV_SECONDS;
5818 mcp->flags = 0;
5819 rval = qla2x00_mailbox_command(vha, mcp);
5820
5821 if (rval != QLA_SUCCESS) {
5822 ql_dbg(ql_dbg_mbx, vha, 0x1144,
5823 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5824 rval, mcp->mb[0], mcp->mb[1]);
5825 ha->isp_ops->fw_dump(vha, 0);
5826 } else {
5827 ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
5828 }
5829
5830 return rval;
5831}
5832
5833int
5834qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
5835 uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
5836{
5837 int rval;
5838 mbx_cmd_t mc;
5839 mbx_cmd_t *mcp = &mc;
5840 uint8_t subcode = (uint8_t)options;
5841 struct qla_hw_data *ha = vha->hw;
5842
5843 if (!IS_QLA8031(ha))
5844 return QLA_FUNCTION_FAILED;
5845
5846 ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
5847
5848 mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
5849 mcp->mb[1] = options;
5850 mcp->out_mb = MBX_1|MBX_0;
5851 if (subcode & BIT_2) {
5852 mcp->mb[2] = LSW(start_addr);
5853 mcp->mb[3] = MSW(start_addr);
5854 mcp->mb[4] = LSW(end_addr);
5855 mcp->mb[5] = MSW(end_addr);
5856 mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
5857 }
5858 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5859 if (!(subcode & (BIT_2 | BIT_5)))
5860 mcp->in_mb |= MBX_4|MBX_3;
5861 mcp->tov = MBX_TOV_SECONDS;
5862 mcp->flags = 0;
5863 rval = qla2x00_mailbox_command(vha, mcp);
5864
5865 if (rval != QLA_SUCCESS) {
5866 ql_dbg(ql_dbg_mbx, vha, 0x1147,
5867 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
5868 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
5869 mcp->mb[4]);
5870 ha->isp_ops->fw_dump(vha, 0);
5871 } else {
5872 if (subcode & BIT_5)
5873 *sector_size = mcp->mb[1];
5874 else if (subcode & (BIT_6 | BIT_7)) {
5875 ql_dbg(ql_dbg_mbx, vha, 0x1148,
5876 "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5877 } else if (subcode & (BIT_3 | BIT_4)) {
5878 ql_dbg(ql_dbg_mbx, vha, 0x1149,
5879 "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5880 }
5881 ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
5882 }
5883
5884 return rval;
5885}
Saurav Kashyap81178772012-08-22 14:21:04 -04005886
5887int
5888qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
5889 uint32_t size)
5890{
5891 int rval;
5892 mbx_cmd_t mc;
5893 mbx_cmd_t *mcp = &mc;
5894
5895 if (!IS_MCTP_CAPABLE(vha->hw))
5896 return QLA_FUNCTION_FAILED;
5897
5898 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,
5899 "Entered %s.\n", __func__);
5900
5901 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
5902 mcp->mb[1] = LSW(addr);
5903 mcp->mb[2] = MSW(req_dma);
5904 mcp->mb[3] = LSW(req_dma);
5905 mcp->mb[4] = MSW(size);
5906 mcp->mb[5] = LSW(size);
5907 mcp->mb[6] = MSW(MSD(req_dma));
5908 mcp->mb[7] = LSW(MSD(req_dma));
5909 mcp->mb[8] = MSW(addr);
5910 /* Setting RAM ID to valid */
5911 mcp->mb[10] |= BIT_7;
5912 /* For MCTP RAM ID is 0x40 */
5913 mcp->mb[10] |= 0x40;
5914
5915 mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
5916 MBX_0;
5917
5918 mcp->in_mb = MBX_0;
5919 mcp->tov = MBX_TOV_SECONDS;
5920 mcp->flags = 0;
5921 rval = qla2x00_mailbox_command(vha, mcp);
5922
5923 if (rval != QLA_SUCCESS) {
5924 ql_dbg(ql_dbg_mbx, vha, 0x114e,
5925 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5926 } else {
5927 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,
5928 "Done %s.\n", __func__);
5929 }
5930
5931 return rval;
5932}
Joe Carnuccioec891462016-07-06 11:14:26 -04005933
5934int
5935qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
5936 void *dd_buf, uint size, uint options)
5937{
5938 int rval;
5939 mbx_cmd_t mc;
5940 mbx_cmd_t *mcp = &mc;
5941 dma_addr_t dd_dma;
5942
5943 if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
5944 return QLA_FUNCTION_FAILED;
5945
Quinn Tran83548fe2017-06-02 09:12:01 -07005946 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f,
Joe Carnuccioec891462016-07-06 11:14:26 -04005947 "Entered %s.\n", __func__);
5948
Joe Carnuccioec891462016-07-06 11:14:26 -04005949 dd_dma = dma_map_single(&vha->hw->pdev->dev,
5950 dd_buf, size, DMA_FROM_DEVICE);
Pan Bian0b2ce192017-08-08 21:55:30 +08005951 if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) {
Joe Carnuccioec891462016-07-06 11:14:26 -04005952 ql_log(ql_log_warn, vha, 0x1194, "Failed to map dma buffer.\n");
5953 return QLA_MEMORY_ALLOC_FAILED;
5954 }
5955
5956 memset(dd_buf, 0, size);
5957
5958 mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;
5959 mcp->mb[1] = options;
5960 mcp->mb[2] = MSW(LSD(dd_dma));
5961 mcp->mb[3] = LSW(LSD(dd_dma));
5962 mcp->mb[6] = MSW(MSD(dd_dma));
5963 mcp->mb[7] = LSW(MSD(dd_dma));
5964 mcp->mb[8] = size;
5965 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
5966 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5967 mcp->buf_size = size;
5968 mcp->flags = MBX_DMA_IN;
5969 mcp->tov = MBX_TOV_SECONDS * 4;
5970 rval = qla2x00_mailbox_command(vha, mcp);
5971
5972 if (rval != QLA_SUCCESS) {
5973 ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval);
5974 } else {
5975 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196,
5976 "Done %s.\n", __func__);
5977 }
5978
5979 dma_unmap_single(&vha->hw->pdev->dev, dd_dma,
5980 size, DMA_FROM_DEVICE);
5981
5982 return rval;
5983}
Quinn Tran15f30a52017-03-15 09:48:52 -07005984
5985static void qla2x00_async_mb_sp_done(void *s, int res)
5986{
5987 struct srb *sp = s;
5988
5989 sp->u.iocb_cmd.u.mbx.rc = res;
5990
5991 complete(&sp->u.iocb_cmd.u.mbx.comp);
5992 /* don't free sp here. Let the caller do the free */
5993}
5994
5995/*
5996 * This mailbox uses the iocb interface to send MB command.
5997 * This allows non-critial (non chip setup) command to go
5998 * out in parrallel.
5999 */
6000int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)
6001{
6002 int rval = QLA_FUNCTION_FAILED;
6003 srb_t *sp;
6004 struct srb_iocb *c;
6005
6006 if (!vha->hw->flags.fw_started)
6007 goto done;
6008
6009 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
6010 if (!sp)
6011 goto done;
6012
6013 sp->type = SRB_MB_IOCB;
6014 sp->name = mb_to_str(mcp->mb[0]);
6015
Quinn Tran15f30a52017-03-15 09:48:52 -07006016 c = &sp->u.iocb_cmd;
6017 c->timeout = qla2x00_async_iocb_timeout;
6018 init_completion(&c->u.mbx.comp);
6019
Ben Hutchingse74e7d92018-03-20 21:36:14 +00006020 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
6021
6022 memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG);
6023
Quinn Tran15f30a52017-03-15 09:48:52 -07006024 sp->done = qla2x00_async_mb_sp_done;
6025
6026 rval = qla2x00_start_sp(sp);
6027 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006028 ql_dbg(ql_dbg_mbx, vha, 0x1018,
Quinn Tran15f30a52017-03-15 09:48:52 -07006029 "%s: %s Failed submission. %x.\n",
6030 __func__, sp->name, rval);
6031 goto done_free_sp;
6032 }
6033
Quinn Tran83548fe2017-06-02 09:12:01 -07006034 ql_dbg(ql_dbg_mbx, vha, 0x113f, "MB:%s hndl %x submitted\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006035 sp->name, sp->handle);
6036
6037 wait_for_completion(&c->u.mbx.comp);
6038 memcpy(mcp->mb, sp->u.iocb_cmd.u.mbx.in_mb, SIZEOF_IOCB_MB_REG);
6039
6040 rval = c->u.mbx.rc;
6041 switch (rval) {
6042 case QLA_FUNCTION_TIMEOUT:
Quinn Tran83548fe2017-06-02 09:12:01 -07006043 ql_dbg(ql_dbg_mbx, vha, 0x1140, "%s: %s Timeout. %x.\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006044 __func__, sp->name, rval);
6045 break;
6046 case QLA_SUCCESS:
Quinn Tran83548fe2017-06-02 09:12:01 -07006047 ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006048 __func__, sp->name);
6049 sp->free(sp);
6050 break;
6051 default:
Quinn Tran83548fe2017-06-02 09:12:01 -07006052 ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006053 __func__, sp->name, rval);
6054 sp->free(sp);
6055 break;
6056 }
6057
6058 return rval;
6059
6060done_free_sp:
6061 sp->free(sp);
6062done:
6063 return rval;
6064}
6065
6066/*
6067 * qla24xx_gpdb_wait
6068 * NOTE: Do not call this routine from DPC thread
6069 */
6070int qla24xx_gpdb_wait(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
6071{
6072 int rval = QLA_FUNCTION_FAILED;
6073 dma_addr_t pd_dma;
6074 struct port_database_24xx *pd;
6075 struct qla_hw_data *ha = vha->hw;
6076 mbx_cmd_t mc;
6077
6078 if (!vha->hw->flags.fw_started)
6079 goto done;
6080
Thomas Meyer08eb7f42017-09-21 08:15:26 +02006081 pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Quinn Tran15f30a52017-03-15 09:48:52 -07006082 if (pd == NULL) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006083 ql_log(ql_log_warn, vha, 0xd047,
6084 "Failed to allocate port database structure.\n");
Quinn Tran15f30a52017-03-15 09:48:52 -07006085 goto done_free_sp;
6086 }
Quinn Tran15f30a52017-03-15 09:48:52 -07006087
6088 memset(&mc, 0, sizeof(mc));
6089 mc.mb[0] = MBC_GET_PORT_DATABASE;
6090 mc.mb[1] = cpu_to_le16(fcport->loop_id);
6091 mc.mb[2] = MSW(pd_dma);
6092 mc.mb[3] = LSW(pd_dma);
6093 mc.mb[6] = MSW(MSD(pd_dma));
6094 mc.mb[7] = LSW(MSD(pd_dma));
6095 mc.mb[9] = cpu_to_le16(vha->vp_idx);
6096 mc.mb[10] = cpu_to_le16((uint16_t)opt);
6097
6098 rval = qla24xx_send_mb_cmd(vha, &mc);
6099 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006100 ql_dbg(ql_dbg_mbx, vha, 0x1193,
Quinn Tran15f30a52017-03-15 09:48:52 -07006101 "%s: %8phC fail\n", __func__, fcport->port_name);
6102 goto done_free_sp;
6103 }
6104
6105 rval = __qla24xx_parse_gpdb(vha, fcport, pd);
6106
Quinn Tran83548fe2017-06-02 09:12:01 -07006107 ql_dbg(ql_dbg_mbx, vha, 0x1197, "%s: %8phC done\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006108 __func__, fcport->port_name);
6109
6110done_free_sp:
6111 if (pd)
6112 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
6113done:
6114 return rval;
6115}
6116
6117int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
6118 struct port_database_24xx *pd)
6119{
6120 int rval = QLA_SUCCESS;
6121 uint64_t zero = 0;
Duane Grigsbya5d42f42017-06-21 13:48:41 -07006122 u8 current_login_state, last_login_state;
6123
6124 if (fcport->fc4f_nvme) {
6125 current_login_state = pd->current_login_state >> 4;
6126 last_login_state = pd->last_login_state >> 4;
6127 } else {
6128 current_login_state = pd->current_login_state & 0xf;
6129 last_login_state = pd->last_login_state & 0xf;
6130 }
Quinn Tran15f30a52017-03-15 09:48:52 -07006131
6132 /* Check for logged in state. */
Quinn Tran23c64552017-12-04 14:45:08 -08006133 if (current_login_state != PDS_PRLI_COMPLETE) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006134 ql_dbg(ql_dbg_mbx, vha, 0x119a,
6135 "Unable to verify login-state (%x/%x) for loop_id %x.\n",
Duane Grigsbya5d42f42017-06-21 13:48:41 -07006136 current_login_state, last_login_state, fcport->loop_id);
Quinn Tran15f30a52017-03-15 09:48:52 -07006137 rval = QLA_FUNCTION_FAILED;
6138 goto gpd_error_out;
6139 }
6140
6141 if (fcport->loop_id == FC_NO_LOOP_ID ||
6142 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
6143 memcmp(fcport->port_name, pd->port_name, 8))) {
6144 /* We lost the device mid way. */
6145 rval = QLA_NOT_LOGGED_IN;
6146 goto gpd_error_out;
6147 }
6148
6149 /* Names are little-endian. */
6150 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
6151 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
6152
6153 /* Get port_id of device. */
6154 fcport->d_id.b.domain = pd->port_id[0];
6155 fcport->d_id.b.area = pd->port_id[1];
6156 fcport->d_id.b.al_pa = pd->port_id[2];
6157 fcport->d_id.b.rsvd_1 = 0;
6158
Duane Grigsbya5d42f42017-06-21 13:48:41 -07006159 if (fcport->fc4f_nvme) {
6160 fcport->nvme_prli_service_param =
6161 pd->prli_nvme_svc_param_word_3;
6162 fcport->port_type = FCT_NVME;
6163 } else {
6164 /* If not target must be initiator or unknown type. */
6165 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
6166 fcport->port_type = FCT_INITIATOR;
6167 else
6168 fcport->port_type = FCT_TARGET;
6169 }
Quinn Tran15f30a52017-03-15 09:48:52 -07006170 /* Passback COS information. */
6171 fcport->supported_classes = (pd->flags & PDF_CLASS_2) ?
6172 FC_COS_CLASS2 : FC_COS_CLASS3;
6173
6174 if (pd->prli_svc_param_word_3[0] & BIT_7) {
6175 fcport->flags |= FCF_CONF_COMP_SUPPORTED;
6176 fcport->conf_compl_supported = 1;
6177 }
6178
6179gpd_error_out:
6180 return rval;
6181}
6182
6183/*
6184 * qla24xx_gidlist__wait
6185 * NOTE: don't call this routine from DPC thread.
6186 */
6187int qla24xx_gidlist_wait(struct scsi_qla_host *vha,
6188 void *id_list, dma_addr_t id_list_dma, uint16_t *entries)
6189{
6190 int rval = QLA_FUNCTION_FAILED;
6191 mbx_cmd_t mc;
6192
6193 if (!vha->hw->flags.fw_started)
6194 goto done;
6195
6196 memset(&mc, 0, sizeof(mc));
6197 mc.mb[0] = MBC_GET_ID_LIST;
6198 mc.mb[2] = MSW(id_list_dma);
6199 mc.mb[3] = LSW(id_list_dma);
6200 mc.mb[6] = MSW(MSD(id_list_dma));
6201 mc.mb[7] = LSW(MSD(id_list_dma));
6202 mc.mb[8] = 0;
6203 mc.mb[9] = cpu_to_le16(vha->vp_idx);
6204
6205 rval = qla24xx_send_mb_cmd(vha, &mc);
6206 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006207 ql_dbg(ql_dbg_mbx, vha, 0x119b,
6208 "%s: fail\n", __func__);
Quinn Tran15f30a52017-03-15 09:48:52 -07006209 } else {
6210 *entries = mc.mb[1];
Quinn Tran83548fe2017-06-02 09:12:01 -07006211 ql_dbg(ql_dbg_mbx, vha, 0x119c,
6212 "%s: done\n", __func__);
Quinn Tran15f30a52017-03-15 09:48:52 -07006213 }
6214done:
6215 return rval;
6216}
Duane Grigsbydeeae7a2017-07-21 09:32:25 -07006217
6218int qla27xx_set_zio_threshold(scsi_qla_host_t *vha, uint16_t value)
6219{
6220 int rval;
6221 mbx_cmd_t mc;
6222 mbx_cmd_t *mcp = &mc;
6223
6224 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1200,
6225 "Entered %s\n", __func__);
6226
6227 memset(mcp->mb, 0 , sizeof(mcp->mb));
6228 mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD;
6229 mcp->mb[1] = cpu_to_le16(1);
6230 mcp->mb[2] = cpu_to_le16(value);
6231 mcp->out_mb = MBX_2 | MBX_1 | MBX_0;
6232 mcp->in_mb = MBX_2 | MBX_0;
6233 mcp->tov = MBX_TOV_SECONDS;
6234 mcp->flags = 0;
6235
6236 rval = qla2x00_mailbox_command(vha, mcp);
6237
6238 ql_dbg(ql_dbg_mbx, vha, 0x1201, "%s %x\n",
6239 (rval != QLA_SUCCESS) ? "Failed" : "Done", rval);
6240
6241 return rval;
6242}
6243
6244int qla27xx_get_zio_threshold(scsi_qla_host_t *vha, uint16_t *value)
6245{
6246 int rval;
6247 mbx_cmd_t mc;
6248 mbx_cmd_t *mcp = &mc;
6249
6250 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1203,
6251 "Entered %s\n", __func__);
6252
6253 memset(mcp->mb, 0, sizeof(mcp->mb));
6254 mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD;
6255 mcp->mb[1] = cpu_to_le16(0);
6256 mcp->out_mb = MBX_1 | MBX_0;
6257 mcp->in_mb = MBX_2 | MBX_0;
6258 mcp->tov = MBX_TOV_SECONDS;
6259 mcp->flags = 0;
6260
6261 rval = qla2x00_mailbox_command(vha, mcp);
6262 if (rval == QLA_SUCCESS)
6263 *value = mc.mb[2];
6264
6265 ql_dbg(ql_dbg_mbx, vha, 0x1205, "%s %x\n",
6266 (rval != QLA_SUCCESS) ? "Failed" : "Done", rval);
6267
6268 return rval;
6269}
Quinn Trane4e3a2c2017-08-23 15:05:07 -07006270
6271int
6272qla2x00_read_sfp_dev(struct scsi_qla_host *vha, char *buf, int count)
6273{
6274 struct qla_hw_data *ha = vha->hw;
6275 uint16_t iter, addr, offset;
6276 dma_addr_t phys_addr;
6277 int rval, c;
6278 u8 *sfp_data;
6279
6280 memset(ha->sfp_data, 0, SFP_DEV_SIZE);
6281 addr = 0xa0;
6282 phys_addr = ha->sfp_data_dma;
6283 sfp_data = ha->sfp_data;
6284 offset = c = 0;
6285
6286 for (iter = 0; iter < SFP_DEV_SIZE / SFP_BLOCK_SIZE; iter++) {
6287 if (iter == 4) {
6288 /* Skip to next device address. */
6289 addr = 0xa2;
6290 offset = 0;
6291 }
6292
6293 rval = qla2x00_read_sfp(vha, phys_addr, sfp_data,
6294 addr, offset, SFP_BLOCK_SIZE, BIT_1);
6295 if (rval != QLA_SUCCESS) {
6296 ql_log(ql_log_warn, vha, 0x706d,
6297 "Unable to read SFP data (%x/%x/%x).\n", rval,
6298 addr, offset);
6299
6300 return rval;
6301 }
6302
6303 if (buf && (c < count)) {
6304 u16 sz;
6305
6306 if ((count - c) >= SFP_BLOCK_SIZE)
6307 sz = SFP_BLOCK_SIZE;
6308 else
6309 sz = count - c;
6310
6311 memcpy(buf, sfp_data, sz);
6312 buf += SFP_BLOCK_SIZE;
6313 c += sz;
6314 }
6315 phys_addr += SFP_BLOCK_SIZE;
6316 sfp_data += SFP_BLOCK_SIZE;
6317 offset += SFP_BLOCK_SIZE;
6318 }
6319
6320 return rval;
6321}
Quinn Tran94d83e32017-12-28 12:33:23 -08006322
6323int qla24xx_res_count_wait(struct scsi_qla_host *vha,
6324 uint16_t *out_mb, int out_mb_sz)
6325{
6326 int rval = QLA_FUNCTION_FAILED;
6327 mbx_cmd_t mc;
6328
6329 if (!vha->hw->flags.fw_started)
6330 goto done;
6331
6332 memset(&mc, 0, sizeof(mc));
6333 mc.mb[0] = MBC_GET_RESOURCE_COUNTS;
6334
6335 rval = qla24xx_send_mb_cmd(vha, &mc);
6336 if (rval != QLA_SUCCESS) {
6337 ql_dbg(ql_dbg_mbx, vha, 0xffff,
6338 "%s: fail\n", __func__);
6339 } else {
6340 if (out_mb_sz <= SIZEOF_IOCB_MB_REG)
6341 memcpy(out_mb, mc.mb, out_mb_sz);
6342 else
6343 memcpy(out_mb, mc.mb, SIZEOF_IOCB_MB_REG);
6344
6345 ql_dbg(ql_dbg_mbx, vha, 0xffff,
6346 "%s: done\n", __func__);
6347 }
6348done:
6349 return rval;
6350}