blob: 7c07a939cf15a9ca2fb143f5883c59fe6ddac71c [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 },
Quinn Tran8777e432018-08-02 13:16:57 -070062 { MBC_GET_RNID_PARAMS },
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -080063};
64
65static int is_rom_cmd(uint16_t cmd)
66{
67 int i;
68 struct rom_cmd *wc;
69
70 for (i = 0; i < ARRAY_SIZE(rom_cmds); i++) {
71 wc = rom_cmds + i;
72 if (wc->cmd == cmd)
73 return 1;
74 }
75
76 return 0;
77}
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
79/*
80 * qla2x00_mailbox_command
81 * Issue mailbox command and waits for completion.
82 *
83 * Input:
84 * ha = adapter block pointer.
85 * mcp = driver internal mbx struct pointer.
86 *
87 * Output:
88 * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
89 *
90 * Returns:
91 * 0 : QLA_SUCCESS = cmd performed success
92 * 1 : QLA_FUNCTION_FAILED (error encountered)
93 * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
94 *
95 * Context:
96 * Kernel context.
97 */
98static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080099qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100{
Himanshu Madhanid14e72f2015-04-09 15:00:03 -0400101 int rval, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 unsigned long flags = 0;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500103 device_reg_t *reg;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700104 uint8_t abort_active;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700105 uint8_t io_lock_on;
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700106 uint16_t command = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 uint16_t *iptr;
108 uint16_t __iomem *optr;
109 uint32_t cnt;
110 uint32_t mboxes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 unsigned long wait_time;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800112 struct qla_hw_data *ha = vha->hw;
113 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
Quinn Tranb2000802018-08-02 13:16:52 -0700114 u32 chip_reset;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700115
Himanshu Madhanid14e72f2015-04-09 15:00:03 -0400116
Arun Easi5e19ed92012-02-09 11:15:51 -0800117 ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700118
119 if (ha->pdev->error_state > pci_channel_io_frozen) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800120 ql_log(ql_log_warn, vha, 0x1001,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700121 "error_state is greater than pci_channel_io_frozen, "
122 "exiting.\n");
Seokmann Jub9b12f72009-03-24 09:08:18 -0700123 return QLA_FUNCTION_TIMEOUT;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700124 }
Seokmann Jub9b12f72009-03-24 09:08:18 -0700125
Giridhar Malavalia9083012010-04-12 17:59:55 -0700126 if (vha->device_flags & DFLG_DEV_FAILED) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800127 ql_log(ql_log_warn, vha, 0x1002,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700128 "Device in failed state, exiting.\n");
Giridhar Malavalia9083012010-04-12 17:59:55 -0700129 return QLA_FUNCTION_TIMEOUT;
130 }
131
Bart Van Asschec2a5d942017-01-11 15:58:58 -0800132 /* if PCI error, then avoid mbx processing.*/
Sawan Chandakba175892017-06-02 09:11:58 -0700133 if (test_bit(PFLG_DISCONNECTED, &base_vha->dpc_flags) &&
134 test_bit(UNLOADING, &base_vha->dpc_flags)) {
Quinn Tran83548fe2017-06-02 09:12:01 -0700135 ql_log(ql_log_warn, vha, 0xd04e,
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400136 "PCI error, exiting.\n");
137 return QLA_FUNCTION_TIMEOUT;
Bart Van Asschec2a5d942017-01-11 15:58:58 -0800138 }
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400139
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700140 reg = ha->iobase;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800141 io_lock_on = base_vha->flags.init_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142
143 rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800144 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Quinn Tranb2000802018-08-02 13:16:52 -0700145 chip_reset = ha->chip_reset;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700146
Andrew Vasquez85880802009-12-15 21:29:46 -0800147 if (ha->flags.pci_channel_io_perm_failure) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800148 ql_log(ql_log_warn, vha, 0x1003,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700149 "Perm failure on EEH timeout MBX, exiting.\n");
Andrew Vasquez85880802009-12-15 21:29:46 -0800150 return QLA_FUNCTION_TIMEOUT;
151 }
152
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400153 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Giridhar Malavali862cd012011-02-23 15:27:11 -0800154 /* Setting Link-Down error */
155 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
Arun Easi5e19ed92012-02-09 11:15:51 -0800156 ql_log(ql_log_warn, vha, 0x1004,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700157 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Andrew Vasquez1806fcd2011-11-18 09:02:15 -0800158 return QLA_FUNCTION_TIMEOUT;
Giridhar Malavali862cd012011-02-23 15:27:11 -0800159 }
160
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -0800161 /* check if ISP abort is active and return cmd with timeout */
162 if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
163 test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
164 test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) &&
165 !is_rom_cmd(mcp->mb[0])) {
166 ql_log(ql_log_info, vha, 0x1005,
167 "Cmd 0x%x aborted with timeout since ISP Abort is pending\n",
168 mcp->mb[0]);
169 return QLA_FUNCTION_TIMEOUT;
170 }
171
Quinn Tranb2000802018-08-02 13:16:52 -0700172 atomic_inc(&ha->num_pend_mbx_stage1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700174 * Wait for active mailbox commands to finish by waiting at most tov
175 * seconds. This is to serialize actual issuing of mailbox cmds during
176 * non ISP abort time.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800178 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
179 /* Timeout occurred. Return error. */
Quinn Tran83548fe2017-06-02 09:12:01 -0700180 ql_log(ql_log_warn, vha, 0xd035,
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800181 "Cmd access timeout, cmd=0x%x, Exiting.\n",
182 mcp->mb[0]);
Quinn Tranb2000802018-08-02 13:16:52 -0700183 atomic_dec(&ha->num_pend_mbx_stage1);
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800184 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 }
Quinn Tranb2000802018-08-02 13:16:52 -0700186 atomic_dec(&ha->num_pend_mbx_stage1);
187 if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) {
188 rval = QLA_ABORTED;
189 goto premature_exit;
190 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191
192 ha->flags.mbox_busy = 1;
193 /* Save mailbox command for debug */
194 ha->mcp = mcp;
195
Arun Easi5e19ed92012-02-09 11:15:51 -0800196 ql_dbg(ql_dbg_mbx, vha, 0x1006,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700197 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198
199 spin_lock_irqsave(&ha->hardware_lock, flags);
200
Quinn Tranb2000802018-08-02 13:16:52 -0700201 if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) {
202 rval = QLA_ABORTED;
203 ha->flags.mbox_busy = 0;
204 spin_unlock_irqrestore(&ha->hardware_lock, flags);
205 goto premature_exit;
206 }
207
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 /* Load mailbox registers. */
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400209 if (IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -0700210 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400211 else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700212 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
213 else
214 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
216 iptr = mcp->mb;
217 command = mcp->mb[0];
218 mboxes = mcp->out_mb;
219
Joe Carnuccio7b711622014-09-25 05:16:43 -0400220 ql_dbg(ql_dbg_mbx, vha, 0x1111,
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700221 "Mailbox registers (OUT):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
223 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700224 optr =
225 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700226 if (mboxes & BIT_0) {
227 ql_dbg(ql_dbg_mbx, vha, 0x1112,
228 "mbox[%d]<-0x%04x\n", cnt, *iptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 WRT_REG_WORD(optr, *iptr);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700230 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231
232 mboxes >>= 1;
233 optr++;
234 iptr++;
235 }
236
Arun Easi5e19ed92012-02-09 11:15:51 -0800237 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700238 "I/O Address = %p.\n", optr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239
240 /* Issue set host interrupt command to send cmd out. */
241 ha->flags.mbox_int = 0;
242 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
243
244 /* Unlock mbx registers and wait for interrupt */
Arun Easi5e19ed92012-02-09 11:15:51 -0800245 ql_dbg(ql_dbg_mbx, vha, 0x100f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700246 "Going to unlock irq & waiting for interrupts. "
247 "jiffies=%lx.\n", jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700248
249 /* Wait for mbx cmd completion until timeout */
Quinn Tranb2000802018-08-02 13:16:52 -0700250 atomic_inc(&ha->num_pend_mbx_stage2);
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800251 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
253
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400254 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700255 if (RD_REG_DWORD(&reg->isp82.hint) &
256 HINT_MBX_INT_PENDING) {
257 spin_unlock_irqrestore(&ha->hardware_lock,
258 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800259 ha->flags.mbox_busy = 0;
Quinn Tranb2000802018-08-02 13:16:52 -0700260 atomic_dec(&ha->num_pend_mbx_stage2);
Arun Easi5e19ed92012-02-09 11:15:51 -0800261 ql_dbg(ql_dbg_mbx, vha, 0x1010,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700262 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700263 rval = QLA_FUNCTION_TIMEOUT;
264 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700265 }
266 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
267 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700268 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
269 else
270 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 spin_unlock_irqrestore(&ha->hardware_lock, flags);
272
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -0800273 wait_time = jiffies;
Quinn Tranb2000802018-08-02 13:16:52 -0700274 atomic_inc(&ha->num_pend_mbx_stage3);
Giridhar Malavali754d1242013-06-25 11:27:16 -0400275 if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
276 mcp->tov * HZ)) {
277 ql_dbg(ql_dbg_mbx, vha, 0x117a,
278 "cmd=%x Timeout.\n", command);
279 spin_lock_irqsave(&ha->hardware_lock, flags);
280 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
281 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Quinn Tranb2000802018-08-02 13:16:52 -0700282
283 } else if (ha->flags.purge_mbox ||
284 chip_reset != ha->chip_reset) {
285 ha->flags.mbox_busy = 0;
286 atomic_dec(&ha->num_pend_mbx_stage2);
287 atomic_dec(&ha->num_pend_mbx_stage3);
288 rval = QLA_ABORTED;
289 goto premature_exit;
Giridhar Malavali754d1242013-06-25 11:27:16 -0400290 }
Quinn Tranb2000802018-08-02 13:16:52 -0700291 atomic_dec(&ha->num_pend_mbx_stage3);
292
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -0800293 if (time_after(jiffies, wait_time + 5 * HZ))
294 ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",
295 command, jiffies_to_msecs(jiffies - wait_time));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 } else {
Arun Easi5e19ed92012-02-09 11:15:51 -0800297 ql_dbg(ql_dbg_mbx, vha, 0x1011,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700298 "Cmd=%x Polling Mode.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400300 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700301 if (RD_REG_DWORD(&reg->isp82.hint) &
302 HINT_MBX_INT_PENDING) {
303 spin_unlock_irqrestore(&ha->hardware_lock,
304 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800305 ha->flags.mbox_busy = 0;
Quinn Tranb2000802018-08-02 13:16:52 -0700306 atomic_dec(&ha->num_pend_mbx_stage2);
Arun Easi5e19ed92012-02-09 11:15:51 -0800307 ql_dbg(ql_dbg_mbx, vha, 0x1012,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700308 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700309 rval = QLA_FUNCTION_TIMEOUT;
310 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700311 }
312 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
313 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700314 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
315 else
316 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318
319 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
320 while (!ha->flags.mbox_int) {
Quinn Tranb2000802018-08-02 13:16:52 -0700321 if (ha->flags.purge_mbox ||
322 chip_reset != ha->chip_reset) {
323 ha->flags.mbox_busy = 0;
324 atomic_dec(&ha->num_pend_mbx_stage2);
325 rval = QLA_ABORTED;
326 goto premature_exit;
327 }
328
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 if (time_after(jiffies, wait_time))
330 break;
331
Rodrigo R. Galvao3cb182b2018-05-28 14:58:44 -0300332 /*
333 * Check if it's UNLOADING, cause we cannot poll in
334 * this case, or else a NULL pointer dereference
335 * is triggered.
336 */
337 if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags)))
338 return QLA_FUNCTION_TIMEOUT;
339
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800341 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342
Andrew Vasquez85880802009-12-15 21:29:46 -0800343 if (!ha->flags.mbox_int &&
344 !(IS_QLA2200(ha) &&
345 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800346 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 } /* while */
Arun Easi5e19ed92012-02-09 11:15:51 -0800348 ql_dbg(ql_dbg_mbx, vha, 0x1013,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700349 "Waited %d sec.\n",
350 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 }
Quinn Tranb2000802018-08-02 13:16:52 -0700352 atomic_dec(&ha->num_pend_mbx_stage2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 /* Check whether we timed out */
355 if (ha->flags.mbox_int) {
356 uint16_t *iptr2;
357
Arun Easi5e19ed92012-02-09 11:15:51 -0800358 ql_dbg(ql_dbg_mbx, vha, 0x1014,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700359 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360
361 /* Got interrupt. Clear the flag. */
362 ha->flags.mbox_int = 0;
363 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
364
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400365 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700366 ha->flags.mbox_busy = 0;
367 /* Setting Link-Down error */
368 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
369 ha->mcp = NULL;
370 rval = QLA_FUNCTION_FAILED;
Quinn Tran83548fe2017-06-02 09:12:01 -0700371 ql_log(ql_log_warn, vha, 0xd048,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700372 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700373 goto premature_exit;
374 }
375
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400376 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378
379 /* Load return mailbox registers. */
380 iptr2 = mcp->mb;
381 iptr = (uint16_t *)&ha->mailbox_out[0];
382 mboxes = mcp->in_mb;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700383
384 ql_dbg(ql_dbg_mbx, vha, 0x1113,
385 "Mailbox registers (IN):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700387 if (mboxes & BIT_0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388 *iptr2 = *iptr;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700389 ql_dbg(ql_dbg_mbx, vha, 0x1114,
390 "mbox[%d]->0x%04x\n", cnt, *iptr2);
391 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392
393 mboxes >>= 1;
394 iptr2++;
395 iptr++;
396 }
397 } else {
398
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800399 uint16_t mb[8];
400 uint32_t ictrl, host_status, hccr;
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400401 uint16_t w;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700402
Andrew Vasqueze4289242007-07-19 15:05:56 -0700403 if (IS_FWI2_CAPABLE(ha)) {
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800404 mb[0] = RD_REG_WORD(&reg->isp24.mailbox0);
405 mb[1] = RD_REG_WORD(&reg->isp24.mailbox1);
406 mb[2] = RD_REG_WORD(&reg->isp24.mailbox2);
407 mb[3] = RD_REG_WORD(&reg->isp24.mailbox3);
408 mb[7] = RD_REG_WORD(&reg->isp24.mailbox7);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700409 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800410 host_status = RD_REG_DWORD(&reg->isp24.host_status);
411 hccr = RD_REG_DWORD(&reg->isp24.hccr);
412
Quinn Tran83548fe2017-06-02 09:12:01 -0700413 ql_log(ql_log_warn, vha, 0xd04c,
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800414 "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
415 "mb[0-3]=[0x%x 0x%x 0x%x 0x%x] mb7 0x%x host_status 0x%x hccr 0x%x\n",
416 command, ictrl, jiffies, mb[0], mb[1], mb[2], mb[3],
417 mb[7], host_status, hccr);
418
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700419 } else {
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800420 mb[0] = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700421 ictrl = RD_REG_WORD(&reg->isp.ictrl);
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800422 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119,
423 "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
424 "mb[0]=0x%x\n", command, ictrl, jiffies, mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700425 }
Arun Easi5e19ed92012-02-09 11:15:51 -0800426 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400428 /* Capture FW dump only, if PCI device active */
429 if (!pci_channel_offline(vha->hw->pdev)) {
430 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
Quinn Tranb2000802018-08-02 13:16:52 -0700431 if (w == 0xffff || ictrl == 0xffffffff ||
432 (chip_reset != ha->chip_reset)) {
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400433 /* This is special case if there is unload
434 * of driver happening and if PCI device go
435 * into bad state due to PCI error condition
436 * then only PCI ERR flag would be set.
437 * we will do premature exit for above case.
438 */
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400439 ha->flags.mbox_busy = 0;
440 rval = QLA_FUNCTION_TIMEOUT;
441 goto premature_exit;
442 }
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800443
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400444 /* Attempt to capture firmware dump for further
445 * anallysis of the current formware state. we do not
446 * need to do this if we are intentionally generating
447 * a dump
448 */
449 if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR)
450 ha->isp_ops->fw_dump(vha, 0);
451 rval = QLA_FUNCTION_TIMEOUT;
452 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 }
454
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 ha->flags.mbox_busy = 0;
456
457 /* Clean up */
458 ha->mcp = NULL;
459
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800460 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800461 ql_dbg(ql_dbg_mbx, vha, 0x101a,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700462 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463
464 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800465 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 }
467
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700468 if (rval == QLA_FUNCTION_TIMEOUT &&
469 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800470 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
471 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 /* not in dpc. schedule it for dpc to take over. */
Arun Easi5e19ed92012-02-09 11:15:51 -0800473 ql_dbg(ql_dbg_mbx, vha, 0x101b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700474 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700475
476 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
477 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
478 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800479 if (IS_QLA82XX(ha)) {
480 ql_dbg(ql_dbg_mbx, vha, 0x112a,
481 "disabling pause transmit on port "
482 "0 & 1.\n");
483 qla82xx_wr_32(ha,
484 QLA82XX_CRB_NIU + 0x98,
485 CRB_NIU_XG_PAUSE_CTL_P0|
486 CRB_NIU_XG_PAUSE_CTL_P1);
487 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700488 ql_log(ql_log_info, base_vha, 0x101c,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400489 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800490 "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "
491 "abort.\n", command, mcp->mb[0],
492 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700493 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
494 qla2xxx_wake_dpc(vha);
495 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 /* call abort directly since we are in the DPC thread */
Arun Easi5e19ed92012-02-09 11:15:51 -0800498 ql_dbg(ql_dbg_mbx, vha, 0x101d,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700499 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700501 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
502 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
503 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800504 if (IS_QLA82XX(ha)) {
505 ql_dbg(ql_dbg_mbx, vha, 0x112b,
506 "disabling pause transmit on port "
507 "0 & 1.\n");
508 qla82xx_wr_32(ha,
509 QLA82XX_CRB_NIU + 0x98,
510 CRB_NIU_XG_PAUSE_CTL_P0|
511 CRB_NIU_XG_PAUSE_CTL_P1);
512 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700513 ql_log(ql_log_info, base_vha, 0x101e,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400514 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800515 "mb[0]=0x%x. Scheduling ISP abort ",
516 command, mcp->mb[0]);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700517 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
518 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
Giridhar Malavalid3360962012-02-09 11:14:10 -0800519 /* Allow next mbx cmd to come in. */
520 complete(&ha->mbx_cmd_comp);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700521 if (ha->isp_ops->abort_isp(vha)) {
522 /* Failed. retry later. */
523 set_bit(ISP_ABORT_NEEDED,
524 &vha->dpc_flags);
525 }
526 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Arun Easi5e19ed92012-02-09 11:15:51 -0800527 ql_dbg(ql_dbg_mbx, vha, 0x101f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700528 "Finished abort_isp.\n");
Giridhar Malavalid3360962012-02-09 11:14:10 -0800529 goto mbx_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531 }
532 }
533
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700534premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800536 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537
Giridhar Malavalid3360962012-02-09 11:14:10 -0800538mbx_done:
Quinn Tranb2000802018-08-02 13:16:52 -0700539 if (rval == QLA_ABORTED) {
540 ql_log(ql_log_info, vha, 0xd035,
541 "Chip Reset in progress. Purging Mbox cmd=0x%x.\n",
542 mcp->mb[0]);
543 } else if (rval) {
Joe Carnuccio050dc762017-08-23 15:05:14 -0700544 if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) {
545 pr_warn("%s [%s]-%04x:%ld: **** Failed", QL_MSGHDR,
546 dev_name(&ha->pdev->dev), 0x1020+0x800,
547 vha->host_no);
548 mboxes = mcp->in_mb;
549 cnt = 4;
550 for (i = 0; i < ha->mbx_count && cnt; i++, mboxes >>= 1)
551 if (mboxes & BIT_0) {
552 printk(" mb[%u]=%x", i, mcp->mb[i]);
553 cnt--;
554 }
555 pr_warn(" cmd=%x ****\n", command);
556 }
Meelis Roosf7e59e92018-03-08 15:44:07 +0200557 if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) {
558 ql_dbg(ql_dbg_mbx, vha, 0x1198,
559 "host_status=%#x intr_ctrl=%#x intr_status=%#x\n",
560 RD_REG_DWORD(&reg->isp24.host_status),
561 RD_REG_DWORD(&reg->isp24.ictrl),
562 RD_REG_DWORD(&reg->isp24.istatus));
563 } else {
564 ql_dbg(ql_dbg_mbx, vha, 0x1206,
565 "ctrl_status=%#x ictrl=%#x istatus=%#x\n",
566 RD_REG_WORD(&reg->isp.ctrl_status),
567 RD_REG_WORD(&reg->isp.ictrl),
568 RD_REG_WORD(&reg->isp.istatus));
569 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700571 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 }
573
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 return rval;
575}
576
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800578qla2x00_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 -0800579 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580{
581 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800582 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 mbx_cmd_t mc;
584 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400586 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022,
587 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588
Andrew Vasqueze4289242007-07-19 15:05:56 -0700589 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800590 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
591 mcp->mb[8] = MSW(risc_addr);
592 mcp->out_mb = MBX_8|MBX_0;
593 } else {
594 mcp->mb[0] = MBC_LOAD_RISC_RAM;
595 mcp->out_mb = MBX_0;
596 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 mcp->mb[1] = LSW(risc_addr);
598 mcp->mb[2] = MSW(req_dma);
599 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 mcp->mb[6] = MSW(MSD(req_dma));
601 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800602 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700603 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700604 mcp->mb[4] = MSW(risc_code_size);
605 mcp->mb[5] = LSW(risc_code_size);
606 mcp->out_mb |= MBX_5|MBX_4;
607 } else {
608 mcp->mb[4] = LSW(risc_code_size);
609 mcp->out_mb |= MBX_4;
610 }
611
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700613 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800615 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700618 ql_dbg(ql_dbg_mbx, vha, 0x1023,
619 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400621 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,
622 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 }
624
625 return rval;
626}
627
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700628#define EXTENDED_BB_CREDITS BIT_0
Duane Grigsbye84067d2017-06-21 13:48:43 -0700629#define NVME_ENABLE_FLAG BIT_3
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700630static inline uint16_t qla25xx_set_sfp_lr_dist(struct qla_hw_data *ha)
631{
632 uint16_t mb4 = BIT_0;
633
634 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
635 mb4 |= ha->long_range_distance << LR_DIST_FW_POS;
636
637 return mb4;
638}
639
640static inline uint16_t qla25xx_set_nvr_lr_dist(struct qla_hw_data *ha)
641{
642 uint16_t mb4 = BIT_0;
643
644 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
645 struct nvram_81xx *nv = ha->nvram;
646
647 mb4 |= LR_DIST_FW_FIELD(nv->enhanced_features);
648 }
649
650 return mb4;
651}
Duane Grigsbye84067d2017-06-21 13:48:43 -0700652
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653/*
654 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700655 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 *
657 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700658 * ha = adapter block pointer.
659 * TARGET_QUEUE_LOCK must be released.
660 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 *
662 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700663 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 *
665 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700666 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 */
668int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800669qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670{
671 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800672 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700673 mbx_cmd_t mc;
674 mbx_cmd_t *mcp = &mc;
675
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400676 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,
677 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678
679 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700680 mcp->out_mb = MBX_0;
681 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700682 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700683 mcp->mb[1] = MSW(risc_addr);
684 mcp->mb[2] = LSW(risc_addr);
685 mcp->mb[3] = 0;
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700686 mcp->mb[4] = 0;
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700687 ha->flags.using_lr_setting = 0;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500688 if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
689 IS_QLA27XX(ha)) {
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700690 if (ql2xautodetectsfp) {
691 if (ha->flags.detected_lr_sfp) {
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700692 mcp->mb[4] |=
693 qla25xx_set_sfp_lr_dist(ha);
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700694 ha->flags.using_lr_setting = 1;
695 }
696 } else {
697 struct nvram_81xx *nv = ha->nvram;
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700698 /* set LR distance if specified in nvram */
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700699 if (nv->enhanced_features &
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700700 NEF_LR_DIST_ENABLE) {
701 mcp->mb[4] |=
702 qla25xx_set_nvr_lr_dist(ha);
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700703 ha->flags.using_lr_setting = 1;
704 }
705 }
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700706 }
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500707
Duane Grigsbye84067d2017-06-21 13:48:43 -0700708 if (ql2xnvmeenable && IS_QLA27XX(ha))
709 mcp->mb[4] |= NVME_ENABLE_FLAG;
710
Sawan Chandak92d44082017-08-23 15:05:16 -0700711 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
712 struct nvram_81xx *nv = ha->nvram;
713 /* set minimum speed if specified in nvram */
714 if (nv->min_link_speed >= 2 &&
715 nv->min_link_speed <= 5) {
716 mcp->mb[4] |= BIT_4;
717 mcp->mb[11] = nv->min_link_speed;
718 mcp->out_mb |= MBX_11;
719 mcp->in_mb |= BIT_5;
720 vha->min_link_speed_feat = nv->min_link_speed;
721 }
722 }
723
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500724 if (ha->flags.exlogins_enabled)
725 mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;
726
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -0500727 if (ha->flags.exchoffld_enabled)
728 mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
729
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700730 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700731 mcp->in_mb |= MBX_3 | MBX_2 | MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700732 } else {
733 mcp->mb[1] = LSW(risc_addr);
734 mcp->out_mb |= MBX_1;
735 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
736 mcp->mb[2] = 0;
737 mcp->out_mb |= MBX_2;
738 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 }
740
Ravi Anandb93480e2008-04-03 13:13:25 -0700741 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700742 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800743 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700745 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700746 ql_dbg(ql_dbg_mbx, vha, 0x1026,
747 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700748 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700749 if (IS_FWI2_CAPABLE(ha)) {
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700750 ha->fw_ability_mask = mcp->mb[3] << 16 | mcp->mb[2];
751 ql_dbg(ql_dbg_mbx, vha, 0x119a,
752 "fw_ability_mask=%x.\n", ha->fw_ability_mask);
Sawan Chandak92d44082017-08-23 15:05:16 -0700753 ql_dbg(ql_dbg_mbx, vha, 0x1027,
754 "exchanges=%x.\n", mcp->mb[1]);
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700755 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
756 ha->max_speed_sup = mcp->mb[2] & BIT_0;
Sawan Chandak92d44082017-08-23 15:05:16 -0700757 ql_dbg(ql_dbg_mbx, vha, 0x119b,
758 "Maximum speed supported=%s.\n",
759 ha->max_speed_sup ? "32Gps" : "16Gps");
760 if (vha->min_link_speed_feat) {
761 ha->min_link_speed = mcp->mb[5];
762 ql_dbg(ql_dbg_mbx, vha, 0x119c,
763 "Minimum speed set=%s.\n",
764 mcp->mb[5] == 5 ? "32Gps" :
765 mcp->mb[5] == 4 ? "16Gps" :
766 mcp->mb[5] == 3 ? "8Gps" :
767 mcp->mb[5] == 2 ? "4Gps" :
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700768 "unknown");
Sawan Chandak92d44082017-08-23 15:05:16 -0700769 }
770 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700771 }
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700772 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
773 "Done.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700774 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775
776 return rval;
777}
778
779/*
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500780 * qla_get_exlogin_status
781 * Get extended login status
782 * uses the memory offload control/status Mailbox
783 *
784 * Input:
785 * ha: adapter state pointer.
786 * fwopt: firmware options
787 *
788 * Returns:
789 * qla2x00 local function status
790 *
791 * Context:
792 * Kernel context.
793 */
794#define FETCH_XLOGINS_STAT 0x8
795int
796qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
797 uint16_t *ex_logins_cnt)
798{
799 int rval;
800 mbx_cmd_t mc;
801 mbx_cmd_t *mcp = &mc;
802
803 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f,
804 "Entered %s\n", __func__);
805
806 memset(mcp->mb, 0 , sizeof(mcp->mb));
807 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
808 mcp->mb[1] = FETCH_XLOGINS_STAT;
809 mcp->out_mb = MBX_1|MBX_0;
810 mcp->in_mb = MBX_10|MBX_4|MBX_0;
811 mcp->tov = MBX_TOV_SECONDS;
812 mcp->flags = 0;
813
814 rval = qla2x00_mailbox_command(vha, mcp);
815 if (rval != QLA_SUCCESS) {
816 ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval);
817 } else {
818 *buf_sz = mcp->mb[4];
819 *ex_logins_cnt = mcp->mb[10];
820
821 ql_log(ql_log_info, vha, 0x1190,
822 "buffer size 0x%x, exchange login count=%d\n",
823 mcp->mb[4], mcp->mb[10]);
824
825 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116,
826 "Done %s.\n", __func__);
827 }
828
829 return rval;
830}
831
832/*
833 * qla_set_exlogin_mem_cfg
834 * set extended login memory configuration
835 * Mbx needs to be issues before init_cb is set
836 *
837 * Input:
838 * ha: adapter state pointer.
839 * buffer: buffer pointer
840 * phys_addr: physical address of buffer
841 * size: size of buffer
842 * TARGET_QUEUE_LOCK must be released
843 * ADAPTER_STATE_LOCK must be release
844 *
845 * Returns:
846 * qla2x00 local funxtion status code.
847 *
848 * Context:
849 * Kernel context.
850 */
851#define CONFIG_XLOGINS_MEM 0x3
852int
853qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
854{
855 int rval;
856 mbx_cmd_t mc;
857 mbx_cmd_t *mcp = &mc;
858 struct qla_hw_data *ha = vha->hw;
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500859
860 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a,
861 "Entered %s.\n", __func__);
862
863 memset(mcp->mb, 0 , sizeof(mcp->mb));
864 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
865 mcp->mb[1] = CONFIG_XLOGINS_MEM;
866 mcp->mb[2] = MSW(phys_addr);
867 mcp->mb[3] = LSW(phys_addr);
868 mcp->mb[6] = MSW(MSD(phys_addr));
869 mcp->mb[7] = LSW(MSD(phys_addr));
870 mcp->mb[8] = MSW(ha->exlogin_size);
871 mcp->mb[9] = LSW(ha->exlogin_size);
872 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
873 mcp->in_mb = MBX_11|MBX_0;
874 mcp->tov = MBX_TOV_SECONDS;
875 mcp->flags = 0;
876 rval = qla2x00_mailbox_command(vha, mcp);
877 if (rval != QLA_SUCCESS) {
878 /*EMPTY*/
879 ql_dbg(ql_dbg_mbx, vha, 0x111b, "Failed=%x.\n", rval);
880 } else {
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500881 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
882 "Done %s.\n", __func__);
883 }
884
885 return rval;
886}
887
888/*
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -0500889 * qla_get_exchoffld_status
890 * Get exchange offload status
891 * uses the memory offload control/status Mailbox
892 *
893 * Input:
894 * ha: adapter state pointer.
895 * fwopt: firmware options
896 *
897 * Returns:
898 * qla2x00 local function status
899 *
900 * Context:
901 * Kernel context.
902 */
903#define FETCH_XCHOFFLD_STAT 0x2
904int
905qla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
906 uint16_t *ex_logins_cnt)
907{
908 int rval;
909 mbx_cmd_t mc;
910 mbx_cmd_t *mcp = &mc;
911
912 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1019,
913 "Entered %s\n", __func__);
914
915 memset(mcp->mb, 0 , sizeof(mcp->mb));
916 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
917 mcp->mb[1] = FETCH_XCHOFFLD_STAT;
918 mcp->out_mb = MBX_1|MBX_0;
919 mcp->in_mb = MBX_10|MBX_4|MBX_0;
920 mcp->tov = MBX_TOV_SECONDS;
921 mcp->flags = 0;
922
923 rval = qla2x00_mailbox_command(vha, mcp);
924 if (rval != QLA_SUCCESS) {
925 ql_dbg(ql_dbg_mbx, vha, 0x1155, "Failed=%x.\n", rval);
926 } else {
927 *buf_sz = mcp->mb[4];
928 *ex_logins_cnt = mcp->mb[10];
929
930 ql_log(ql_log_info, vha, 0x118e,
931 "buffer size 0x%x, exchange offload count=%d\n",
932 mcp->mb[4], mcp->mb[10]);
933
934 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1156,
935 "Done %s.\n", __func__);
936 }
937
938 return rval;
939}
940
941/*
942 * qla_set_exchoffld_mem_cfg
943 * Set exchange offload memory configuration
944 * Mbx needs to be issues before init_cb is set
945 *
946 * Input:
947 * ha: adapter state pointer.
948 * buffer: buffer pointer
949 * phys_addr: physical address of buffer
950 * size: size of buffer
951 * TARGET_QUEUE_LOCK must be released
952 * ADAPTER_STATE_LOCK must be release
953 *
954 * Returns:
955 * qla2x00 local funxtion status code.
956 *
957 * Context:
958 * Kernel context.
959 */
960#define CONFIG_XCHOFFLD_MEM 0x3
961int
Quinn Tran99e1b682017-06-02 09:12:03 -0700962qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha)
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -0500963{
964 int rval;
965 mbx_cmd_t mc;
966 mbx_cmd_t *mcp = &mc;
967 struct qla_hw_data *ha = vha->hw;
968
969 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1157,
970 "Entered %s.\n", __func__);
971
972 memset(mcp->mb, 0 , sizeof(mcp->mb));
973 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
974 mcp->mb[1] = CONFIG_XCHOFFLD_MEM;
Quinn Tran99e1b682017-06-02 09:12:03 -0700975 mcp->mb[2] = MSW(ha->exchoffld_buf_dma);
976 mcp->mb[3] = LSW(ha->exchoffld_buf_dma);
977 mcp->mb[6] = MSW(MSD(ha->exchoffld_buf_dma));
978 mcp->mb[7] = LSW(MSD(ha->exchoffld_buf_dma));
979 mcp->mb[8] = MSW(ha->exchoffld_size);
980 mcp->mb[9] = LSW(ha->exchoffld_size);
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -0500981 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
982 mcp->in_mb = MBX_11|MBX_0;
983 mcp->tov = MBX_TOV_SECONDS;
984 mcp->flags = 0;
985 rval = qla2x00_mailbox_command(vha, mcp);
986 if (rval != QLA_SUCCESS) {
987 /*EMPTY*/
988 ql_dbg(ql_dbg_mbx, vha, 0x1158, "Failed=%x.\n", rval);
989 } else {
990 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192,
991 "Done %s.\n", __func__);
992 }
993
994 return rval;
995}
996
997/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 * qla2x00_get_fw_version
999 * Get firmware version.
1000 *
1001 * Input:
1002 * ha: adapter state pointer.
1003 * major: pointer for major number.
1004 * minor: pointer for minor number.
1005 * subminor: pointer for subminor number.
1006 *
1007 * Returns:
1008 * qla2x00 local function return status code.
1009 *
1010 * Context:
1011 * Kernel context.
1012 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -07001013int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001014qla2x00_get_fw_version(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015{
1016 int rval;
1017 mbx_cmd_t mc;
1018 mbx_cmd_t *mcp = &mc;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001019 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001021 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029,
1022 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023
1024 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
1025 mcp->out_mb = MBX_0;
1026 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001027 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha))
Andrew Vasquez55a96152009-03-24 09:08:03 -07001028 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Saurav Kashyapfb0effe2012-08-22 14:21:28 -04001029 if (IS_FWI2_CAPABLE(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001030 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001031 if (IS_QLA27XX(ha))
Joe Carnuccioad1ef172016-07-06 11:14:18 -04001032 mcp->in_mb |=
1033 MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18|
1034 MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8;
Sawan Chandak03aa8682015-08-04 13:37:59 -04001035
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001037 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001038 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -07001039 if (rval != QLA_SUCCESS)
1040 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001041
1042 /* Return mailbox data. */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001043 ha->fw_major_version = mcp->mb[1];
1044 ha->fw_minor_version = mcp->mb[2];
1045 ha->fw_subminor_version = mcp->mb[3];
1046 ha->fw_attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001047 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001048 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001049 else
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001050 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
Sawan Chandak03aa8682015-08-04 13:37:59 -04001051
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001052 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001053 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->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
1057 ha->phy_version[0] = mcp->mb[8] & 0xff;
1058 ha->phy_version[1] = mcp->mb[9] >> 8;
1059 ha->phy_version[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001060 }
Sawan Chandak03aa8682015-08-04 13:37:59 -04001061
Saurav Kashyap81178772012-08-22 14:21:04 -04001062 if (IS_FWI2_CAPABLE(ha)) {
1063 ha->fw_attributes_h = mcp->mb[15];
1064 ha->fw_attributes_ext[0] = mcp->mb[16];
1065 ha->fw_attributes_ext[1] = mcp->mb[17];
1066 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,
1067 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
1068 __func__, mcp->mb[15], mcp->mb[6]);
1069 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
1070 "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
1071 __func__, mcp->mb[17], mcp->mb[16]);
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -05001072
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -05001073 if (ha->fw_attributes_h & 0x4)
1074 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d,
1075 "%s: Firmware supports Extended Login 0x%x\n",
1076 __func__, ha->fw_attributes_h);
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -05001077
1078 if (ha->fw_attributes_h & 0x8)
1079 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191,
1080 "%s: Firmware supports Exchange Offload 0x%x\n",
1081 __func__, ha->fw_attributes_h);
Duane Grigsbye84067d2017-06-21 13:48:43 -07001082
Duane Grigsbydeeae7a2017-07-21 09:32:25 -07001083 /*
1084 * FW supports nvme and driver load parameter requested nvme.
1085 * BIT 26 of fw_attributes indicates NVMe support.
1086 */
Darren Trapp1cbc0ef2018-03-20 23:09:37 -07001087 if ((ha->fw_attributes_h & 0x400) && ql2xnvmeenable) {
Duane Grigsbye84067d2017-06-21 13:48:43 -07001088 vha->flags.nvme_enabled = 1;
Darren Trapp1cbc0ef2018-03-20 23:09:37 -07001089 ql_log(ql_log_info, vha, 0xd302,
1090 "%s: FC-NVMe is Enabled (0x%x)\n",
1091 __func__, ha->fw_attributes_h);
1092 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001093 }
Sawan Chandak03aa8682015-08-04 13:37:59 -04001094
Chad Dupuisf73cb692014-02-26 04:15:06 -05001095 if (IS_QLA27XX(ha)) {
Sawan Chandak03aa8682015-08-04 13:37:59 -04001096 ha->mpi_version[0] = mcp->mb[10] & 0xff;
1097 ha->mpi_version[1] = mcp->mb[11] >> 8;
1098 ha->mpi_version[2] = mcp->mb[11] & 0xff;
1099 ha->pep_version[0] = mcp->mb[13] & 0xff;
1100 ha->pep_version[1] = mcp->mb[14] >> 8;
1101 ha->pep_version[2] = mcp->mb[14] & 0xff;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001102 ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18];
1103 ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20];
Joe Carnuccioad1ef172016-07-06 11:14:18 -04001104 ha->fw_ddr_ram_start = (mcp->mb[23] << 16) | mcp->mb[22];
1105 ha->fw_ddr_ram_end = (mcp->mb[25] << 16) | mcp->mb[24];
Chad Dupuisf73cb692014-02-26 04:15:06 -05001106 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001107
Andrew Vasquezca9e9c32009-06-03 09:55:20 -07001108failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001109 if (rval != QLA_SUCCESS) {
1110 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001111 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 } else {
1113 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001114 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b,
1115 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001116 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -07001117 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118}
1119
1120/*
1121 * qla2x00_get_fw_options
1122 * Set firmware options.
1123 *
1124 * Input:
1125 * ha = adapter block pointer.
1126 * fwopt = pointer for firmware options.
1127 *
1128 * Returns:
1129 * qla2x00 local function return status code.
1130 *
1131 * Context:
1132 * Kernel context.
1133 */
1134int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001135qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136{
1137 int rval;
1138 mbx_cmd_t mc;
1139 mbx_cmd_t *mcp = &mc;
1140
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001141 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c,
1142 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143
1144 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
1145 mcp->out_mb = MBX_0;
1146 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001147 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001148 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001149 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150
1151 if (rval != QLA_SUCCESS) {
1152 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001153 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001154 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001155 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 fwopts[1] = mcp->mb[1];
1157 fwopts[2] = mcp->mb[2];
1158 fwopts[3] = mcp->mb[3];
1159
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001160 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e,
1161 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162 }
1163
1164 return rval;
1165}
1166
1167
1168/*
1169 * qla2x00_set_fw_options
1170 * Set firmware options.
1171 *
1172 * Input:
1173 * ha = adapter block pointer.
1174 * fwopt = pointer for firmware options.
1175 *
1176 * Returns:
1177 * qla2x00 local function return status code.
1178 *
1179 * Context:
1180 * Kernel context.
1181 */
1182int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001183qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184{
1185 int rval;
1186 mbx_cmd_t mc;
1187 mbx_cmd_t *mcp = &mc;
1188
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001189 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f,
1190 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191
1192 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
1193 mcp->mb[1] = fwopts[1];
1194 mcp->mb[2] = fwopts[2];
1195 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001196 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001198 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001199 mcp->in_mb |= MBX_1;
Quinn Tran2da52732017-06-02 09:12:05 -07001200 mcp->mb[10] = fwopts[10];
1201 mcp->out_mb |= MBX_10;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001202 } else {
1203 mcp->mb[10] = fwopts[10];
1204 mcp->mb[11] = fwopts[11];
1205 mcp->mb[12] = 0; /* Undocumented, but used */
1206 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
1207 }
Ravi Anandb93480e2008-04-03 13:13:25 -07001208 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001210 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001211
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001212 fwopts[0] = mcp->mb[0];
1213
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 if (rval != QLA_SUCCESS) {
1215 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001216 ql_dbg(ql_dbg_mbx, vha, 0x1030,
1217 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 } else {
1219 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001220 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031,
1221 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 }
1223
1224 return rval;
1225}
1226
1227/*
1228 * qla2x00_mbx_reg_test
1229 * Mailbox register wrap test.
1230 *
1231 * Input:
1232 * ha = adapter block pointer.
1233 * TARGET_QUEUE_LOCK must be released.
1234 * ADAPTER_STATE_LOCK must be released.
1235 *
1236 * Returns:
1237 * qla2x00 local function return status code.
1238 *
1239 * Context:
1240 * Kernel context.
1241 */
1242int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001243qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244{
1245 int rval;
1246 mbx_cmd_t mc;
1247 mbx_cmd_t *mcp = &mc;
1248
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001249 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032,
1250 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251
1252 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
1253 mcp->mb[1] = 0xAAAA;
1254 mcp->mb[2] = 0x5555;
1255 mcp->mb[3] = 0xAA55;
1256 mcp->mb[4] = 0x55AA;
1257 mcp->mb[5] = 0xA5A5;
1258 mcp->mb[6] = 0x5A5A;
1259 mcp->mb[7] = 0x2525;
1260 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1261 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 -07001262 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001264 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265
1266 if (rval == QLA_SUCCESS) {
1267 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
1268 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
1269 rval = QLA_FUNCTION_FAILED;
1270 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
1271 mcp->mb[7] != 0x2525)
1272 rval = QLA_FUNCTION_FAILED;
1273 }
1274
1275 if (rval != QLA_SUCCESS) {
1276 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001277 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278 } else {
1279 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001280 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034,
1281 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 }
1283
1284 return rval;
1285}
1286
1287/*
1288 * qla2x00_verify_checksum
1289 * Verify firmware checksum.
1290 *
1291 * Input:
1292 * ha = adapter block pointer.
1293 * TARGET_QUEUE_LOCK must be released.
1294 * ADAPTER_STATE_LOCK must be released.
1295 *
1296 * Returns:
1297 * qla2x00 local function return status code.
1298 *
1299 * Context:
1300 * Kernel context.
1301 */
1302int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001303qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304{
1305 int rval;
1306 mbx_cmd_t mc;
1307 mbx_cmd_t *mcp = &mc;
1308
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001309 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035,
1310 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311
1312 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001313 mcp->out_mb = MBX_0;
1314 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001315 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001316 mcp->mb[1] = MSW(risc_addr);
1317 mcp->mb[2] = LSW(risc_addr);
1318 mcp->out_mb |= MBX_2|MBX_1;
1319 mcp->in_mb |= MBX_2|MBX_1;
1320 } else {
1321 mcp->mb[1] = LSW(risc_addr);
1322 mcp->out_mb |= MBX_1;
1323 mcp->in_mb |= MBX_1;
1324 }
1325
Ravi Anandb93480e2008-04-03 13:13:25 -07001326 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001328 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329
1330 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001331 ql_dbg(ql_dbg_mbx, vha, 0x1036,
1332 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
1333 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001335 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037,
1336 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 }
1338
1339 return rval;
1340}
1341
1342/*
1343 * qla2x00_issue_iocb
1344 * Issue IOCB using mailbox command
1345 *
1346 * Input:
1347 * ha = adapter state pointer.
1348 * buffer = buffer pointer.
1349 * phys_addr = physical address of buffer.
1350 * size = size of buffer.
1351 * TARGET_QUEUE_LOCK must be released.
1352 * ADAPTER_STATE_LOCK must be released.
1353 *
1354 * Returns:
1355 * qla2x00 local function return status code.
1356 *
1357 * Context:
1358 * Kernel context.
1359 */
Giridhar Malavali6e980162010-03-19 17:03:58 -07001360int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001361qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001362 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363{
1364 int rval;
1365 mbx_cmd_t mc;
1366 mbx_cmd_t *mcp = &mc;
1367
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001368 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038,
1369 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001370
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
1372 mcp->mb[1] = 0;
1373 mcp->mb[2] = MSW(phys_addr);
1374 mcp->mb[3] = LSW(phys_addr);
1375 mcp->mb[6] = MSW(MSD(phys_addr));
1376 mcp->mb[7] = LSW(MSD(phys_addr));
1377 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1378 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001379 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001381 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382
1383 if (rval != QLA_SUCCESS) {
1384 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001385 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -07001387 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
1388
1389 /* Mask reserved bits. */
1390 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001391 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001392 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a,
1393 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394 }
1395
1396 return rval;
1397}
1398
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001399int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001400qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001401 size_t size)
1402{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001403 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001404 MBX_TOV_SECONDS);
1405}
1406
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407/*
1408 * qla2x00_abort_command
1409 * Abort command aborts a specified IOCB.
1410 *
1411 * Input:
1412 * ha = adapter block pointer.
1413 * sp = SB structure pointer.
1414 *
1415 * Returns:
1416 * qla2x00 local function return status code.
1417 *
1418 * Context:
1419 * Kernel context.
1420 */
1421int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001422qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423{
1424 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001426 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427 mbx_cmd_t mc;
1428 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001429 fc_port_t *fcport = sp->fcport;
1430 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001431 struct qla_hw_data *ha = vha->hw;
Michael Hernandezd7459522016-12-12 14:40:07 -08001432 struct req_que *req;
Giridhar Malavali9ba56b92012-02-09 11:15:36 -08001433 struct scsi_cmnd *cmd = GET_CMD_SP(sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001435 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b,
1436 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437
Michael Hernandezd7459522016-12-12 14:40:07 -08001438 if (vha->flags.qpairs_available && sp->qpair)
1439 req = sp->qpair->req;
1440 else
1441 req = vha->req;
1442
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -07001443 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05001444 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001445 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 break;
1447 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -07001448 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449
Chad Dupuis8d93f552013-01-30 03:34:37 -05001450 if (handle == req->num_outstanding_cmds) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 /* command not found */
1452 return QLA_FUNCTION_FAILED;
1453 }
1454
1455 mcp->mb[0] = MBC_ABORT_COMMAND;
1456 if (HAS_EXTENDED_IDS(ha))
1457 mcp->mb[1] = fcport->loop_id;
1458 else
1459 mcp->mb[1] = fcport->loop_id << 8;
1460 mcp->mb[2] = (uint16_t)handle;
1461 mcp->mb[3] = (uint16_t)(handle >> 16);
Giridhar Malavali9ba56b92012-02-09 11:15:36 -08001462 mcp->mb[6] = (uint16_t)cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1464 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001465 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001467 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001468
1469 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001470 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001472 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d,
1473 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474 }
1475
1476 return rval;
1477}
1478
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001480qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481{
Andrew Vasquez523ec772008-04-03 13:13:24 -07001482 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 mbx_cmd_t mc;
1484 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001485 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001486 struct req_que *req;
1487 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488
Andrew Vasquez523ec772008-04-03 13:13:24 -07001489 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001490 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001491
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001492 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e,
1493 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001494
Giridhar Malavali7e2b8952010-05-28 15:08:17 -07001495 req = vha->hw->req_q_map[0];
1496 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001498 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001499 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500 mcp->mb[1] = fcport->loop_id;
1501 mcp->mb[10] = 0;
1502 mcp->out_mb |= MBX_10;
1503 } else {
1504 mcp->mb[1] = fcport->loop_id << 8;
1505 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001506 mcp->mb[2] = vha->hw->loop_reset_delay;
1507 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508
1509 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001510 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001512 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001514 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f,
1515 "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001516 }
1517
1518 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001519 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
1520 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001521 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001522 ql_dbg(ql_dbg_mbx, vha, 0x1040,
1523 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001525 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041,
1526 "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001527 }
1528
1529 return rval;
1530}
1531
1532int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001533qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07001534{
1535 int rval, rval2;
1536 mbx_cmd_t mc;
1537 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001538 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001539 struct req_que *req;
1540 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001541
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001542 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001543
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001544 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042,
1545 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001546
Giridhar Malavali7e2b8952010-05-28 15:08:17 -07001547 req = vha->hw->req_q_map[0];
1548 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001549 mcp->mb[0] = MBC_LUN_RESET;
1550 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001551 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -07001552 mcp->mb[1] = fcport->loop_id;
1553 else
1554 mcp->mb[1] = fcport->loop_id << 8;
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001555 mcp->mb[2] = (u32)l;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001556 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001557 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001558
1559 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001560 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001561 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001562 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001563 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001564 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001565 }
1566
1567 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001568 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1569 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001570 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001571 ql_dbg(ql_dbg_mbx, vha, 0x1044,
1572 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001573 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001574 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045,
1575 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 }
1577
1578 return rval;
1579}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580
1581/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 * qla2x00_get_adapter_id
1583 * Get adapter ID and topology.
1584 *
1585 * Input:
1586 * ha = adapter block pointer.
1587 * id = pointer for loop ID.
1588 * al_pa = pointer for AL_PA.
1589 * area = pointer for area.
1590 * domain = pointer for domain.
1591 * top = pointer for topology.
1592 * TARGET_QUEUE_LOCK must be released.
1593 * ADAPTER_STATE_LOCK must be released.
1594 *
1595 * Returns:
1596 * qla2x00 local function return status code.
1597 *
1598 * Context:
1599 * Kernel context.
1600 */
1601int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001602qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001603 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604{
1605 int rval;
1606 mbx_cmd_t mc;
1607 mbx_cmd_t *mcp = &mc;
1608
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001609 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046,
1610 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611
1612 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001613 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001614 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001615 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001616 if (IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001617 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001618 if (IS_FWI2_CAPABLE(vha->hw))
1619 mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16;
Sawan Chandak969a6192016-01-27 12:03:32 -05001620 if (IS_QLA27XX(vha->hw))
1621 mcp->in_mb |= MBX_15;
Ravi Anandb93480e2008-04-03 13:13:25 -07001622 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001624 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001625 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1626 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001627 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1628 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629
1630 /* Return data. */
1631 *id = mcp->mb[1];
1632 *al_pa = LSB(mcp->mb[2]);
1633 *area = MSB(mcp->mb[2]);
1634 *domain = LSB(mcp->mb[3]);
1635 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001636 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637
1638 if (rval != QLA_SUCCESS) {
1639 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001640 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001642 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048,
1643 "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001644
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001645 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001646 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1647 vha->fcoe_fcf_idx = mcp->mb[10];
1648 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1649 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1650 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1651 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1652 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1653 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1654 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001655 /* If FA-WWN supported */
Saurav Kashyapd6b9b422015-08-04 13:37:55 -04001656 if (IS_FAWWN_CAPABLE(vha->hw)) {
1657 if (mcp->mb[7] & BIT_14) {
1658 vha->port_name[0] = MSB(mcp->mb[16]);
1659 vha->port_name[1] = LSB(mcp->mb[16]);
1660 vha->port_name[2] = MSB(mcp->mb[17]);
1661 vha->port_name[3] = LSB(mcp->mb[17]);
1662 vha->port_name[4] = MSB(mcp->mb[18]);
1663 vha->port_name[5] = LSB(mcp->mb[18]);
1664 vha->port_name[6] = MSB(mcp->mb[19]);
1665 vha->port_name[7] = LSB(mcp->mb[19]);
1666 fc_host_port_name(vha->host) =
1667 wwn_to_u64(vha->port_name);
1668 ql_dbg(ql_dbg_mbx, vha, 0x10ca,
1669 "FA-WWN acquired %016llx\n",
1670 wwn_to_u64(vha->port_name));
1671 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001672 }
Sawan Chandak969a6192016-01-27 12:03:32 -05001673
1674 if (IS_QLA27XX(vha->hw))
1675 vha->bbcr = mcp->mb[15];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 }
1677
1678 return rval;
1679}
1680
1681/*
1682 * qla2x00_get_retry_cnt
1683 * Get current firmware login retry count and delay.
1684 *
1685 * Input:
1686 * ha = adapter block pointer.
1687 * retry_cnt = pointer to login retry count.
1688 * tov = pointer to login timeout value.
1689 *
1690 * Returns:
1691 * qla2x00 local function return status code.
1692 *
1693 * Context:
1694 * Kernel context.
1695 */
1696int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001697qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 uint16_t *r_a_tov)
1699{
1700 int rval;
1701 uint16_t ratov;
1702 mbx_cmd_t mc;
1703 mbx_cmd_t *mcp = &mc;
1704
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001705 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049,
1706 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707
1708 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1709 mcp->out_mb = MBX_0;
1710 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001711 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001713 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714
1715 if (rval != QLA_SUCCESS) {
1716 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001717 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1718 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 } else {
1720 /* Convert returned data and check our values. */
1721 *r_a_tov = mcp->mb[3] / 2;
1722 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1723 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1724 /* Update to the larger values */
1725 *retry_cnt = (uint8_t)mcp->mb[1];
1726 *tov = ratov;
1727 }
1728
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001729 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001730 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 }
1732
1733 return rval;
1734}
1735
1736/*
1737 * qla2x00_init_firmware
1738 * Initialize adapter firmware.
1739 *
1740 * Input:
1741 * ha = adapter block pointer.
1742 * dptr = Initialization control block pointer.
1743 * size = size of initialization control block.
1744 * TARGET_QUEUE_LOCK must be released.
1745 * ADAPTER_STATE_LOCK must be released.
1746 *
1747 * Returns:
1748 * qla2x00 local function return status code.
1749 *
1750 * Context:
1751 * Kernel context.
1752 */
1753int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001754qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755{
1756 int rval;
1757 mbx_cmd_t mc;
1758 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001759 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001761 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,
1762 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001764 if (IS_P3P_TYPE(ha) && ql2xdbwr)
Bart Van Assche8dfa4b5a2015-07-09 07:24:50 -07001765 qla82xx_wr_32(ha, (uintptr_t __force)ha->nxdb_wr_ptr,
Giridhar Malavalia9083012010-04-12 17:59:55 -07001766 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1767
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001768 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001769 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1770 else
1771 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1772
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001773 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 mcp->mb[2] = MSW(ha->init_cb_dma);
1775 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1777 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001778 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Joe Carnuccio4ef21bd2013-10-30 03:38:11 -04001779 if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001780 mcp->mb[1] = BIT_0;
1781 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1782 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1783 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1784 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1785 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1786 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1787 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001788 /* 1 and 2 should normally be captured. */
1789 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001790 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001791 /* mb3 is additional info about the installed SFP. */
1792 mcp->in_mb |= MBX_3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 mcp->buf_size = size;
1794 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001795 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001796 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
1798 if (rval != QLA_SUCCESS) {
1799 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001800 ql_dbg(ql_dbg_mbx, vha, 0x104d,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001801 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1802 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 } else {
Sawan Chandak92d44082017-08-23 15:05:16 -07001804 if (IS_QLA27XX(ha)) {
1805 if (mcp->mb[2] == 6 || mcp->mb[3] == 2)
1806 ql_dbg(ql_dbg_mbx, vha, 0x119d,
1807 "Invalid SFP/Validation Failed\n");
1808 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001809 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,
1810 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811 }
1812
1813 return rval;
1814}
1815
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001816
1817/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 * qla2x00_get_port_database
1819 * Issue normal/enhanced get port database mailbox command
1820 * and copy device name as necessary.
1821 *
1822 * Input:
1823 * ha = adapter state pointer.
1824 * dev = structure pointer.
1825 * opt = enhanced cmd option byte.
1826 *
1827 * Returns:
1828 * qla2x00 local function return status code.
1829 *
1830 * Context:
1831 * Kernel context.
1832 */
1833int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001834qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835{
1836 int rval;
1837 mbx_cmd_t mc;
1838 mbx_cmd_t *mcp = &mc;
1839 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001840 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001842 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001844 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f,
1845 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001847 pd24 = NULL;
Thomas Meyer08eb7f42017-09-21 08:15:26 +02001848 pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001850 ql_log(ql_log_warn, vha, 0x1050,
1851 "Failed to allocate port database structure.\n");
Duane Grigsbyedd05de2017-10-13 09:34:06 -07001852 fcport->query = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 return QLA_MEMORY_ALLOC_FAILED;
1854 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001856 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001857 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859 mcp->mb[2] = MSW(pd_dma);
1860 mcp->mb[3] = LSW(pd_dma);
1861 mcp->mb[6] = MSW(MSD(pd_dma));
1862 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001863 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001864 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001866 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001867 mcp->mb[1] = fcport->loop_id;
1868 mcp->mb[10] = opt;
1869 mcp->out_mb |= MBX_10|MBX_1;
1870 mcp->in_mb |= MBX_1;
1871 } else if (HAS_EXTENDED_IDS(ha)) {
1872 mcp->mb[1] = fcport->loop_id;
1873 mcp->mb[10] = opt;
1874 mcp->out_mb |= MBX_10|MBX_1;
1875 } else {
1876 mcp->mb[1] = fcport->loop_id << 8 | opt;
1877 mcp->out_mb |= MBX_1;
1878 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001879 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1880 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881 mcp->flags = MBX_DMA_IN;
1882 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001883 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 if (rval != QLA_SUCCESS)
1885 goto gpd_error_out;
1886
Andrew Vasqueze4289242007-07-19 15:05:56 -07001887 if (IS_FWI2_CAPABLE(ha)) {
Arun Easi0eba25d2012-02-09 11:15:58 -08001888 uint64_t zero = 0;
Duane Grigsbyc0c462c2017-10-13 09:34:05 -07001889 u8 current_login_state, last_login_state;
1890
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001891 pd24 = (struct port_database_24xx *) pd;
1892
1893 /* Check for logged in state. */
Duane Grigsbyc0c462c2017-10-13 09:34:05 -07001894 if (fcport->fc4f_nvme) {
1895 current_login_state = pd24->current_login_state >> 4;
1896 last_login_state = pd24->last_login_state >> 4;
1897 } else {
1898 current_login_state = pd24->current_login_state & 0xf;
1899 last_login_state = pd24->last_login_state & 0xf;
1900 }
1901 fcport->current_login_state = pd24->current_login_state;
1902 fcport->last_login_state = pd24->last_login_state;
1903
1904 /* Check for logged in state. */
1905 if (current_login_state != PDS_PRLI_COMPLETE &&
1906 last_login_state != PDS_PRLI_COMPLETE) {
1907 ql_dbg(ql_dbg_mbx, vha, 0x119a,
1908 "Unable to verify login-state (%x/%x) for loop_id %x.\n",
1909 current_login_state, last_login_state,
1910 fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001911 rval = QLA_FUNCTION_FAILED;
Duane Grigsbyc0c462c2017-10-13 09:34:05 -07001912
1913 if (!fcport->query)
1914 goto gpd_error_out;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001915 }
1916
Arun Easi0eba25d2012-02-09 11:15:58 -08001917 if (fcport->loop_id == FC_NO_LOOP_ID ||
1918 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1919 memcmp(fcport->port_name, pd24->port_name, 8))) {
1920 /* We lost the device mid way. */
1921 rval = QLA_NOT_LOGGED_IN;
1922 goto gpd_error_out;
1923 }
1924
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001925 /* Names are little-endian. */
1926 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1927 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1928
1929 /* Get port_id of device. */
1930 fcport->d_id.b.domain = pd24->port_id[0];
1931 fcport->d_id.b.area = pd24->port_id[1];
1932 fcport->d_id.b.al_pa = pd24->port_id[2];
1933 fcport->d_id.b.rsvd_1 = 0;
1934
1935 /* If not target must be initiator or unknown type. */
1936 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1937 fcport->port_type = FCT_INITIATOR;
1938 else
1939 fcport->port_type = FCT_TARGET;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001940
1941 /* Passback COS information. */
1942 fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ?
1943 FC_COS_CLASS2 : FC_COS_CLASS3;
1944
1945 if (pd24->prli_svc_param_word_3[0] & BIT_7)
1946 fcport->flags |= FCF_CONF_COMP_SUPPORTED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001947 } else {
Arun Easi0eba25d2012-02-09 11:15:58 -08001948 uint64_t zero = 0;
1949
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001950 /* Check for logged in state. */
1951 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1952 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001953 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1954 "Unable to verify login-state (%x/%x) - "
1955 "portid=%02x%02x%02x.\n", pd->master_state,
1956 pd->slave_state, fcport->d_id.b.domain,
1957 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001958 rval = QLA_FUNCTION_FAILED;
1959 goto gpd_error_out;
1960 }
1961
Arun Easi0eba25d2012-02-09 11:15:58 -08001962 if (fcport->loop_id == FC_NO_LOOP_ID ||
1963 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1964 memcmp(fcport->port_name, pd->port_name, 8))) {
1965 /* We lost the device mid way. */
1966 rval = QLA_NOT_LOGGED_IN;
1967 goto gpd_error_out;
1968 }
1969
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001970 /* Names are little-endian. */
1971 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1972 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1973
1974 /* Get port_id of device. */
1975 fcport->d_id.b.domain = pd->port_id[0];
1976 fcport->d_id.b.area = pd->port_id[3];
1977 fcport->d_id.b.al_pa = pd->port_id[2];
1978 fcport->d_id.b.rsvd_1 = 0;
1979
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001980 /* If not target must be initiator or unknown type. */
1981 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1982 fcport->port_type = FCT_INITIATOR;
1983 else
1984 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001985
1986 /* Passback COS information. */
1987 fcport->supported_classes = (pd->options & BIT_4) ?
1988 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 }
1990
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991gpd_error_out:
1992 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
Duane Grigsbyedd05de2017-10-13 09:34:06 -07001993 fcport->query = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994
1995 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001996 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1997 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1998 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001999 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002000 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053,
2001 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002 }
2003
2004 return rval;
2005}
2006
2007/*
2008 * qla2x00_get_firmware_state
2009 * Get adapter firmware state.
2010 *
2011 * Input:
2012 * ha = adapter block pointer.
2013 * dptr = pointer for firmware state.
2014 * TARGET_QUEUE_LOCK must be released.
2015 * ADAPTER_STATE_LOCK must be released.
2016 *
2017 * Returns:
2018 * qla2x00 local function return status code.
2019 *
2020 * Context:
2021 * Kernel context.
2022 */
2023int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002024qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025{
2026 int rval;
2027 mbx_cmd_t mc;
2028 mbx_cmd_t *mcp = &mc;
Sawan Chandak92d44082017-08-23 15:05:16 -07002029 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002031 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
2032 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033
2034 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
2035 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002036 if (IS_FWI2_CAPABLE(vha->hw))
Joe Carnucciob5a340d2014-09-25 05:16:48 -04002037 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002038 else
2039 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002040 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002042 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002043
Harihara Kadayam4d4df192008-04-03 13:13:26 -07002044 /* Return firmware states. */
2045 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002046 if (IS_FWI2_CAPABLE(vha->hw)) {
2047 states[1] = mcp->mb[2];
Joe Carnuccioec891462016-07-06 11:14:26 -04002048 states[2] = mcp->mb[3]; /* SFP info */
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002049 states[3] = mcp->mb[4];
2050 states[4] = mcp->mb[5];
Joe Carnucciob5a340d2014-09-25 05:16:48 -04002051 states[5] = mcp->mb[6]; /* DPORT status */
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002052 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002053
2054 if (rval != QLA_SUCCESS) {
2055 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002056 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002057 } else {
Sawan Chandak92d44082017-08-23 15:05:16 -07002058 if (IS_QLA27XX(ha)) {
2059 if (mcp->mb[2] == 6 || mcp->mb[3] == 2)
2060 ql_dbg(ql_dbg_mbx, vha, 0x119e,
2061 "Invalid SFP/Validation Failed\n");
2062 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002063 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,
2064 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065 }
2066
2067 return rval;
2068}
2069
2070/*
2071 * qla2x00_get_port_name
2072 * Issue get port name mailbox command.
2073 * Returned name is in big endian format.
2074 *
2075 * Input:
2076 * ha = adapter block pointer.
2077 * loop_id = loop ID of device.
2078 * name = pointer for name.
2079 * TARGET_QUEUE_LOCK must be released.
2080 * ADAPTER_STATE_LOCK must be released.
2081 *
2082 * Returns:
2083 * qla2x00 local function return status code.
2084 *
2085 * Context:
2086 * Kernel context.
2087 */
2088int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002089qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 uint8_t opt)
2091{
2092 int rval;
2093 mbx_cmd_t mc;
2094 mbx_cmd_t *mcp = &mc;
2095
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002096 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057,
2097 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002098
2099 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002100 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002101 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002102 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103 mcp->mb[1] = loop_id;
2104 mcp->mb[10] = opt;
2105 mcp->out_mb |= MBX_10;
2106 } else {
2107 mcp->mb[1] = loop_id << 8 | opt;
2108 }
2109
2110 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002111 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002112 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002113 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114
2115 if (rval != QLA_SUCCESS) {
2116 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002117 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118 } else {
2119 if (name != NULL) {
2120 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05002121 name[0] = MSB(mcp->mb[2]);
2122 name[1] = LSB(mcp->mb[2]);
2123 name[2] = MSB(mcp->mb[3]);
2124 name[3] = LSB(mcp->mb[3]);
2125 name[4] = MSB(mcp->mb[6]);
2126 name[5] = LSB(mcp->mb[6]);
2127 name[6] = MSB(mcp->mb[7]);
2128 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129 }
2130
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002131 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059,
2132 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002133 }
2134
2135 return rval;
2136}
2137
2138/*
Joe Carnuccio61e1b262013-02-08 01:57:48 -05002139 * qla24xx_link_initialization
2140 * Issue link initialization mailbox command.
2141 *
2142 * Input:
2143 * ha = adapter block pointer.
2144 * TARGET_QUEUE_LOCK must be released.
2145 * ADAPTER_STATE_LOCK must be released.
2146 *
2147 * Returns:
2148 * qla2x00 local function return status code.
2149 *
2150 * Context:
2151 * Kernel context.
2152 */
2153int
2154qla24xx_link_initialize(scsi_qla_host_t *vha)
2155{
2156 int rval;
2157 mbx_cmd_t mc;
2158 mbx_cmd_t *mcp = &mc;
2159
2160 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152,
2161 "Entered %s.\n", __func__);
2162
2163 if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw))
2164 return QLA_FUNCTION_FAILED;
2165
2166 mcp->mb[0] = MBC_LINK_INITIALIZATION;
Joe Carnuccio5a5c27b2013-08-27 01:37:49 -04002167 mcp->mb[1] = BIT_4;
2168 if (vha->hw->operating_mode == LOOP)
2169 mcp->mb[1] |= BIT_6;
2170 else
2171 mcp->mb[1] |= BIT_5;
Joe Carnuccio61e1b262013-02-08 01:57:48 -05002172 mcp->mb[2] = 0;
2173 mcp->mb[3] = 0;
2174 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2175 mcp->in_mb = MBX_0;
2176 mcp->tov = MBX_TOV_SECONDS;
2177 mcp->flags = 0;
2178 rval = qla2x00_mailbox_command(vha, mcp);
2179
2180 if (rval != QLA_SUCCESS) {
2181 ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval);
2182 } else {
2183 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154,
2184 "Done %s.\n", __func__);
2185 }
2186
2187 return rval;
2188}
2189
2190/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191 * qla2x00_lip_reset
2192 * Issue LIP reset mailbox command.
2193 *
2194 * Input:
2195 * ha = adapter block pointer.
2196 * TARGET_QUEUE_LOCK must be released.
2197 * ADAPTER_STATE_LOCK must be released.
2198 *
2199 * Returns:
2200 * qla2x00 local function return status code.
2201 *
2202 * Context:
2203 * Kernel context.
2204 */
2205int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002206qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207{
2208 int rval;
2209 mbx_cmd_t mc;
2210 mbx_cmd_t *mcp = &mc;
2211
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002212 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a,
2213 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002215 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08002216 /* Logout across all FCFs. */
2217 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2218 mcp->mb[1] = BIT_1;
2219 mcp->mb[2] = 0;
2220 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2221 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002222 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Quinn Tran48acad02018-08-02 13:16:44 -07002223 if (N2N_TOPO(vha->hw))
2224 mcp->mb[1] = BIT_4; /* re-init */
2225 else
2226 mcp->mb[1] = BIT_6; /* LIP */
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002227 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002228 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002229 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002231 mcp->mb[0] = MBC_LIP_RESET;
2232 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002233 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002234 mcp->mb[1] = 0x00ff;
2235 mcp->mb[10] = 0;
2236 mcp->out_mb |= MBX_10;
2237 } else {
2238 mcp->mb[1] = 0xff00;
2239 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002240 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002241 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002242 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002244 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002246 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247
2248 if (rval != QLA_SUCCESS) {
2249 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002250 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251 } else {
2252 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002253 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c,
2254 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 }
2256
2257 return rval;
2258}
2259
2260/*
2261 * qla2x00_send_sns
2262 * Send SNS command.
2263 *
2264 * Input:
2265 * ha = adapter block pointer.
2266 * sns = pointer for command.
2267 * cmd_size = command size.
2268 * buf_size = response/command size.
2269 * TARGET_QUEUE_LOCK must be released.
2270 * ADAPTER_STATE_LOCK must be released.
2271 *
2272 * Returns:
2273 * qla2x00 local function return status code.
2274 *
2275 * Context:
2276 * Kernel context.
2277 */
2278int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002279qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280 uint16_t cmd_size, size_t buf_size)
2281{
2282 int rval;
2283 mbx_cmd_t mc;
2284 mbx_cmd_t *mcp = &mc;
2285
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002286 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d,
2287 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002289 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002290 "Retry cnt=%d ratov=%d total tov=%d.\n",
2291 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292
2293 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
2294 mcp->mb[1] = cmd_size;
2295 mcp->mb[2] = MSW(sns_phys_address);
2296 mcp->mb[3] = LSW(sns_phys_address);
2297 mcp->mb[6] = MSW(MSD(sns_phys_address));
2298 mcp->mb[7] = LSW(MSD(sns_phys_address));
2299 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2300 mcp->in_mb = MBX_0|MBX_1;
2301 mcp->buf_size = buf_size;
2302 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002303 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
2304 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305
2306 if (rval != QLA_SUCCESS) {
2307 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002308 ql_dbg(ql_dbg_mbx, vha, 0x105f,
2309 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2310 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002311 } else {
2312 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002313 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060,
2314 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315 }
2316
2317 return rval;
2318}
2319
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002320int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002321qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002322 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
2323{
2324 int rval;
2325
2326 struct logio_entry_24xx *lg;
2327 dma_addr_t lg_dma;
2328 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002329 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002330 struct req_que *req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002331
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002332 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061,
2333 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002334
Michael Hernandezd7459522016-12-12 14:40:07 -08002335 if (vha->vp_idx && vha->qpair)
2336 req = vha->qpair->req;
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002337 else
Michael Hernandezd7459522016-12-12 14:40:07 -08002338 req = ha->req_q_map[0];
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002339
Thomas Meyer08eb7f42017-09-21 08:15:26 +02002340 lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002341 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002342 ql_log(ql_log_warn, vha, 0x1062,
2343 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002344 return QLA_MEMORY_ALLOC_FAILED;
2345 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002346
2347 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2348 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002349 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002350 lg->nport_handle = cpu_to_le16(loop_id);
Bart Van Asschead950362015-07-09 07:24:08 -07002351 lg->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002352 if (opt & BIT_0)
Bart Van Asschead950362015-07-09 07:24:08 -07002353 lg->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07002354 if (opt & BIT_1)
Bart Van Asschead950362015-07-09 07:24:08 -07002355 lg->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002356 lg->port_id[0] = al_pa;
2357 lg->port_id[1] = area;
2358 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002359 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08002360 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2361 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002362 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002363 ql_dbg(ql_dbg_mbx, vha, 0x1063,
2364 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002365 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002366 ql_dbg(ql_dbg_mbx, vha, 0x1064,
2367 "Failed to complete IOCB -- error status (%x).\n",
2368 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002369 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002370 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002371 iop[0] = le32_to_cpu(lg->io_parameter[0]);
2372 iop[1] = le32_to_cpu(lg->io_parameter[1]);
2373
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002374 ql_dbg(ql_dbg_mbx, vha, 0x1065,
2375 "Failed to complete IOCB -- completion status (%x) "
2376 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
2377 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002378
2379 switch (iop[0]) {
2380 case LSC_SCODE_PORTID_USED:
2381 mb[0] = MBS_PORT_ID_USED;
2382 mb[1] = LSW(iop[1]);
2383 break;
2384 case LSC_SCODE_NPORT_USED:
2385 mb[0] = MBS_LOOP_ID_USED;
2386 break;
2387 case LSC_SCODE_NOLINK:
2388 case LSC_SCODE_NOIOCB:
2389 case LSC_SCODE_NOXCB:
2390 case LSC_SCODE_CMD_FAILED:
2391 case LSC_SCODE_NOFABRIC:
2392 case LSC_SCODE_FW_NOT_READY:
2393 case LSC_SCODE_NOT_LOGGED_IN:
2394 case LSC_SCODE_NOPCB:
2395 case LSC_SCODE_ELS_REJECT:
2396 case LSC_SCODE_CMD_PARAM_ERR:
2397 case LSC_SCODE_NONPORT:
2398 case LSC_SCODE_LOGGED_IN:
2399 case LSC_SCODE_NOFLOGI_ACC:
2400 default:
2401 mb[0] = MBS_COMMAND_ERROR;
2402 break;
2403 }
2404 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002405 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066,
2406 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002407
2408 iop[0] = le32_to_cpu(lg->io_parameter[0]);
2409
2410 mb[0] = MBS_COMMAND_COMPLETE;
2411 mb[1] = 0;
2412 if (iop[0] & BIT_4) {
2413 if (iop[0] & BIT_8)
2414 mb[1] |= BIT_1;
2415 } else
2416 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07002417
2418 /* Passback COS information. */
2419 mb[10] = 0;
2420 if (lg->io_parameter[7] || lg->io_parameter[8])
2421 mb[10] |= BIT_0; /* Class 2. */
2422 if (lg->io_parameter[9] || lg->io_parameter[10])
2423 mb[10] |= BIT_1; /* Class 3. */
Bart Van Asschead950362015-07-09 07:24:08 -07002424 if (lg->io_parameter[0] & cpu_to_le32(BIT_7))
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04002425 mb[10] |= BIT_7; /* Confirmed Completion
2426 * Allowed
2427 */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002428 }
2429
2430 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2431
2432 return rval;
2433}
2434
Linus Torvalds1da177e2005-04-16 15:20:36 -07002435/*
2436 * qla2x00_login_fabric
2437 * Issue login fabric port mailbox command.
2438 *
2439 * Input:
2440 * ha = adapter block pointer.
2441 * loop_id = device loop ID.
2442 * domain = device domain.
2443 * area = device area.
2444 * al_pa = device AL_PA.
2445 * status = pointer for return status.
2446 * opt = command options.
2447 * TARGET_QUEUE_LOCK must be released.
2448 * ADAPTER_STATE_LOCK must be released.
2449 *
2450 * Returns:
2451 * qla2x00 local function return status code.
2452 *
2453 * Context:
2454 * Kernel context.
2455 */
2456int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002457qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
2459{
2460 int rval;
2461 mbx_cmd_t mc;
2462 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002463 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002464
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002465 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067,
2466 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467
2468 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
2469 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2470 if (HAS_EXTENDED_IDS(ha)) {
2471 mcp->mb[1] = loop_id;
2472 mcp->mb[10] = opt;
2473 mcp->out_mb |= MBX_10;
2474 } else {
2475 mcp->mb[1] = (loop_id << 8) | opt;
2476 }
2477 mcp->mb[2] = domain;
2478 mcp->mb[3] = area << 8 | al_pa;
2479
2480 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
2481 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2482 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002483 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002484
2485 /* Return mailbox statuses. */
2486 if (mb != NULL) {
2487 mb[0] = mcp->mb[0];
2488 mb[1] = mcp->mb[1];
2489 mb[2] = mcp->mb[2];
2490 mb[6] = mcp->mb[6];
2491 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07002492 /* COS retrieved from Get-Port-Database mailbox command. */
2493 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494 }
2495
2496 if (rval != QLA_SUCCESS) {
2497 /* RLU tmp code: need to change main mailbox_command function to
2498 * return ok even when the mailbox completion value is not
2499 * SUCCESS. The caller needs to be responsible to interpret
2500 * the return values of this mailbox command if we're not
2501 * to change too much of the existing code.
2502 */
2503 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
2504 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
2505 mcp->mb[0] == 0x4006)
2506 rval = QLA_SUCCESS;
2507
2508 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002509 ql_dbg(ql_dbg_mbx, vha, 0x1068,
2510 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
2511 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002512 } else {
2513 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002514 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069,
2515 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516 }
2517
2518 return rval;
2519}
2520
2521/*
2522 * qla2x00_login_local_device
2523 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002524 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525 * Input:
2526 * ha = adapter block pointer.
2527 * loop_id = device loop ID.
2528 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002529 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530 * Returns:
2531 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002532 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002533 * Context:
2534 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002535 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536 */
2537int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002538qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 uint16_t *mb_ret, uint8_t opt)
2540{
2541 int rval;
2542 mbx_cmd_t mc;
2543 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002544 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002545
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002546 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a,
2547 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002548
Andrew Vasqueze4289242007-07-19 15:05:56 -07002549 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002550 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002551 fcport->d_id.b.domain, fcport->d_id.b.area,
2552 fcport->d_id.b.al_pa, mb_ret, opt);
2553
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
2555 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002556 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557 else
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002558 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002559 mcp->mb[2] = opt;
2560 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2561 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
2562 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2563 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002564 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565
2566 /* Return mailbox statuses. */
2567 if (mb_ret != NULL) {
2568 mb_ret[0] = mcp->mb[0];
2569 mb_ret[1] = mcp->mb[1];
2570 mb_ret[6] = mcp->mb[6];
2571 mb_ret[7] = mcp->mb[7];
2572 }
2573
2574 if (rval != QLA_SUCCESS) {
2575 /* AV tmp code: need to change main mailbox_command function to
2576 * return ok even when the mailbox completion value is not
2577 * SUCCESS. The caller needs to be responsible to interpret
2578 * the return values of this mailbox command if we're not
2579 * to change too much of the existing code.
2580 */
2581 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
2582 rval = QLA_SUCCESS;
2583
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002584 ql_dbg(ql_dbg_mbx, vha, 0x106b,
2585 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
2586 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002587 } else {
2588 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002589 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c,
2590 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002591 }
2592
2593 return (rval);
2594}
2595
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002596int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002597qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002598 uint8_t area, uint8_t al_pa)
2599{
2600 int rval;
2601 struct logio_entry_24xx *lg;
2602 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002603 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002604 struct req_que *req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002605
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002606 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d,
2607 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002608
Thomas Meyer08eb7f42017-09-21 08:15:26 +02002609 lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002610 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002611 ql_log(ql_log_warn, vha, 0x106e,
2612 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002613 return QLA_MEMORY_ALLOC_FAILED;
2614 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002615
Michael Hernandezd7459522016-12-12 14:40:07 -08002616 req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002617 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2618 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002619 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002620 lg->nport_handle = cpu_to_le16(loop_id);
2621 lg->control_flags =
Bart Van Asschead950362015-07-09 07:24:08 -07002622 cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
Andrew Vasquezc8d66912011-03-30 11:46:21 -07002623 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002624 lg->port_id[0] = al_pa;
2625 lg->port_id[1] = area;
2626 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002627 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08002628 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2629 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002630 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002631 ql_dbg(ql_dbg_mbx, vha, 0x106f,
2632 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002633 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002634 ql_dbg(ql_dbg_mbx, vha, 0x1070,
2635 "Failed to complete IOCB -- error status (%x).\n",
2636 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002637 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002638 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002639 ql_dbg(ql_dbg_mbx, vha, 0x1071,
2640 "Failed to complete IOCB -- completion status (%x) "
2641 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002642 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002643 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002644 } else {
2645 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002646 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072,
2647 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002648 }
2649
2650 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2651
2652 return rval;
2653}
2654
Linus Torvalds1da177e2005-04-16 15:20:36 -07002655/*
2656 * qla2x00_fabric_logout
2657 * Issue logout fabric port mailbox command.
2658 *
2659 * Input:
2660 * ha = adapter block pointer.
2661 * loop_id = device loop ID.
2662 * TARGET_QUEUE_LOCK must be released.
2663 * ADAPTER_STATE_LOCK must be released.
2664 *
2665 * Returns:
2666 * qla2x00 local function return status code.
2667 *
2668 * Context:
2669 * Kernel context.
2670 */
2671int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002672qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002673 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002674{
2675 int rval;
2676 mbx_cmd_t mc;
2677 mbx_cmd_t *mcp = &mc;
2678
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002679 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073,
2680 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681
2682 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
2683 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002684 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002685 mcp->mb[1] = loop_id;
2686 mcp->mb[10] = 0;
2687 mcp->out_mb |= MBX_10;
2688 } else {
2689 mcp->mb[1] = loop_id << 8;
2690 }
2691
2692 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002693 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002694 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002695 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696
2697 if (rval != QLA_SUCCESS) {
2698 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002699 ql_dbg(ql_dbg_mbx, vha, 0x1074,
2700 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002701 } else {
2702 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002703 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075,
2704 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705 }
2706
2707 return rval;
2708}
2709
2710/*
2711 * qla2x00_full_login_lip
2712 * Issue full login LIP mailbox command.
2713 *
2714 * Input:
2715 * ha = adapter block pointer.
2716 * TARGET_QUEUE_LOCK must be released.
2717 * ADAPTER_STATE_LOCK must be released.
2718 *
2719 * Returns:
2720 * qla2x00 local function return status code.
2721 *
2722 * Context:
2723 * Kernel context.
2724 */
2725int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002726qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002727{
2728 int rval;
2729 mbx_cmd_t mc;
2730 mbx_cmd_t *mcp = &mc;
2731
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002732 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076,
2733 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002734
2735 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002736 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002737 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738 mcp->mb[3] = 0;
2739 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2740 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002741 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002743 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744
2745 if (rval != QLA_SUCCESS) {
2746 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002747 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748 } else {
2749 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002750 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078,
2751 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752 }
2753
2754 return rval;
2755}
2756
2757/*
2758 * qla2x00_get_id_list
2759 *
2760 * Input:
2761 * ha = adapter block pointer.
2762 *
2763 * Returns:
2764 * qla2x00 local function return status code.
2765 *
2766 * Context:
2767 * Kernel context.
2768 */
2769int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002770qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002771 uint16_t *entries)
2772{
2773 int rval;
2774 mbx_cmd_t mc;
2775 mbx_cmd_t *mcp = &mc;
2776
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002777 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079,
2778 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002779
2780 if (id_list == NULL)
2781 return QLA_FUNCTION_FAILED;
2782
2783 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002784 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002785 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002786 mcp->mb[2] = MSW(id_list_dma);
2787 mcp->mb[3] = LSW(id_list_dma);
2788 mcp->mb[6] = MSW(MSD(id_list_dma));
2789 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002790 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002791 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002792 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002793 } else {
2794 mcp->mb[1] = MSW(id_list_dma);
2795 mcp->mb[2] = LSW(id_list_dma);
2796 mcp->mb[3] = MSW(MSD(id_list_dma));
2797 mcp->mb[6] = LSW(MSD(id_list_dma));
2798 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2799 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002800 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002801 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002802 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002803 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002804
2805 if (rval != QLA_SUCCESS) {
2806 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002807 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002808 } else {
2809 *entries = mcp->mb[1];
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002810 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b,
2811 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002812 }
2813
2814 return rval;
2815}
2816
2817/*
2818 * qla2x00_get_resource_cnts
2819 * Get current firmware resource counts.
2820 *
2821 * Input:
2822 * ha = adapter block pointer.
2823 *
2824 * Returns:
2825 * qla2x00 local function return status code.
2826 *
2827 * Context:
2828 * Kernel context.
2829 */
2830int
Quinn Tran03e8c682015-12-17 14:56:59 -05002831qla2x00_get_resource_cnts(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002832{
Quinn Tran03e8c682015-12-17 14:56:59 -05002833 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 int rval;
2835 mbx_cmd_t mc;
2836 mbx_cmd_t *mcp = &mc;
2837
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002838 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c,
2839 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840
2841 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2842 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002843 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 -05002844 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) || IS_QLA27XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002845 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002846 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002848 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849
2850 if (rval != QLA_SUCCESS) {
2851 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002852 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2853 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002855 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002856 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2857 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2858 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2859 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002860
Quinn Tran03e8c682015-12-17 14:56:59 -05002861 ha->orig_fw_tgt_xcb_count = mcp->mb[1];
2862 ha->cur_fw_tgt_xcb_count = mcp->mb[2];
2863 ha->cur_fw_xcb_count = mcp->mb[3];
2864 ha->orig_fw_xcb_count = mcp->mb[6];
2865 ha->cur_fw_iocb_count = mcp->mb[7];
2866 ha->orig_fw_iocb_count = mcp->mb[10];
2867 if (ha->flags.npiv_supported)
2868 ha->max_npiv_vports = mcp->mb[11];
2869 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
2870 ha->fw_max_fcf_count = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871 }
2872
2873 return (rval);
2874}
2875
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876/*
2877 * qla2x00_get_fcal_position_map
2878 * Get FCAL (LILP) position map using mailbox command
2879 *
2880 * Input:
2881 * ha = adapter state pointer.
2882 * pos_map = buffer pointer (can be NULL).
2883 *
2884 * Returns:
2885 * qla2x00 local function return status code.
2886 *
2887 * Context:
2888 * Kernel context.
2889 */
2890int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002891qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892{
2893 int rval;
2894 mbx_cmd_t mc;
2895 mbx_cmd_t *mcp = &mc;
2896 char *pmap;
2897 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002898 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002899
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002900 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f,
2901 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002902
Thomas Meyer08eb7f42017-09-21 08:15:26 +02002903 pmap = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002905 ql_log(ql_log_warn, vha, 0x1080,
2906 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002907 return QLA_MEMORY_ALLOC_FAILED;
2908 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909
2910 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2911 mcp->mb[2] = MSW(pmap_dma);
2912 mcp->mb[3] = LSW(pmap_dma);
2913 mcp->mb[6] = MSW(MSD(pmap_dma));
2914 mcp->mb[7] = LSW(MSD(pmap_dma));
2915 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2916 mcp->in_mb = MBX_1|MBX_0;
2917 mcp->buf_size = FCAL_MAP_SIZE;
2918 mcp->flags = MBX_DMA_IN;
2919 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002920 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921
2922 if (rval == QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002923 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002924 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2925 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2926 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2927 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928
2929 if (pos_map)
2930 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2931 }
2932 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2933
2934 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002935 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002937 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083,
2938 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002939 }
2940
2941 return rval;
2942}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002943
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002944/*
2945 * qla2x00_get_link_status
2946 *
2947 * Input:
2948 * ha = adapter block pointer.
2949 * loop_id = device loop ID.
2950 * ret_buf = pointer to link status return buffer.
2951 *
2952 * Returns:
2953 * 0 = success.
2954 * BIT_0 = mem alloc error.
2955 * BIT_1 = mailbox error.
2956 */
2957int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002958qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002959 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002960{
2961 int rval;
2962 mbx_cmd_t mc;
2963 mbx_cmd_t *mcp = &mc;
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04002964 uint32_t *iter = (void *)stats;
2965 ushort dwords = offsetof(typeof(*stats), link_up_cnt)/sizeof(*iter);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002966 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002967
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002968 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084,
2969 "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002970
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002971 mcp->mb[0] = MBC_GET_LINK_STATUS;
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04002972 mcp->mb[2] = MSW(LSD(stats_dma));
2973 mcp->mb[3] = LSW(LSD(stats_dma));
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002974 mcp->mb[6] = MSW(MSD(stats_dma));
2975 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002976 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2977 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002978 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002979 mcp->mb[1] = loop_id;
2980 mcp->mb[4] = 0;
2981 mcp->mb[10] = 0;
2982 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2983 mcp->in_mb |= MBX_1;
2984 } else if (HAS_EXTENDED_IDS(ha)) {
2985 mcp->mb[1] = loop_id;
2986 mcp->mb[10] = 0;
2987 mcp->out_mb |= MBX_10|MBX_1;
2988 } else {
2989 mcp->mb[1] = loop_id << 8;
2990 mcp->out_mb |= MBX_1;
2991 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002992 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002993 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002994 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002995
2996 if (rval == QLA_SUCCESS) {
2997 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002998 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2999 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08003000 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003001 } else {
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04003002 /* Re-endianize - firmware data is le32. */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003003 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086,
3004 "Done %s.\n", __func__);
Joe Carnuccioda08ef52016-01-27 12:03:34 -05003005 for ( ; dwords--; iter++)
3006 le32_to_cpus(iter);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003007 }
3008 } else {
3009 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003010 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003011 }
3012
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003013 return rval;
3014}
3015
3016int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003017qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Quinn Tran15f30a52017-03-15 09:48:52 -07003018 dma_addr_t stats_dma, uint16_t options)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003019{
3020 int rval;
3021 mbx_cmd_t mc;
3022 mbx_cmd_t *mcp = &mc;
Joe Carnuccioda08ef52016-01-27 12:03:34 -05003023 uint32_t *iter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003024
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003025 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,
3026 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003027
Quinn Tran15f30a52017-03-15 09:48:52 -07003028 memset(&mc, 0, sizeof(mc));
3029 mc.mb[0] = MBC_GET_LINK_PRIV_STATS;
3030 mc.mb[2] = MSW(stats_dma);
3031 mc.mb[3] = LSW(stats_dma);
3032 mc.mb[6] = MSW(MSD(stats_dma));
3033 mc.mb[7] = LSW(MSD(stats_dma));
3034 mc.mb[8] = sizeof(struct link_statistics) / 4;
3035 mc.mb[9] = cpu_to_le16(vha->vp_idx);
3036 mc.mb[10] = cpu_to_le16(options);
3037
3038 rval = qla24xx_send_mb_cmd(vha, &mc);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003039
3040 if (rval == QLA_SUCCESS) {
3041 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003042 ql_dbg(ql_dbg_mbx, vha, 0x1089,
3043 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08003044 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003045 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003046 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a,
3047 "Done %s.\n", __func__);
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04003048 /* Re-endianize - firmware data is le32. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08003049 dwords = sizeof(struct link_statistics) / 4;
Joe Carnuccioda08ef52016-01-27 12:03:34 -05003050 iter = &stats->link_fail_cnt;
3051 for ( ; dwords--; iter++)
3052 le32_to_cpus(iter);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003053 }
3054 } else {
3055 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003056 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003057 }
3058
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003059 return rval;
3060}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003061
3062int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003063qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003064{
3065 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003066 unsigned long flags = 0;
3067
3068 struct abort_entry_24xx *abt;
3069 dma_addr_t abt_dma;
3070 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003071 fc_port_t *fcport = sp->fcport;
3072 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003073 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07003074 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003075
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003076 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,
3077 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003078
Michael Hernandezd7459522016-12-12 14:40:07 -08003079 if (vha->flags.qpairs_available && sp->qpair)
3080 req = sp->qpair->req;
3081
Armen Baloyan4440e462014-02-26 04:15:18 -05003082 if (ql2xasynctmfenable)
3083 return qla24xx_async_abort_command(sp);
3084
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003085 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05003086 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003087 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003088 break;
3089 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003090 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05003091 if (handle == req->num_outstanding_cmds) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003092 /* Command not found. */
3093 return QLA_FUNCTION_FAILED;
3094 }
3095
Thomas Meyer08eb7f42017-09-21 08:15:26 +02003096 abt = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003097 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003098 ql_log(ql_log_warn, vha, 0x108d,
3099 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003100 return QLA_MEMORY_ALLOC_FAILED;
3101 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003102
3103 abt->entry_type = ABORT_IOCB_TYPE;
3104 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003105 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003106 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07003107 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003108 abt->port_id[0] = fcport->d_id.b.al_pa;
3109 abt->port_id[1] = fcport->d_id.b.area;
3110 abt->port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04003111 abt->vp_index = fcport->vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003112
3113 abt->req_que_no = cpu_to_le16(req->id);
3114
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003115 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003116 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003117 ql_dbg(ql_dbg_mbx, vha, 0x108e,
3118 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003119 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003120 ql_dbg(ql_dbg_mbx, vha, 0x108f,
3121 "Failed to complete IOCB -- error status (%x).\n",
3122 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003123 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07003124 } else if (abt->nport_handle != cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003125 ql_dbg(ql_dbg_mbx, vha, 0x1090,
3126 "Failed to complete IOCB -- completion status (%x).\n",
3127 le16_to_cpu(abt->nport_handle));
Chad Dupuisf934c9d2014-04-11 16:54:31 -04003128 if (abt->nport_handle == CS_IOCB_ERROR)
3129 rval = QLA_FUNCTION_PARAMETER_ERROR;
3130 else
3131 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003132 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003133 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
3134 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003135 }
3136
3137 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
3138
3139 return rval;
3140}
3141
3142struct tsk_mgmt_cmd {
3143 union {
3144 struct tsk_mgmt_entry tsk;
3145 struct sts_entry_24xx sts;
3146 } p;
3147};
3148
Andrew Vasquez523ec772008-04-03 13:13:24 -07003149static int
3150__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02003151 uint64_t l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003152{
Andrew Vasquez523ec772008-04-03 13:13:24 -07003153 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003154 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003155 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003156 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003157 scsi_qla_host_t *vha;
3158 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003159 struct req_que *req;
3160 struct rsp_que *rsp;
Michael Hernandezd7459522016-12-12 14:40:07 -08003161 struct qla_qpair *qpair;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003162
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003163 vha = fcport->vha;
3164 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003165 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003166
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003167 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092,
3168 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003169
Michael Hernandezd7459522016-12-12 14:40:07 -08003170 if (vha->vp_idx && vha->qpair) {
3171 /* NPIV port */
3172 qpair = vha->qpair;
3173 rsp = qpair->rsp;
3174 req = qpair->req;
3175 } else {
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07003176 rsp = req->rsp;
Michael Hernandezd7459522016-12-12 14:40:07 -08003177 }
3178
Thomas Meyer08eb7f42017-09-21 08:15:26 +02003179 tsk = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003180 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003181 ql_log(ql_log_warn, vha, 0x1093,
3182 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003183 return QLA_MEMORY_ALLOC_FAILED;
3184 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003185
3186 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
3187 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003188 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003189 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08003190 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07003191 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003192 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
3193 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
3194 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04003195 tsk->p.tsk.vp_index = fcport->vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07003196 if (type == TCF_LUN_RESET) {
3197 int_to_scsilun(l, &tsk->p.tsk.lun);
3198 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
3199 sizeof(tsk->p.tsk.lun));
3200 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003201
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003202 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003203 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003204 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003205 ql_dbg(ql_dbg_mbx, vha, 0x1094,
3206 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003207 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003208 ql_dbg(ql_dbg_mbx, vha, 0x1095,
3209 "Failed to complete IOCB -- error status (%x).\n",
3210 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003211 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07003212 } else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003213 ql_dbg(ql_dbg_mbx, vha, 0x1096,
3214 "Failed to complete IOCB -- completion status (%x).\n",
3215 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003216 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08003217 } else if (le16_to_cpu(sts->scsi_status) &
3218 SS_RESPONSE_INFO_LEN_VALID) {
3219 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003220 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003221 "Ignoring inconsistent data length -- not enough "
3222 "response info (%d).\n",
3223 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08003224 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003225 ql_dbg(ql_dbg_mbx, vha, 0x1098,
3226 "Failed to complete IOCB -- response (%x).\n",
3227 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08003228 rval = QLA_FUNCTION_FAILED;
3229 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003230 }
3231
3232 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003233 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07003234 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
3235 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003236 ql_dbg(ql_dbg_mbx, vha, 0x1099,
3237 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003238 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003239 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a,
3240 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003241 }
3242
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003243 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003244
3245 return rval;
3246}
3247
Andrew Vasquez523ec772008-04-03 13:13:24 -07003248int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02003249qla24xx_abort_target(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07003250{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07003251 struct qla_hw_data *ha = fcport->vha->hw;
3252
3253 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
3254 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
3255
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003256 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07003257}
3258
3259int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02003260qla24xx_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07003261{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07003262 struct qla_hw_data *ha = fcport->vha->hw;
3263
3264 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
3265 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
3266
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003267 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07003268}
3269
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003270int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003271qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003272{
3273 int rval;
3274 mbx_cmd_t mc;
3275 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003276 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003277
Andrew Vasquez68af0812008-05-12 22:21:13 -07003278 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003279 return QLA_FUNCTION_FAILED;
3280
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003281 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b,
3282 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003283
3284 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
3285 mcp->out_mb = MBX_0;
3286 mcp->in_mb = MBX_0;
3287 mcp->tov = 5;
3288 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003289 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003290
3291 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003292 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003293 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003294 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d,
3295 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003296 }
3297
3298 return rval;
3299}
3300
Joe Carnucciodb64e932013-10-30 03:38:18 -04003301int
3302qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data)
3303{
3304 int rval;
3305 mbx_cmd_t mc;
3306 mbx_cmd_t *mcp = &mc;
3307
Joe Carnucciof299c7c2015-08-04 13:37:51 -04003308 if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
3309 !IS_QLA27XX(vha->hw))
Joe Carnucciodb64e932013-10-30 03:38:18 -04003310 return QLA_FUNCTION_FAILED;
3311
3312 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182,
3313 "Entered %s.\n", __func__);
3314
3315 mcp->mb[0] = MBC_WRITE_SERDES;
3316 mcp->mb[1] = addr;
Andrew Vasquez064135e2015-04-09 15:00:02 -04003317 if (IS_QLA2031(vha->hw))
3318 mcp->mb[2] = data & 0xff;
3319 else
3320 mcp->mb[2] = data;
3321
Joe Carnucciodb64e932013-10-30 03:38:18 -04003322 mcp->mb[3] = 0;
3323 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3324 mcp->in_mb = MBX_0;
3325 mcp->tov = MBX_TOV_SECONDS;
3326 mcp->flags = 0;
3327 rval = qla2x00_mailbox_command(vha, mcp);
3328
3329 if (rval != QLA_SUCCESS) {
3330 ql_dbg(ql_dbg_mbx, vha, 0x1183,
3331 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3332 } else {
3333 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184,
3334 "Done %s.\n", __func__);
3335 }
3336
3337 return rval;
3338}
3339
3340int
3341qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)
3342{
3343 int rval;
3344 mbx_cmd_t mc;
3345 mbx_cmd_t *mcp = &mc;
3346
Joe Carnucciof299c7c2015-08-04 13:37:51 -04003347 if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
3348 !IS_QLA27XX(vha->hw))
Joe Carnucciodb64e932013-10-30 03:38:18 -04003349 return QLA_FUNCTION_FAILED;
3350
3351 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185,
3352 "Entered %s.\n", __func__);
3353
3354 mcp->mb[0] = MBC_READ_SERDES;
3355 mcp->mb[1] = addr;
3356 mcp->mb[3] = 0;
3357 mcp->out_mb = MBX_3|MBX_1|MBX_0;
3358 mcp->in_mb = MBX_1|MBX_0;
3359 mcp->tov = MBX_TOV_SECONDS;
3360 mcp->flags = 0;
3361 rval = qla2x00_mailbox_command(vha, mcp);
3362
Andrew Vasquez064135e2015-04-09 15:00:02 -04003363 if (IS_QLA2031(vha->hw))
3364 *data = mcp->mb[1] & 0xff;
3365 else
3366 *data = mcp->mb[1];
Joe Carnucciodb64e932013-10-30 03:38:18 -04003367
3368 if (rval != QLA_SUCCESS) {
3369 ql_dbg(ql_dbg_mbx, vha, 0x1186,
3370 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3371 } else {
3372 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187,
3373 "Done %s.\n", __func__);
3374 }
3375
3376 return rval;
3377}
3378
Joe Carnuccioe8887c52014-04-11 16:54:17 -04003379int
3380qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)
3381{
3382 int rval;
3383 mbx_cmd_t mc;
3384 mbx_cmd_t *mcp = &mc;
3385
3386 if (!IS_QLA8044(vha->hw))
3387 return QLA_FUNCTION_FAILED;
3388
Quinn Tran83548fe2017-06-02 09:12:01 -07003389 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x11a0,
Joe Carnuccioe8887c52014-04-11 16:54:17 -04003390 "Entered %s.\n", __func__);
3391
3392 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3393 mcp->mb[1] = HCS_WRITE_SERDES;
3394 mcp->mb[3] = LSW(addr);
3395 mcp->mb[4] = MSW(addr);
3396 mcp->mb[5] = LSW(data);
3397 mcp->mb[6] = MSW(data);
3398 mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
3399 mcp->in_mb = MBX_0;
3400 mcp->tov = MBX_TOV_SECONDS;
3401 mcp->flags = 0;
3402 rval = qla2x00_mailbox_command(vha, mcp);
3403
3404 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07003405 ql_dbg(ql_dbg_mbx, vha, 0x11a1,
Joe Carnuccioe8887c52014-04-11 16:54:17 -04003406 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3407 } else {
3408 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188,
3409 "Done %s.\n", __func__);
3410 }
3411
3412 return rval;
3413}
3414
3415int
3416qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
3417{
3418 int rval;
3419 mbx_cmd_t mc;
3420 mbx_cmd_t *mcp = &mc;
3421
3422 if (!IS_QLA8044(vha->hw))
3423 return QLA_FUNCTION_FAILED;
3424
3425 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189,
3426 "Entered %s.\n", __func__);
3427
3428 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3429 mcp->mb[1] = HCS_READ_SERDES;
3430 mcp->mb[3] = LSW(addr);
3431 mcp->mb[4] = MSW(addr);
3432 mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0;
3433 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3434 mcp->tov = MBX_TOV_SECONDS;
3435 mcp->flags = 0;
3436 rval = qla2x00_mailbox_command(vha, mcp);
3437
3438 *data = mcp->mb[2] << 16 | mcp->mb[1];
3439
3440 if (rval != QLA_SUCCESS) {
3441 ql_dbg(ql_dbg_mbx, vha, 0x118a,
3442 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3443 } else {
3444 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b,
3445 "Done %s.\n", __func__);
3446 }
3447
3448 return rval;
3449}
3450
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003451/**
3452 * qla2x00_set_serdes_params() -
Bart Van Assche2db62282018-01-23 16:33:51 -08003453 * @vha: HA context
3454 * @sw_em_1g:
3455 * @sw_em_2g:
3456 * @sw_em_4g:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003457 *
3458 * Returns
3459 */
3460int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003461qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003462 uint16_t sw_em_2g, uint16_t sw_em_4g)
3463{
3464 int rval;
3465 mbx_cmd_t mc;
3466 mbx_cmd_t *mcp = &mc;
3467
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003468 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e,
3469 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003470
3471 mcp->mb[0] = MBC_SERDES_PARAMS;
3472 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08003473 mcp->mb[2] = sw_em_1g | BIT_15;
3474 mcp->mb[3] = sw_em_2g | BIT_15;
3475 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003476 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3477 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003478 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003479 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003480 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003481
3482 if (rval != QLA_SUCCESS) {
3483 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003484 ql_dbg(ql_dbg_mbx, vha, 0x109f,
3485 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003486 } else {
3487 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003488 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0,
3489 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003490 }
3491
3492 return rval;
3493}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003494
3495int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003496qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003497{
3498 int rval;
3499 mbx_cmd_t mc;
3500 mbx_cmd_t *mcp = &mc;
3501
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003502 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003503 return QLA_FUNCTION_FAILED;
3504
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003505 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1,
3506 "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003507
3508 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08003509 mcp->mb[1] = 0;
3510 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003511 mcp->in_mb = MBX_0;
3512 mcp->tov = 5;
3513 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003514 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003515
3516 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003517 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07003518 if (mcp->mb[0] == MBS_INVALID_COMMAND)
3519 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003520 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003521 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3,
3522 "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003523 }
3524
3525 return rval;
3526}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003527
3528int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003529qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003530 uint16_t buffers)
3531{
3532 int rval;
3533 mbx_cmd_t mc;
3534 mbx_cmd_t *mcp = &mc;
3535
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003536 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4,
3537 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003538
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003539 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003540 return QLA_FUNCTION_FAILED;
3541
Andrew Vasquez85880802009-12-15 21:29:46 -08003542 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3543 return QLA_FUNCTION_FAILED;
3544
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003545 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003546 mcp->mb[1] = TC_EFT_ENABLE;
3547 mcp->mb[2] = LSW(eft_dma);
3548 mcp->mb[3] = MSW(eft_dma);
3549 mcp->mb[4] = LSW(MSD(eft_dma));
3550 mcp->mb[5] = MSW(MSD(eft_dma));
3551 mcp->mb[6] = buffers;
3552 mcp->mb[7] = TC_AEN_DISABLE;
3553 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 -07003554 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003555 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003556 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003557 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003558 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003559 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
3560 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3561 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003562 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003563 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6,
3564 "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003565 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003566
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003567 return rval;
3568}
3569
3570int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003571qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003572{
3573 int rval;
3574 mbx_cmd_t mc;
3575 mbx_cmd_t *mcp = &mc;
3576
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003577 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7,
3578 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003579
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003580 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003581 return QLA_FUNCTION_FAILED;
3582
Andrew Vasquez85880802009-12-15 21:29:46 -08003583 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3584 return QLA_FUNCTION_FAILED;
3585
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003586 mcp->mb[0] = MBC_TRACE_CONTROL;
3587 mcp->mb[1] = TC_EFT_DISABLE;
3588 mcp->out_mb = MBX_1|MBX_0;
3589 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003590 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003591 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003592 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003593 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003594 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
3595 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3596 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003597 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003598 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9,
3599 "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003600 }
3601
3602 return rval;
3603}
3604
Andrew Vasquez88729e52006-06-23 16:10:50 -07003605int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003606qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003607 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
3608{
3609 int rval;
3610 mbx_cmd_t mc;
3611 mbx_cmd_t *mcp = &mc;
3612
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003613 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa,
3614 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003615
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003616 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
Chad Dupuisf73cb692014-02-26 04:15:06 -05003617 !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003618 return QLA_FUNCTION_FAILED;
3619
Andrew Vasquez85880802009-12-15 21:29:46 -08003620 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3621 return QLA_FUNCTION_FAILED;
3622
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003623 mcp->mb[0] = MBC_TRACE_CONTROL;
3624 mcp->mb[1] = TC_FCE_ENABLE;
3625 mcp->mb[2] = LSW(fce_dma);
3626 mcp->mb[3] = MSW(fce_dma);
3627 mcp->mb[4] = LSW(MSD(fce_dma));
3628 mcp->mb[5] = MSW(MSD(fce_dma));
3629 mcp->mb[6] = buffers;
3630 mcp->mb[7] = TC_AEN_DISABLE;
3631 mcp->mb[8] = 0;
3632 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
3633 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
3634 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3635 MBX_1|MBX_0;
3636 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003637 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003638 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003639 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003640 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003641 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
3642 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3643 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003644 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003645 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac,
3646 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003647
3648 if (mb)
3649 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
3650 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07003651 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003652 }
3653
3654 return rval;
3655}
3656
3657int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003658qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003659{
3660 int rval;
3661 mbx_cmd_t mc;
3662 mbx_cmd_t *mcp = &mc;
3663
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003664 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad,
3665 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003666
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003667 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003668 return QLA_FUNCTION_FAILED;
3669
Andrew Vasquez85880802009-12-15 21:29:46 -08003670 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3671 return QLA_FUNCTION_FAILED;
3672
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003673 mcp->mb[0] = MBC_TRACE_CONTROL;
3674 mcp->mb[1] = TC_FCE_DISABLE;
3675 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
3676 mcp->out_mb = MBX_2|MBX_1|MBX_0;
3677 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3678 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003679 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003680 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003681 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003682 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003683 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
3684 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3685 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003686 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003687 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af,
3688 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003689
3690 if (wr)
3691 *wr = (uint64_t) mcp->mb[5] << 48 |
3692 (uint64_t) mcp->mb[4] << 32 |
3693 (uint64_t) mcp->mb[3] << 16 |
3694 (uint64_t) mcp->mb[2];
3695 if (rd)
3696 *rd = (uint64_t) mcp->mb[9] << 48 |
3697 (uint64_t) mcp->mb[8] << 32 |
3698 (uint64_t) mcp->mb[7] << 16 |
3699 (uint64_t) mcp->mb[6];
3700 }
3701
3702 return rval;
3703}
3704
3705int
Giridhar Malavali6e980162010-03-19 17:03:58 -07003706qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
3707 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, 0x10b0,
3714 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003715
Giridhar Malavali6e980162010-03-19 17:03:58 -07003716 if (!IS_IIDMA_CAPABLE(vha->hw))
3717 return QLA_FUNCTION_FAILED;
3718
Giridhar Malavali6e980162010-03-19 17:03:58 -07003719 mcp->mb[0] = MBC_PORT_PARAMS;
3720 mcp->mb[1] = loop_id;
3721 mcp->mb[2] = mcp->mb[3] = 0;
3722 mcp->mb[9] = vha->vp_idx;
3723 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3724 mcp->in_mb = MBX_3|MBX_1|MBX_0;
3725 mcp->tov = MBX_TOV_SECONDS;
3726 mcp->flags = 0;
3727 rval = qla2x00_mailbox_command(vha, mcp);
3728
3729 /* Return mailbox statuses. */
3730 if (mb != NULL) {
3731 mb[0] = mcp->mb[0];
3732 mb[1] = mcp->mb[1];
3733 mb[3] = mcp->mb[3];
3734 }
3735
3736 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003737 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003738 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003739 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2,
3740 "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003741 if (port_speed)
3742 *port_speed = mcp->mb[3];
3743 }
3744
3745 return rval;
3746}
3747
3748int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003749qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003750 uint16_t port_speed, uint16_t *mb)
3751{
3752 int rval;
3753 mbx_cmd_t mc;
3754 mbx_cmd_t *mcp = &mc;
3755
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003756 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3,
3757 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003758
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003759 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003760 return QLA_FUNCTION_FAILED;
3761
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003762 mcp->mb[0] = MBC_PORT_PARAMS;
3763 mcp->mb[1] = loop_id;
3764 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003765 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07003766 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
3767 else
3768 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
3769 mcp->mb[9] = vha->vp_idx;
3770 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3771 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003772 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003773 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003774 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003775
3776 /* Return mailbox statuses. */
3777 if (mb != NULL) {
3778 mb[0] = mcp->mb[0];
3779 mb[1] = mcp->mb[1];
3780 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003781 }
3782
3783 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003784 ql_dbg(ql_dbg_mbx, vha, 0x10b4,
3785 "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003786 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003787 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5,
3788 "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003789 }
3790
3791 return rval;
3792}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003793
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003794void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003795qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003796 struct vp_rpt_id_entry_24xx *rptid_entry)
3797{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003798 struct qla_hw_data *ha = vha->hw;
Quinn Tran41dc5292017-01-19 22:28:03 -08003799 scsi_qla_host_t *vp = NULL;
Arun Easifeafb7b2010-09-03 14:57:00 -07003800 unsigned long flags;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003801 int found;
Quinn Tran482c9dc2017-03-15 09:48:54 -07003802 port_id_t id;
Quinn Tran9cd883f2017-12-28 12:33:24 -08003803 struct fc_port *fcport;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003804
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003805 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
3806 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003807
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003808 if (rptid_entry->entry_status != 0)
3809 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003810
Quinn Tran482c9dc2017-03-15 09:48:54 -07003811 id.b.domain = rptid_entry->port_id[2];
3812 id.b.area = rptid_entry->port_id[1];
3813 id.b.al_pa = rptid_entry->port_id[0];
3814 id.b.rsvd_1 = 0;
Darren Trapp1763c1f2018-03-20 23:09:34 -07003815 ha->flags.n2n_ae = 0;
Quinn Tran482c9dc2017-03-15 09:48:54 -07003816
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003817 if (rptid_entry->format == 0) {
Quinn Tran41dc5292017-01-19 22:28:03 -08003818 /* loop */
Quinn Tranec7193e2017-03-15 09:48:55 -07003819 ql_dbg(ql_dbg_async, vha, 0x10b7,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003820 "Format 0 : Number of VPs setup %d, number of "
Quinn Tran41dc5292017-01-19 22:28:03 -08003821 "VPs acquired %d.\n", rptid_entry->vp_setup,
3822 rptid_entry->vp_acquired);
Quinn Tranec7193e2017-03-15 09:48:55 -07003823 ql_dbg(ql_dbg_async, vha, 0x10b8,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003824 "Primary port id %02x%02x%02x.\n",
3825 rptid_entry->port_id[2], rptid_entry->port_id[1],
3826 rptid_entry->port_id[0]);
Quinn Tran9cd883f2017-12-28 12:33:24 -08003827 ha->current_topology = ISP_CFG_NL;
Quinn Tran482c9dc2017-03-15 09:48:54 -07003828 qlt_update_host_map(vha, id);
Quinn Tran41dc5292017-01-19 22:28:03 -08003829
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003830 } else if (rptid_entry->format == 1) {
Quinn Tran41dc5292017-01-19 22:28:03 -08003831 /* fabric */
Quinn Tranec7193e2017-03-15 09:48:55 -07003832 ql_dbg(ql_dbg_async, vha, 0x10b9,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003833 "Format 1: VP[%d] enabled - status %d - with "
Quinn Tran41dc5292017-01-19 22:28:03 -08003834 "port id %02x%02x%02x.\n", rptid_entry->vp_idx,
3835 rptid_entry->vp_status,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003836 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003837 rptid_entry->port_id[0]);
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003838 ql_dbg(ql_dbg_async, vha, 0x5075,
3839 "Format 1: Remote WWPN %8phC.\n",
3840 rptid_entry->u.f1.port_name);
3841
3842 ql_dbg(ql_dbg_async, vha, 0x5075,
3843 "Format 1: WWPN %8phC.\n",
3844 vha->port_name);
3845
Quinn Tran8777e432018-08-02 13:16:57 -07003846 switch (rptid_entry->u.f1.flags & TOPO_MASK) {
3847 case TOPO_N2N:
3848 ha->current_topology = ISP_CFG_N;
3849 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
3850 fcport = qla2x00_find_fcport_by_wwpn(vha,
3851 rptid_entry->u.f1.port_name, 1);
3852 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3853
3854 if (fcport) {
3855 fcport->plogi_nack_done_deadline = jiffies + HZ;
3856 fcport->dm_login_expire = jiffies + 3*HZ;
3857 fcport->scan_state = QLA_FCPORT_FOUND;
3858 switch (fcport->disc_state) {
3859 case DSC_DELETED:
3860 set_bit(RELOGIN_NEEDED,
3861 &vha->dpc_flags);
3862 break;
3863 case DSC_DELETE_PEND:
3864 break;
3865 default:
3866 qlt_schedule_sess_for_deletion(fcport);
3867 break;
3868 }
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003869 } else {
Quinn Tran8777e432018-08-02 13:16:57 -07003870 id.b24 = 0;
3871 if (wwn_to_u64(vha->port_name) >
3872 wwn_to_u64(rptid_entry->u.f1.port_name)) {
3873 vha->d_id.b24 = 0;
3874 vha->d_id.b.al_pa = 1;
3875 ha->flags.n2n_bigger = 1;
3876
3877 id.b.al_pa = 2;
3878 ql_dbg(ql_dbg_async, vha, 0x5075,
3879 "Format 1: assign local id %x remote id %x\n",
3880 vha->d_id.b24, id.b24);
3881 } else {
3882 ql_dbg(ql_dbg_async, vha, 0x5075,
3883 "Format 1: Remote login - Waiting for WWPN %8phC.\n",
3884 rptid_entry->u.f1.port_name);
3885 ha->flags.n2n_bigger = 0;
3886 }
3887 qla24xx_post_newsess_work(vha, &id,
3888 rptid_entry->u.f1.port_name,
3889 rptid_entry->u.f1.node_name,
3890 NULL,
3891 FC4_TYPE_UNKNOWN);
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003892 }
3893
Quinn Tran8777e432018-08-02 13:16:57 -07003894 /* if our portname is higher then initiate N2N login */
3895
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003896 set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
Darren Trapp1763c1f2018-03-20 23:09:34 -07003897 ha->flags.n2n_ae = 1;
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003898 return;
Quinn Tran8777e432018-08-02 13:16:57 -07003899 break;
3900 case TOPO_FL:
3901 ha->current_topology = ISP_CFG_FL;
3902 break;
3903 case TOPO_F:
3904 ha->current_topology = ISP_CFG_F;
3905 break;
3906 default:
3907 break;
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003908 }
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003909
Quinn Tran9cd883f2017-12-28 12:33:24 -08003910 ha->flags.gpsc_supported = 1;
3911 ha->current_topology = ISP_CFG_F;
Sawan Chandak969a6192016-01-27 12:03:32 -05003912 /* buffer to buffer credit flag */
Quinn Tran41dc5292017-01-19 22:28:03 -08003913 vha->flags.bbcr_enable = (rptid_entry->u.f1.bbcr & 0xf) != 0;
Sawan Chandak969a6192016-01-27 12:03:32 -05003914
Quinn Tran41dc5292017-01-19 22:28:03 -08003915 if (rptid_entry->vp_idx == 0) {
3916 if (rptid_entry->vp_status == VP_STAT_COMPL) {
3917 /* FA-WWN is only for physical port */
3918 if (qla_ini_mode_enabled(vha) &&
3919 ha->flags.fawwpn_enabled &&
3920 (rptid_entry->u.f1.flags &
Sawan Chandakfcc5b5c2017-08-23 15:05:02 -07003921 BIT_6)) {
Quinn Tran41dc5292017-01-19 22:28:03 -08003922 memcpy(vha->port_name,
3923 rptid_entry->u.f1.port_name,
3924 WWN_SIZE);
3925 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04003926
Quinn Tran482c9dc2017-03-15 09:48:54 -07003927 qlt_update_host_map(vha, id);
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04003928 }
Quinn Tran41dc5292017-01-19 22:28:03 -08003929
Quinn Tran41dc5292017-01-19 22:28:03 -08003930 set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
3931 set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
3932 } else {
3933 if (rptid_entry->vp_status != VP_STAT_COMPL &&
3934 rptid_entry->vp_status != VP_STAT_ID_CHG) {
3935 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
3936 "Could not acquire ID for VP[%d].\n",
3937 rptid_entry->vp_idx);
3938 return;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003939 }
Quinn Tran41dc5292017-01-19 22:28:03 -08003940
3941 found = 0;
3942 spin_lock_irqsave(&ha->vport_slock, flags);
3943 list_for_each_entry(vp, &ha->vp_list, list) {
3944 if (rptid_entry->vp_idx == vp->vp_idx) {
3945 found = 1;
3946 break;
3947 }
3948 }
3949 spin_unlock_irqrestore(&ha->vport_slock, flags);
3950
3951 if (!found)
3952 return;
3953
Quinn Tran482c9dc2017-03-15 09:48:54 -07003954 qlt_update_host_map(vp, id);
Quinn Tran41dc5292017-01-19 22:28:03 -08003955
3956 /*
3957 * Cannot configure here as we are still sitting on the
3958 * response queue. Handle it in dpc context.
3959 */
3960 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
3961 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
3962 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003963 }
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003964 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003965 qla2xxx_wake_dpc(vha);
Quinn Tran41dc5292017-01-19 22:28:03 -08003966 } else if (rptid_entry->format == 2) {
Quinn Tran83548fe2017-06-02 09:12:01 -07003967 ql_dbg(ql_dbg_async, vha, 0x505f,
Quinn Tran41dc5292017-01-19 22:28:03 -08003968 "RIDA: format 2/N2N Primary port id %02x%02x%02x.\n",
3969 rptid_entry->port_id[2], rptid_entry->port_id[1],
3970 rptid_entry->port_id[0]);
3971
Quinn Tran83548fe2017-06-02 09:12:01 -07003972 ql_dbg(ql_dbg_async, vha, 0x5075,
Quinn Tran41dc5292017-01-19 22:28:03 -08003973 "N2N: Remote WWPN %8phC.\n",
3974 rptid_entry->u.f2.port_name);
3975
3976 /* N2N. direct connect */
Quinn Tran9cd883f2017-12-28 12:33:24 -08003977 ha->current_topology = ISP_CFG_N;
3978 ha->flags.rida_fmt2 = 1;
Quinn Tran41dc5292017-01-19 22:28:03 -08003979 vha->d_id.b.domain = rptid_entry->port_id[2];
3980 vha->d_id.b.area = rptid_entry->port_id[1];
3981 vha->d_id.b.al_pa = rptid_entry->port_id[0];
3982
Darren Trapp1763c1f2018-03-20 23:09:34 -07003983 ha->flags.n2n_ae = 1;
Quinn Tran41dc5292017-01-19 22:28:03 -08003984 spin_lock_irqsave(&ha->vport_slock, flags);
3985 qlt_update_vp_map(vha, SET_AL_PA);
3986 spin_unlock_irqrestore(&ha->vport_slock, flags);
Quinn Tran9cd883f2017-12-28 12:33:24 -08003987
3988 list_for_each_entry(fcport, &vha->vp_fcports, list) {
3989 fcport->scan_state = QLA_FCPORT_SCAN;
3990 }
3991
3992 fcport = qla2x00_find_fcport_by_wwpn(vha,
3993 rptid_entry->u.f2.port_name, 1);
3994
3995 if (fcport) {
Quinn Tran23dd98a2018-08-02 13:16:45 -07003996 fcport->login_retry = vha->hw->login_retry_count;
Quinn Tran9cd883f2017-12-28 12:33:24 -08003997 fcport->plogi_nack_done_deadline = jiffies + HZ;
3998 fcport->scan_state = QLA_FCPORT_FOUND;
Quinn Tran9cd883f2017-12-28 12:33:24 -08003999 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004000 }
4001}
4002
4003/*
4004 * qla24xx_modify_vp_config
4005 * Change VP configuration for vha
4006 *
4007 * Input:
4008 * vha = adapter block pointer.
4009 *
4010 * Returns:
4011 * qla2xxx local function return status code.
4012 *
4013 * Context:
4014 * Kernel context.
4015 */
4016int
4017qla24xx_modify_vp_config(scsi_qla_host_t *vha)
4018{
4019 int rval;
4020 struct vp_config_entry_24xx *vpmod;
4021 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004022 struct qla_hw_data *ha = vha->hw;
4023 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004024
4025 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004026
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004027 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb,
4028 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004029
Thomas Meyer08eb7f42017-09-21 08:15:26 +02004030 vpmod = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004031 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004032 ql_log(ql_log_warn, vha, 0x10bc,
4033 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004034 return QLA_MEMORY_ALLOC_FAILED;
4035 }
4036
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004037 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
4038 vpmod->entry_count = 1;
4039 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
4040 vpmod->vp_count = 1;
4041 vpmod->vp_index1 = vha->vp_idx;
4042 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04004043
4044 qlt_modify_vp_config(vha, vpmod);
4045
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004046 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
4047 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
4048 vpmod->entry_count = 1;
4049
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004050 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004051 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004052 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
4053 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004054 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004055 ql_dbg(ql_dbg_mbx, vha, 0x10be,
4056 "Failed to complete IOCB -- error status (%x).\n",
4057 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004058 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07004059 } else if (vpmod->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004060 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
4061 "Failed to complete IOCB -- completion status (%x).\n",
4062 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004063 rval = QLA_FUNCTION_FAILED;
4064 } else {
4065 /* EMPTY */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004066 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0,
4067 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004068 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
4069 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004070 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004071
4072 return rval;
4073}
4074
4075/*
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004076 * qla2x00_send_change_request
4077 * Receive or disable RSCN request from fabric controller
4078 *
4079 * Input:
4080 * ha = adapter block pointer
4081 * format = registration format:
4082 * 0 - Reserved
4083 * 1 - Fabric detected registration
4084 * 2 - N_port detected registration
4085 * 3 - Full registration
4086 * FF - clear registration
4087 * vp_idx = Virtual port index
4088 *
4089 * Returns:
4090 * qla2x00 local function return status code.
4091 *
4092 * Context:
4093 * Kernel Context
4094 */
4095
4096int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004097qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004098 uint16_t vp_idx)
4099{
4100 int rval;
4101 mbx_cmd_t mc;
4102 mbx_cmd_t *mcp = &mc;
4103
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004104 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7,
4105 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004106
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004107 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
4108 mcp->mb[1] = format;
4109 mcp->mb[9] = vp_idx;
4110 mcp->out_mb = MBX_9|MBX_1|MBX_0;
4111 mcp->in_mb = MBX_0|MBX_1;
4112 mcp->tov = MBX_TOV_SECONDS;
4113 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004114 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004115
4116 if (rval == QLA_SUCCESS) {
4117 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
4118 rval = BIT_1;
4119 }
4120 } else
4121 rval = BIT_1;
4122
4123 return rval;
4124}
Andrew Vasquez338c9162007-09-20 14:07:33 -07004125
4126int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004127qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07004128 uint32_t size)
4129{
4130 int rval;
4131 mbx_cmd_t mc;
4132 mbx_cmd_t *mcp = &mc;
4133
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004134 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009,
4135 "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004136
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004137 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07004138 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
4139 mcp->mb[8] = MSW(addr);
4140 mcp->out_mb = MBX_8|MBX_0;
4141 } else {
4142 mcp->mb[0] = MBC_DUMP_RISC_RAM;
4143 mcp->out_mb = MBX_0;
4144 }
4145 mcp->mb[1] = LSW(addr);
4146 mcp->mb[2] = MSW(req_dma);
4147 mcp->mb[3] = LSW(req_dma);
4148 mcp->mb[6] = MSW(MSD(req_dma));
4149 mcp->mb[7] = LSW(MSD(req_dma));
4150 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004151 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07004152 mcp->mb[4] = MSW(size);
4153 mcp->mb[5] = LSW(size);
4154 mcp->out_mb |= MBX_5|MBX_4;
4155 } else {
4156 mcp->mb[4] = LSW(size);
4157 mcp->out_mb |= MBX_4;
4158 }
4159
4160 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07004161 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07004162 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004163 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004164
4165 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004166 ql_dbg(ql_dbg_mbx, vha, 0x1008,
4167 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004168 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004169 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007,
4170 "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004171 }
4172
4173 return rval;
4174}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004175/* 84XX Support **************************************************************/
4176
4177struct cs84xx_mgmt_cmd {
4178 union {
4179 struct verify_chip_entry_84xx req;
4180 struct verify_chip_rsp_84xx rsp;
4181 } p;
4182};
4183
4184int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004185qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004186{
4187 int rval, retry;
4188 struct cs84xx_mgmt_cmd *mn;
4189 dma_addr_t mn_dma;
4190 uint16_t options;
4191 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004192 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004193
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004194 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8,
4195 "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004196
4197 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
4198 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004199 return QLA_MEMORY_ALLOC_FAILED;
4200 }
4201
4202 /* Force Update? */
4203 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
4204 /* Diagnostic firmware? */
4205 /* options |= MENLO_DIAG_FW; */
4206 /* We update the firmware with only one data sequence. */
4207 options |= VCO_END_OF_DATA;
4208
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004209 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07004210 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004211 memset(mn, 0, sizeof(*mn));
4212 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
4213 mn->p.req.entry_count = 1;
4214 mn->p.req.options = cpu_to_le16(options);
4215
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004216 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
4217 "Dump of Verify Request.\n");
4218 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
4219 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004220
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004221 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004222 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004223 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
4224 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004225 goto verify_done;
4226 }
4227
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004228 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
4229 "Dump of Verify Response.\n");
4230 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
4231 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004232
4233 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
4234 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
4235 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004236 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004237 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004238
4239 if (status[0] != CS_COMPLETE) {
4240 rval = QLA_FUNCTION_FAILED;
4241 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004242 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
4243 "Firmware update failed. Retrying "
4244 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004245 options |= VCO_DONT_UPDATE_FW;
4246 options &= ~VCO_FORCE_UPDATE;
4247 retry = 1;
4248 }
4249 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004250 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004251 "Firmware updated to %x.\n",
4252 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004253
4254 /* NOTE: we only update OP firmware. */
4255 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
4256 ha->cs84xx->op_fw_version =
4257 le32_to_cpu(mn->p.rsp.fw_ver);
4258 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
4259 flags);
4260 }
4261 } while (retry);
4262
4263verify_done:
4264 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
4265
4266 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004267 ql_dbg(ql_dbg_mbx, vha, 0x10d1,
4268 "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004269 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004270 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2,
4271 "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004272 }
4273
4274 return rval;
4275}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004276
4277int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004278qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004279{
4280 int rval;
4281 unsigned long flags;
4282 mbx_cmd_t mc;
4283 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004284 struct qla_hw_data *ha = vha->hw;
4285
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004286 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
4287 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004288
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004289 if (IS_SHADOW_REG_CAPABLE(ha))
4290 req->options |= BIT_13;
4291
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004292 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004293 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004294 mcp->mb[2] = MSW(LSD(req->dma));
4295 mcp->mb[3] = LSW(LSD(req->dma));
4296 mcp->mb[6] = MSW(MSD(req->dma));
4297 mcp->mb[7] = LSW(MSD(req->dma));
4298 mcp->mb[5] = req->length;
4299 if (req->rsp)
4300 mcp->mb[10] = req->rsp->id;
4301 mcp->mb[12] = req->qos;
4302 mcp->mb[11] = req->vp_idx;
4303 mcp->mb[13] = req->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004304 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004305 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004306
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004307 mcp->mb[4] = req->id;
4308 /* que in ptr index */
4309 mcp->mb[8] = 0;
4310 /* que out ptr index */
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004311 mcp->mb[9] = *req->out_ptr = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004312 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
4313 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4314 mcp->in_mb = MBX_0;
4315 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004316 mcp->tov = MBX_TOV_SECONDS * 2;
4317
Chad Dupuisf73cb692014-02-26 04:15:06 -05004318 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004319 mcp->in_mb |= MBX_1;
Joe Carnuccioba4828b2014-04-11 16:54:10 -04004320 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004321 mcp->out_mb |= MBX_15;
4322 /* debug q create issue in SR-IOV */
4323 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
4324 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004325
4326 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004327 if (!(req->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004328 WRT_REG_DWORD(req->req_q_in, 0);
Joe Carnuccio29db41c2014-04-11 16:54:09 -04004329 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004330 WRT_REG_DWORD(req->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004331 }
4332 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4333
Anirban Chakraborty17d98632008-12-18 10:06:15 -08004334 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004335 if (rval != QLA_SUCCESS) {
4336 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
4337 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4338 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004339 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5,
4340 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004341 }
4342
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004343 return rval;
4344}
4345
4346int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004347qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004348{
4349 int rval;
4350 unsigned long flags;
4351 mbx_cmd_t mc;
4352 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004353 struct qla_hw_data *ha = vha->hw;
4354
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004355 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
4356 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004357
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004358 if (IS_SHADOW_REG_CAPABLE(ha))
4359 rsp->options |= BIT_13;
4360
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004361 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004362 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004363 mcp->mb[2] = MSW(LSD(rsp->dma));
4364 mcp->mb[3] = LSW(LSD(rsp->dma));
4365 mcp->mb[6] = MSW(MSD(rsp->dma));
4366 mcp->mb[7] = LSW(MSD(rsp->dma));
4367 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08004368 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004369 mcp->mb[13] = rsp->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004370 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004371 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004372
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004373 mcp->mb[4] = rsp->id;
4374 /* que in ptr index */
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004375 mcp->mb[8] = *rsp->in_ptr = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004376 /* que out ptr index */
4377 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07004378 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004379 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4380 mcp->in_mb = MBX_0;
4381 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004382 mcp->tov = MBX_TOV_SECONDS * 2;
4383
4384 if (IS_QLA81XX(ha)) {
4385 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
4386 mcp->in_mb |= MBX_1;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004387 } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004388 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
4389 mcp->in_mb |= MBX_1;
4390 /* debug q create issue in SR-IOV */
4391 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
4392 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004393
4394 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004395 if (!(rsp->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004396 WRT_REG_DWORD(rsp->rsp_q_out, 0);
Himanshu Madhanib20f02e2015-06-10 11:05:18 -04004397 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004398 WRT_REG_DWORD(rsp->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004399 }
4400
4401 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4402
Anirban Chakraborty17d98632008-12-18 10:06:15 -08004403 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004404 if (rval != QLA_SUCCESS) {
4405 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
4406 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4407 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004408 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8,
4409 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004410 }
4411
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004412 return rval;
4413}
4414
Andrew Vasquez8a659572009-02-08 20:50:12 -08004415int
4416qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
4417{
4418 int rval;
4419 mbx_cmd_t mc;
4420 mbx_cmd_t *mcp = &mc;
4421
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004422 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9,
4423 "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004424
4425 mcp->mb[0] = MBC_IDC_ACK;
4426 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
4427 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4428 mcp->in_mb = MBX_0;
4429 mcp->tov = MBX_TOV_SECONDS;
4430 mcp->flags = 0;
4431 rval = qla2x00_mailbox_command(vha, mcp);
4432
4433 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004434 ql_dbg(ql_dbg_mbx, vha, 0x10da,
4435 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004436 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004437 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db,
4438 "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004439 }
4440
4441 return rval;
4442}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004443
4444int
4445qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
4446{
4447 int rval;
4448 mbx_cmd_t mc;
4449 mbx_cmd_t *mcp = &mc;
4450
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004451 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc,
4452 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004453
Chad Dupuisf73cb692014-02-26 04:15:06 -05004454 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4455 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004456 return QLA_FUNCTION_FAILED;
4457
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004458 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4459 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
4460 mcp->out_mb = MBX_1|MBX_0;
4461 mcp->in_mb = MBX_1|MBX_0;
4462 mcp->tov = MBX_TOV_SECONDS;
4463 mcp->flags = 0;
4464 rval = qla2x00_mailbox_command(vha, mcp);
4465
4466 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004467 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
4468 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4469 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004470 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004471 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de,
4472 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004473 *sector_size = mcp->mb[1];
4474 }
4475
4476 return rval;
4477}
4478
4479int
4480qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
4481{
4482 int rval;
4483 mbx_cmd_t mc;
4484 mbx_cmd_t *mcp = &mc;
4485
Chad Dupuisf73cb692014-02-26 04:15:06 -05004486 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4487 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004488 return QLA_FUNCTION_FAILED;
4489
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004490 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df,
4491 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004492
4493 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4494 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
4495 FAC_OPT_CMD_WRITE_PROTECT;
4496 mcp->out_mb = MBX_1|MBX_0;
4497 mcp->in_mb = MBX_1|MBX_0;
4498 mcp->tov = MBX_TOV_SECONDS;
4499 mcp->flags = 0;
4500 rval = qla2x00_mailbox_command(vha, mcp);
4501
4502 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004503 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
4504 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4505 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004506 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004507 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1,
4508 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004509 }
4510
4511 return rval;
4512}
4513
4514int
4515qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
4516{
4517 int rval;
4518 mbx_cmd_t mc;
4519 mbx_cmd_t *mcp = &mc;
4520
Chad Dupuisf73cb692014-02-26 04:15:06 -05004521 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4522 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004523 return QLA_FUNCTION_FAILED;
4524
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004525 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,
4526 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004527
4528 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4529 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
4530 mcp->mb[2] = LSW(start);
4531 mcp->mb[3] = MSW(start);
4532 mcp->mb[4] = LSW(finish);
4533 mcp->mb[5] = MSW(finish);
4534 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4535 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4536 mcp->tov = MBX_TOV_SECONDS;
4537 mcp->flags = 0;
4538 rval = qla2x00_mailbox_command(vha, mcp);
4539
4540 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004541 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
4542 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4543 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004544 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004545 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,
4546 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004547 }
4548
4549 return rval;
4550}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004551
4552int
4553qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
4554{
4555 int rval = 0;
4556 mbx_cmd_t mc;
4557 mbx_cmd_t *mcp = &mc;
4558
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004559 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5,
4560 "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004561
4562 mcp->mb[0] = MBC_RESTART_MPI_FW;
4563 mcp->out_mb = MBX_0;
4564 mcp->in_mb = MBX_0|MBX_1;
4565 mcp->tov = MBX_TOV_SECONDS;
4566 mcp->flags = 0;
4567 rval = qla2x00_mailbox_command(vha, mcp);
4568
4569 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004570 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
4571 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4572 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004573 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004574 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7,
4575 "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004576 }
4577
4578 return rval;
4579}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004580
Joe Carnuccioc46e65c2013-08-27 01:37:35 -04004581int
4582qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4583{
4584 int rval;
4585 mbx_cmd_t mc;
4586 mbx_cmd_t *mcp = &mc;
4587 int i;
4588 int len;
4589 uint16_t *str;
4590 struct qla_hw_data *ha = vha->hw;
4591
4592 if (!IS_P3P_TYPE(ha))
4593 return QLA_FUNCTION_FAILED;
4594
4595 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b,
4596 "Entered %s.\n", __func__);
4597
4598 str = (void *)version;
4599 len = strlen(version);
4600
4601 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4602 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8;
4603 mcp->out_mb = MBX_1|MBX_0;
4604 for (i = 4; i < 16 && len; i++, str++, len -= 2) {
4605 mcp->mb[i] = cpu_to_le16p(str);
4606 mcp->out_mb |= 1<<i;
4607 }
4608 for (; i < 16; i++) {
4609 mcp->mb[i] = 0;
4610 mcp->out_mb |= 1<<i;
4611 }
4612 mcp->in_mb = MBX_1|MBX_0;
4613 mcp->tov = MBX_TOV_SECONDS;
4614 mcp->flags = 0;
4615 rval = qla2x00_mailbox_command(vha, mcp);
4616
4617 if (rval != QLA_SUCCESS) {
4618 ql_dbg(ql_dbg_mbx, vha, 0x117c,
4619 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4620 } else {
4621 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d,
4622 "Done %s.\n", __func__);
4623 }
4624
4625 return rval;
4626}
4627
4628int
4629qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4630{
4631 int rval;
4632 mbx_cmd_t mc;
4633 mbx_cmd_t *mcp = &mc;
4634 int len;
4635 uint16_t dwlen;
4636 uint8_t *str;
4637 dma_addr_t str_dma;
4638 struct qla_hw_data *ha = vha->hw;
4639
4640 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) ||
4641 IS_P3P_TYPE(ha))
4642 return QLA_FUNCTION_FAILED;
4643
4644 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e,
4645 "Entered %s.\n", __func__);
4646
4647 str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);
4648 if (!str) {
4649 ql_log(ql_log_warn, vha, 0x117f,
4650 "Failed to allocate driver version param.\n");
4651 return QLA_MEMORY_ALLOC_FAILED;
4652 }
4653
4654 memcpy(str, "\x7\x3\x11\x0", 4);
4655 dwlen = str[0];
4656 len = dwlen * 4 - 4;
4657 memset(str + 4, 0, len);
4658 if (len > strlen(version))
4659 len = strlen(version);
4660 memcpy(str + 4, version, len);
4661
4662 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4663 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;
4664 mcp->mb[2] = MSW(LSD(str_dma));
4665 mcp->mb[3] = LSW(LSD(str_dma));
4666 mcp->mb[6] = MSW(MSD(str_dma));
4667 mcp->mb[7] = LSW(MSD(str_dma));
4668 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4669 mcp->in_mb = MBX_1|MBX_0;
4670 mcp->tov = MBX_TOV_SECONDS;
4671 mcp->flags = 0;
4672 rval = qla2x00_mailbox_command(vha, mcp);
4673
4674 if (rval != QLA_SUCCESS) {
4675 ql_dbg(ql_dbg_mbx, vha, 0x1180,
4676 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4677 } else {
4678 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181,
4679 "Done %s.\n", __func__);
4680 }
4681
4682 dma_pool_free(ha->s_dma_pool, str, str_dma);
4683
4684 return rval;
4685}
4686
Duane Grigsbyedd05de2017-10-13 09:34:06 -07004687int
4688qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
4689 void *buf, uint16_t bufsiz)
4690{
4691 int rval, i;
4692 mbx_cmd_t mc;
4693 mbx_cmd_t *mcp = &mc;
4694 uint32_t *bp;
4695
4696 if (!IS_FWI2_CAPABLE(vha->hw))
4697 return QLA_FUNCTION_FAILED;
4698
4699 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4700 "Entered %s.\n", __func__);
4701
4702 mcp->mb[0] = MBC_GET_RNID_PARAMS;
4703 mcp->mb[1] = RNID_TYPE_PORT_LOGIN << 8;
4704 mcp->mb[2] = MSW(buf_dma);
4705 mcp->mb[3] = LSW(buf_dma);
4706 mcp->mb[6] = MSW(MSD(buf_dma));
4707 mcp->mb[7] = LSW(MSD(buf_dma));
4708 mcp->mb[8] = bufsiz/4;
4709 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4710 mcp->in_mb = MBX_1|MBX_0;
4711 mcp->tov = MBX_TOV_SECONDS;
4712 mcp->flags = 0;
4713 rval = qla2x00_mailbox_command(vha, mcp);
4714
4715 if (rval != QLA_SUCCESS) {
4716 ql_dbg(ql_dbg_mbx, vha, 0x115a,
4717 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4718 } else {
4719 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4720 "Done %s.\n", __func__);
4721 bp = (uint32_t *) buf;
4722 for (i = 0; i < (bufsiz-4)/4; i++, bp++)
Quinn Tran8777e432018-08-02 13:16:57 -07004723 *bp = le32_to_cpu(*bp);
Duane Grigsbyedd05de2017-10-13 09:34:06 -07004724 }
4725
4726 return rval;
4727}
4728
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004729static int
4730qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
4731{
4732 int rval;
4733 mbx_cmd_t mc;
4734 mbx_cmd_t *mcp = &mc;
4735
4736 if (!IS_FWI2_CAPABLE(vha->hw))
4737 return QLA_FUNCTION_FAILED;
4738
4739 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4740 "Entered %s.\n", __func__);
4741
4742 mcp->mb[0] = MBC_GET_RNID_PARAMS;
4743 mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8;
4744 mcp->out_mb = MBX_1|MBX_0;
4745 mcp->in_mb = MBX_1|MBX_0;
4746 mcp->tov = MBX_TOV_SECONDS;
4747 mcp->flags = 0;
4748 rval = qla2x00_mailbox_command(vha, mcp);
4749 *temp = mcp->mb[1];
4750
4751 if (rval != QLA_SUCCESS) {
4752 ql_dbg(ql_dbg_mbx, vha, 0x115a,
4753 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4754 } else {
4755 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4756 "Done %s.\n", __func__);
4757 }
4758
4759 return rval;
4760}
4761
Joe Carnuccio3a117112013-02-08 01:58:00 -05004762int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004763qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4764 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004765{
4766 int rval;
4767 mbx_cmd_t mc;
4768 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004769 struct qla_hw_data *ha = vha->hw;
4770
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004771 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,
4772 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004773
Joe Carnuccio6766df92011-05-10 11:30:15 -07004774 if (!IS_FWI2_CAPABLE(ha))
4775 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004776
Joe Carnuccio6766df92011-05-10 11:30:15 -07004777 if (len == 1)
4778 opt |= BIT_0;
4779
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004780 mcp->mb[0] = MBC_READ_SFP;
4781 mcp->mb[1] = dev;
4782 mcp->mb[2] = MSW(sfp_dma);
4783 mcp->mb[3] = LSW(sfp_dma);
4784 mcp->mb[6] = MSW(MSD(sfp_dma));
4785 mcp->mb[7] = LSW(MSD(sfp_dma));
4786 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004787 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004788 mcp->mb[10] = opt;
4789 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 -07004790 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004791 mcp->tov = MBX_TOV_SECONDS;
4792 mcp->flags = 0;
4793 rval = qla2x00_mailbox_command(vha, mcp);
4794
4795 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004796 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004797
4798 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004799 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
4800 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Quinn Trane4e3a2c2017-08-23 15:05:07 -07004801 if (mcp->mb[0] == MBS_COMMAND_ERROR &&
4802 mcp->mb[1] == 0x22)
4803 /* sfp is not there */
4804 rval = QLA_INTERFACE_ERROR;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004805 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004806 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
4807 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004808 }
4809
4810 return rval;
4811}
4812
4813int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004814qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4815 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004816{
4817 int rval;
4818 mbx_cmd_t mc;
4819 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004820 struct qla_hw_data *ha = vha->hw;
4821
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004822 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb,
4823 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004824
Joe Carnuccio6766df92011-05-10 11:30:15 -07004825 if (!IS_FWI2_CAPABLE(ha))
4826 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004827
Joe Carnuccio6766df92011-05-10 11:30:15 -07004828 if (len == 1)
4829 opt |= BIT_0;
4830
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004831 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004832 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004833
4834 mcp->mb[0] = MBC_WRITE_SFP;
4835 mcp->mb[1] = dev;
4836 mcp->mb[2] = MSW(sfp_dma);
4837 mcp->mb[3] = LSW(sfp_dma);
4838 mcp->mb[6] = MSW(MSD(sfp_dma));
4839 mcp->mb[7] = LSW(MSD(sfp_dma));
4840 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004841 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004842 mcp->mb[10] = opt;
4843 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 -07004844 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004845 mcp->tov = MBX_TOV_SECONDS;
4846 mcp->flags = 0;
4847 rval = qla2x00_mailbox_command(vha, mcp);
4848
4849 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004850 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
4851 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004852 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004853 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed,
4854 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004855 }
4856
4857 return rval;
4858}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004859
4860int
4861qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
4862 uint16_t size_in_bytes, uint16_t *actual_size)
4863{
4864 int rval;
4865 mbx_cmd_t mc;
4866 mbx_cmd_t *mcp = &mc;
4867
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004868 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee,
4869 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004870
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004871 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004872 return QLA_FUNCTION_FAILED;
4873
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004874 mcp->mb[0] = MBC_GET_XGMAC_STATS;
4875 mcp->mb[2] = MSW(stats_dma);
4876 mcp->mb[3] = LSW(stats_dma);
4877 mcp->mb[6] = MSW(MSD(stats_dma));
4878 mcp->mb[7] = LSW(MSD(stats_dma));
4879 mcp->mb[8] = size_in_bytes >> 2;
4880 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4881 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4882 mcp->tov = MBX_TOV_SECONDS;
4883 mcp->flags = 0;
4884 rval = qla2x00_mailbox_command(vha, mcp);
4885
4886 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004887 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
4888 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4889 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004890 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004891 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0,
4892 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004893
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004894
4895 *actual_size = mcp->mb[2] << 2;
4896 }
4897
4898 return rval;
4899}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004900
4901int
4902qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
4903 uint16_t size)
4904{
4905 int rval;
4906 mbx_cmd_t mc;
4907 mbx_cmd_t *mcp = &mc;
4908
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004909 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1,
4910 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004911
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004912 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004913 return QLA_FUNCTION_FAILED;
4914
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004915 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4916 mcp->mb[1] = 0;
4917 mcp->mb[2] = MSW(tlv_dma);
4918 mcp->mb[3] = LSW(tlv_dma);
4919 mcp->mb[6] = MSW(MSD(tlv_dma));
4920 mcp->mb[7] = LSW(MSD(tlv_dma));
4921 mcp->mb[8] = size;
4922 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4923 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4924 mcp->tov = MBX_TOV_SECONDS;
4925 mcp->flags = 0;
4926 rval = qla2x00_mailbox_command(vha, mcp);
4927
4928 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004929 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
4930 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4931 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004932 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004933 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3,
4934 "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004935 }
4936
4937 return rval;
4938}
Andrew Vasquez18e75552009-06-03 09:55:30 -07004939
4940int
4941qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
4942{
4943 int rval;
4944 mbx_cmd_t mc;
4945 mbx_cmd_t *mcp = &mc;
4946
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004947 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4,
4948 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004949
Andrew Vasquez18e75552009-06-03 09:55:30 -07004950 if (!IS_FWI2_CAPABLE(vha->hw))
4951 return QLA_FUNCTION_FAILED;
4952
Andrew Vasquez18e75552009-06-03 09:55:30 -07004953 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
4954 mcp->mb[1] = LSW(risc_addr);
4955 mcp->mb[8] = MSW(risc_addr);
4956 mcp->out_mb = MBX_8|MBX_1|MBX_0;
4957 mcp->in_mb = MBX_3|MBX_2|MBX_0;
4958 mcp->tov = 30;
4959 mcp->flags = 0;
4960 rval = qla2x00_mailbox_command(vha, mcp);
4961 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004962 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
4963 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004964 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004965 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6,
4966 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004967 *data = mcp->mb[3] << 16 | mcp->mb[2];
4968 }
4969
4970 return rval;
4971}
4972
4973int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004974qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4975 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004976{
4977 int rval;
4978 mbx_cmd_t mc;
4979 mbx_cmd_t *mcp = &mc;
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004980
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004981 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7,
4982 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004983
4984 memset(mcp->mb, 0 , sizeof(mcp->mb));
4985 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
4986 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
4987
4988 /* transfer count */
4989 mcp->mb[10] = LSW(mreq->transfer_size);
4990 mcp->mb[11] = MSW(mreq->transfer_size);
4991
4992 /* send data address */
4993 mcp->mb[14] = LSW(mreq->send_dma);
4994 mcp->mb[15] = MSW(mreq->send_dma);
4995 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4996 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4997
Lucas De Marchi25985ed2011-03-30 22:57:33 -03004998 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004999 mcp->mb[16] = LSW(mreq->rcv_dma);
5000 mcp->mb[17] = MSW(mreq->rcv_dma);
5001 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
5002 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
5003
5004 /* Iteration count */
Joe Carnuccio1b98b422013-03-28 08:21:26 -04005005 mcp->mb[18] = LSW(mreq->iteration_count);
5006 mcp->mb[19] = MSW(mreq->iteration_count);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005007
5008 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
5009 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 -08005010 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005011 mcp->out_mb |= MBX_2;
5012 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
5013
5014 mcp->buf_size = mreq->transfer_size;
5015 mcp->tov = MBX_TOV_SECONDS;
5016 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5017
5018 rval = qla2x00_mailbox_command(vha, mcp);
5019
5020 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005021 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
5022 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
5023 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
5024 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005025 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005026 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9,
5027 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005028 }
5029
5030 /* Copy mailbox information */
5031 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005032 return rval;
5033}
5034
5035int
Giridhar Malavalia9083012010-04-12 17:59:55 -07005036qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
5037 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005038{
5039 int rval;
5040 mbx_cmd_t mc;
5041 mbx_cmd_t *mcp = &mc;
5042 struct qla_hw_data *ha = vha->hw;
5043
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005044 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa,
5045 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005046
5047 memset(mcp->mb, 0 , sizeof(mcp->mb));
5048 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
Joe Carnuccio1d634962017-05-24 18:06:22 -07005049 /* BIT_6 specifies 64bit address */
5050 mcp->mb[1] = mreq->options | BIT_15 | BIT_6;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005051 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -07005052 mcp->mb[2] = vha->fcoe_fcf_idx;
5053 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005054 mcp->mb[16] = LSW(mreq->rcv_dma);
5055 mcp->mb[17] = MSW(mreq->rcv_dma);
5056 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
5057 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
5058
5059 mcp->mb[10] = LSW(mreq->transfer_size);
5060
5061 mcp->mb[14] = LSW(mreq->send_dma);
5062 mcp->mb[15] = MSW(mreq->send_dma);
5063 mcp->mb[20] = LSW(MSD(mreq->send_dma));
5064 mcp->mb[21] = MSW(MSD(mreq->send_dma));
5065
5066 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
5067 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005068 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005069 mcp->out_mb |= MBX_2;
5070
5071 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005072 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
5073 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005074 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005075 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005076 mcp->in_mb |= MBX_3;
5077
5078 mcp->tov = MBX_TOV_SECONDS;
5079 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5080 mcp->buf_size = mreq->transfer_size;
5081
5082 rval = qla2x00_mailbox_command(vha, mcp);
5083
5084 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005085 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
5086 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5087 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005088 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005089 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc,
5090 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005091 }
5092
5093 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07005094 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005095 return rval;
5096}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07005097
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005098int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005099qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005100{
5101 int rval;
5102 mbx_cmd_t mc;
5103 mbx_cmd_t *mcp = &mc;
5104
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005105 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005106 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005107
5108 mcp->mb[0] = MBC_ISP84XX_RESET;
5109 mcp->mb[1] = enable_diagnostic;
5110 mcp->out_mb = MBX_1|MBX_0;
5111 mcp->in_mb = MBX_1|MBX_0;
5112 mcp->tov = MBX_TOV_SECONDS;
5113 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005114 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005115
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005116 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005117 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005118 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005119 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff,
5120 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005121
5122 return rval;
5123}
5124
5125int
Andrew Vasquez18e75552009-06-03 09:55:30 -07005126qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
5127{
5128 int rval;
5129 mbx_cmd_t mc;
5130 mbx_cmd_t *mcp = &mc;
5131
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005132 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100,
5133 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005134
Andrew Vasquez18e75552009-06-03 09:55:30 -07005135 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07005136 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07005137
Andrew Vasquez18e75552009-06-03 09:55:30 -07005138 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
5139 mcp->mb[1] = LSW(risc_addr);
5140 mcp->mb[2] = LSW(data);
5141 mcp->mb[3] = MSW(data);
5142 mcp->mb[8] = MSW(risc_addr);
5143 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
5144 mcp->in_mb = MBX_0;
5145 mcp->tov = 30;
5146 mcp->flags = 0;
5147 rval = qla2x00_mailbox_command(vha, mcp);
5148 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005149 ql_dbg(ql_dbg_mbx, vha, 0x1101,
5150 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07005151 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005152 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
5153 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07005154 }
5155
5156 return rval;
5157}
Michael Hernandez3064ff32009-12-15 21:29:44 -08005158
5159int
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005160qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
5161{
5162 int rval;
5163 uint32_t stat, timer;
5164 uint16_t mb0 = 0;
5165 struct qla_hw_data *ha = vha->hw;
5166 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
5167
5168 rval = QLA_SUCCESS;
5169
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005170 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103,
5171 "Entered %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005172
5173 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
5174
5175 /* Write the MBC data to the registers */
5176 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
5177 WRT_REG_WORD(&reg->mailbox1, mb[0]);
5178 WRT_REG_WORD(&reg->mailbox2, mb[1]);
5179 WRT_REG_WORD(&reg->mailbox3, mb[2]);
5180 WRT_REG_WORD(&reg->mailbox4, mb[3]);
5181
5182 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
5183
5184 /* Poll for MBC interrupt */
5185 for (timer = 6000000; timer; timer--) {
5186 /* Check for pending interrupts. */
5187 stat = RD_REG_DWORD(&reg->host_status);
5188 if (stat & HSRX_RISC_INT) {
5189 stat &= 0xff;
5190
5191 if (stat == 0x1 || stat == 0x2 ||
5192 stat == 0x10 || stat == 0x11) {
5193 set_bit(MBX_INTERRUPT,
5194 &ha->mbx_cmd_flags);
5195 mb0 = RD_REG_WORD(&reg->mailbox0);
5196 WRT_REG_DWORD(&reg->hccr,
5197 HCCRX_CLR_RISC_INT);
5198 RD_REG_DWORD(&reg->hccr);
5199 break;
5200 }
5201 }
5202 udelay(5);
5203 }
5204
5205 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
5206 rval = mb0 & MBS_MASK;
5207 else
5208 rval = QLA_FUNCTION_FAILED;
5209
5210 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005211 ql_dbg(ql_dbg_mbx, vha, 0x1104,
5212 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005213 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005214 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105,
5215 "Done %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005216 }
5217
5218 return rval;
5219}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005220
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005221int
Michael Hernandez3064ff32009-12-15 21:29:44 -08005222qla2x00_get_data_rate(scsi_qla_host_t *vha)
5223{
5224 int rval;
5225 mbx_cmd_t mc;
5226 mbx_cmd_t *mcp = &mc;
5227 struct qla_hw_data *ha = vha->hw;
5228
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005229 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
5230 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005231
Michael Hernandez3064ff32009-12-15 21:29:44 -08005232 if (!IS_FWI2_CAPABLE(ha))
5233 return QLA_FUNCTION_FAILED;
5234
Michael Hernandez3064ff32009-12-15 21:29:44 -08005235 mcp->mb[0] = MBC_DATA_RATE;
5236 mcp->mb[1] = 0;
5237 mcp->out_mb = MBX_1|MBX_0;
5238 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05005239 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005240 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08005241 mcp->tov = MBX_TOV_SECONDS;
5242 mcp->flags = 0;
5243 rval = qla2x00_mailbox_command(vha, mcp);
5244 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005245 ql_dbg(ql_dbg_mbx, vha, 0x1107,
5246 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08005247 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005248 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
5249 "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08005250 if (mcp->mb[1] != 0x7)
5251 ha->link_data_rate = mcp->mb[1];
5252 }
5253
5254 return rval;
5255}
Sarang Radke09ff7012010-03-19 17:03:59 -07005256
5257int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005258qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
5259{
5260 int rval;
5261 mbx_cmd_t mc;
5262 mbx_cmd_t *mcp = &mc;
5263 struct qla_hw_data *ha = vha->hw;
5264
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005265 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
5266 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005267
Chad Dupuisf73cb692014-02-26 04:15:06 -05005268 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) &&
5269 !IS_QLA27XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005270 return QLA_FUNCTION_FAILED;
5271 mcp->mb[0] = MBC_GET_PORT_CONFIG;
5272 mcp->out_mb = MBX_0;
5273 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5274 mcp->tov = MBX_TOV_SECONDS;
5275 mcp->flags = 0;
5276
5277 rval = qla2x00_mailbox_command(vha, mcp);
5278
5279 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005280 ql_dbg(ql_dbg_mbx, vha, 0x110a,
5281 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005282 } else {
5283 /* Copy all bits to preserve original value */
5284 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
5285
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005286 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b,
5287 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005288 }
5289 return rval;
5290}
5291
5292int
5293qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
5294{
5295 int rval;
5296 mbx_cmd_t mc;
5297 mbx_cmd_t *mcp = &mc;
5298
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005299 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c,
5300 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005301
5302 mcp->mb[0] = MBC_SET_PORT_CONFIG;
5303 /* Copy all bits to preserve original setting */
5304 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
5305 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5306 mcp->in_mb = MBX_0;
5307 mcp->tov = MBX_TOV_SECONDS;
5308 mcp->flags = 0;
5309 rval = qla2x00_mailbox_command(vha, mcp);
5310
5311 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005312 ql_dbg(ql_dbg_mbx, vha, 0x110d,
5313 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005314 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005315 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e,
5316 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005317
5318 return rval;
5319}
5320
5321
5322int
Sarang Radke09ff7012010-03-19 17:03:59 -07005323qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
5324 uint16_t *mb)
5325{
5326 int rval;
5327 mbx_cmd_t mc;
5328 mbx_cmd_t *mcp = &mc;
5329 struct qla_hw_data *ha = vha->hw;
5330
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005331 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f,
5332 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005333
Sarang Radke09ff7012010-03-19 17:03:59 -07005334 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
5335 return QLA_FUNCTION_FAILED;
5336
Sarang Radke09ff7012010-03-19 17:03:59 -07005337 mcp->mb[0] = MBC_PORT_PARAMS;
5338 mcp->mb[1] = loop_id;
5339 if (ha->flags.fcp_prio_enabled)
5340 mcp->mb[2] = BIT_1;
5341 else
5342 mcp->mb[2] = BIT_2;
5343 mcp->mb[4] = priority & 0xf;
5344 mcp->mb[9] = vha->vp_idx;
5345 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5346 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5347 mcp->tov = 30;
5348 mcp->flags = 0;
5349 rval = qla2x00_mailbox_command(vha, mcp);
5350 if (mb != NULL) {
5351 mb[0] = mcp->mb[0];
5352 mb[1] = mcp->mb[1];
5353 mb[3] = mcp->mb[3];
5354 mb[4] = mcp->mb[4];
5355 }
5356
5357 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005358 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07005359 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005360 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc,
5361 "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07005362 }
5363
5364 return rval;
5365}
Giridhar Malavalia9083012010-04-12 17:59:55 -07005366
5367int
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005368qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)
Andrew Vasquez794a5692010-12-21 16:00:21 -08005369{
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005370 int rval = QLA_FUNCTION_FAILED;
Andrew Vasquez794a5692010-12-21 16:00:21 -08005371 struct qla_hw_data *ha = vha->hw;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005372 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08005373
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005374 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) {
5375 ql_dbg(ql_dbg_mbx, vha, 0x1150,
5376 "Thermal not supported by this card.\n");
5377 return rval;
Andrew Vasquez794a5692010-12-21 16:00:21 -08005378 }
Andrew Vasquez794a5692010-12-21 16:00:21 -08005379
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005380 if (IS_QLA25XX(ha)) {
5381 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
5382 ha->pdev->subsystem_device == 0x0175) {
5383 rval = qla2x00_read_sfp(vha, 0, &byte,
5384 0x98, 0x1, 1, BIT_13|BIT_0);
5385 *temp = byte;
5386 return rval;
5387 }
5388 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
5389 ha->pdev->subsystem_device == 0x338e) {
5390 rval = qla2x00_read_sfp(vha, 0, &byte,
5391 0x98, 0x1, 1, BIT_15|BIT_14|BIT_0);
5392 *temp = byte;
5393 return rval;
5394 }
5395 ql_dbg(ql_dbg_mbx, vha, 0x10c9,
5396 "Thermal not supported by this card.\n");
5397 return rval;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005398 }
5399
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005400 if (IS_QLA82XX(ha)) {
5401 *temp = qla82xx_read_temperature(vha);
5402 rval = QLA_SUCCESS;
5403 return rval;
5404 } else if (IS_QLA8044(ha)) {
5405 *temp = qla8044_read_temperature(vha);
5406 rval = QLA_SUCCESS;
5407 return rval;
5408 }
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005409
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005410 rval = qla2x00_read_asic_temperature(vha, temp);
Andrew Vasquez794a5692010-12-21 16:00:21 -08005411 return rval;
5412}
5413
5414int
Giridhar Malavalia9083012010-04-12 17:59:55 -07005415qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
5416{
5417 int rval;
5418 struct qla_hw_data *ha = vha->hw;
5419 mbx_cmd_t mc;
5420 mbx_cmd_t *mcp = &mc;
5421
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005422 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017,
5423 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005424
Giridhar Malavalia9083012010-04-12 17:59:55 -07005425 if (!IS_FWI2_CAPABLE(ha))
5426 return QLA_FUNCTION_FAILED;
5427
Giridhar Malavalia9083012010-04-12 17:59:55 -07005428 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05005429 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07005430 mcp->mb[1] = 1;
5431
5432 mcp->out_mb = MBX_1|MBX_0;
5433 mcp->in_mb = MBX_0;
5434 mcp->tov = 30;
5435 mcp->flags = 0;
5436
5437 rval = qla2x00_mailbox_command(vha, mcp);
5438 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005439 ql_dbg(ql_dbg_mbx, vha, 0x1016,
5440 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005441 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005442 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e,
5443 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005444 }
5445
5446 return rval;
5447}
5448
5449int
5450qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
5451{
5452 int rval;
5453 struct qla_hw_data *ha = vha->hw;
5454 mbx_cmd_t mc;
5455 mbx_cmd_t *mcp = &mc;
5456
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005457 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
5458 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005459
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005460 if (!IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -07005461 return QLA_FUNCTION_FAILED;
5462
Giridhar Malavalia9083012010-04-12 17:59:55 -07005463 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05005464 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07005465 mcp->mb[1] = 0;
5466
5467 mcp->out_mb = MBX_1|MBX_0;
5468 mcp->in_mb = MBX_0;
5469 mcp->tov = 30;
5470 mcp->flags = 0;
5471
5472 rval = qla2x00_mailbox_command(vha, mcp);
5473 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005474 ql_dbg(ql_dbg_mbx, vha, 0x100c,
5475 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005476 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005477 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b,
5478 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005479 }
5480
5481 return rval;
5482}
Giridhar Malavali08de2842011-08-16 11:31:44 -07005483
5484int
5485qla82xx_md_get_template_size(scsi_qla_host_t *vha)
5486{
5487 struct qla_hw_data *ha = vha->hw;
5488 mbx_cmd_t mc;
5489 mbx_cmd_t *mcp = &mc;
5490 int rval = QLA_FUNCTION_FAILED;
5491
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005492 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f,
5493 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005494
5495 memset(mcp->mb, 0 , sizeof(mcp->mb));
5496 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5497 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5498 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
5499 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
5500
5501 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5502 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
5503 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5504
5505 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5506 mcp->tov = MBX_TOV_SECONDS;
5507 rval = qla2x00_mailbox_command(vha, mcp);
5508
5509 /* Always copy back return mailbox values. */
5510 if (rval != QLA_SUCCESS) {
5511 ql_dbg(ql_dbg_mbx, vha, 0x1120,
5512 "mailbox command FAILED=0x%x, subcode=%x.\n",
5513 (mcp->mb[1] << 16) | mcp->mb[0],
5514 (mcp->mb[3] << 16) | mcp->mb[2]);
5515 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005516 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121,
5517 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005518 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
5519 if (!ha->md_template_size) {
5520 ql_dbg(ql_dbg_mbx, vha, 0x1122,
5521 "Null template size obtained.\n");
5522 rval = QLA_FUNCTION_FAILED;
5523 }
5524 }
5525 return rval;
5526}
5527
5528int
5529qla82xx_md_get_template(scsi_qla_host_t *vha)
5530{
5531 struct qla_hw_data *ha = vha->hw;
5532 mbx_cmd_t mc;
5533 mbx_cmd_t *mcp = &mc;
5534 int rval = QLA_FUNCTION_FAILED;
5535
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005536 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123,
5537 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005538
5539 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
5540 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
5541 if (!ha->md_tmplt_hdr) {
5542 ql_log(ql_log_warn, vha, 0x1124,
5543 "Unable to allocate memory for Minidump template.\n");
5544 return rval;
5545 }
5546
5547 memset(mcp->mb, 0 , sizeof(mcp->mb));
5548 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5549 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5550 mcp->mb[2] = LSW(RQST_TMPLT);
5551 mcp->mb[3] = MSW(RQST_TMPLT);
5552 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
5553 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
5554 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
5555 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
5556 mcp->mb[8] = LSW(ha->md_template_size);
5557 mcp->mb[9] = MSW(ha->md_template_size);
5558
5559 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5560 mcp->tov = MBX_TOV_SECONDS;
5561 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5562 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5563 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5564 rval = qla2x00_mailbox_command(vha, mcp);
5565
5566 if (rval != QLA_SUCCESS) {
5567 ql_dbg(ql_dbg_mbx, vha, 0x1125,
5568 "mailbox command FAILED=0x%x, subcode=%x.\n",
5569 ((mcp->mb[1] << 16) | mcp->mb[0]),
5570 ((mcp->mb[3] << 16) | mcp->mb[2]));
5571 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005572 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126,
5573 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005574 return rval;
5575}
Saurav Kashyap999916d2011-08-16 11:31:45 -07005576
5577int
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005578qla8044_md_get_template(scsi_qla_host_t *vha)
5579{
5580 struct qla_hw_data *ha = vha->hw;
5581 mbx_cmd_t mc;
5582 mbx_cmd_t *mcp = &mc;
5583 int rval = QLA_FUNCTION_FAILED;
5584 int offset = 0, size = MINIDUMP_SIZE_36K;
5585 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,
5586 "Entered %s.\n", __func__);
5587
5588 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
5589 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
5590 if (!ha->md_tmplt_hdr) {
5591 ql_log(ql_log_warn, vha, 0xb11b,
5592 "Unable to allocate memory for Minidump template.\n");
5593 return rval;
5594 }
5595
5596 memset(mcp->mb, 0 , sizeof(mcp->mb));
5597 while (offset < ha->md_template_size) {
5598 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5599 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5600 mcp->mb[2] = LSW(RQST_TMPLT);
5601 mcp->mb[3] = MSW(RQST_TMPLT);
5602 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));
5603 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));
5604 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));
5605 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));
5606 mcp->mb[8] = LSW(size);
5607 mcp->mb[9] = MSW(size);
5608 mcp->mb[10] = offset & 0x0000FFFF;
5609 mcp->mb[11] = offset & 0xFFFF0000;
5610 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5611 mcp->tov = MBX_TOV_SECONDS;
5612 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5613 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5614 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5615 rval = qla2x00_mailbox_command(vha, mcp);
5616
5617 if (rval != QLA_SUCCESS) {
5618 ql_dbg(ql_dbg_mbx, vha, 0xb11c,
5619 "mailbox command FAILED=0x%x, subcode=%x.\n",
5620 ((mcp->mb[1] << 16) | mcp->mb[0]),
5621 ((mcp->mb[3] << 16) | mcp->mb[2]));
5622 return rval;
5623 } else
5624 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,
5625 "Done %s.\n", __func__);
5626 offset = offset + size;
5627 }
5628 return rval;
5629}
5630
5631int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005632qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5633{
5634 int rval;
5635 struct qla_hw_data *ha = vha->hw;
5636 mbx_cmd_t mc;
5637 mbx_cmd_t *mcp = &mc;
5638
5639 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5640 return QLA_FUNCTION_FAILED;
5641
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005642 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133,
5643 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005644
5645 memset(mcp, 0, sizeof(mbx_cmd_t));
5646 mcp->mb[0] = MBC_SET_LED_CONFIG;
5647 mcp->mb[1] = led_cfg[0];
5648 mcp->mb[2] = led_cfg[1];
5649 if (IS_QLA8031(ha)) {
5650 mcp->mb[3] = led_cfg[2];
5651 mcp->mb[4] = led_cfg[3];
5652 mcp->mb[5] = led_cfg[4];
5653 mcp->mb[6] = led_cfg[5];
5654 }
5655
5656 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5657 if (IS_QLA8031(ha))
5658 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5659 mcp->in_mb = MBX_0;
5660 mcp->tov = 30;
5661 mcp->flags = 0;
5662
5663 rval = qla2x00_mailbox_command(vha, mcp);
5664 if (rval != QLA_SUCCESS) {
5665 ql_dbg(ql_dbg_mbx, vha, 0x1134,
5666 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5667 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005668 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135,
5669 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005670 }
5671
5672 return rval;
5673}
5674
5675int
5676qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5677{
5678 int rval;
5679 struct qla_hw_data *ha = vha->hw;
5680 mbx_cmd_t mc;
5681 mbx_cmd_t *mcp = &mc;
5682
5683 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5684 return QLA_FUNCTION_FAILED;
5685
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005686 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136,
5687 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005688
5689 memset(mcp, 0, sizeof(mbx_cmd_t));
5690 mcp->mb[0] = MBC_GET_LED_CONFIG;
5691
5692 mcp->out_mb = MBX_0;
5693 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5694 if (IS_QLA8031(ha))
5695 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5696 mcp->tov = 30;
5697 mcp->flags = 0;
5698
5699 rval = qla2x00_mailbox_command(vha, mcp);
5700 if (rval != QLA_SUCCESS) {
5701 ql_dbg(ql_dbg_mbx, vha, 0x1137,
5702 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5703 } else {
5704 led_cfg[0] = mcp->mb[1];
5705 led_cfg[1] = mcp->mb[2];
5706 if (IS_QLA8031(ha)) {
5707 led_cfg[2] = mcp->mb[3];
5708 led_cfg[3] = mcp->mb[4];
5709 led_cfg[4] = mcp->mb[5];
5710 led_cfg[5] = mcp->mb[6];
5711 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005712 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138,
5713 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005714 }
5715
5716 return rval;
5717}
5718
5719int
Saurav Kashyap999916d2011-08-16 11:31:45 -07005720qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
5721{
5722 int rval;
5723 struct qla_hw_data *ha = vha->hw;
5724 mbx_cmd_t mc;
5725 mbx_cmd_t *mcp = &mc;
5726
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005727 if (!IS_P3P_TYPE(ha))
Saurav Kashyap999916d2011-08-16 11:31:45 -07005728 return QLA_FUNCTION_FAILED;
5729
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005730 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005731 "Entered %s.\n", __func__);
5732
5733 memset(mcp, 0, sizeof(mbx_cmd_t));
5734 mcp->mb[0] = MBC_SET_LED_CONFIG;
5735 if (enable)
5736 mcp->mb[7] = 0xE;
5737 else
5738 mcp->mb[7] = 0xD;
5739
5740 mcp->out_mb = MBX_7|MBX_0;
5741 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005742 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07005743 mcp->flags = 0;
5744
5745 rval = qla2x00_mailbox_command(vha, mcp);
5746 if (rval != QLA_SUCCESS) {
5747 ql_dbg(ql_dbg_mbx, vha, 0x1128,
5748 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5749 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005750 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005751 "Done %s.\n", __func__);
5752 }
5753
5754 return rval;
5755}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005756
5757int
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005758qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005759{
5760 int rval;
5761 struct qla_hw_data *ha = vha->hw;
5762 mbx_cmd_t mc;
5763 mbx_cmd_t *mcp = &mc;
5764
Chad Dupuisf73cb692014-02-26 04:15:06 -05005765 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005766 return QLA_FUNCTION_FAILED;
5767
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005768 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130,
5769 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005770
5771 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
5772 mcp->mb[1] = LSW(reg);
5773 mcp->mb[2] = MSW(reg);
5774 mcp->mb[3] = LSW(data);
5775 mcp->mb[4] = MSW(data);
5776 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5777
5778 mcp->in_mb = MBX_1|MBX_0;
5779 mcp->tov = MBX_TOV_SECONDS;
5780 mcp->flags = 0;
5781 rval = qla2x00_mailbox_command(vha, mcp);
5782
5783 if (rval != QLA_SUCCESS) {
5784 ql_dbg(ql_dbg_mbx, vha, 0x1131,
5785 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5786 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005787 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005788 "Done %s.\n", __func__);
5789 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005790
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005791 return rval;
5792}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005793
5794int
5795qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
5796{
5797 int rval;
5798 struct qla_hw_data *ha = vha->hw;
5799 mbx_cmd_t mc;
5800 mbx_cmd_t *mcp = &mc;
5801
5802 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005803 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b,
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005804 "Implicit LOGO Unsupported.\n");
5805 return QLA_FUNCTION_FAILED;
5806 }
5807
5808
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005809 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c,
5810 "Entering %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005811
5812 /* Perform Implicit LOGO. */
5813 mcp->mb[0] = MBC_PORT_LOGOUT;
5814 mcp->mb[1] = fcport->loop_id;
5815 mcp->mb[10] = BIT_15;
5816 mcp->out_mb = MBX_10|MBX_1|MBX_0;
5817 mcp->in_mb = MBX_0;
5818 mcp->tov = MBX_TOV_SECONDS;
5819 mcp->flags = 0;
5820 rval = qla2x00_mailbox_command(vha, mcp);
5821 if (rval != QLA_SUCCESS)
5822 ql_dbg(ql_dbg_mbx, vha, 0x113d,
5823 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5824 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005825 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e,
5826 "Done %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005827
5828 return rval;
5829}
5830
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005831int
5832qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
5833{
5834 int rval;
5835 mbx_cmd_t mc;
5836 mbx_cmd_t *mcp = &mc;
5837 struct qla_hw_data *ha = vha->hw;
5838 unsigned long retry_max_time = jiffies + (2 * HZ);
5839
Chad Dupuisf73cb692014-02-26 04:15:06 -05005840 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005841 return QLA_FUNCTION_FAILED;
5842
5843 ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
5844
5845retry_rd_reg:
5846 mcp->mb[0] = MBC_READ_REMOTE_REG;
5847 mcp->mb[1] = LSW(reg);
5848 mcp->mb[2] = MSW(reg);
5849 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5850 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5851 mcp->tov = MBX_TOV_SECONDS;
5852 mcp->flags = 0;
5853 rval = qla2x00_mailbox_command(vha, mcp);
5854
5855 if (rval != QLA_SUCCESS) {
5856 ql_dbg(ql_dbg_mbx, vha, 0x114c,
5857 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5858 rval, mcp->mb[0], mcp->mb[1]);
5859 } else {
5860 *data = (mcp->mb[3] | (mcp->mb[4] << 16));
5861 if (*data == QLA8XXX_BAD_VALUE) {
5862 /*
5863 * During soft-reset CAMRAM register reads might
5864 * return 0xbad0bad0. So retry for MAX of 2 sec
5865 * while reading camram registers.
5866 */
5867 if (time_after(jiffies, retry_max_time)) {
5868 ql_dbg(ql_dbg_mbx, vha, 0x1141,
5869 "Failure to read CAMRAM register. "
5870 "data=0x%x.\n", *data);
5871 return QLA_FUNCTION_FAILED;
5872 }
5873 msleep(100);
5874 goto retry_rd_reg;
5875 }
5876 ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
5877 }
5878
5879 return rval;
5880}
5881
5882int
5883qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
5884{
5885 int rval;
5886 mbx_cmd_t mc;
5887 mbx_cmd_t *mcp = &mc;
5888 struct qla_hw_data *ha = vha->hw;
5889
Himanshu Madhanib20f02e2015-06-10 11:05:18 -04005890 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005891 return QLA_FUNCTION_FAILED;
5892
5893 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
5894
5895 mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
5896 mcp->out_mb = MBX_0;
5897 mcp->in_mb = MBX_1|MBX_0;
5898 mcp->tov = MBX_TOV_SECONDS;
5899 mcp->flags = 0;
5900 rval = qla2x00_mailbox_command(vha, mcp);
5901
5902 if (rval != QLA_SUCCESS) {
5903 ql_dbg(ql_dbg_mbx, vha, 0x1144,
5904 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5905 rval, mcp->mb[0], mcp->mb[1]);
5906 ha->isp_ops->fw_dump(vha, 0);
5907 } else {
5908 ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
5909 }
5910
5911 return rval;
5912}
5913
5914int
5915qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
5916 uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
5917{
5918 int rval;
5919 mbx_cmd_t mc;
5920 mbx_cmd_t *mcp = &mc;
5921 uint8_t subcode = (uint8_t)options;
5922 struct qla_hw_data *ha = vha->hw;
5923
5924 if (!IS_QLA8031(ha))
5925 return QLA_FUNCTION_FAILED;
5926
5927 ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
5928
5929 mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
5930 mcp->mb[1] = options;
5931 mcp->out_mb = MBX_1|MBX_0;
5932 if (subcode & BIT_2) {
5933 mcp->mb[2] = LSW(start_addr);
5934 mcp->mb[3] = MSW(start_addr);
5935 mcp->mb[4] = LSW(end_addr);
5936 mcp->mb[5] = MSW(end_addr);
5937 mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
5938 }
5939 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5940 if (!(subcode & (BIT_2 | BIT_5)))
5941 mcp->in_mb |= MBX_4|MBX_3;
5942 mcp->tov = MBX_TOV_SECONDS;
5943 mcp->flags = 0;
5944 rval = qla2x00_mailbox_command(vha, mcp);
5945
5946 if (rval != QLA_SUCCESS) {
5947 ql_dbg(ql_dbg_mbx, vha, 0x1147,
5948 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
5949 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
5950 mcp->mb[4]);
5951 ha->isp_ops->fw_dump(vha, 0);
5952 } else {
5953 if (subcode & BIT_5)
5954 *sector_size = mcp->mb[1];
5955 else if (subcode & (BIT_6 | BIT_7)) {
5956 ql_dbg(ql_dbg_mbx, vha, 0x1148,
5957 "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5958 } else if (subcode & (BIT_3 | BIT_4)) {
5959 ql_dbg(ql_dbg_mbx, vha, 0x1149,
5960 "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5961 }
5962 ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
5963 }
5964
5965 return rval;
5966}
Saurav Kashyap81178772012-08-22 14:21:04 -04005967
5968int
5969qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
5970 uint32_t size)
5971{
5972 int rval;
5973 mbx_cmd_t mc;
5974 mbx_cmd_t *mcp = &mc;
5975
5976 if (!IS_MCTP_CAPABLE(vha->hw))
5977 return QLA_FUNCTION_FAILED;
5978
5979 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,
5980 "Entered %s.\n", __func__);
5981
5982 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
5983 mcp->mb[1] = LSW(addr);
5984 mcp->mb[2] = MSW(req_dma);
5985 mcp->mb[3] = LSW(req_dma);
5986 mcp->mb[4] = MSW(size);
5987 mcp->mb[5] = LSW(size);
5988 mcp->mb[6] = MSW(MSD(req_dma));
5989 mcp->mb[7] = LSW(MSD(req_dma));
5990 mcp->mb[8] = MSW(addr);
5991 /* Setting RAM ID to valid */
5992 mcp->mb[10] |= BIT_7;
5993 /* For MCTP RAM ID is 0x40 */
5994 mcp->mb[10] |= 0x40;
5995
5996 mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
5997 MBX_0;
5998
5999 mcp->in_mb = MBX_0;
6000 mcp->tov = MBX_TOV_SECONDS;
6001 mcp->flags = 0;
6002 rval = qla2x00_mailbox_command(vha, mcp);
6003
6004 if (rval != QLA_SUCCESS) {
6005 ql_dbg(ql_dbg_mbx, vha, 0x114e,
6006 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
6007 } else {
6008 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,
6009 "Done %s.\n", __func__);
6010 }
6011
6012 return rval;
6013}
Joe Carnuccioec891462016-07-06 11:14:26 -04006014
6015int
6016qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
6017 void *dd_buf, uint size, uint options)
6018{
6019 int rval;
6020 mbx_cmd_t mc;
6021 mbx_cmd_t *mcp = &mc;
6022 dma_addr_t dd_dma;
6023
6024 if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
6025 return QLA_FUNCTION_FAILED;
6026
Quinn Tran83548fe2017-06-02 09:12:01 -07006027 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f,
Joe Carnuccioec891462016-07-06 11:14:26 -04006028 "Entered %s.\n", __func__);
6029
Joe Carnuccioec891462016-07-06 11:14:26 -04006030 dd_dma = dma_map_single(&vha->hw->pdev->dev,
6031 dd_buf, size, DMA_FROM_DEVICE);
Pan Bian0b2ce192017-08-08 21:55:30 +08006032 if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) {
Joe Carnuccioec891462016-07-06 11:14:26 -04006033 ql_log(ql_log_warn, vha, 0x1194, "Failed to map dma buffer.\n");
6034 return QLA_MEMORY_ALLOC_FAILED;
6035 }
6036
6037 memset(dd_buf, 0, size);
6038
6039 mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;
6040 mcp->mb[1] = options;
6041 mcp->mb[2] = MSW(LSD(dd_dma));
6042 mcp->mb[3] = LSW(LSD(dd_dma));
6043 mcp->mb[6] = MSW(MSD(dd_dma));
6044 mcp->mb[7] = LSW(MSD(dd_dma));
6045 mcp->mb[8] = size;
6046 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
6047 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
6048 mcp->buf_size = size;
6049 mcp->flags = MBX_DMA_IN;
6050 mcp->tov = MBX_TOV_SECONDS * 4;
6051 rval = qla2x00_mailbox_command(vha, mcp);
6052
6053 if (rval != QLA_SUCCESS) {
6054 ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval);
6055 } else {
6056 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196,
6057 "Done %s.\n", __func__);
6058 }
6059
6060 dma_unmap_single(&vha->hw->pdev->dev, dd_dma,
6061 size, DMA_FROM_DEVICE);
6062
6063 return rval;
6064}
Quinn Tran15f30a52017-03-15 09:48:52 -07006065
6066static void qla2x00_async_mb_sp_done(void *s, int res)
6067{
6068 struct srb *sp = s;
6069
6070 sp->u.iocb_cmd.u.mbx.rc = res;
6071
6072 complete(&sp->u.iocb_cmd.u.mbx.comp);
6073 /* don't free sp here. Let the caller do the free */
6074}
6075
6076/*
6077 * This mailbox uses the iocb interface to send MB command.
6078 * This allows non-critial (non chip setup) command to go
6079 * out in parrallel.
6080 */
6081int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)
6082{
6083 int rval = QLA_FUNCTION_FAILED;
6084 srb_t *sp;
6085 struct srb_iocb *c;
6086
6087 if (!vha->hw->flags.fw_started)
6088 goto done;
6089
6090 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
6091 if (!sp)
6092 goto done;
6093
6094 sp->type = SRB_MB_IOCB;
6095 sp->name = mb_to_str(mcp->mb[0]);
6096
Quinn Tran15f30a52017-03-15 09:48:52 -07006097 c = &sp->u.iocb_cmd;
6098 c->timeout = qla2x00_async_iocb_timeout;
6099 init_completion(&c->u.mbx.comp);
6100
Ben Hutchingse74e7d92018-03-20 21:36:14 +00006101 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
6102
6103 memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG);
6104
Quinn Tran15f30a52017-03-15 09:48:52 -07006105 sp->done = qla2x00_async_mb_sp_done;
6106
6107 rval = qla2x00_start_sp(sp);
6108 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006109 ql_dbg(ql_dbg_mbx, vha, 0x1018,
Quinn Tran15f30a52017-03-15 09:48:52 -07006110 "%s: %s Failed submission. %x.\n",
6111 __func__, sp->name, rval);
6112 goto done_free_sp;
6113 }
6114
Quinn Tran83548fe2017-06-02 09:12:01 -07006115 ql_dbg(ql_dbg_mbx, vha, 0x113f, "MB:%s hndl %x submitted\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006116 sp->name, sp->handle);
6117
6118 wait_for_completion(&c->u.mbx.comp);
6119 memcpy(mcp->mb, sp->u.iocb_cmd.u.mbx.in_mb, SIZEOF_IOCB_MB_REG);
6120
6121 rval = c->u.mbx.rc;
6122 switch (rval) {
6123 case QLA_FUNCTION_TIMEOUT:
Quinn Tran83548fe2017-06-02 09:12:01 -07006124 ql_dbg(ql_dbg_mbx, vha, 0x1140, "%s: %s Timeout. %x.\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006125 __func__, sp->name, rval);
6126 break;
6127 case QLA_SUCCESS:
Quinn Tran83548fe2017-06-02 09:12:01 -07006128 ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006129 __func__, sp->name);
6130 sp->free(sp);
6131 break;
6132 default:
Quinn Tran83548fe2017-06-02 09:12:01 -07006133 ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006134 __func__, sp->name, rval);
6135 sp->free(sp);
6136 break;
6137 }
6138
6139 return rval;
6140
6141done_free_sp:
6142 sp->free(sp);
6143done:
6144 return rval;
6145}
6146
6147/*
6148 * qla24xx_gpdb_wait
6149 * NOTE: Do not call this routine from DPC thread
6150 */
6151int qla24xx_gpdb_wait(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
6152{
6153 int rval = QLA_FUNCTION_FAILED;
6154 dma_addr_t pd_dma;
6155 struct port_database_24xx *pd;
6156 struct qla_hw_data *ha = vha->hw;
6157 mbx_cmd_t mc;
6158
6159 if (!vha->hw->flags.fw_started)
6160 goto done;
6161
Thomas Meyer08eb7f42017-09-21 08:15:26 +02006162 pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Quinn Tran15f30a52017-03-15 09:48:52 -07006163 if (pd == NULL) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006164 ql_log(ql_log_warn, vha, 0xd047,
6165 "Failed to allocate port database structure.\n");
Quinn Tran15f30a52017-03-15 09:48:52 -07006166 goto done_free_sp;
6167 }
Quinn Tran15f30a52017-03-15 09:48:52 -07006168
6169 memset(&mc, 0, sizeof(mc));
6170 mc.mb[0] = MBC_GET_PORT_DATABASE;
6171 mc.mb[1] = cpu_to_le16(fcport->loop_id);
6172 mc.mb[2] = MSW(pd_dma);
6173 mc.mb[3] = LSW(pd_dma);
6174 mc.mb[6] = MSW(MSD(pd_dma));
6175 mc.mb[7] = LSW(MSD(pd_dma));
6176 mc.mb[9] = cpu_to_le16(vha->vp_idx);
6177 mc.mb[10] = cpu_to_le16((uint16_t)opt);
6178
6179 rval = qla24xx_send_mb_cmd(vha, &mc);
6180 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006181 ql_dbg(ql_dbg_mbx, vha, 0x1193,
Quinn Tran15f30a52017-03-15 09:48:52 -07006182 "%s: %8phC fail\n", __func__, fcport->port_name);
6183 goto done_free_sp;
6184 }
6185
6186 rval = __qla24xx_parse_gpdb(vha, fcport, pd);
6187
Quinn Tran83548fe2017-06-02 09:12:01 -07006188 ql_dbg(ql_dbg_mbx, vha, 0x1197, "%s: %8phC done\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006189 __func__, fcport->port_name);
6190
6191done_free_sp:
6192 if (pd)
6193 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
6194done:
6195 return rval;
6196}
6197
6198int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
6199 struct port_database_24xx *pd)
6200{
6201 int rval = QLA_SUCCESS;
6202 uint64_t zero = 0;
Duane Grigsbya5d42f42017-06-21 13:48:41 -07006203 u8 current_login_state, last_login_state;
6204
6205 if (fcport->fc4f_nvme) {
6206 current_login_state = pd->current_login_state >> 4;
6207 last_login_state = pd->last_login_state >> 4;
6208 } else {
6209 current_login_state = pd->current_login_state & 0xf;
6210 last_login_state = pd->last_login_state & 0xf;
6211 }
Quinn Tran15f30a52017-03-15 09:48:52 -07006212
6213 /* Check for logged in state. */
Quinn Tran23c64552017-12-04 14:45:08 -08006214 if (current_login_state != PDS_PRLI_COMPLETE) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006215 ql_dbg(ql_dbg_mbx, vha, 0x119a,
6216 "Unable to verify login-state (%x/%x) for loop_id %x.\n",
Duane Grigsbya5d42f42017-06-21 13:48:41 -07006217 current_login_state, last_login_state, fcport->loop_id);
Quinn Tran15f30a52017-03-15 09:48:52 -07006218 rval = QLA_FUNCTION_FAILED;
6219 goto gpd_error_out;
6220 }
6221
6222 if (fcport->loop_id == FC_NO_LOOP_ID ||
6223 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
6224 memcmp(fcport->port_name, pd->port_name, 8))) {
6225 /* We lost the device mid way. */
6226 rval = QLA_NOT_LOGGED_IN;
6227 goto gpd_error_out;
6228 }
6229
6230 /* Names are little-endian. */
6231 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
6232 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
6233
6234 /* Get port_id of device. */
6235 fcport->d_id.b.domain = pd->port_id[0];
6236 fcport->d_id.b.area = pd->port_id[1];
6237 fcport->d_id.b.al_pa = pd->port_id[2];
6238 fcport->d_id.b.rsvd_1 = 0;
6239
Duane Grigsbya5d42f42017-06-21 13:48:41 -07006240 if (fcport->fc4f_nvme) {
6241 fcport->nvme_prli_service_param =
6242 pd->prli_nvme_svc_param_word_3;
6243 fcport->port_type = FCT_NVME;
6244 } else {
6245 /* If not target must be initiator or unknown type. */
6246 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
6247 fcport->port_type = FCT_INITIATOR;
6248 else
6249 fcport->port_type = FCT_TARGET;
6250 }
Quinn Tran15f30a52017-03-15 09:48:52 -07006251 /* Passback COS information. */
6252 fcport->supported_classes = (pd->flags & PDF_CLASS_2) ?
6253 FC_COS_CLASS2 : FC_COS_CLASS3;
6254
6255 if (pd->prli_svc_param_word_3[0] & BIT_7) {
6256 fcport->flags |= FCF_CONF_COMP_SUPPORTED;
6257 fcport->conf_compl_supported = 1;
6258 }
6259
6260gpd_error_out:
6261 return rval;
6262}
6263
6264/*
6265 * qla24xx_gidlist__wait
6266 * NOTE: don't call this routine from DPC thread.
6267 */
6268int qla24xx_gidlist_wait(struct scsi_qla_host *vha,
6269 void *id_list, dma_addr_t id_list_dma, uint16_t *entries)
6270{
6271 int rval = QLA_FUNCTION_FAILED;
6272 mbx_cmd_t mc;
6273
6274 if (!vha->hw->flags.fw_started)
6275 goto done;
6276
6277 memset(&mc, 0, sizeof(mc));
6278 mc.mb[0] = MBC_GET_ID_LIST;
6279 mc.mb[2] = MSW(id_list_dma);
6280 mc.mb[3] = LSW(id_list_dma);
6281 mc.mb[6] = MSW(MSD(id_list_dma));
6282 mc.mb[7] = LSW(MSD(id_list_dma));
6283 mc.mb[8] = 0;
6284 mc.mb[9] = cpu_to_le16(vha->vp_idx);
6285
6286 rval = qla24xx_send_mb_cmd(vha, &mc);
6287 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006288 ql_dbg(ql_dbg_mbx, vha, 0x119b,
6289 "%s: fail\n", __func__);
Quinn Tran15f30a52017-03-15 09:48:52 -07006290 } else {
6291 *entries = mc.mb[1];
Quinn Tran83548fe2017-06-02 09:12:01 -07006292 ql_dbg(ql_dbg_mbx, vha, 0x119c,
6293 "%s: done\n", __func__);
Quinn Tran15f30a52017-03-15 09:48:52 -07006294 }
6295done:
6296 return rval;
6297}
Duane Grigsbydeeae7a2017-07-21 09:32:25 -07006298
6299int qla27xx_set_zio_threshold(scsi_qla_host_t *vha, uint16_t value)
6300{
6301 int rval;
6302 mbx_cmd_t mc;
6303 mbx_cmd_t *mcp = &mc;
6304
6305 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1200,
6306 "Entered %s\n", __func__);
6307
6308 memset(mcp->mb, 0 , sizeof(mcp->mb));
6309 mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD;
6310 mcp->mb[1] = cpu_to_le16(1);
6311 mcp->mb[2] = cpu_to_le16(value);
6312 mcp->out_mb = MBX_2 | MBX_1 | MBX_0;
6313 mcp->in_mb = MBX_2 | MBX_0;
6314 mcp->tov = MBX_TOV_SECONDS;
6315 mcp->flags = 0;
6316
6317 rval = qla2x00_mailbox_command(vha, mcp);
6318
6319 ql_dbg(ql_dbg_mbx, vha, 0x1201, "%s %x\n",
6320 (rval != QLA_SUCCESS) ? "Failed" : "Done", rval);
6321
6322 return rval;
6323}
6324
6325int qla27xx_get_zio_threshold(scsi_qla_host_t *vha, uint16_t *value)
6326{
6327 int rval;
6328 mbx_cmd_t mc;
6329 mbx_cmd_t *mcp = &mc;
6330
6331 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1203,
6332 "Entered %s\n", __func__);
6333
6334 memset(mcp->mb, 0, sizeof(mcp->mb));
6335 mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD;
6336 mcp->mb[1] = cpu_to_le16(0);
6337 mcp->out_mb = MBX_1 | MBX_0;
6338 mcp->in_mb = MBX_2 | MBX_0;
6339 mcp->tov = MBX_TOV_SECONDS;
6340 mcp->flags = 0;
6341
6342 rval = qla2x00_mailbox_command(vha, mcp);
6343 if (rval == QLA_SUCCESS)
6344 *value = mc.mb[2];
6345
6346 ql_dbg(ql_dbg_mbx, vha, 0x1205, "%s %x\n",
6347 (rval != QLA_SUCCESS) ? "Failed" : "Done", rval);
6348
6349 return rval;
6350}
Quinn Trane4e3a2c2017-08-23 15:05:07 -07006351
6352int
6353qla2x00_read_sfp_dev(struct scsi_qla_host *vha, char *buf, int count)
6354{
6355 struct qla_hw_data *ha = vha->hw;
6356 uint16_t iter, addr, offset;
6357 dma_addr_t phys_addr;
6358 int rval, c;
6359 u8 *sfp_data;
6360
6361 memset(ha->sfp_data, 0, SFP_DEV_SIZE);
6362 addr = 0xa0;
6363 phys_addr = ha->sfp_data_dma;
6364 sfp_data = ha->sfp_data;
6365 offset = c = 0;
6366
6367 for (iter = 0; iter < SFP_DEV_SIZE / SFP_BLOCK_SIZE; iter++) {
6368 if (iter == 4) {
6369 /* Skip to next device address. */
6370 addr = 0xa2;
6371 offset = 0;
6372 }
6373
6374 rval = qla2x00_read_sfp(vha, phys_addr, sfp_data,
6375 addr, offset, SFP_BLOCK_SIZE, BIT_1);
6376 if (rval != QLA_SUCCESS) {
6377 ql_log(ql_log_warn, vha, 0x706d,
6378 "Unable to read SFP data (%x/%x/%x).\n", rval,
6379 addr, offset);
6380
6381 return rval;
6382 }
6383
6384 if (buf && (c < count)) {
6385 u16 sz;
6386
6387 if ((count - c) >= SFP_BLOCK_SIZE)
6388 sz = SFP_BLOCK_SIZE;
6389 else
6390 sz = count - c;
6391
6392 memcpy(buf, sfp_data, sz);
6393 buf += SFP_BLOCK_SIZE;
6394 c += sz;
6395 }
6396 phys_addr += SFP_BLOCK_SIZE;
6397 sfp_data += SFP_BLOCK_SIZE;
6398 offset += SFP_BLOCK_SIZE;
6399 }
6400
6401 return rval;
6402}
Quinn Tran94d83e32017-12-28 12:33:23 -08006403
6404int qla24xx_res_count_wait(struct scsi_qla_host *vha,
6405 uint16_t *out_mb, int out_mb_sz)
6406{
6407 int rval = QLA_FUNCTION_FAILED;
6408 mbx_cmd_t mc;
6409
6410 if (!vha->hw->flags.fw_started)
6411 goto done;
6412
6413 memset(&mc, 0, sizeof(mc));
6414 mc.mb[0] = MBC_GET_RESOURCE_COUNTS;
6415
6416 rval = qla24xx_send_mb_cmd(vha, &mc);
6417 if (rval != QLA_SUCCESS) {
6418 ql_dbg(ql_dbg_mbx, vha, 0xffff,
6419 "%s: fail\n", __func__);
6420 } else {
6421 if (out_mb_sz <= SIZEOF_IOCB_MB_REG)
6422 memcpy(out_mb, mc.mb, out_mb_sz);
6423 else
6424 memcpy(out_mb, mc.mb, SIZEOF_IOCB_MB_REG);
6425
6426 ql_dbg(ql_dbg_mbx, vha, 0xffff,
6427 "%s: done\n", __func__);
6428 }
6429done:
6430 return rval;
6431}