blob: e016ee9c6d8e3d9a5a7c53c338ffdf3a8c4edafa [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 },
Quinn Tran8b4673b2018-09-04 14:19:14 -070063 { MBC_GET_SET_ZIO_THRESHOLD },
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -080064};
65
66static int is_rom_cmd(uint16_t cmd)
67{
68 int i;
69 struct rom_cmd *wc;
70
71 for (i = 0; i < ARRAY_SIZE(rom_cmds); i++) {
72 wc = rom_cmds + i;
73 if (wc->cmd == cmd)
74 return 1;
75 }
76
77 return 0;
78}
Linus Torvalds1da177e2005-04-16 15:20:36 -070079
80/*
81 * qla2x00_mailbox_command
82 * Issue mailbox command and waits for completion.
83 *
84 * Input:
85 * ha = adapter block pointer.
86 * mcp = driver internal mbx struct pointer.
87 *
88 * Output:
89 * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
90 *
91 * Returns:
92 * 0 : QLA_SUCCESS = cmd performed success
93 * 1 : QLA_FUNCTION_FAILED (error encountered)
94 * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
95 *
96 * Context:
97 * Kernel context.
98 */
99static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800100qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101{
Himanshu Madhanid14e72f2015-04-09 15:00:03 -0400102 int rval, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 unsigned long flags = 0;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500104 device_reg_t *reg;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700105 uint8_t abort_active;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700106 uint8_t io_lock_on;
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700107 uint16_t command = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 uint16_t *iptr;
109 uint16_t __iomem *optr;
110 uint32_t cnt;
111 uint32_t mboxes;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 unsigned long wait_time;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800113 struct qla_hw_data *ha = vha->hw;
114 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
Quinn Tranb2000802018-08-02 13:16:52 -0700115 u32 chip_reset;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700116
Himanshu Madhanid14e72f2015-04-09 15:00:03 -0400117
Arun Easi5e19ed92012-02-09 11:15:51 -0800118 ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700119
120 if (ha->pdev->error_state > pci_channel_io_frozen) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800121 ql_log(ql_log_warn, vha, 0x1001,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700122 "error_state is greater than pci_channel_io_frozen, "
123 "exiting.\n");
Seokmann Jub9b12f72009-03-24 09:08:18 -0700124 return QLA_FUNCTION_TIMEOUT;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700125 }
Seokmann Jub9b12f72009-03-24 09:08:18 -0700126
Giridhar Malavalia9083012010-04-12 17:59:55 -0700127 if (vha->device_flags & DFLG_DEV_FAILED) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800128 ql_log(ql_log_warn, vha, 0x1002,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700129 "Device in failed state, exiting.\n");
Giridhar Malavalia9083012010-04-12 17:59:55 -0700130 return QLA_FUNCTION_TIMEOUT;
131 }
132
Bart Van Asschec2a5d942017-01-11 15:58:58 -0800133 /* if PCI error, then avoid mbx processing.*/
Sawan Chandakba175892017-06-02 09:11:58 -0700134 if (test_bit(PFLG_DISCONNECTED, &base_vha->dpc_flags) &&
135 test_bit(UNLOADING, &base_vha->dpc_flags)) {
Quinn Tran83548fe2017-06-02 09:12:01 -0700136 ql_log(ql_log_warn, vha, 0xd04e,
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400137 "PCI error, exiting.\n");
138 return QLA_FUNCTION_TIMEOUT;
Bart Van Asschec2a5d942017-01-11 15:58:58 -0800139 }
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400140
Seokmann Ju2c3dfe32007-07-05 13:16:51 -0700141 reg = ha->iobase;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800142 io_lock_on = base_vha->flags.init_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143
144 rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800145 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Quinn Tranb2000802018-08-02 13:16:52 -0700146 chip_reset = ha->chip_reset;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700147
Andrew Vasquez85880802009-12-15 21:29:46 -0800148 if (ha->flags.pci_channel_io_perm_failure) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800149 ql_log(ql_log_warn, vha, 0x1003,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700150 "Perm failure on EEH timeout MBX, exiting.\n");
Andrew Vasquez85880802009-12-15 21:29:46 -0800151 return QLA_FUNCTION_TIMEOUT;
152 }
153
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400154 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Giridhar Malavali862cd012011-02-23 15:27:11 -0800155 /* Setting Link-Down error */
156 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
Arun Easi5e19ed92012-02-09 11:15:51 -0800157 ql_log(ql_log_warn, vha, 0x1004,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700158 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Andrew Vasquez1806fcd2011-11-18 09:02:15 -0800159 return QLA_FUNCTION_TIMEOUT;
Giridhar Malavali862cd012011-02-23 15:27:11 -0800160 }
161
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -0800162 /* check if ISP abort is active and return cmd with timeout */
163 if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
164 test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
165 test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) &&
166 !is_rom_cmd(mcp->mb[0])) {
167 ql_log(ql_log_info, vha, 0x1005,
168 "Cmd 0x%x aborted with timeout since ISP Abort is pending\n",
169 mcp->mb[0]);
170 return QLA_FUNCTION_TIMEOUT;
171 }
172
Quinn Tranb2000802018-08-02 13:16:52 -0700173 atomic_inc(&ha->num_pend_mbx_stage1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700175 * Wait for active mailbox commands to finish by waiting at most tov
176 * seconds. This is to serialize actual issuing of mailbox cmds during
177 * non ISP abort time.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800179 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
180 /* Timeout occurred. Return error. */
Quinn Tran83548fe2017-06-02 09:12:01 -0700181 ql_log(ql_log_warn, vha, 0xd035,
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800182 "Cmd access timeout, cmd=0x%x, Exiting.\n",
183 mcp->mb[0]);
Quinn Tranb2000802018-08-02 13:16:52 -0700184 atomic_dec(&ha->num_pend_mbx_stage1);
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800185 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 }
Quinn Tranb2000802018-08-02 13:16:52 -0700187 atomic_dec(&ha->num_pend_mbx_stage1);
188 if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) {
189 rval = QLA_ABORTED;
190 goto premature_exit;
191 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700193
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 /* Save mailbox command for debug */
195 ha->mcp = mcp;
196
Arun Easi5e19ed92012-02-09 11:15:51 -0800197 ql_dbg(ql_dbg_mbx, vha, 0x1006,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700198 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199
200 spin_lock_irqsave(&ha->hardware_lock, flags);
201
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700202 if (ha->flags.purge_mbox || chip_reset != ha->chip_reset ||
203 ha->flags.mbox_busy) {
Quinn Tranb2000802018-08-02 13:16:52 -0700204 rval = QLA_ABORTED;
Quinn Tranb2000802018-08-02 13:16:52 -0700205 spin_unlock_irqrestore(&ha->hardware_lock, flags);
206 goto premature_exit;
207 }
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700208 ha->flags.mbox_busy = 1;
Quinn Tranb2000802018-08-02 13:16:52 -0700209
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 /* Load mailbox registers. */
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400211 if (IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -0700212 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400213 else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700214 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
215 else
216 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217
218 iptr = mcp->mb;
219 command = mcp->mb[0];
220 mboxes = mcp->out_mb;
221
Joe Carnuccio7b711622014-09-25 05:16:43 -0400222 ql_dbg(ql_dbg_mbx, vha, 0x1111,
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700223 "Mailbox registers (OUT):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
225 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700226 optr =
227 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700228 if (mboxes & BIT_0) {
229 ql_dbg(ql_dbg_mbx, vha, 0x1112,
230 "mbox[%d]<-0x%04x\n", cnt, *iptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 WRT_REG_WORD(optr, *iptr);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700232 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233
234 mboxes >>= 1;
235 optr++;
236 iptr++;
237 }
238
Arun Easi5e19ed92012-02-09 11:15:51 -0800239 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700240 "I/O Address = %p.\n", optr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241
242 /* Issue set host interrupt command to send cmd out. */
243 ha->flags.mbox_int = 0;
244 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
245
246 /* Unlock mbx registers and wait for interrupt */
Arun Easi5e19ed92012-02-09 11:15:51 -0800247 ql_dbg(ql_dbg_mbx, vha, 0x100f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700248 "Going to unlock irq & waiting for interrupts. "
249 "jiffies=%lx.\n", jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250
251 /* Wait for mbx cmd completion until timeout */
Quinn Tranb2000802018-08-02 13:16:52 -0700252 atomic_inc(&ha->num_pend_mbx_stage2);
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800253 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
255
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400256 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700257 if (RD_REG_DWORD(&reg->isp82.hint) &
258 HINT_MBX_INT_PENDING) {
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700259 ha->flags.mbox_busy = 0;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700260 spin_unlock_irqrestore(&ha->hardware_lock,
261 flags);
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700262
Quinn Tranb2000802018-08-02 13:16:52 -0700263 atomic_dec(&ha->num_pend_mbx_stage2);
Arun Easi5e19ed92012-02-09 11:15:51 -0800264 ql_dbg(ql_dbg_mbx, vha, 0x1010,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700265 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700266 rval = QLA_FUNCTION_TIMEOUT;
267 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700268 }
269 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
270 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700271 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
272 else
273 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274 spin_unlock_irqrestore(&ha->hardware_lock, flags);
275
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -0800276 wait_time = jiffies;
Quinn Tranb2000802018-08-02 13:16:52 -0700277 atomic_inc(&ha->num_pend_mbx_stage3);
Giridhar Malavali754d1242013-06-25 11:27:16 -0400278 if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
279 mcp->tov * HZ)) {
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700280 if (chip_reset != ha->chip_reset) {
281 spin_lock_irqsave(&ha->hardware_lock, flags);
282 ha->flags.mbox_busy = 0;
283 spin_unlock_irqrestore(&ha->hardware_lock,
284 flags);
285 atomic_dec(&ha->num_pend_mbx_stage2);
286 atomic_dec(&ha->num_pend_mbx_stage3);
287 rval = QLA_ABORTED;
288 goto premature_exit;
289 }
Giridhar Malavali754d1242013-06-25 11:27:16 -0400290 ql_dbg(ql_dbg_mbx, vha, 0x117a,
291 "cmd=%x Timeout.\n", command);
292 spin_lock_irqsave(&ha->hardware_lock, flags);
293 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
294 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Quinn Tranb2000802018-08-02 13:16:52 -0700295
296 } else if (ha->flags.purge_mbox ||
297 chip_reset != ha->chip_reset) {
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700298 spin_lock_irqsave(&ha->hardware_lock, flags);
Quinn Tranb2000802018-08-02 13:16:52 -0700299 ha->flags.mbox_busy = 0;
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700300 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Quinn Tranb2000802018-08-02 13:16:52 -0700301 atomic_dec(&ha->num_pend_mbx_stage2);
302 atomic_dec(&ha->num_pend_mbx_stage3);
303 rval = QLA_ABORTED;
304 goto premature_exit;
Giridhar Malavali754d1242013-06-25 11:27:16 -0400305 }
Quinn Tranb2000802018-08-02 13:16:52 -0700306 atomic_dec(&ha->num_pend_mbx_stage3);
307
himanshu.madhani@cavium.com77ddb942016-12-12 14:40:05 -0800308 if (time_after(jiffies, wait_time + 5 * HZ))
309 ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n",
310 command, jiffies_to_msecs(jiffies - wait_time));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311 } else {
Arun Easi5e19ed92012-02-09 11:15:51 -0800312 ql_dbg(ql_dbg_mbx, vha, 0x1011,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700313 "Cmd=%x Polling Mode.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400315 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700316 if (RD_REG_DWORD(&reg->isp82.hint) &
317 HINT_MBX_INT_PENDING) {
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700318 ha->flags.mbox_busy = 0;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700319 spin_unlock_irqrestore(&ha->hardware_lock,
320 flags);
Quinn Tranb2000802018-08-02 13:16:52 -0700321 atomic_dec(&ha->num_pend_mbx_stage2);
Arun Easi5e19ed92012-02-09 11:15:51 -0800322 ql_dbg(ql_dbg_mbx, vha, 0x1012,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700323 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700324 rval = QLA_FUNCTION_TIMEOUT;
325 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700326 }
327 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
328 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700329 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
330 else
331 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333
334 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
335 while (!ha->flags.mbox_int) {
Quinn Tranb2000802018-08-02 13:16:52 -0700336 if (ha->flags.purge_mbox ||
337 chip_reset != ha->chip_reset) {
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700338 spin_lock_irqsave(&ha->hardware_lock, flags);
Quinn Tranb2000802018-08-02 13:16:52 -0700339 ha->flags.mbox_busy = 0;
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700340 spin_unlock_irqrestore(&ha->hardware_lock,
341 flags);
Quinn Tranb2000802018-08-02 13:16:52 -0700342 atomic_dec(&ha->num_pend_mbx_stage2);
343 rval = QLA_ABORTED;
344 goto premature_exit;
345 }
346
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347 if (time_after(jiffies, wait_time))
348 break;
349
Rodrigo R. Galvao3cb182b2018-05-28 14:58:44 -0300350 /*
351 * Check if it's UNLOADING, cause we cannot poll in
352 * this case, or else a NULL pointer dereference
353 * is triggered.
354 */
355 if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags)))
356 return QLA_FUNCTION_TIMEOUT;
357
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800359 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360
Andrew Vasquez85880802009-12-15 21:29:46 -0800361 if (!ha->flags.mbox_int &&
362 !(IS_QLA2200(ha) &&
363 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800364 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 } /* while */
Arun Easi5e19ed92012-02-09 11:15:51 -0800366 ql_dbg(ql_dbg_mbx, vha, 0x1013,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700367 "Waited %d sec.\n",
368 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 }
Quinn Tranb2000802018-08-02 13:16:52 -0700370 atomic_dec(&ha->num_pend_mbx_stage2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 /* Check whether we timed out */
373 if (ha->flags.mbox_int) {
374 uint16_t *iptr2;
375
Arun Easi5e19ed92012-02-09 11:15:51 -0800376 ql_dbg(ql_dbg_mbx, vha, 0x1014,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700377 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378
379 /* Got interrupt. Clear the flag. */
380 ha->flags.mbox_int = 0;
381 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
382
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400383 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700384 spin_lock_irqsave(&ha->hardware_lock, flags);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700385 ha->flags.mbox_busy = 0;
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700386 spin_unlock_irqrestore(&ha->hardware_lock, flags);
387
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700388 /* Setting Link-Down error */
389 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
390 ha->mcp = NULL;
391 rval = QLA_FUNCTION_FAILED;
Quinn Tran83548fe2017-06-02 09:12:01 -0700392 ql_log(ql_log_warn, vha, 0xd048,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700393 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700394 goto premature_exit;
395 }
396
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400397 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399
400 /* Load return mailbox registers. */
401 iptr2 = mcp->mb;
402 iptr = (uint16_t *)&ha->mailbox_out[0];
403 mboxes = mcp->in_mb;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700404
405 ql_dbg(ql_dbg_mbx, vha, 0x1113,
406 "Mailbox registers (IN):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700408 if (mboxes & BIT_0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 *iptr2 = *iptr;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700410 ql_dbg(ql_dbg_mbx, vha, 0x1114,
411 "mbox[%d]->0x%04x\n", cnt, *iptr2);
412 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413
414 mboxes >>= 1;
415 iptr2++;
416 iptr++;
417 }
418 } else {
419
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800420 uint16_t mb[8];
421 uint32_t ictrl, host_status, hccr;
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400422 uint16_t w;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700423
Andrew Vasqueze4289242007-07-19 15:05:56 -0700424 if (IS_FWI2_CAPABLE(ha)) {
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800425 mb[0] = RD_REG_WORD(&reg->isp24.mailbox0);
426 mb[1] = RD_REG_WORD(&reg->isp24.mailbox1);
427 mb[2] = RD_REG_WORD(&reg->isp24.mailbox2);
428 mb[3] = RD_REG_WORD(&reg->isp24.mailbox3);
429 mb[7] = RD_REG_WORD(&reg->isp24.mailbox7);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700430 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800431 host_status = RD_REG_DWORD(&reg->isp24.host_status);
432 hccr = RD_REG_DWORD(&reg->isp24.hccr);
433
Quinn Tran83548fe2017-06-02 09:12:01 -0700434 ql_log(ql_log_warn, vha, 0xd04c,
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800435 "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
436 "mb[0-3]=[0x%x 0x%x 0x%x 0x%x] mb7 0x%x host_status 0x%x hccr 0x%x\n",
437 command, ictrl, jiffies, mb[0], mb[1], mb[2], mb[3],
438 mb[7], host_status, hccr);
439
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700440 } else {
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800441 mb[0] = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700442 ictrl = RD_REG_WORD(&reg->isp.ictrl);
Quinn Tran8d3c9c22016-12-23 18:06:09 -0800443 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119,
444 "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
445 "mb[0]=0x%x\n", command, ictrl, jiffies, mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700446 }
Arun Easi5e19ed92012-02-09 11:15:51 -0800447 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400449 /* Capture FW dump only, if PCI device active */
450 if (!pci_channel_offline(vha->hw->pdev)) {
451 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
Quinn Tranb2000802018-08-02 13:16:52 -0700452 if (w == 0xffff || ictrl == 0xffffffff ||
453 (chip_reset != ha->chip_reset)) {
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400454 /* This is special case if there is unload
455 * of driver happening and if PCI device go
456 * into bad state due to PCI error condition
457 * then only PCI ERR flag would be set.
458 * we will do premature exit for above case.
459 */
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700460 spin_lock_irqsave(&ha->hardware_lock, flags);
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400461 ha->flags.mbox_busy = 0;
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700462 spin_unlock_irqrestore(&ha->hardware_lock,
463 flags);
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400464 rval = QLA_FUNCTION_TIMEOUT;
465 goto premature_exit;
466 }
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800467
Sawan Chandak783e0dc2016-07-06 11:14:25 -0400468 /* Attempt to capture firmware dump for further
469 * anallysis of the current formware state. we do not
470 * need to do this if we are intentionally generating
471 * a dump
472 */
473 if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR)
474 ha->isp_ops->fw_dump(vha, 0);
475 rval = QLA_FUNCTION_TIMEOUT;
476 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 }
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700478 spin_lock_irqsave(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 ha->flags.mbox_busy = 0;
Quinn Tranb6faaaf2018-09-04 14:19:09 -0700480 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
482 /* Clean up */
483 ha->mcp = NULL;
484
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800485 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800486 ql_dbg(ql_dbg_mbx, vha, 0x101a,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700487 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700488
489 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800490 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491 }
492
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700493 if (rval == QLA_FUNCTION_TIMEOUT &&
494 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800495 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
496 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 /* not in dpc. schedule it for dpc to take over. */
Arun Easi5e19ed92012-02-09 11:15:51 -0800498 ql_dbg(ql_dbg_mbx, vha, 0x101b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700499 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700500
501 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, 0x112a,
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, 0x101c,
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, eeh_busy=0x%x. Scheduling ISP "
516 "abort.\n", command, mcp->mb[0],
517 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700518 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
519 qla2xxx_wake_dpc(vha);
520 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 /* call abort directly since we are in the DPC thread */
Arun Easi5e19ed92012-02-09 11:15:51 -0800523 ql_dbg(ql_dbg_mbx, vha, 0x101d,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700524 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700526 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
527 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
528 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800529 if (IS_QLA82XX(ha)) {
530 ql_dbg(ql_dbg_mbx, vha, 0x112b,
531 "disabling pause transmit on port "
532 "0 & 1.\n");
533 qla82xx_wr_32(ha,
534 QLA82XX_CRB_NIU + 0x98,
535 CRB_NIU_XG_PAUSE_CTL_P0|
536 CRB_NIU_XG_PAUSE_CTL_P1);
537 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700538 ql_log(ql_log_info, base_vha, 0x101e,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400539 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800540 "mb[0]=0x%x. Scheduling ISP abort ",
541 command, mcp->mb[0]);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700542 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
543 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
Giridhar Malavalid3360962012-02-09 11:14:10 -0800544 /* Allow next mbx cmd to come in. */
545 complete(&ha->mbx_cmd_comp);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700546 if (ha->isp_ops->abort_isp(vha)) {
547 /* Failed. retry later. */
548 set_bit(ISP_ABORT_NEEDED,
549 &vha->dpc_flags);
550 }
551 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Arun Easi5e19ed92012-02-09 11:15:51 -0800552 ql_dbg(ql_dbg_mbx, vha, 0x101f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700553 "Finished abort_isp.\n");
Giridhar Malavalid3360962012-02-09 11:14:10 -0800554 goto mbx_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 }
557 }
558
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700559premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800561 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562
Giridhar Malavalid3360962012-02-09 11:14:10 -0800563mbx_done:
Quinn Tranb2000802018-08-02 13:16:52 -0700564 if (rval == QLA_ABORTED) {
565 ql_log(ql_log_info, vha, 0xd035,
566 "Chip Reset in progress. Purging Mbox cmd=0x%x.\n",
567 mcp->mb[0]);
568 } else if (rval) {
Joe Carnuccio050dc762017-08-23 15:05:14 -0700569 if (ql2xextended_error_logging & (ql_dbg_disc|ql_dbg_mbx)) {
570 pr_warn("%s [%s]-%04x:%ld: **** Failed", QL_MSGHDR,
571 dev_name(&ha->pdev->dev), 0x1020+0x800,
572 vha->host_no);
573 mboxes = mcp->in_mb;
574 cnt = 4;
575 for (i = 0; i < ha->mbx_count && cnt; i++, mboxes >>= 1)
576 if (mboxes & BIT_0) {
577 printk(" mb[%u]=%x", i, mcp->mb[i]);
578 cnt--;
579 }
580 pr_warn(" cmd=%x ****\n", command);
581 }
Meelis Roosf7e59e92018-03-08 15:44:07 +0200582 if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) {
583 ql_dbg(ql_dbg_mbx, vha, 0x1198,
584 "host_status=%#x intr_ctrl=%#x intr_status=%#x\n",
585 RD_REG_DWORD(&reg->isp24.host_status),
586 RD_REG_DWORD(&reg->isp24.ictrl),
587 RD_REG_DWORD(&reg->isp24.istatus));
588 } else {
589 ql_dbg(ql_dbg_mbx, vha, 0x1206,
590 "ctrl_status=%#x ictrl=%#x istatus=%#x\n",
591 RD_REG_WORD(&reg->isp.ctrl_status),
592 RD_REG_WORD(&reg->isp.ictrl),
593 RD_REG_WORD(&reg->isp.istatus));
594 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700596 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 }
598
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 return rval;
600}
601
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800603qla2x00_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 -0800604 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605{
606 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800607 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 mbx_cmd_t mc;
609 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400611 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022,
612 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
Andrew Vasqueze4289242007-07-19 15:05:56 -0700614 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800615 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
616 mcp->mb[8] = MSW(risc_addr);
617 mcp->out_mb = MBX_8|MBX_0;
618 } else {
619 mcp->mb[0] = MBC_LOAD_RISC_RAM;
620 mcp->out_mb = MBX_0;
621 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 mcp->mb[1] = LSW(risc_addr);
623 mcp->mb[2] = MSW(req_dma);
624 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 mcp->mb[6] = MSW(MSD(req_dma));
626 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800627 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700628 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700629 mcp->mb[4] = MSW(risc_code_size);
630 mcp->mb[5] = LSW(risc_code_size);
631 mcp->out_mb |= MBX_5|MBX_4;
632 } else {
633 mcp->mb[4] = LSW(risc_code_size);
634 mcp->out_mb |= MBX_4;
635 }
636
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700638 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800640 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700643 ql_dbg(ql_dbg_mbx, vha, 0x1023,
644 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400646 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,
647 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 }
649
650 return rval;
651}
652
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700653#define EXTENDED_BB_CREDITS BIT_0
Duane Grigsbye84067d2017-06-21 13:48:43 -0700654#define NVME_ENABLE_FLAG BIT_3
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700655static inline uint16_t qla25xx_set_sfp_lr_dist(struct qla_hw_data *ha)
656{
657 uint16_t mb4 = BIT_0;
658
659 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
660 mb4 |= ha->long_range_distance << LR_DIST_FW_POS;
661
662 return mb4;
663}
664
665static inline uint16_t qla25xx_set_nvr_lr_dist(struct qla_hw_data *ha)
666{
667 uint16_t mb4 = BIT_0;
668
669 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
670 struct nvram_81xx *nv = ha->nvram;
671
672 mb4 |= LR_DIST_FW_FIELD(nv->enhanced_features);
673 }
674
675 return mb4;
676}
Duane Grigsbye84067d2017-06-21 13:48:43 -0700677
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678/*
679 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700680 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 *
682 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700683 * ha = adapter block pointer.
684 * TARGET_QUEUE_LOCK must be released.
685 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 *
687 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700688 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689 *
690 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700691 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692 */
693int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800694qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695{
696 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800697 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 mbx_cmd_t mc;
699 mbx_cmd_t *mcp = &mc;
700
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400701 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,
702 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703
704 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700705 mcp->out_mb = MBX_0;
706 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700707 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700708 mcp->mb[1] = MSW(risc_addr);
709 mcp->mb[2] = LSW(risc_addr);
710 mcp->mb[3] = 0;
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700711 mcp->mb[4] = 0;
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700712 ha->flags.using_lr_setting = 0;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500713 if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
714 IS_QLA27XX(ha)) {
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700715 if (ql2xautodetectsfp) {
716 if (ha->flags.detected_lr_sfp) {
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700717 mcp->mb[4] |=
718 qla25xx_set_sfp_lr_dist(ha);
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700719 ha->flags.using_lr_setting = 1;
720 }
721 } else {
722 struct nvram_81xx *nv = ha->nvram;
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700723 /* set LR distance if specified in nvram */
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700724 if (nv->enhanced_features &
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700725 NEF_LR_DIST_ENABLE) {
726 mcp->mb[4] |=
727 qla25xx_set_nvr_lr_dist(ha);
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700728 ha->flags.using_lr_setting = 1;
729 }
730 }
Quinn Trane4e3a2c2017-08-23 15:05:07 -0700731 }
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500732
Duane Grigsbye84067d2017-06-21 13:48:43 -0700733 if (ql2xnvmeenable && IS_QLA27XX(ha))
734 mcp->mb[4] |= NVME_ENABLE_FLAG;
735
Sawan Chandak92d44082017-08-23 15:05:16 -0700736 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
737 struct nvram_81xx *nv = ha->nvram;
738 /* set minimum speed if specified in nvram */
739 if (nv->min_link_speed >= 2 &&
740 nv->min_link_speed <= 5) {
741 mcp->mb[4] |= BIT_4;
742 mcp->mb[11] = nv->min_link_speed;
743 mcp->out_mb |= MBX_11;
744 mcp->in_mb |= BIT_5;
745 vha->min_link_speed_feat = nv->min_link_speed;
746 }
747 }
748
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500749 if (ha->flags.exlogins_enabled)
750 mcp->mb[4] |= ENABLE_EXTENDED_LOGIN;
751
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -0500752 if (ha->flags.exchoffld_enabled)
753 mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
754
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700755 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700756 mcp->in_mb |= MBX_3 | MBX_2 | MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700757 } else {
758 mcp->mb[1] = LSW(risc_addr);
759 mcp->out_mb |= MBX_1;
760 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
761 mcp->mb[2] = 0;
762 mcp->out_mb |= MBX_2;
763 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 }
765
Ravi Anandb93480e2008-04-03 13:13:25 -0700766 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800768 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700769
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700770 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700771 ql_dbg(ql_dbg_mbx, vha, 0x1026,
772 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700773 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700774 if (IS_FWI2_CAPABLE(ha)) {
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700775 ha->fw_ability_mask = mcp->mb[3] << 16 | mcp->mb[2];
776 ql_dbg(ql_dbg_mbx, vha, 0x119a,
777 "fw_ability_mask=%x.\n", ha->fw_ability_mask);
Sawan Chandak92d44082017-08-23 15:05:16 -0700778 ql_dbg(ql_dbg_mbx, vha, 0x1027,
779 "exchanges=%x.\n", mcp->mb[1]);
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700780 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
781 ha->max_speed_sup = mcp->mb[2] & BIT_0;
Sawan Chandak92d44082017-08-23 15:05:16 -0700782 ql_dbg(ql_dbg_mbx, vha, 0x119b,
783 "Maximum speed supported=%s.\n",
784 ha->max_speed_sup ? "32Gps" : "16Gps");
785 if (vha->min_link_speed_feat) {
786 ha->min_link_speed = mcp->mb[5];
787 ql_dbg(ql_dbg_mbx, vha, 0x119c,
788 "Minimum speed set=%s.\n",
789 mcp->mb[5] == 5 ? "32Gps" :
790 mcp->mb[5] == 4 ? "16Gps" :
791 mcp->mb[5] == 3 ? "8Gps" :
792 mcp->mb[5] == 2 ? "4Gps" :
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700793 "unknown");
Sawan Chandak92d44082017-08-23 15:05:16 -0700794 }
795 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700796 }
Joe Carnuccio1f4c7c32017-08-23 15:05:17 -0700797 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
798 "Done.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700799 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
801 return rval;
802}
803
804/*
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500805 * qla_get_exlogin_status
806 * Get extended login status
807 * uses the memory offload control/status Mailbox
808 *
809 * Input:
810 * ha: adapter state pointer.
811 * fwopt: firmware options
812 *
813 * Returns:
814 * qla2x00 local function status
815 *
816 * Context:
817 * Kernel context.
818 */
819#define FETCH_XLOGINS_STAT 0x8
820int
821qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
822 uint16_t *ex_logins_cnt)
823{
824 int rval;
825 mbx_cmd_t mc;
826 mbx_cmd_t *mcp = &mc;
827
828 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118f,
829 "Entered %s\n", __func__);
830
831 memset(mcp->mb, 0 , sizeof(mcp->mb));
832 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
833 mcp->mb[1] = FETCH_XLOGINS_STAT;
834 mcp->out_mb = MBX_1|MBX_0;
835 mcp->in_mb = MBX_10|MBX_4|MBX_0;
836 mcp->tov = MBX_TOV_SECONDS;
837 mcp->flags = 0;
838
839 rval = qla2x00_mailbox_command(vha, mcp);
840 if (rval != QLA_SUCCESS) {
841 ql_dbg(ql_dbg_mbx, vha, 0x1115, "Failed=%x.\n", rval);
842 } else {
843 *buf_sz = mcp->mb[4];
844 *ex_logins_cnt = mcp->mb[10];
845
846 ql_log(ql_log_info, vha, 0x1190,
847 "buffer size 0x%x, exchange login count=%d\n",
848 mcp->mb[4], mcp->mb[10]);
849
850 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1116,
851 "Done %s.\n", __func__);
852 }
853
854 return rval;
855}
856
857/*
858 * qla_set_exlogin_mem_cfg
859 * set extended login memory configuration
860 * Mbx needs to be issues before init_cb is set
861 *
862 * Input:
863 * ha: adapter state pointer.
864 * buffer: buffer pointer
865 * phys_addr: physical address of buffer
866 * size: size of buffer
867 * TARGET_QUEUE_LOCK must be released
868 * ADAPTER_STATE_LOCK must be release
869 *
870 * Returns:
871 * qla2x00 local funxtion status code.
872 *
873 * Context:
874 * Kernel context.
875 */
876#define CONFIG_XLOGINS_MEM 0x3
877int
878qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr)
879{
880 int rval;
881 mbx_cmd_t mc;
882 mbx_cmd_t *mcp = &mc;
883 struct qla_hw_data *ha = vha->hw;
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500884
885 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111a,
886 "Entered %s.\n", __func__);
887
888 memset(mcp->mb, 0 , sizeof(mcp->mb));
889 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
890 mcp->mb[1] = CONFIG_XLOGINS_MEM;
891 mcp->mb[2] = MSW(phys_addr);
892 mcp->mb[3] = LSW(phys_addr);
893 mcp->mb[6] = MSW(MSD(phys_addr));
894 mcp->mb[7] = LSW(MSD(phys_addr));
895 mcp->mb[8] = MSW(ha->exlogin_size);
896 mcp->mb[9] = LSW(ha->exlogin_size);
897 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
898 mcp->in_mb = MBX_11|MBX_0;
899 mcp->tov = MBX_TOV_SECONDS;
900 mcp->flags = 0;
901 rval = qla2x00_mailbox_command(vha, mcp);
902 if (rval != QLA_SUCCESS) {
903 /*EMPTY*/
904 ql_dbg(ql_dbg_mbx, vha, 0x111b, "Failed=%x.\n", rval);
905 } else {
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -0500906 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c,
907 "Done %s.\n", __func__);
908 }
909
910 return rval;
911}
912
913/*
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -0500914 * qla_get_exchoffld_status
915 * Get exchange offload status
916 * uses the memory offload control/status Mailbox
917 *
918 * Input:
919 * ha: adapter state pointer.
920 * fwopt: firmware options
921 *
922 * Returns:
923 * qla2x00 local function status
924 *
925 * Context:
926 * Kernel context.
927 */
928#define FETCH_XCHOFFLD_STAT 0x2
929int
930qla_get_exchoffld_status(scsi_qla_host_t *vha, uint16_t *buf_sz,
931 uint16_t *ex_logins_cnt)
932{
933 int rval;
934 mbx_cmd_t mc;
935 mbx_cmd_t *mcp = &mc;
936
937 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1019,
938 "Entered %s\n", __func__);
939
940 memset(mcp->mb, 0 , sizeof(mcp->mb));
941 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
942 mcp->mb[1] = FETCH_XCHOFFLD_STAT;
943 mcp->out_mb = MBX_1|MBX_0;
944 mcp->in_mb = MBX_10|MBX_4|MBX_0;
945 mcp->tov = MBX_TOV_SECONDS;
946 mcp->flags = 0;
947
948 rval = qla2x00_mailbox_command(vha, mcp);
949 if (rval != QLA_SUCCESS) {
950 ql_dbg(ql_dbg_mbx, vha, 0x1155, "Failed=%x.\n", rval);
951 } else {
952 *buf_sz = mcp->mb[4];
953 *ex_logins_cnt = mcp->mb[10];
954
955 ql_log(ql_log_info, vha, 0x118e,
956 "buffer size 0x%x, exchange offload count=%d\n",
957 mcp->mb[4], mcp->mb[10]);
958
959 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1156,
960 "Done %s.\n", __func__);
961 }
962
963 return rval;
964}
965
966/*
967 * qla_set_exchoffld_mem_cfg
968 * Set exchange offload memory configuration
969 * Mbx needs to be issues before init_cb is set
970 *
971 * Input:
972 * ha: adapter state pointer.
973 * buffer: buffer pointer
974 * phys_addr: physical address of buffer
975 * size: size of buffer
976 * TARGET_QUEUE_LOCK must be released
977 * ADAPTER_STATE_LOCK must be release
978 *
979 * Returns:
980 * qla2x00 local funxtion status code.
981 *
982 * Context:
983 * Kernel context.
984 */
985#define CONFIG_XCHOFFLD_MEM 0x3
986int
Quinn Tran99e1b682017-06-02 09:12:03 -0700987qla_set_exchoffld_mem_cfg(scsi_qla_host_t *vha)
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -0500988{
989 int rval;
990 mbx_cmd_t mc;
991 mbx_cmd_t *mcp = &mc;
992 struct qla_hw_data *ha = vha->hw;
993
994 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1157,
995 "Entered %s.\n", __func__);
996
997 memset(mcp->mb, 0 , sizeof(mcp->mb));
998 mcp->mb[0] = MBC_GET_MEM_OFFLOAD_CNTRL_STAT;
999 mcp->mb[1] = CONFIG_XCHOFFLD_MEM;
Quinn Tran99e1b682017-06-02 09:12:03 -07001000 mcp->mb[2] = MSW(ha->exchoffld_buf_dma);
1001 mcp->mb[3] = LSW(ha->exchoffld_buf_dma);
1002 mcp->mb[6] = MSW(MSD(ha->exchoffld_buf_dma));
1003 mcp->mb[7] = LSW(MSD(ha->exchoffld_buf_dma));
1004 mcp->mb[8] = MSW(ha->exchoffld_size);
1005 mcp->mb[9] = LSW(ha->exchoffld_size);
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -05001006 mcp->out_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1007 mcp->in_mb = MBX_11|MBX_0;
1008 mcp->tov = MBX_TOV_SECONDS;
1009 mcp->flags = 0;
1010 rval = qla2x00_mailbox_command(vha, mcp);
1011 if (rval != QLA_SUCCESS) {
1012 /*EMPTY*/
1013 ql_dbg(ql_dbg_mbx, vha, 0x1158, "Failed=%x.\n", rval);
1014 } else {
1015 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1192,
1016 "Done %s.\n", __func__);
1017 }
1018
1019 return rval;
1020}
1021
1022/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 * qla2x00_get_fw_version
1024 * Get firmware version.
1025 *
1026 * Input:
1027 * ha: adapter state pointer.
1028 * major: pointer for major number.
1029 * minor: pointer for minor number.
1030 * subminor: pointer for subminor number.
1031 *
1032 * Returns:
1033 * qla2x00 local function return status code.
1034 *
1035 * Context:
1036 * Kernel context.
1037 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -07001038int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001039qla2x00_get_fw_version(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040{
1041 int rval;
1042 mbx_cmd_t mc;
1043 mbx_cmd_t *mcp = &mc;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001044 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001046 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029,
1047 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
1049 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
1050 mcp->out_mb = MBX_0;
1051 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001052 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha))
Andrew Vasquez55a96152009-03-24 09:08:03 -07001053 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Saurav Kashyapfb0effe2012-08-22 14:21:28 -04001054 if (IS_FWI2_CAPABLE(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001055 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001056 if (IS_QLA27XX(ha))
Joe Carnuccioad1ef172016-07-06 11:14:18 -04001057 mcp->in_mb |=
1058 MBX_25|MBX_24|MBX_23|MBX_22|MBX_21|MBX_20|MBX_19|MBX_18|
1059 MBX_14|MBX_13|MBX_11|MBX_10|MBX_9|MBX_8;
Sawan Chandak03aa8682015-08-04 13:37:59 -04001060
Linus Torvalds1da177e2005-04-16 15:20:36 -07001061 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001062 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001063 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -07001064 if (rval != QLA_SUCCESS)
1065 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066
1067 /* Return mailbox data. */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001068 ha->fw_major_version = mcp->mb[1];
1069 ha->fw_minor_version = mcp->mb[2];
1070 ha->fw_subminor_version = mcp->mb[3];
1071 ha->fw_attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001072 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001073 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 else
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001075 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
Sawan Chandak03aa8682015-08-04 13:37:59 -04001076
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001077 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001078 ha->mpi_version[0] = mcp->mb[10] & 0xff;
1079 ha->mpi_version[1] = mcp->mb[11] >> 8;
1080 ha->mpi_version[2] = mcp->mb[11] & 0xff;
1081 ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
1082 ha->phy_version[0] = mcp->mb[8] & 0xff;
1083 ha->phy_version[1] = mcp->mb[9] >> 8;
1084 ha->phy_version[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001085 }
Sawan Chandak03aa8682015-08-04 13:37:59 -04001086
Saurav Kashyap81178772012-08-22 14:21:04 -04001087 if (IS_FWI2_CAPABLE(ha)) {
1088 ha->fw_attributes_h = mcp->mb[15];
1089 ha->fw_attributes_ext[0] = mcp->mb[16];
1090 ha->fw_attributes_ext[1] = mcp->mb[17];
1091 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,
1092 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
1093 __func__, mcp->mb[15], mcp->mb[6]);
1094 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
1095 "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
1096 __func__, mcp->mb[17], mcp->mb[16]);
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -05001097
Himanshu Madhanib0d6cab2015-12-17 14:56:56 -05001098 if (ha->fw_attributes_h & 0x4)
1099 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118d,
1100 "%s: Firmware supports Extended Login 0x%x\n",
1101 __func__, ha->fw_attributes_h);
Himanshu Madhani2f56a7f2015-12-17 14:56:57 -05001102
1103 if (ha->fw_attributes_h & 0x8)
1104 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1191,
1105 "%s: Firmware supports Exchange Offload 0x%x\n",
1106 __func__, ha->fw_attributes_h);
Duane Grigsbye84067d2017-06-21 13:48:43 -07001107
Duane Grigsbydeeae7a2017-07-21 09:32:25 -07001108 /*
1109 * FW supports nvme and driver load parameter requested nvme.
1110 * BIT 26 of fw_attributes indicates NVMe support.
1111 */
Darren Trapp1cbc0ef2018-03-20 23:09:37 -07001112 if ((ha->fw_attributes_h & 0x400) && ql2xnvmeenable) {
Duane Grigsbye84067d2017-06-21 13:48:43 -07001113 vha->flags.nvme_enabled = 1;
Darren Trapp1cbc0ef2018-03-20 23:09:37 -07001114 ql_log(ql_log_info, vha, 0xd302,
1115 "%s: FC-NVMe is Enabled (0x%x)\n",
1116 __func__, ha->fw_attributes_h);
1117 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001118 }
Sawan Chandak03aa8682015-08-04 13:37:59 -04001119
Chad Dupuisf73cb692014-02-26 04:15:06 -05001120 if (IS_QLA27XX(ha)) {
Sawan Chandak03aa8682015-08-04 13:37:59 -04001121 ha->mpi_version[0] = mcp->mb[10] & 0xff;
1122 ha->mpi_version[1] = mcp->mb[11] >> 8;
1123 ha->mpi_version[2] = mcp->mb[11] & 0xff;
1124 ha->pep_version[0] = mcp->mb[13] & 0xff;
1125 ha->pep_version[1] = mcp->mb[14] >> 8;
1126 ha->pep_version[2] = mcp->mb[14] & 0xff;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001127 ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18];
1128 ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20];
Joe Carnuccioad1ef172016-07-06 11:14:18 -04001129 ha->fw_ddr_ram_start = (mcp->mb[23] << 16) | mcp->mb[22];
1130 ha->fw_ddr_ram_end = (mcp->mb[25] << 16) | mcp->mb[24];
Chad Dupuisf73cb692014-02-26 04:15:06 -05001131 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001132
Andrew Vasquezca9e9c32009-06-03 09:55:20 -07001133failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001134 if (rval != QLA_SUCCESS) {
1135 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001136 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137 } else {
1138 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001139 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b,
1140 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -07001142 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143}
1144
1145/*
1146 * qla2x00_get_fw_options
1147 * Set firmware options.
1148 *
1149 * Input:
1150 * ha = adapter block pointer.
1151 * fwopt = pointer for firmware options.
1152 *
1153 * Returns:
1154 * qla2x00 local function return status code.
1155 *
1156 * Context:
1157 * Kernel context.
1158 */
1159int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001160qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161{
1162 int rval;
1163 mbx_cmd_t mc;
1164 mbx_cmd_t *mcp = &mc;
1165
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001166 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c,
1167 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168
1169 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
1170 mcp->out_mb = MBX_0;
1171 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001172 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001174 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175
1176 if (rval != QLA_SUCCESS) {
1177 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001178 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001180 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001181 fwopts[1] = mcp->mb[1];
1182 fwopts[2] = mcp->mb[2];
1183 fwopts[3] = mcp->mb[3];
1184
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001185 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e,
1186 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187 }
1188
1189 return rval;
1190}
1191
1192
1193/*
1194 * qla2x00_set_fw_options
1195 * Set firmware options.
1196 *
1197 * Input:
1198 * ha = adapter block pointer.
1199 * fwopt = pointer for firmware options.
1200 *
1201 * Returns:
1202 * qla2x00 local function return status code.
1203 *
1204 * Context:
1205 * Kernel context.
1206 */
1207int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001208qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209{
1210 int rval;
1211 mbx_cmd_t mc;
1212 mbx_cmd_t *mcp = &mc;
1213
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001214 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f,
1215 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216
1217 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
1218 mcp->mb[1] = fwopts[1];
1219 mcp->mb[2] = fwopts[2];
1220 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001221 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001223 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001224 mcp->in_mb |= MBX_1;
Quinn Tran2da52732017-06-02 09:12:05 -07001225 mcp->mb[10] = fwopts[10];
1226 mcp->out_mb |= MBX_10;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001227 } else {
1228 mcp->mb[10] = fwopts[10];
1229 mcp->mb[11] = fwopts[11];
1230 mcp->mb[12] = 0; /* Undocumented, but used */
1231 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
1232 }
Ravi Anandb93480e2008-04-03 13:13:25 -07001233 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001235 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001237 fwopts[0] = mcp->mb[0];
1238
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239 if (rval != QLA_SUCCESS) {
1240 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001241 ql_dbg(ql_dbg_mbx, vha, 0x1030,
1242 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 } else {
1244 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001245 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031,
1246 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 }
1248
1249 return rval;
1250}
1251
1252/*
1253 * qla2x00_mbx_reg_test
1254 * Mailbox register wrap test.
1255 *
1256 * Input:
1257 * ha = adapter block pointer.
1258 * TARGET_QUEUE_LOCK must be released.
1259 * ADAPTER_STATE_LOCK must be released.
1260 *
1261 * Returns:
1262 * qla2x00 local function return status code.
1263 *
1264 * Context:
1265 * Kernel context.
1266 */
1267int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001268qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269{
1270 int rval;
1271 mbx_cmd_t mc;
1272 mbx_cmd_t *mcp = &mc;
1273
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001274 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032,
1275 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276
1277 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
1278 mcp->mb[1] = 0xAAAA;
1279 mcp->mb[2] = 0x5555;
1280 mcp->mb[3] = 0xAA55;
1281 mcp->mb[4] = 0x55AA;
1282 mcp->mb[5] = 0xA5A5;
1283 mcp->mb[6] = 0x5A5A;
1284 mcp->mb[7] = 0x2525;
1285 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1286 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 -07001287 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001289 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001290
1291 if (rval == QLA_SUCCESS) {
1292 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
1293 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
1294 rval = QLA_FUNCTION_FAILED;
1295 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
1296 mcp->mb[7] != 0x2525)
1297 rval = QLA_FUNCTION_FAILED;
1298 }
1299
1300 if (rval != QLA_SUCCESS) {
1301 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001302 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001303 } else {
1304 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001305 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034,
1306 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 }
1308
1309 return rval;
1310}
1311
1312/*
1313 * qla2x00_verify_checksum
1314 * Verify firmware checksum.
1315 *
1316 * Input:
1317 * ha = adapter block pointer.
1318 * TARGET_QUEUE_LOCK must be released.
1319 * ADAPTER_STATE_LOCK must be released.
1320 *
1321 * Returns:
1322 * qla2x00 local function return status code.
1323 *
1324 * Context:
1325 * Kernel context.
1326 */
1327int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001328qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329{
1330 int rval;
1331 mbx_cmd_t mc;
1332 mbx_cmd_t *mcp = &mc;
1333
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001334 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035,
1335 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336
1337 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001338 mcp->out_mb = MBX_0;
1339 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001340 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001341 mcp->mb[1] = MSW(risc_addr);
1342 mcp->mb[2] = LSW(risc_addr);
1343 mcp->out_mb |= MBX_2|MBX_1;
1344 mcp->in_mb |= MBX_2|MBX_1;
1345 } else {
1346 mcp->mb[1] = LSW(risc_addr);
1347 mcp->out_mb |= MBX_1;
1348 mcp->in_mb |= MBX_1;
1349 }
1350
Ravi Anandb93480e2008-04-03 13:13:25 -07001351 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001353 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354
1355 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001356 ql_dbg(ql_dbg_mbx, vha, 0x1036,
1357 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
1358 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001360 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037,
1361 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362 }
1363
1364 return rval;
1365}
1366
1367/*
1368 * qla2x00_issue_iocb
1369 * Issue IOCB using mailbox command
1370 *
1371 * Input:
1372 * ha = adapter state pointer.
1373 * buffer = buffer pointer.
1374 * phys_addr = physical address of buffer.
1375 * size = size of buffer.
1376 * TARGET_QUEUE_LOCK must be released.
1377 * ADAPTER_STATE_LOCK must be released.
1378 *
1379 * Returns:
1380 * qla2x00 local function return status code.
1381 *
1382 * Context:
1383 * Kernel context.
1384 */
Giridhar Malavali6e980162010-03-19 17:03:58 -07001385int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001386qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001387 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388{
1389 int rval;
1390 mbx_cmd_t mc;
1391 mbx_cmd_t *mcp = &mc;
1392
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001393 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038,
1394 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001395
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
1397 mcp->mb[1] = 0;
1398 mcp->mb[2] = MSW(phys_addr);
1399 mcp->mb[3] = LSW(phys_addr);
1400 mcp->mb[6] = MSW(MSD(phys_addr));
1401 mcp->mb[7] = LSW(MSD(phys_addr));
1402 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1403 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001404 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001406 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
1408 if (rval != QLA_SUCCESS) {
1409 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001410 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -07001412 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
1413
1414 /* Mask reserved bits. */
1415 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001416 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001417 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a,
1418 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 }
1420
1421 return rval;
1422}
1423
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001424int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001425qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001426 size_t size)
1427{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001428 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001429 MBX_TOV_SECONDS);
1430}
1431
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432/*
1433 * qla2x00_abort_command
1434 * Abort command aborts a specified IOCB.
1435 *
1436 * Input:
1437 * ha = adapter block pointer.
1438 * sp = SB structure pointer.
1439 *
1440 * Returns:
1441 * qla2x00 local function return status code.
1442 *
1443 * Context:
1444 * Kernel context.
1445 */
1446int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001447qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448{
1449 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001451 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452 mbx_cmd_t mc;
1453 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001454 fc_port_t *fcport = sp->fcport;
1455 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001456 struct qla_hw_data *ha = vha->hw;
Michael Hernandezd7459522016-12-12 14:40:07 -08001457 struct req_que *req;
Giridhar Malavali9ba56b92012-02-09 11:15:36 -08001458 struct scsi_cmnd *cmd = GET_CMD_SP(sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001460 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b,
1461 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462
Michael Hernandezd7459522016-12-12 14:40:07 -08001463 if (vha->flags.qpairs_available && sp->qpair)
1464 req = sp->qpair->req;
1465 else
1466 req = vha->req;
1467
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -07001468 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05001469 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001470 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471 break;
1472 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -07001473 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474
Chad Dupuis8d93f552013-01-30 03:34:37 -05001475 if (handle == req->num_outstanding_cmds) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 /* command not found */
1477 return QLA_FUNCTION_FAILED;
1478 }
1479
1480 mcp->mb[0] = MBC_ABORT_COMMAND;
1481 if (HAS_EXTENDED_IDS(ha))
1482 mcp->mb[1] = fcport->loop_id;
1483 else
1484 mcp->mb[1] = fcport->loop_id << 8;
1485 mcp->mb[2] = (uint16_t)handle;
1486 mcp->mb[3] = (uint16_t)(handle >> 16);
Giridhar Malavali9ba56b92012-02-09 11:15:36 -08001487 mcp->mb[6] = (uint16_t)cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1489 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001490 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001492 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493
1494 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001495 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001497 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d,
1498 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 }
1500
1501 return rval;
1502}
1503
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001505qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506{
Andrew Vasquez523ec772008-04-03 13:13:24 -07001507 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 mbx_cmd_t mc;
1509 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001510 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001511 struct req_que *req;
1512 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513
Andrew Vasquez523ec772008-04-03 13:13:24 -07001514 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001515 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001516
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001517 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e,
1518 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001519
Giridhar Malavali7e2b8952010-05-28 15:08:17 -07001520 req = vha->hw->req_q_map[0];
1521 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001523 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001524 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 mcp->mb[1] = fcport->loop_id;
1526 mcp->mb[10] = 0;
1527 mcp->out_mb |= MBX_10;
1528 } else {
1529 mcp->mb[1] = fcport->loop_id << 8;
1530 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001531 mcp->mb[2] = vha->hw->loop_reset_delay;
1532 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533
1534 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001535 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001537 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001539 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f,
1540 "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001541 }
1542
1543 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001544 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
1545 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001546 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001547 ql_dbg(ql_dbg_mbx, vha, 0x1040,
1548 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001550 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041,
1551 "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001552 }
1553
1554 return rval;
1555}
1556
1557int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001558qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07001559{
1560 int rval, rval2;
1561 mbx_cmd_t mc;
1562 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001563 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001564 struct req_que *req;
1565 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001566
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001567 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001568
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001569 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042,
1570 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001571
Giridhar Malavali7e2b8952010-05-28 15:08:17 -07001572 req = vha->hw->req_q_map[0];
1573 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001574 mcp->mb[0] = MBC_LUN_RESET;
1575 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001576 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -07001577 mcp->mb[1] = fcport->loop_id;
1578 else
1579 mcp->mb[1] = fcport->loop_id << 8;
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001580 mcp->mb[2] = (u32)l;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001581 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001582 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001583
1584 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001585 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001586 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001587 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001588 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001589 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001590 }
1591
1592 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001593 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1594 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001595 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001596 ql_dbg(ql_dbg_mbx, vha, 0x1044,
1597 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001598 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001599 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045,
1600 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 }
1602
1603 return rval;
1604}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605
1606/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 * qla2x00_get_adapter_id
1608 * Get adapter ID and topology.
1609 *
1610 * Input:
1611 * ha = adapter block pointer.
1612 * id = pointer for loop ID.
1613 * al_pa = pointer for AL_PA.
1614 * area = pointer for area.
1615 * domain = pointer for domain.
1616 * top = pointer for topology.
1617 * TARGET_QUEUE_LOCK must be released.
1618 * ADAPTER_STATE_LOCK must be released.
1619 *
1620 * Returns:
1621 * qla2x00 local function return status code.
1622 *
1623 * Context:
1624 * Kernel context.
1625 */
1626int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001627qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001628 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629{
1630 int rval;
1631 mbx_cmd_t mc;
1632 mbx_cmd_t *mcp = &mc;
1633
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001634 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046,
1635 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636
1637 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001638 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001639 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001640 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001641 if (IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001642 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001643 if (IS_FWI2_CAPABLE(vha->hw))
1644 mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16;
Sawan Chandak969a6192016-01-27 12:03:32 -05001645 if (IS_QLA27XX(vha->hw))
1646 mcp->in_mb |= MBX_15;
Ravi Anandb93480e2008-04-03 13:13:25 -07001647 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001649 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001650 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1651 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001652 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1653 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654
1655 /* Return data. */
1656 *id = mcp->mb[1];
1657 *al_pa = LSB(mcp->mb[2]);
1658 *area = MSB(mcp->mb[2]);
1659 *domain = LSB(mcp->mb[3]);
1660 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001661 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662
1663 if (rval != QLA_SUCCESS) {
1664 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001665 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001667 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048,
1668 "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001669
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001670 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001671 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1672 vha->fcoe_fcf_idx = mcp->mb[10];
1673 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1674 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1675 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1676 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1677 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1678 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1679 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001680 /* If FA-WWN supported */
Saurav Kashyapd6b9b422015-08-04 13:37:55 -04001681 if (IS_FAWWN_CAPABLE(vha->hw)) {
1682 if (mcp->mb[7] & BIT_14) {
1683 vha->port_name[0] = MSB(mcp->mb[16]);
1684 vha->port_name[1] = LSB(mcp->mb[16]);
1685 vha->port_name[2] = MSB(mcp->mb[17]);
1686 vha->port_name[3] = LSB(mcp->mb[17]);
1687 vha->port_name[4] = MSB(mcp->mb[18]);
1688 vha->port_name[5] = LSB(mcp->mb[18]);
1689 vha->port_name[6] = MSB(mcp->mb[19]);
1690 vha->port_name[7] = LSB(mcp->mb[19]);
1691 fc_host_port_name(vha->host) =
1692 wwn_to_u64(vha->port_name);
1693 ql_dbg(ql_dbg_mbx, vha, 0x10ca,
1694 "FA-WWN acquired %016llx\n",
1695 wwn_to_u64(vha->port_name));
1696 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001697 }
Sawan Chandak969a6192016-01-27 12:03:32 -05001698
1699 if (IS_QLA27XX(vha->hw))
1700 vha->bbcr = mcp->mb[15];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 }
1702
1703 return rval;
1704}
1705
1706/*
1707 * qla2x00_get_retry_cnt
1708 * Get current firmware login retry count and delay.
1709 *
1710 * Input:
1711 * ha = adapter block pointer.
1712 * retry_cnt = pointer to login retry count.
1713 * tov = pointer to login timeout value.
1714 *
1715 * Returns:
1716 * qla2x00 local function return status code.
1717 *
1718 * Context:
1719 * Kernel context.
1720 */
1721int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001722qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 uint16_t *r_a_tov)
1724{
1725 int rval;
1726 uint16_t ratov;
1727 mbx_cmd_t mc;
1728 mbx_cmd_t *mcp = &mc;
1729
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001730 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049,
1731 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732
1733 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1734 mcp->out_mb = MBX_0;
1735 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001736 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001738 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739
1740 if (rval != QLA_SUCCESS) {
1741 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001742 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1743 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744 } else {
1745 /* Convert returned data and check our values. */
1746 *r_a_tov = mcp->mb[3] / 2;
1747 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1748 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1749 /* Update to the larger values */
1750 *retry_cnt = (uint8_t)mcp->mb[1];
1751 *tov = ratov;
1752 }
1753
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001754 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001755 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001756 }
1757
1758 return rval;
1759}
1760
1761/*
1762 * qla2x00_init_firmware
1763 * Initialize adapter firmware.
1764 *
1765 * Input:
1766 * ha = adapter block pointer.
1767 * dptr = Initialization control block pointer.
1768 * size = size of initialization control block.
1769 * TARGET_QUEUE_LOCK must be released.
1770 * ADAPTER_STATE_LOCK must be released.
1771 *
1772 * Returns:
1773 * qla2x00 local function return status code.
1774 *
1775 * Context:
1776 * Kernel context.
1777 */
1778int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001779qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780{
1781 int rval;
1782 mbx_cmd_t mc;
1783 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001784 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001786 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,
1787 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001789 if (IS_P3P_TYPE(ha) && ql2xdbwr)
Bart Van Assche8dfa4b5a2015-07-09 07:24:50 -07001790 qla82xx_wr_32(ha, (uintptr_t __force)ha->nxdb_wr_ptr,
Giridhar Malavalia9083012010-04-12 17:59:55 -07001791 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1792
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001793 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001794 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1795 else
1796 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1797
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001798 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 mcp->mb[2] = MSW(ha->init_cb_dma);
1800 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1802 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001803 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Joe Carnuccio4ef21bd2013-10-30 03:38:11 -04001804 if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001805 mcp->mb[1] = BIT_0;
1806 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1807 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1808 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1809 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1810 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1811 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1812 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001813 /* 1 and 2 should normally be captured. */
1814 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001815 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001816 /* mb3 is additional info about the installed SFP. */
1817 mcp->in_mb |= MBX_3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 mcp->buf_size = size;
1819 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001820 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001821 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822
1823 if (rval != QLA_SUCCESS) {
1824 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001825 ql_dbg(ql_dbg_mbx, vha, 0x104d,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001826 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1827 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 } else {
Sawan Chandak92d44082017-08-23 15:05:16 -07001829 if (IS_QLA27XX(ha)) {
1830 if (mcp->mb[2] == 6 || mcp->mb[3] == 2)
1831 ql_dbg(ql_dbg_mbx, vha, 0x119d,
1832 "Invalid SFP/Validation Failed\n");
1833 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001834 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,
1835 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836 }
1837
1838 return rval;
1839}
1840
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001841
1842/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843 * qla2x00_get_port_database
1844 * Issue normal/enhanced get port database mailbox command
1845 * and copy device name as necessary.
1846 *
1847 * Input:
1848 * ha = adapter state pointer.
1849 * dev = structure pointer.
1850 * opt = enhanced cmd option byte.
1851 *
1852 * Returns:
1853 * qla2x00 local function return status code.
1854 *
1855 * Context:
1856 * Kernel context.
1857 */
1858int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001859qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860{
1861 int rval;
1862 mbx_cmd_t mc;
1863 mbx_cmd_t *mcp = &mc;
1864 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001865 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001867 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001869 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f,
1870 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001872 pd24 = NULL;
Thomas Meyer08eb7f42017-09-21 08:15:26 +02001873 pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001874 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001875 ql_log(ql_log_warn, vha, 0x1050,
1876 "Failed to allocate port database structure.\n");
Duane Grigsbyedd05de2017-10-13 09:34:06 -07001877 fcport->query = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 return QLA_MEMORY_ALLOC_FAILED;
1879 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001881 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001882 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884 mcp->mb[2] = MSW(pd_dma);
1885 mcp->mb[3] = LSW(pd_dma);
1886 mcp->mb[6] = MSW(MSD(pd_dma));
1887 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001888 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001889 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001891 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001892 mcp->mb[1] = fcport->loop_id;
1893 mcp->mb[10] = opt;
1894 mcp->out_mb |= MBX_10|MBX_1;
1895 mcp->in_mb |= MBX_1;
1896 } else if (HAS_EXTENDED_IDS(ha)) {
1897 mcp->mb[1] = fcport->loop_id;
1898 mcp->mb[10] = opt;
1899 mcp->out_mb |= MBX_10|MBX_1;
1900 } else {
1901 mcp->mb[1] = fcport->loop_id << 8 | opt;
1902 mcp->out_mb |= MBX_1;
1903 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001904 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1905 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906 mcp->flags = MBX_DMA_IN;
1907 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001908 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 if (rval != QLA_SUCCESS)
1910 goto gpd_error_out;
1911
Andrew Vasqueze4289242007-07-19 15:05:56 -07001912 if (IS_FWI2_CAPABLE(ha)) {
Arun Easi0eba25d2012-02-09 11:15:58 -08001913 uint64_t zero = 0;
Duane Grigsbyc0c462c2017-10-13 09:34:05 -07001914 u8 current_login_state, last_login_state;
1915
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001916 pd24 = (struct port_database_24xx *) pd;
1917
1918 /* Check for logged in state. */
Duane Grigsbyc0c462c2017-10-13 09:34:05 -07001919 if (fcport->fc4f_nvme) {
1920 current_login_state = pd24->current_login_state >> 4;
1921 last_login_state = pd24->last_login_state >> 4;
1922 } else {
1923 current_login_state = pd24->current_login_state & 0xf;
1924 last_login_state = pd24->last_login_state & 0xf;
1925 }
1926 fcport->current_login_state = pd24->current_login_state;
1927 fcport->last_login_state = pd24->last_login_state;
1928
1929 /* Check for logged in state. */
1930 if (current_login_state != PDS_PRLI_COMPLETE &&
1931 last_login_state != PDS_PRLI_COMPLETE) {
1932 ql_dbg(ql_dbg_mbx, vha, 0x119a,
1933 "Unable to verify login-state (%x/%x) for loop_id %x.\n",
1934 current_login_state, last_login_state,
1935 fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001936 rval = QLA_FUNCTION_FAILED;
Duane Grigsbyc0c462c2017-10-13 09:34:05 -07001937
1938 if (!fcport->query)
1939 goto gpd_error_out;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001940 }
1941
Arun Easi0eba25d2012-02-09 11:15:58 -08001942 if (fcport->loop_id == FC_NO_LOOP_ID ||
1943 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1944 memcmp(fcport->port_name, pd24->port_name, 8))) {
1945 /* We lost the device mid way. */
1946 rval = QLA_NOT_LOGGED_IN;
1947 goto gpd_error_out;
1948 }
1949
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001950 /* Names are little-endian. */
1951 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1952 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1953
1954 /* Get port_id of device. */
1955 fcport->d_id.b.domain = pd24->port_id[0];
1956 fcport->d_id.b.area = pd24->port_id[1];
1957 fcport->d_id.b.al_pa = pd24->port_id[2];
1958 fcport->d_id.b.rsvd_1 = 0;
1959
1960 /* If not target must be initiator or unknown type. */
1961 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1962 fcport->port_type = FCT_INITIATOR;
1963 else
1964 fcport->port_type = FCT_TARGET;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001965
1966 /* Passback COS information. */
1967 fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ?
1968 FC_COS_CLASS2 : FC_COS_CLASS3;
1969
1970 if (pd24->prli_svc_param_word_3[0] & BIT_7)
1971 fcport->flags |= FCF_CONF_COMP_SUPPORTED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001972 } else {
Arun Easi0eba25d2012-02-09 11:15:58 -08001973 uint64_t zero = 0;
1974
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001975 /* Check for logged in state. */
1976 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1977 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001978 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1979 "Unable to verify login-state (%x/%x) - "
1980 "portid=%02x%02x%02x.\n", pd->master_state,
1981 pd->slave_state, fcport->d_id.b.domain,
1982 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001983 rval = QLA_FUNCTION_FAILED;
1984 goto gpd_error_out;
1985 }
1986
Arun Easi0eba25d2012-02-09 11:15:58 -08001987 if (fcport->loop_id == FC_NO_LOOP_ID ||
1988 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1989 memcmp(fcport->port_name, pd->port_name, 8))) {
1990 /* We lost the device mid way. */
1991 rval = QLA_NOT_LOGGED_IN;
1992 goto gpd_error_out;
1993 }
1994
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001995 /* Names are little-endian. */
1996 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1997 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1998
1999 /* Get port_id of device. */
2000 fcport->d_id.b.domain = pd->port_id[0];
2001 fcport->d_id.b.area = pd->port_id[3];
2002 fcport->d_id.b.al_pa = pd->port_id[2];
2003 fcport->d_id.b.rsvd_1 = 0;
2004
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002005 /* If not target must be initiator or unknown type. */
2006 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
2007 fcport->port_type = FCT_INITIATOR;
2008 else
2009 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07002010
2011 /* Passback COS information. */
2012 fcport->supported_classes = (pd->options & BIT_4) ?
2013 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014 }
2015
Linus Torvalds1da177e2005-04-16 15:20:36 -07002016gpd_error_out:
2017 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
Duane Grigsbyedd05de2017-10-13 09:34:06 -07002018 fcport->query = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019
2020 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002021 ql_dbg(ql_dbg_mbx, vha, 0x1052,
2022 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
2023 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002024 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002025 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053,
2026 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 }
2028
2029 return rval;
2030}
2031
2032/*
2033 * qla2x00_get_firmware_state
2034 * Get adapter firmware state.
2035 *
2036 * Input:
2037 * ha = adapter block pointer.
2038 * dptr = pointer for firmware state.
2039 * TARGET_QUEUE_LOCK must be released.
2040 * ADAPTER_STATE_LOCK must be released.
2041 *
2042 * Returns:
2043 * qla2x00 local function return status code.
2044 *
2045 * Context:
2046 * Kernel context.
2047 */
2048int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002049qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050{
2051 int rval;
2052 mbx_cmd_t mc;
2053 mbx_cmd_t *mcp = &mc;
Sawan Chandak92d44082017-08-23 15:05:16 -07002054 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002055
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002056 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
2057 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058
2059 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
2060 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002061 if (IS_FWI2_CAPABLE(vha->hw))
Joe Carnucciob5a340d2014-09-25 05:16:48 -04002062 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002063 else
2064 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002065 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002067 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068
Harihara Kadayam4d4df192008-04-03 13:13:26 -07002069 /* Return firmware states. */
2070 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002071 if (IS_FWI2_CAPABLE(vha->hw)) {
2072 states[1] = mcp->mb[2];
Joe Carnuccioec891462016-07-06 11:14:26 -04002073 states[2] = mcp->mb[3]; /* SFP info */
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002074 states[3] = mcp->mb[4];
2075 states[4] = mcp->mb[5];
Joe Carnucciob5a340d2014-09-25 05:16:48 -04002076 states[5] = mcp->mb[6]; /* DPORT status */
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07002077 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078
2079 if (rval != QLA_SUCCESS) {
2080 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002081 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082 } else {
Sawan Chandak92d44082017-08-23 15:05:16 -07002083 if (IS_QLA27XX(ha)) {
2084 if (mcp->mb[2] == 6 || mcp->mb[3] == 2)
2085 ql_dbg(ql_dbg_mbx, vha, 0x119e,
2086 "Invalid SFP/Validation Failed\n");
2087 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002088 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,
2089 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002090 }
2091
2092 return rval;
2093}
2094
2095/*
2096 * qla2x00_get_port_name
2097 * Issue get port name mailbox command.
2098 * Returned name is in big endian format.
2099 *
2100 * Input:
2101 * ha = adapter block pointer.
2102 * loop_id = loop ID of device.
2103 * name = pointer for name.
2104 * TARGET_QUEUE_LOCK must be released.
2105 * ADAPTER_STATE_LOCK must be released.
2106 *
2107 * Returns:
2108 * qla2x00 local function return status code.
2109 *
2110 * Context:
2111 * Kernel context.
2112 */
2113int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002114qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002115 uint8_t opt)
2116{
2117 int rval;
2118 mbx_cmd_t mc;
2119 mbx_cmd_t *mcp = &mc;
2120
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002121 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057,
2122 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002123
2124 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002125 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002126 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002127 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002128 mcp->mb[1] = loop_id;
2129 mcp->mb[10] = opt;
2130 mcp->out_mb |= MBX_10;
2131 } else {
2132 mcp->mb[1] = loop_id << 8 | opt;
2133 }
2134
2135 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002136 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002137 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002138 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139
2140 if (rval != QLA_SUCCESS) {
2141 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002142 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002143 } else {
2144 if (name != NULL) {
2145 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05002146 name[0] = MSB(mcp->mb[2]);
2147 name[1] = LSB(mcp->mb[2]);
2148 name[2] = MSB(mcp->mb[3]);
2149 name[3] = LSB(mcp->mb[3]);
2150 name[4] = MSB(mcp->mb[6]);
2151 name[5] = LSB(mcp->mb[6]);
2152 name[6] = MSB(mcp->mb[7]);
2153 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002154 }
2155
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002156 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059,
2157 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 }
2159
2160 return rval;
2161}
2162
2163/*
Joe Carnuccio61e1b262013-02-08 01:57:48 -05002164 * qla24xx_link_initialization
2165 * Issue link initialization mailbox command.
2166 *
2167 * Input:
2168 * ha = adapter block pointer.
2169 * TARGET_QUEUE_LOCK must be released.
2170 * ADAPTER_STATE_LOCK must be released.
2171 *
2172 * Returns:
2173 * qla2x00 local function return status code.
2174 *
2175 * Context:
2176 * Kernel context.
2177 */
2178int
2179qla24xx_link_initialize(scsi_qla_host_t *vha)
2180{
2181 int rval;
2182 mbx_cmd_t mc;
2183 mbx_cmd_t *mcp = &mc;
2184
2185 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152,
2186 "Entered %s.\n", __func__);
2187
2188 if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw))
2189 return QLA_FUNCTION_FAILED;
2190
2191 mcp->mb[0] = MBC_LINK_INITIALIZATION;
Joe Carnuccio5a5c27b2013-08-27 01:37:49 -04002192 mcp->mb[1] = BIT_4;
2193 if (vha->hw->operating_mode == LOOP)
2194 mcp->mb[1] |= BIT_6;
2195 else
2196 mcp->mb[1] |= BIT_5;
Joe Carnuccio61e1b262013-02-08 01:57:48 -05002197 mcp->mb[2] = 0;
2198 mcp->mb[3] = 0;
2199 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2200 mcp->in_mb = MBX_0;
2201 mcp->tov = MBX_TOV_SECONDS;
2202 mcp->flags = 0;
2203 rval = qla2x00_mailbox_command(vha, mcp);
2204
2205 if (rval != QLA_SUCCESS) {
2206 ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval);
2207 } else {
2208 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154,
2209 "Done %s.\n", __func__);
2210 }
2211
2212 return rval;
2213}
2214
2215/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216 * qla2x00_lip_reset
2217 * Issue LIP reset mailbox command.
2218 *
2219 * Input:
2220 * ha = adapter block pointer.
2221 * TARGET_QUEUE_LOCK must be released.
2222 * ADAPTER_STATE_LOCK must be released.
2223 *
2224 * Returns:
2225 * qla2x00 local function return status code.
2226 *
2227 * Context:
2228 * Kernel context.
2229 */
2230int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002231qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002232{
2233 int rval;
2234 mbx_cmd_t mc;
2235 mbx_cmd_t *mcp = &mc;
2236
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002237 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a,
2238 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002239
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002240 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08002241 /* Logout across all FCFs. */
2242 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
2243 mcp->mb[1] = BIT_1;
2244 mcp->mb[2] = 0;
2245 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2246 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002247 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Quinn Tran48acad02018-08-02 13:16:44 -07002248 if (N2N_TOPO(vha->hw))
2249 mcp->mb[1] = BIT_4; /* re-init */
2250 else
2251 mcp->mb[1] = BIT_6; /* LIP */
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002252 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002253 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002254 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002256 mcp->mb[0] = MBC_LIP_RESET;
2257 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002258 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002259 mcp->mb[1] = 0x00ff;
2260 mcp->mb[10] = 0;
2261 mcp->out_mb |= MBX_10;
2262 } else {
2263 mcp->mb[1] = 0xff00;
2264 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002265 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002266 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002267 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002269 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002270 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002271 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002272
2273 if (rval != QLA_SUCCESS) {
2274 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002275 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276 } else {
2277 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002278 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c,
2279 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280 }
2281
2282 return rval;
2283}
2284
2285/*
2286 * qla2x00_send_sns
2287 * Send SNS command.
2288 *
2289 * Input:
2290 * ha = adapter block pointer.
2291 * sns = pointer for command.
2292 * cmd_size = command size.
2293 * buf_size = response/command size.
2294 * TARGET_QUEUE_LOCK must be released.
2295 * ADAPTER_STATE_LOCK must be released.
2296 *
2297 * Returns:
2298 * qla2x00 local function return status code.
2299 *
2300 * Context:
2301 * Kernel context.
2302 */
2303int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002304qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305 uint16_t cmd_size, size_t buf_size)
2306{
2307 int rval;
2308 mbx_cmd_t mc;
2309 mbx_cmd_t *mcp = &mc;
2310
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002311 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d,
2312 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002314 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002315 "Retry cnt=%d ratov=%d total tov=%d.\n",
2316 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317
2318 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
2319 mcp->mb[1] = cmd_size;
2320 mcp->mb[2] = MSW(sns_phys_address);
2321 mcp->mb[3] = LSW(sns_phys_address);
2322 mcp->mb[6] = MSW(MSD(sns_phys_address));
2323 mcp->mb[7] = LSW(MSD(sns_phys_address));
2324 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
2325 mcp->in_mb = MBX_0|MBX_1;
2326 mcp->buf_size = buf_size;
2327 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002328 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
2329 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002330
2331 if (rval != QLA_SUCCESS) {
2332 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002333 ql_dbg(ql_dbg_mbx, vha, 0x105f,
2334 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2335 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336 } else {
2337 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002338 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060,
2339 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002340 }
2341
2342 return rval;
2343}
2344
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002345int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002346qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002347 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
2348{
2349 int rval;
2350
2351 struct logio_entry_24xx *lg;
2352 dma_addr_t lg_dma;
2353 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002354 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002355 struct req_que *req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002356
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002357 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061,
2358 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002359
Michael Hernandezd7459522016-12-12 14:40:07 -08002360 if (vha->vp_idx && vha->qpair)
2361 req = vha->qpair->req;
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002362 else
Michael Hernandezd7459522016-12-12 14:40:07 -08002363 req = ha->req_q_map[0];
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002364
Thomas Meyer08eb7f42017-09-21 08:15:26 +02002365 lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002366 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002367 ql_log(ql_log_warn, vha, 0x1062,
2368 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002369 return QLA_MEMORY_ALLOC_FAILED;
2370 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002371
2372 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2373 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002374 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002375 lg->nport_handle = cpu_to_le16(loop_id);
Bart Van Asschead950362015-07-09 07:24:08 -07002376 lg->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002377 if (opt & BIT_0)
Bart Van Asschead950362015-07-09 07:24:08 -07002378 lg->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07002379 if (opt & BIT_1)
Bart Van Asschead950362015-07-09 07:24:08 -07002380 lg->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002381 lg->port_id[0] = al_pa;
2382 lg->port_id[1] = area;
2383 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002384 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08002385 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2386 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002387 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002388 ql_dbg(ql_dbg_mbx, vha, 0x1063,
2389 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002390 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002391 ql_dbg(ql_dbg_mbx, vha, 0x1064,
2392 "Failed to complete IOCB -- error status (%x).\n",
2393 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002394 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002395 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002396 iop[0] = le32_to_cpu(lg->io_parameter[0]);
2397 iop[1] = le32_to_cpu(lg->io_parameter[1]);
2398
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002399 ql_dbg(ql_dbg_mbx, vha, 0x1065,
2400 "Failed to complete IOCB -- completion status (%x) "
2401 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
2402 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002403
2404 switch (iop[0]) {
2405 case LSC_SCODE_PORTID_USED:
2406 mb[0] = MBS_PORT_ID_USED;
2407 mb[1] = LSW(iop[1]);
2408 break;
2409 case LSC_SCODE_NPORT_USED:
2410 mb[0] = MBS_LOOP_ID_USED;
2411 break;
2412 case LSC_SCODE_NOLINK:
2413 case LSC_SCODE_NOIOCB:
2414 case LSC_SCODE_NOXCB:
2415 case LSC_SCODE_CMD_FAILED:
2416 case LSC_SCODE_NOFABRIC:
2417 case LSC_SCODE_FW_NOT_READY:
2418 case LSC_SCODE_NOT_LOGGED_IN:
2419 case LSC_SCODE_NOPCB:
2420 case LSC_SCODE_ELS_REJECT:
2421 case LSC_SCODE_CMD_PARAM_ERR:
2422 case LSC_SCODE_NONPORT:
2423 case LSC_SCODE_LOGGED_IN:
2424 case LSC_SCODE_NOFLOGI_ACC:
2425 default:
2426 mb[0] = MBS_COMMAND_ERROR;
2427 break;
2428 }
2429 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002430 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066,
2431 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002432
2433 iop[0] = le32_to_cpu(lg->io_parameter[0]);
2434
2435 mb[0] = MBS_COMMAND_COMPLETE;
2436 mb[1] = 0;
2437 if (iop[0] & BIT_4) {
2438 if (iop[0] & BIT_8)
2439 mb[1] |= BIT_1;
2440 } else
2441 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07002442
2443 /* Passback COS information. */
2444 mb[10] = 0;
2445 if (lg->io_parameter[7] || lg->io_parameter[8])
2446 mb[10] |= BIT_0; /* Class 2. */
2447 if (lg->io_parameter[9] || lg->io_parameter[10])
2448 mb[10] |= BIT_1; /* Class 3. */
Bart Van Asschead950362015-07-09 07:24:08 -07002449 if (lg->io_parameter[0] & cpu_to_le32(BIT_7))
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04002450 mb[10] |= BIT_7; /* Confirmed Completion
2451 * Allowed
2452 */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002453 }
2454
2455 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2456
2457 return rval;
2458}
2459
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460/*
2461 * qla2x00_login_fabric
2462 * Issue login fabric port mailbox command.
2463 *
2464 * Input:
2465 * ha = adapter block pointer.
2466 * loop_id = device loop ID.
2467 * domain = device domain.
2468 * area = device area.
2469 * al_pa = device AL_PA.
2470 * status = pointer for return status.
2471 * opt = command options.
2472 * TARGET_QUEUE_LOCK must be released.
2473 * ADAPTER_STATE_LOCK must be released.
2474 *
2475 * Returns:
2476 * qla2x00 local function return status code.
2477 *
2478 * Context:
2479 * Kernel context.
2480 */
2481int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002482qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
2484{
2485 int rval;
2486 mbx_cmd_t mc;
2487 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002488 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002489
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002490 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067,
2491 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002492
2493 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
2494 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2495 if (HAS_EXTENDED_IDS(ha)) {
2496 mcp->mb[1] = loop_id;
2497 mcp->mb[10] = opt;
2498 mcp->out_mb |= MBX_10;
2499 } else {
2500 mcp->mb[1] = (loop_id << 8) | opt;
2501 }
2502 mcp->mb[2] = domain;
2503 mcp->mb[3] = area << 8 | al_pa;
2504
2505 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
2506 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2507 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002508 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002509
2510 /* Return mailbox statuses. */
2511 if (mb != NULL) {
2512 mb[0] = mcp->mb[0];
2513 mb[1] = mcp->mb[1];
2514 mb[2] = mcp->mb[2];
2515 mb[6] = mcp->mb[6];
2516 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07002517 /* COS retrieved from Get-Port-Database mailbox command. */
2518 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002519 }
2520
2521 if (rval != QLA_SUCCESS) {
2522 /* RLU tmp code: need to change main mailbox_command function to
2523 * return ok even when the mailbox completion value is not
2524 * SUCCESS. The caller needs to be responsible to interpret
2525 * the return values of this mailbox command if we're not
2526 * to change too much of the existing code.
2527 */
2528 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
2529 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
2530 mcp->mb[0] == 0x4006)
2531 rval = QLA_SUCCESS;
2532
2533 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002534 ql_dbg(ql_dbg_mbx, vha, 0x1068,
2535 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
2536 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537 } else {
2538 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002539 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069,
2540 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541 }
2542
2543 return rval;
2544}
2545
2546/*
2547 * qla2x00_login_local_device
2548 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002549 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002550 * Input:
2551 * ha = adapter block pointer.
2552 * loop_id = device loop ID.
2553 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002554 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555 * Returns:
2556 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002557 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558 * Context:
2559 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002560 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561 */
2562int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002563qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 uint16_t *mb_ret, uint8_t opt)
2565{
2566 int rval;
2567 mbx_cmd_t mc;
2568 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002569 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002571 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a,
2572 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002573
Andrew Vasqueze4289242007-07-19 15:05:56 -07002574 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002575 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002576 fcport->d_id.b.domain, fcport->d_id.b.area,
2577 fcport->d_id.b.al_pa, mb_ret, opt);
2578
Linus Torvalds1da177e2005-04-16 15:20:36 -07002579 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
2580 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002581 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002582 else
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002583 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002584 mcp->mb[2] = opt;
2585 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2586 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
2587 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2588 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002589 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002590
2591 /* Return mailbox statuses. */
2592 if (mb_ret != NULL) {
2593 mb_ret[0] = mcp->mb[0];
2594 mb_ret[1] = mcp->mb[1];
2595 mb_ret[6] = mcp->mb[6];
2596 mb_ret[7] = mcp->mb[7];
2597 }
2598
2599 if (rval != QLA_SUCCESS) {
2600 /* AV tmp code: need to change main mailbox_command function to
2601 * return ok even when the mailbox completion value is not
2602 * SUCCESS. The caller needs to be responsible to interpret
2603 * the return values of this mailbox command if we're not
2604 * to change too much of the existing code.
2605 */
2606 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
2607 rval = QLA_SUCCESS;
2608
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002609 ql_dbg(ql_dbg_mbx, vha, 0x106b,
2610 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
2611 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612 } else {
2613 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002614 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c,
2615 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002616 }
2617
2618 return (rval);
2619}
2620
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002621int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002622qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002623 uint8_t area, uint8_t al_pa)
2624{
2625 int rval;
2626 struct logio_entry_24xx *lg;
2627 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002628 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002629 struct req_que *req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002630
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002631 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d,
2632 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002633
Thomas Meyer08eb7f42017-09-21 08:15:26 +02002634 lg = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002635 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002636 ql_log(ql_log_warn, vha, 0x106e,
2637 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002638 return QLA_MEMORY_ALLOC_FAILED;
2639 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002640
Michael Hernandezd7459522016-12-12 14:40:07 -08002641 req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002642 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2643 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002644 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002645 lg->nport_handle = cpu_to_le16(loop_id);
2646 lg->control_flags =
Bart Van Asschead950362015-07-09 07:24:08 -07002647 cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
Andrew Vasquezc8d66912011-03-30 11:46:21 -07002648 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002649 lg->port_id[0] = al_pa;
2650 lg->port_id[1] = area;
2651 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002652 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08002653 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2654 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002655 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002656 ql_dbg(ql_dbg_mbx, vha, 0x106f,
2657 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002658 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002659 ql_dbg(ql_dbg_mbx, vha, 0x1070,
2660 "Failed to complete IOCB -- error status (%x).\n",
2661 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002662 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002663 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002664 ql_dbg(ql_dbg_mbx, vha, 0x1071,
2665 "Failed to complete IOCB -- completion status (%x) "
2666 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002667 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002668 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002669 } else {
2670 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002671 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072,
2672 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002673 }
2674
2675 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2676
2677 return rval;
2678}
2679
Linus Torvalds1da177e2005-04-16 15:20:36 -07002680/*
2681 * qla2x00_fabric_logout
2682 * Issue logout fabric port mailbox command.
2683 *
2684 * Input:
2685 * ha = adapter block pointer.
2686 * loop_id = device loop ID.
2687 * TARGET_QUEUE_LOCK must be released.
2688 * ADAPTER_STATE_LOCK must be released.
2689 *
2690 * Returns:
2691 * qla2x00 local function return status code.
2692 *
2693 * Context:
2694 * Kernel context.
2695 */
2696int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002697qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002698 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699{
2700 int rval;
2701 mbx_cmd_t mc;
2702 mbx_cmd_t *mcp = &mc;
2703
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002704 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073,
2705 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706
2707 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
2708 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002709 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710 mcp->mb[1] = loop_id;
2711 mcp->mb[10] = 0;
2712 mcp->out_mb |= MBX_10;
2713 } else {
2714 mcp->mb[1] = loop_id << 8;
2715 }
2716
2717 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002718 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002720 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721
2722 if (rval != QLA_SUCCESS) {
2723 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002724 ql_dbg(ql_dbg_mbx, vha, 0x1074,
2725 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002726 } else {
2727 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002728 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075,
2729 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730 }
2731
2732 return rval;
2733}
2734
2735/*
2736 * qla2x00_full_login_lip
2737 * Issue full login LIP mailbox command.
2738 *
2739 * Input:
2740 * ha = adapter block pointer.
2741 * TARGET_QUEUE_LOCK must be released.
2742 * ADAPTER_STATE_LOCK must be released.
2743 *
2744 * Returns:
2745 * qla2x00 local function return status code.
2746 *
2747 * Context:
2748 * Kernel context.
2749 */
2750int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002751qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002752{
2753 int rval;
2754 mbx_cmd_t mc;
2755 mbx_cmd_t *mcp = &mc;
2756
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002757 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076,
2758 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002759
2760 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002761 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002762 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002763 mcp->mb[3] = 0;
2764 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2765 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002766 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002767 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002768 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002769
2770 if (rval != QLA_SUCCESS) {
2771 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002772 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002773 } else {
2774 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002775 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078,
2776 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002777 }
2778
2779 return rval;
2780}
2781
2782/*
2783 * qla2x00_get_id_list
2784 *
2785 * Input:
2786 * ha = adapter block pointer.
2787 *
2788 * Returns:
2789 * qla2x00 local function return status code.
2790 *
2791 * Context:
2792 * Kernel context.
2793 */
2794int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002795qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002796 uint16_t *entries)
2797{
2798 int rval;
2799 mbx_cmd_t mc;
2800 mbx_cmd_t *mcp = &mc;
2801
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002802 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079,
2803 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002804
2805 if (id_list == NULL)
2806 return QLA_FUNCTION_FAILED;
2807
2808 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002809 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002810 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002811 mcp->mb[2] = MSW(id_list_dma);
2812 mcp->mb[3] = LSW(id_list_dma);
2813 mcp->mb[6] = MSW(MSD(id_list_dma));
2814 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002815 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002816 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002817 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002818 } else {
2819 mcp->mb[1] = MSW(id_list_dma);
2820 mcp->mb[2] = LSW(id_list_dma);
2821 mcp->mb[3] = MSW(MSD(id_list_dma));
2822 mcp->mb[6] = LSW(MSD(id_list_dma));
2823 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2824 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002825 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002826 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002827 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002828 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829
2830 if (rval != QLA_SUCCESS) {
2831 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002832 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833 } else {
2834 *entries = mcp->mb[1];
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002835 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b,
2836 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837 }
2838
2839 return rval;
2840}
2841
2842/*
2843 * qla2x00_get_resource_cnts
2844 * Get current firmware resource counts.
2845 *
2846 * Input:
2847 * ha = adapter block pointer.
2848 *
2849 * Returns:
2850 * qla2x00 local function return status code.
2851 *
2852 * Context:
2853 * Kernel context.
2854 */
2855int
Quinn Tran03e8c682015-12-17 14:56:59 -05002856qla2x00_get_resource_cnts(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857{
Quinn Tran03e8c682015-12-17 14:56:59 -05002858 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 int rval;
2860 mbx_cmd_t mc;
2861 mbx_cmd_t *mcp = &mc;
2862
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002863 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c,
2864 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865
2866 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2867 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002868 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 -05002869 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) || IS_QLA27XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002870 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002871 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002872 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002873 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874
2875 if (rval != QLA_SUCCESS) {
2876 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002877 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2878 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002880 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002881 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2882 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2883 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2884 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885
Quinn Tran03e8c682015-12-17 14:56:59 -05002886 ha->orig_fw_tgt_xcb_count = mcp->mb[1];
2887 ha->cur_fw_tgt_xcb_count = mcp->mb[2];
2888 ha->cur_fw_xcb_count = mcp->mb[3];
2889 ha->orig_fw_xcb_count = mcp->mb[6];
2890 ha->cur_fw_iocb_count = mcp->mb[7];
2891 ha->orig_fw_iocb_count = mcp->mb[10];
2892 if (ha->flags.npiv_supported)
2893 ha->max_npiv_vports = mcp->mb[11];
2894 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
2895 ha->fw_max_fcf_count = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002896 }
2897
2898 return (rval);
2899}
2900
Linus Torvalds1da177e2005-04-16 15:20:36 -07002901/*
2902 * qla2x00_get_fcal_position_map
2903 * Get FCAL (LILP) position map using mailbox command
2904 *
2905 * Input:
2906 * ha = adapter state pointer.
2907 * pos_map = buffer pointer (can be NULL).
2908 *
2909 * Returns:
2910 * qla2x00 local function return status code.
2911 *
2912 * Context:
2913 * Kernel context.
2914 */
2915int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002916qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917{
2918 int rval;
2919 mbx_cmd_t mc;
2920 mbx_cmd_t *mcp = &mc;
2921 char *pmap;
2922 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002923 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002925 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f,
2926 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002927
Thomas Meyer08eb7f42017-09-21 08:15:26 +02002928 pmap = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002929 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002930 ql_log(ql_log_warn, vha, 0x1080,
2931 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002932 return QLA_MEMORY_ALLOC_FAILED;
2933 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002934
2935 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2936 mcp->mb[2] = MSW(pmap_dma);
2937 mcp->mb[3] = LSW(pmap_dma);
2938 mcp->mb[6] = MSW(MSD(pmap_dma));
2939 mcp->mb[7] = LSW(MSD(pmap_dma));
2940 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2941 mcp->in_mb = MBX_1|MBX_0;
2942 mcp->buf_size = FCAL_MAP_SIZE;
2943 mcp->flags = MBX_DMA_IN;
2944 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002945 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946
2947 if (rval == QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002948 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002949 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2950 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2951 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2952 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002953
2954 if (pos_map)
2955 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2956 }
2957 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2958
2959 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002960 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002961 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002962 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083,
2963 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964 }
2965
2966 return rval;
2967}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002968
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002969/*
2970 * qla2x00_get_link_status
2971 *
2972 * Input:
2973 * ha = adapter block pointer.
2974 * loop_id = device loop ID.
2975 * ret_buf = pointer to link status return buffer.
2976 *
2977 * Returns:
2978 * 0 = success.
2979 * BIT_0 = mem alloc error.
2980 * BIT_1 = mailbox error.
2981 */
2982int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002983qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002984 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002985{
2986 int rval;
2987 mbx_cmd_t mc;
2988 mbx_cmd_t *mcp = &mc;
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04002989 uint32_t *iter = (void *)stats;
2990 ushort dwords = offsetof(typeof(*stats), link_up_cnt)/sizeof(*iter);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002991 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002992
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002993 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084,
2994 "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002995
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002996 mcp->mb[0] = MBC_GET_LINK_STATUS;
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04002997 mcp->mb[2] = MSW(LSD(stats_dma));
2998 mcp->mb[3] = LSW(LSD(stats_dma));
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002999 mcp->mb[6] = MSW(MSD(stats_dma));
3000 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003001 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
3002 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07003003 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003004 mcp->mb[1] = loop_id;
3005 mcp->mb[4] = 0;
3006 mcp->mb[10] = 0;
3007 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
3008 mcp->in_mb |= MBX_1;
3009 } else if (HAS_EXTENDED_IDS(ha)) {
3010 mcp->mb[1] = loop_id;
3011 mcp->mb[10] = 0;
3012 mcp->out_mb |= MBX_10|MBX_1;
3013 } else {
3014 mcp->mb[1] = loop_id << 8;
3015 mcp->out_mb |= MBX_1;
3016 }
Ravi Anandb93480e2008-04-03 13:13:25 -07003017 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003018 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003019 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003020
3021 if (rval == QLA_SUCCESS) {
3022 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003023 ql_dbg(ql_dbg_mbx, vha, 0x1085,
3024 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08003025 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003026 } else {
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04003027 /* Re-endianize - firmware data is le32. */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003028 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086,
3029 "Done %s.\n", __func__);
Joe Carnuccioda08ef52016-01-27 12:03:34 -05003030 for ( ; dwords--; iter++)
3031 le32_to_cpus(iter);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003032 }
3033 } else {
3034 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003035 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003036 }
3037
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08003038 return rval;
3039}
3040
3041int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003042qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Quinn Tran15f30a52017-03-15 09:48:52 -07003043 dma_addr_t stats_dma, uint16_t options)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003044{
3045 int rval;
3046 mbx_cmd_t mc;
3047 mbx_cmd_t *mcp = &mc;
Joe Carnuccioda08ef52016-01-27 12:03:34 -05003048 uint32_t *iter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003049
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003050 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,
3051 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003052
Quinn Tran15f30a52017-03-15 09:48:52 -07003053 memset(&mc, 0, sizeof(mc));
3054 mc.mb[0] = MBC_GET_LINK_PRIV_STATS;
3055 mc.mb[2] = MSW(stats_dma);
3056 mc.mb[3] = LSW(stats_dma);
3057 mc.mb[6] = MSW(MSD(stats_dma));
3058 mc.mb[7] = LSW(MSD(stats_dma));
3059 mc.mb[8] = sizeof(struct link_statistics) / 4;
3060 mc.mb[9] = cpu_to_le16(vha->vp_idx);
3061 mc.mb[10] = cpu_to_le16(options);
3062
3063 rval = qla24xx_send_mb_cmd(vha, &mc);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003064
3065 if (rval == QLA_SUCCESS) {
3066 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003067 ql_dbg(ql_dbg_mbx, vha, 0x1089,
3068 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08003069 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003070 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003071 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a,
3072 "Done %s.\n", __func__);
Joe Carnuccioc6dc9902016-07-06 11:14:24 -04003073 /* Re-endianize - firmware data is le32. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08003074 dwords = sizeof(struct link_statistics) / 4;
Joe Carnuccioda08ef52016-01-27 12:03:34 -05003075 iter = &stats->link_fail_cnt;
3076 for ( ; dwords--; iter++)
3077 le32_to_cpus(iter);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003078 }
3079 } else {
3080 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003081 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003082 }
3083
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003084 return rval;
3085}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003086
3087int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003088qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003089{
3090 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003091 unsigned long flags = 0;
3092
3093 struct abort_entry_24xx *abt;
3094 dma_addr_t abt_dma;
3095 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003096 fc_port_t *fcport = sp->fcport;
3097 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003098 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07003099 struct req_que *req = vha->req;
Quinn Tran585def92018-09-04 14:19:20 -07003100 struct qla_qpair *qpair = sp->qpair;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003101
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003102 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,
3103 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003104
Michael Hernandezd7459522016-12-12 14:40:07 -08003105 if (vha->flags.qpairs_available && sp->qpair)
3106 req = sp->qpair->req;
Quinn Tran585def92018-09-04 14:19:20 -07003107 else
3108 return QLA_FUNCTION_FAILED;
Michael Hernandezd7459522016-12-12 14:40:07 -08003109
Armen Baloyan4440e462014-02-26 04:15:18 -05003110 if (ql2xasynctmfenable)
3111 return qla24xx_async_abort_command(sp);
3112
Quinn Tran585def92018-09-04 14:19:20 -07003113 spin_lock_irqsave(qpair->qp_lock_ptr, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05003114 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003115 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003116 break;
3117 }
Quinn Tran585def92018-09-04 14:19:20 -07003118 spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05003119 if (handle == req->num_outstanding_cmds) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003120 /* Command not found. */
3121 return QLA_FUNCTION_FAILED;
3122 }
3123
Thomas Meyer08eb7f42017-09-21 08:15:26 +02003124 abt = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003125 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003126 ql_log(ql_log_warn, vha, 0x108d,
3127 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003128 return QLA_MEMORY_ALLOC_FAILED;
3129 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003130
3131 abt->entry_type = ABORT_IOCB_TYPE;
3132 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003133 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003134 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07003135 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003136 abt->port_id[0] = fcport->d_id.b.al_pa;
3137 abt->port_id[1] = fcport->d_id.b.area;
3138 abt->port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04003139 abt->vp_index = fcport->vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003140
3141 abt->req_que_no = cpu_to_le16(req->id);
3142
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003143 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003144 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003145 ql_dbg(ql_dbg_mbx, vha, 0x108e,
3146 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003147 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003148 ql_dbg(ql_dbg_mbx, vha, 0x108f,
3149 "Failed to complete IOCB -- error status (%x).\n",
3150 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003151 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07003152 } else if (abt->nport_handle != cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003153 ql_dbg(ql_dbg_mbx, vha, 0x1090,
3154 "Failed to complete IOCB -- completion status (%x).\n",
3155 le16_to_cpu(abt->nport_handle));
Chad Dupuisf934c9d2014-04-11 16:54:31 -04003156 if (abt->nport_handle == CS_IOCB_ERROR)
3157 rval = QLA_FUNCTION_PARAMETER_ERROR;
3158 else
3159 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003160 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003161 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
3162 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003163 }
3164
3165 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
3166
3167 return rval;
3168}
3169
3170struct tsk_mgmt_cmd {
3171 union {
3172 struct tsk_mgmt_entry tsk;
3173 struct sts_entry_24xx sts;
3174 } p;
3175};
3176
Andrew Vasquez523ec772008-04-03 13:13:24 -07003177static int
3178__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02003179 uint64_t l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003180{
Andrew Vasquez523ec772008-04-03 13:13:24 -07003181 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003182 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003183 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003184 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003185 scsi_qla_host_t *vha;
3186 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003187 struct req_que *req;
3188 struct rsp_que *rsp;
Michael Hernandezd7459522016-12-12 14:40:07 -08003189 struct qla_qpair *qpair;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003190
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003191 vha = fcport->vha;
3192 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003193 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003194
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003195 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092,
3196 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003197
Michael Hernandezd7459522016-12-12 14:40:07 -08003198 if (vha->vp_idx && vha->qpair) {
3199 /* NPIV port */
3200 qpair = vha->qpair;
3201 rsp = qpair->rsp;
3202 req = qpair->req;
3203 } else {
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07003204 rsp = req->rsp;
Michael Hernandezd7459522016-12-12 14:40:07 -08003205 }
3206
Thomas Meyer08eb7f42017-09-21 08:15:26 +02003207 tsk = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003208 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003209 ql_log(ql_log_warn, vha, 0x1093,
3210 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003211 return QLA_MEMORY_ALLOC_FAILED;
3212 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003213
3214 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
3215 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003216 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003217 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08003218 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07003219 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003220 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
3221 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
3222 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04003223 tsk->p.tsk.vp_index = fcport->vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07003224 if (type == TCF_LUN_RESET) {
3225 int_to_scsilun(l, &tsk->p.tsk.lun);
3226 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
3227 sizeof(tsk->p.tsk.lun));
3228 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003229
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003230 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003231 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003232 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003233 ql_dbg(ql_dbg_mbx, vha, 0x1094,
3234 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003235 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003236 ql_dbg(ql_dbg_mbx, vha, 0x1095,
3237 "Failed to complete IOCB -- error status (%x).\n",
3238 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003239 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07003240 } else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003241 ql_dbg(ql_dbg_mbx, vha, 0x1096,
3242 "Failed to complete IOCB -- completion status (%x).\n",
3243 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07003244 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08003245 } else if (le16_to_cpu(sts->scsi_status) &
3246 SS_RESPONSE_INFO_LEN_VALID) {
3247 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003248 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003249 "Ignoring inconsistent data length -- not enough "
3250 "response info (%d).\n",
3251 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08003252 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003253 ql_dbg(ql_dbg_mbx, vha, 0x1098,
3254 "Failed to complete IOCB -- response (%x).\n",
3255 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08003256 rval = QLA_FUNCTION_FAILED;
3257 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003258 }
3259
3260 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003261 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07003262 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
3263 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003264 ql_dbg(ql_dbg_mbx, vha, 0x1099,
3265 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003266 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003267 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a,
3268 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003269 }
3270
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003271 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003272
3273 return rval;
3274}
3275
Andrew Vasquez523ec772008-04-03 13:13:24 -07003276int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02003277qla24xx_abort_target(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07003278{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07003279 struct qla_hw_data *ha = fcport->vha->hw;
3280
3281 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
3282 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
3283
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003284 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07003285}
3286
3287int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02003288qla24xx_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07003289{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07003290 struct qla_hw_data *ha = fcport->vha->hw;
3291
3292 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
3293 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
3294
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003295 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07003296}
3297
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003298int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003299qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003300{
3301 int rval;
3302 mbx_cmd_t mc;
3303 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003304 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003305
Andrew Vasquez68af0812008-05-12 22:21:13 -07003306 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003307 return QLA_FUNCTION_FAILED;
3308
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003309 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b,
3310 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003311
3312 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
3313 mcp->out_mb = MBX_0;
3314 mcp->in_mb = MBX_0;
3315 mcp->tov = 5;
3316 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003317 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003318
3319 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003320 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003321 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003322 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d,
3323 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003324 }
3325
3326 return rval;
3327}
3328
Joe Carnucciodb64e932013-10-30 03:38:18 -04003329int
3330qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data)
3331{
3332 int rval;
3333 mbx_cmd_t mc;
3334 mbx_cmd_t *mcp = &mc;
3335
Joe Carnucciof299c7c2015-08-04 13:37:51 -04003336 if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
3337 !IS_QLA27XX(vha->hw))
Joe Carnucciodb64e932013-10-30 03:38:18 -04003338 return QLA_FUNCTION_FAILED;
3339
3340 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182,
3341 "Entered %s.\n", __func__);
3342
3343 mcp->mb[0] = MBC_WRITE_SERDES;
3344 mcp->mb[1] = addr;
Andrew Vasquez064135e2015-04-09 15:00:02 -04003345 if (IS_QLA2031(vha->hw))
3346 mcp->mb[2] = data & 0xff;
3347 else
3348 mcp->mb[2] = data;
3349
Joe Carnucciodb64e932013-10-30 03:38:18 -04003350 mcp->mb[3] = 0;
3351 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
3352 mcp->in_mb = MBX_0;
3353 mcp->tov = MBX_TOV_SECONDS;
3354 mcp->flags = 0;
3355 rval = qla2x00_mailbox_command(vha, mcp);
3356
3357 if (rval != QLA_SUCCESS) {
3358 ql_dbg(ql_dbg_mbx, vha, 0x1183,
3359 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3360 } else {
3361 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184,
3362 "Done %s.\n", __func__);
3363 }
3364
3365 return rval;
3366}
3367
3368int
3369qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)
3370{
3371 int rval;
3372 mbx_cmd_t mc;
3373 mbx_cmd_t *mcp = &mc;
3374
Joe Carnucciof299c7c2015-08-04 13:37:51 -04003375 if (!IS_QLA25XX(vha->hw) && !IS_QLA2031(vha->hw) &&
3376 !IS_QLA27XX(vha->hw))
Joe Carnucciodb64e932013-10-30 03:38:18 -04003377 return QLA_FUNCTION_FAILED;
3378
3379 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185,
3380 "Entered %s.\n", __func__);
3381
3382 mcp->mb[0] = MBC_READ_SERDES;
3383 mcp->mb[1] = addr;
3384 mcp->mb[3] = 0;
3385 mcp->out_mb = MBX_3|MBX_1|MBX_0;
3386 mcp->in_mb = MBX_1|MBX_0;
3387 mcp->tov = MBX_TOV_SECONDS;
3388 mcp->flags = 0;
3389 rval = qla2x00_mailbox_command(vha, mcp);
3390
Andrew Vasquez064135e2015-04-09 15:00:02 -04003391 if (IS_QLA2031(vha->hw))
3392 *data = mcp->mb[1] & 0xff;
3393 else
3394 *data = mcp->mb[1];
Joe Carnucciodb64e932013-10-30 03:38:18 -04003395
3396 if (rval != QLA_SUCCESS) {
3397 ql_dbg(ql_dbg_mbx, vha, 0x1186,
3398 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3399 } else {
3400 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187,
3401 "Done %s.\n", __func__);
3402 }
3403
3404 return rval;
3405}
3406
Joe Carnuccioe8887c52014-04-11 16:54:17 -04003407int
3408qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)
3409{
3410 int rval;
3411 mbx_cmd_t mc;
3412 mbx_cmd_t *mcp = &mc;
3413
3414 if (!IS_QLA8044(vha->hw))
3415 return QLA_FUNCTION_FAILED;
3416
Quinn Tran83548fe2017-06-02 09:12:01 -07003417 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x11a0,
Joe Carnuccioe8887c52014-04-11 16:54:17 -04003418 "Entered %s.\n", __func__);
3419
3420 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3421 mcp->mb[1] = HCS_WRITE_SERDES;
3422 mcp->mb[3] = LSW(addr);
3423 mcp->mb[4] = MSW(addr);
3424 mcp->mb[5] = LSW(data);
3425 mcp->mb[6] = MSW(data);
3426 mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
3427 mcp->in_mb = MBX_0;
3428 mcp->tov = MBX_TOV_SECONDS;
3429 mcp->flags = 0;
3430 rval = qla2x00_mailbox_command(vha, mcp);
3431
3432 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07003433 ql_dbg(ql_dbg_mbx, vha, 0x11a1,
Joe Carnuccioe8887c52014-04-11 16:54:17 -04003434 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3435 } else {
3436 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188,
3437 "Done %s.\n", __func__);
3438 }
3439
3440 return rval;
3441}
3442
3443int
3444qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
3445{
3446 int rval;
3447 mbx_cmd_t mc;
3448 mbx_cmd_t *mcp = &mc;
3449
3450 if (!IS_QLA8044(vha->hw))
3451 return QLA_FUNCTION_FAILED;
3452
3453 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189,
3454 "Entered %s.\n", __func__);
3455
3456 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
3457 mcp->mb[1] = HCS_READ_SERDES;
3458 mcp->mb[3] = LSW(addr);
3459 mcp->mb[4] = MSW(addr);
3460 mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0;
3461 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3462 mcp->tov = MBX_TOV_SECONDS;
3463 mcp->flags = 0;
3464 rval = qla2x00_mailbox_command(vha, mcp);
3465
3466 *data = mcp->mb[2] << 16 | mcp->mb[1];
3467
3468 if (rval != QLA_SUCCESS) {
3469 ql_dbg(ql_dbg_mbx, vha, 0x118a,
3470 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3471 } else {
3472 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b,
3473 "Done %s.\n", __func__);
3474 }
3475
3476 return rval;
3477}
3478
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003479/**
3480 * qla2x00_set_serdes_params() -
Bart Van Assche2db62282018-01-23 16:33:51 -08003481 * @vha: HA context
3482 * @sw_em_1g:
3483 * @sw_em_2g:
3484 * @sw_em_4g:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003485 *
3486 * Returns
3487 */
3488int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003489qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003490 uint16_t sw_em_2g, uint16_t sw_em_4g)
3491{
3492 int rval;
3493 mbx_cmd_t mc;
3494 mbx_cmd_t *mcp = &mc;
3495
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003496 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e,
3497 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003498
3499 mcp->mb[0] = MBC_SERDES_PARAMS;
3500 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08003501 mcp->mb[2] = sw_em_1g | BIT_15;
3502 mcp->mb[3] = sw_em_2g | BIT_15;
3503 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003504 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3505 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003506 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003507 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003508 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003509
3510 if (rval != QLA_SUCCESS) {
3511 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003512 ql_dbg(ql_dbg_mbx, vha, 0x109f,
3513 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003514 } else {
3515 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003516 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0,
3517 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003518 }
3519
3520 return rval;
3521}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003522
3523int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003524qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003525{
3526 int rval;
3527 mbx_cmd_t mc;
3528 mbx_cmd_t *mcp = &mc;
3529
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003530 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003531 return QLA_FUNCTION_FAILED;
3532
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003533 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1,
3534 "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003535
3536 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08003537 mcp->mb[1] = 0;
3538 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003539 mcp->in_mb = MBX_0;
3540 mcp->tov = 5;
3541 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003542 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003543
3544 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003545 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07003546 if (mcp->mb[0] == MBS_INVALID_COMMAND)
3547 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003548 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003549 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3,
3550 "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003551 }
3552
3553 return rval;
3554}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003555
3556int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003557qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003558 uint16_t buffers)
3559{
3560 int rval;
3561 mbx_cmd_t mc;
3562 mbx_cmd_t *mcp = &mc;
3563
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003564 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4,
3565 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003566
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003567 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003568 return QLA_FUNCTION_FAILED;
3569
Andrew Vasquez85880802009-12-15 21:29:46 -08003570 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3571 return QLA_FUNCTION_FAILED;
3572
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003573 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003574 mcp->mb[1] = TC_EFT_ENABLE;
3575 mcp->mb[2] = LSW(eft_dma);
3576 mcp->mb[3] = MSW(eft_dma);
3577 mcp->mb[4] = LSW(MSD(eft_dma));
3578 mcp->mb[5] = MSW(MSD(eft_dma));
3579 mcp->mb[6] = buffers;
3580 mcp->mb[7] = TC_AEN_DISABLE;
3581 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 -07003582 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003583 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003584 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003585 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003586 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003587 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
3588 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3589 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003590 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003591 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6,
3592 "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003593 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003594
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003595 return rval;
3596}
3597
3598int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003599qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003600{
3601 int rval;
3602 mbx_cmd_t mc;
3603 mbx_cmd_t *mcp = &mc;
3604
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003605 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7,
3606 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003607
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003608 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003609 return QLA_FUNCTION_FAILED;
3610
Andrew Vasquez85880802009-12-15 21:29:46 -08003611 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3612 return QLA_FUNCTION_FAILED;
3613
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003614 mcp->mb[0] = MBC_TRACE_CONTROL;
3615 mcp->mb[1] = TC_EFT_DISABLE;
3616 mcp->out_mb = MBX_1|MBX_0;
3617 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003618 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003619 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003620 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003621 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003622 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
3623 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3624 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003625 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003626 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9,
3627 "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003628 }
3629
3630 return rval;
3631}
3632
Andrew Vasquez88729e52006-06-23 16:10:50 -07003633int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003634qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003635 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
3636{
3637 int rval;
3638 mbx_cmd_t mc;
3639 mbx_cmd_t *mcp = &mc;
3640
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003641 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa,
3642 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003643
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003644 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
Chad Dupuisf73cb692014-02-26 04:15:06 -05003645 !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003646 return QLA_FUNCTION_FAILED;
3647
Andrew Vasquez85880802009-12-15 21:29:46 -08003648 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3649 return QLA_FUNCTION_FAILED;
3650
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003651 mcp->mb[0] = MBC_TRACE_CONTROL;
3652 mcp->mb[1] = TC_FCE_ENABLE;
3653 mcp->mb[2] = LSW(fce_dma);
3654 mcp->mb[3] = MSW(fce_dma);
3655 mcp->mb[4] = LSW(MSD(fce_dma));
3656 mcp->mb[5] = MSW(MSD(fce_dma));
3657 mcp->mb[6] = buffers;
3658 mcp->mb[7] = TC_AEN_DISABLE;
3659 mcp->mb[8] = 0;
3660 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
3661 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
3662 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3663 MBX_1|MBX_0;
3664 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003665 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003666 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003667 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003668 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003669 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
3670 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3671 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003672 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003673 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac,
3674 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003675
3676 if (mb)
3677 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
3678 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07003679 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003680 }
3681
3682 return rval;
3683}
3684
3685int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003686qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003687{
3688 int rval;
3689 mbx_cmd_t mc;
3690 mbx_cmd_t *mcp = &mc;
3691
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003692 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad,
3693 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003694
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003695 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003696 return QLA_FUNCTION_FAILED;
3697
Andrew Vasquez85880802009-12-15 21:29:46 -08003698 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3699 return QLA_FUNCTION_FAILED;
3700
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003701 mcp->mb[0] = MBC_TRACE_CONTROL;
3702 mcp->mb[1] = TC_FCE_DISABLE;
3703 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
3704 mcp->out_mb = MBX_2|MBX_1|MBX_0;
3705 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3706 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003707 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003708 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003709 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003710 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003711 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
3712 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3713 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003714 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003715 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af,
3716 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003717
3718 if (wr)
3719 *wr = (uint64_t) mcp->mb[5] << 48 |
3720 (uint64_t) mcp->mb[4] << 32 |
3721 (uint64_t) mcp->mb[3] << 16 |
3722 (uint64_t) mcp->mb[2];
3723 if (rd)
3724 *rd = (uint64_t) mcp->mb[9] << 48 |
3725 (uint64_t) mcp->mb[8] << 32 |
3726 (uint64_t) mcp->mb[7] << 16 |
3727 (uint64_t) mcp->mb[6];
3728 }
3729
3730 return rval;
3731}
3732
3733int
Giridhar Malavali6e980162010-03-19 17:03:58 -07003734qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
3735 uint16_t *port_speed, uint16_t *mb)
3736{
3737 int rval;
3738 mbx_cmd_t mc;
3739 mbx_cmd_t *mcp = &mc;
3740
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003741 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0,
3742 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003743
Giridhar Malavali6e980162010-03-19 17:03:58 -07003744 if (!IS_IIDMA_CAPABLE(vha->hw))
3745 return QLA_FUNCTION_FAILED;
3746
Giridhar Malavali6e980162010-03-19 17:03:58 -07003747 mcp->mb[0] = MBC_PORT_PARAMS;
3748 mcp->mb[1] = loop_id;
3749 mcp->mb[2] = mcp->mb[3] = 0;
3750 mcp->mb[9] = vha->vp_idx;
3751 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3752 mcp->in_mb = MBX_3|MBX_1|MBX_0;
3753 mcp->tov = MBX_TOV_SECONDS;
3754 mcp->flags = 0;
3755 rval = qla2x00_mailbox_command(vha, mcp);
3756
3757 /* Return mailbox statuses. */
3758 if (mb != NULL) {
3759 mb[0] = mcp->mb[0];
3760 mb[1] = mcp->mb[1];
3761 mb[3] = mcp->mb[3];
3762 }
3763
3764 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003765 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003766 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003767 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2,
3768 "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003769 if (port_speed)
3770 *port_speed = mcp->mb[3];
3771 }
3772
3773 return rval;
3774}
3775
3776int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003777qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003778 uint16_t port_speed, uint16_t *mb)
3779{
3780 int rval;
3781 mbx_cmd_t mc;
3782 mbx_cmd_t *mcp = &mc;
3783
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003784 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3,
3785 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003786
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003787 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003788 return QLA_FUNCTION_FAILED;
3789
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003790 mcp->mb[0] = MBC_PORT_PARAMS;
3791 mcp->mb[1] = loop_id;
3792 mcp->mb[2] = BIT_0;
Himanshu Madhani4c1458d2018-08-31 11:24:27 -07003793 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07003794 mcp->mb[9] = vha->vp_idx;
3795 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3796 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003797 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003798 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003799 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003800
3801 /* Return mailbox statuses. */
3802 if (mb != NULL) {
3803 mb[0] = mcp->mb[0];
3804 mb[1] = mcp->mb[1];
3805 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003806 }
3807
3808 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003809 ql_dbg(ql_dbg_mbx, vha, 0x10b4,
3810 "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003811 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003812 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5,
3813 "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003814 }
3815
3816 return rval;
3817}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003818
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003819void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003820qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003821 struct vp_rpt_id_entry_24xx *rptid_entry)
3822{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003823 struct qla_hw_data *ha = vha->hw;
Quinn Tran41dc5292017-01-19 22:28:03 -08003824 scsi_qla_host_t *vp = NULL;
Arun Easifeafb7b2010-09-03 14:57:00 -07003825 unsigned long flags;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003826 int found;
Quinn Tran482c9dc2017-03-15 09:48:54 -07003827 port_id_t id;
Quinn Tran9cd883f2017-12-28 12:33:24 -08003828 struct fc_port *fcport;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003829
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003830 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
3831 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003832
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003833 if (rptid_entry->entry_status != 0)
3834 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003835
Quinn Tran482c9dc2017-03-15 09:48:54 -07003836 id.b.domain = rptid_entry->port_id[2];
3837 id.b.area = rptid_entry->port_id[1];
3838 id.b.al_pa = rptid_entry->port_id[0];
3839 id.b.rsvd_1 = 0;
Darren Trapp1763c1f2018-03-20 23:09:34 -07003840 ha->flags.n2n_ae = 0;
Quinn Tran482c9dc2017-03-15 09:48:54 -07003841
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003842 if (rptid_entry->format == 0) {
Quinn Tran41dc5292017-01-19 22:28:03 -08003843 /* loop */
Quinn Tranec7193e2017-03-15 09:48:55 -07003844 ql_dbg(ql_dbg_async, vha, 0x10b7,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003845 "Format 0 : Number of VPs setup %d, number of "
Quinn Tran41dc5292017-01-19 22:28:03 -08003846 "VPs acquired %d.\n", rptid_entry->vp_setup,
3847 rptid_entry->vp_acquired);
Quinn Tranec7193e2017-03-15 09:48:55 -07003848 ql_dbg(ql_dbg_async, vha, 0x10b8,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003849 "Primary port id %02x%02x%02x.\n",
3850 rptid_entry->port_id[2], rptid_entry->port_id[1],
3851 rptid_entry->port_id[0]);
Quinn Tran9cd883f2017-12-28 12:33:24 -08003852 ha->current_topology = ISP_CFG_NL;
Quinn Tran482c9dc2017-03-15 09:48:54 -07003853 qlt_update_host_map(vha, id);
Quinn Tran41dc5292017-01-19 22:28:03 -08003854
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003855 } else if (rptid_entry->format == 1) {
Quinn Tran41dc5292017-01-19 22:28:03 -08003856 /* fabric */
Quinn Tranec7193e2017-03-15 09:48:55 -07003857 ql_dbg(ql_dbg_async, vha, 0x10b9,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003858 "Format 1: VP[%d] enabled - status %d - with "
Quinn Tran41dc5292017-01-19 22:28:03 -08003859 "port id %02x%02x%02x.\n", rptid_entry->vp_idx,
3860 rptid_entry->vp_status,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003861 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003862 rptid_entry->port_id[0]);
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003863 ql_dbg(ql_dbg_async, vha, 0x5075,
3864 "Format 1: Remote WWPN %8phC.\n",
3865 rptid_entry->u.f1.port_name);
3866
3867 ql_dbg(ql_dbg_async, vha, 0x5075,
3868 "Format 1: WWPN %8phC.\n",
3869 vha->port_name);
3870
Quinn Tran8777e432018-08-02 13:16:57 -07003871 switch (rptid_entry->u.f1.flags & TOPO_MASK) {
3872 case TOPO_N2N:
3873 ha->current_topology = ISP_CFG_N;
3874 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
3875 fcport = qla2x00_find_fcport_by_wwpn(vha,
3876 rptid_entry->u.f1.port_name, 1);
3877 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
3878
3879 if (fcport) {
3880 fcport->plogi_nack_done_deadline = jiffies + HZ;
3881 fcport->dm_login_expire = jiffies + 3*HZ;
3882 fcport->scan_state = QLA_FCPORT_FOUND;
3883 switch (fcport->disc_state) {
3884 case DSC_DELETED:
3885 set_bit(RELOGIN_NEEDED,
3886 &vha->dpc_flags);
3887 break;
3888 case DSC_DELETE_PEND:
3889 break;
3890 default:
3891 qlt_schedule_sess_for_deletion(fcport);
3892 break;
3893 }
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003894 } else {
Quinn Tran8777e432018-08-02 13:16:57 -07003895 id.b24 = 0;
3896 if (wwn_to_u64(vha->port_name) >
3897 wwn_to_u64(rptid_entry->u.f1.port_name)) {
3898 vha->d_id.b24 = 0;
3899 vha->d_id.b.al_pa = 1;
3900 ha->flags.n2n_bigger = 1;
3901
3902 id.b.al_pa = 2;
3903 ql_dbg(ql_dbg_async, vha, 0x5075,
3904 "Format 1: assign local id %x remote id %x\n",
3905 vha->d_id.b24, id.b24);
3906 } else {
3907 ql_dbg(ql_dbg_async, vha, 0x5075,
3908 "Format 1: Remote login - Waiting for WWPN %8phC.\n",
3909 rptid_entry->u.f1.port_name);
3910 ha->flags.n2n_bigger = 0;
3911 }
3912 qla24xx_post_newsess_work(vha, &id,
3913 rptid_entry->u.f1.port_name,
3914 rptid_entry->u.f1.node_name,
3915 NULL,
3916 FC4_TYPE_UNKNOWN);
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003917 }
3918
Quinn Tran8777e432018-08-02 13:16:57 -07003919 /* if our portname is higher then initiate N2N login */
3920
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003921 set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags);
Darren Trapp1763c1f2018-03-20 23:09:34 -07003922 ha->flags.n2n_ae = 1;
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003923 return;
Quinn Tran8777e432018-08-02 13:16:57 -07003924 break;
3925 case TOPO_FL:
3926 ha->current_topology = ISP_CFG_FL;
3927 break;
3928 case TOPO_F:
3929 ha->current_topology = ISP_CFG_F;
3930 break;
3931 default:
3932 break;
Duane Grigsbyedd05de2017-10-13 09:34:06 -07003933 }
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003934
Quinn Tran9cd883f2017-12-28 12:33:24 -08003935 ha->flags.gpsc_supported = 1;
3936 ha->current_topology = ISP_CFG_F;
Sawan Chandak969a6192016-01-27 12:03:32 -05003937 /* buffer to buffer credit flag */
Quinn Tran41dc5292017-01-19 22:28:03 -08003938 vha->flags.bbcr_enable = (rptid_entry->u.f1.bbcr & 0xf) != 0;
Sawan Chandak969a6192016-01-27 12:03:32 -05003939
Quinn Tran41dc5292017-01-19 22:28:03 -08003940 if (rptid_entry->vp_idx == 0) {
3941 if (rptid_entry->vp_status == VP_STAT_COMPL) {
3942 /* FA-WWN is only for physical port */
3943 if (qla_ini_mode_enabled(vha) &&
3944 ha->flags.fawwpn_enabled &&
3945 (rptid_entry->u.f1.flags &
Sawan Chandakfcc5b5c2017-08-23 15:05:02 -07003946 BIT_6)) {
Quinn Tran41dc5292017-01-19 22:28:03 -08003947 memcpy(vha->port_name,
3948 rptid_entry->u.f1.port_name,
3949 WWN_SIZE);
3950 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04003951
Quinn Tran482c9dc2017-03-15 09:48:54 -07003952 qlt_update_host_map(vha, id);
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04003953 }
Quinn Tran41dc5292017-01-19 22:28:03 -08003954
Quinn Tran41dc5292017-01-19 22:28:03 -08003955 set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
3956 set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
3957 } else {
3958 if (rptid_entry->vp_status != VP_STAT_COMPL &&
3959 rptid_entry->vp_status != VP_STAT_ID_CHG) {
3960 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
3961 "Could not acquire ID for VP[%d].\n",
3962 rptid_entry->vp_idx);
3963 return;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003964 }
Quinn Tran41dc5292017-01-19 22:28:03 -08003965
3966 found = 0;
3967 spin_lock_irqsave(&ha->vport_slock, flags);
3968 list_for_each_entry(vp, &ha->vp_list, list) {
3969 if (rptid_entry->vp_idx == vp->vp_idx) {
3970 found = 1;
3971 break;
3972 }
3973 }
3974 spin_unlock_irqrestore(&ha->vport_slock, flags);
3975
3976 if (!found)
3977 return;
3978
Quinn Tran482c9dc2017-03-15 09:48:54 -07003979 qlt_update_host_map(vp, id);
Quinn Tran41dc5292017-01-19 22:28:03 -08003980
3981 /*
3982 * Cannot configure here as we are still sitting on the
3983 * response queue. Handle it in dpc context.
3984 */
3985 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
3986 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
3987 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003988 }
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003989 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003990 qla2xxx_wake_dpc(vha);
Quinn Tran41dc5292017-01-19 22:28:03 -08003991 } else if (rptid_entry->format == 2) {
Quinn Tran83548fe2017-06-02 09:12:01 -07003992 ql_dbg(ql_dbg_async, vha, 0x505f,
Quinn Tran41dc5292017-01-19 22:28:03 -08003993 "RIDA: format 2/N2N Primary port id %02x%02x%02x.\n",
3994 rptid_entry->port_id[2], rptid_entry->port_id[1],
3995 rptid_entry->port_id[0]);
3996
Quinn Tran83548fe2017-06-02 09:12:01 -07003997 ql_dbg(ql_dbg_async, vha, 0x5075,
Quinn Tran41dc5292017-01-19 22:28:03 -08003998 "N2N: Remote WWPN %8phC.\n",
3999 rptid_entry->u.f2.port_name);
4000
4001 /* N2N. direct connect */
Quinn Tran9cd883f2017-12-28 12:33:24 -08004002 ha->current_topology = ISP_CFG_N;
4003 ha->flags.rida_fmt2 = 1;
Quinn Tran41dc5292017-01-19 22:28:03 -08004004 vha->d_id.b.domain = rptid_entry->port_id[2];
4005 vha->d_id.b.area = rptid_entry->port_id[1];
4006 vha->d_id.b.al_pa = rptid_entry->port_id[0];
4007
Darren Trapp1763c1f2018-03-20 23:09:34 -07004008 ha->flags.n2n_ae = 1;
Quinn Tran41dc5292017-01-19 22:28:03 -08004009 spin_lock_irqsave(&ha->vport_slock, flags);
4010 qlt_update_vp_map(vha, SET_AL_PA);
4011 spin_unlock_irqrestore(&ha->vport_slock, flags);
Quinn Tran9cd883f2017-12-28 12:33:24 -08004012
4013 list_for_each_entry(fcport, &vha->vp_fcports, list) {
4014 fcport->scan_state = QLA_FCPORT_SCAN;
4015 }
4016
4017 fcport = qla2x00_find_fcport_by_wwpn(vha,
4018 rptid_entry->u.f2.port_name, 1);
4019
4020 if (fcport) {
Quinn Tran23dd98a2018-08-02 13:16:45 -07004021 fcport->login_retry = vha->hw->login_retry_count;
Quinn Tran9cd883f2017-12-28 12:33:24 -08004022 fcport->plogi_nack_done_deadline = jiffies + HZ;
4023 fcport->scan_state = QLA_FCPORT_FOUND;
Quinn Tran9cd883f2017-12-28 12:33:24 -08004024 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004025 }
4026}
4027
4028/*
4029 * qla24xx_modify_vp_config
4030 * Change VP configuration for vha
4031 *
4032 * Input:
4033 * vha = adapter block pointer.
4034 *
4035 * Returns:
4036 * qla2xxx local function return status code.
4037 *
4038 * Context:
4039 * Kernel context.
4040 */
4041int
4042qla24xx_modify_vp_config(scsi_qla_host_t *vha)
4043{
4044 int rval;
4045 struct vp_config_entry_24xx *vpmod;
4046 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004047 struct qla_hw_data *ha = vha->hw;
4048 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004049
4050 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004051
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004052 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb,
4053 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004054
Thomas Meyer08eb7f42017-09-21 08:15:26 +02004055 vpmod = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004056 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004057 ql_log(ql_log_warn, vha, 0x10bc,
4058 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004059 return QLA_MEMORY_ALLOC_FAILED;
4060 }
4061
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004062 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
4063 vpmod->entry_count = 1;
4064 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
4065 vpmod->vp_count = 1;
4066 vpmod->vp_index1 = vha->vp_idx;
4067 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04004068
4069 qlt_modify_vp_config(vha, vpmod);
4070
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004071 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
4072 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
4073 vpmod->entry_count = 1;
4074
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004075 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004076 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004077 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
4078 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004079 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004080 ql_dbg(ql_dbg_mbx, vha, 0x10be,
4081 "Failed to complete IOCB -- error status (%x).\n",
4082 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004083 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07004084 } else if (vpmod->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004085 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
4086 "Failed to complete IOCB -- completion status (%x).\n",
4087 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004088 rval = QLA_FUNCTION_FAILED;
4089 } else {
4090 /* EMPTY */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004091 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0,
4092 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004093 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
4094 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004095 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004096
4097 return rval;
4098}
4099
4100/*
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004101 * qla2x00_send_change_request
4102 * Receive or disable RSCN request from fabric controller
4103 *
4104 * Input:
4105 * ha = adapter block pointer
4106 * format = registration format:
4107 * 0 - Reserved
4108 * 1 - Fabric detected registration
4109 * 2 - N_port detected registration
4110 * 3 - Full registration
4111 * FF - clear registration
4112 * vp_idx = Virtual port index
4113 *
4114 * Returns:
4115 * qla2x00 local function return status code.
4116 *
4117 * Context:
4118 * Kernel Context
4119 */
4120
4121int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004122qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004123 uint16_t vp_idx)
4124{
4125 int rval;
4126 mbx_cmd_t mc;
4127 mbx_cmd_t *mcp = &mc;
4128
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004129 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7,
4130 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004131
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004132 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
4133 mcp->mb[1] = format;
4134 mcp->mb[9] = vp_idx;
4135 mcp->out_mb = MBX_9|MBX_1|MBX_0;
4136 mcp->in_mb = MBX_0|MBX_1;
4137 mcp->tov = MBX_TOV_SECONDS;
4138 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004139 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07004140
4141 if (rval == QLA_SUCCESS) {
4142 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
4143 rval = BIT_1;
4144 }
4145 } else
4146 rval = BIT_1;
4147
4148 return rval;
4149}
Andrew Vasquez338c9162007-09-20 14:07:33 -07004150
4151int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004152qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07004153 uint32_t size)
4154{
4155 int rval;
4156 mbx_cmd_t mc;
4157 mbx_cmd_t *mcp = &mc;
4158
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004159 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009,
4160 "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004161
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004162 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07004163 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
4164 mcp->mb[8] = MSW(addr);
4165 mcp->out_mb = MBX_8|MBX_0;
4166 } else {
4167 mcp->mb[0] = MBC_DUMP_RISC_RAM;
4168 mcp->out_mb = MBX_0;
4169 }
4170 mcp->mb[1] = LSW(addr);
4171 mcp->mb[2] = MSW(req_dma);
4172 mcp->mb[3] = LSW(req_dma);
4173 mcp->mb[6] = MSW(MSD(req_dma));
4174 mcp->mb[7] = LSW(MSD(req_dma));
4175 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004176 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07004177 mcp->mb[4] = MSW(size);
4178 mcp->mb[5] = LSW(size);
4179 mcp->out_mb |= MBX_5|MBX_4;
4180 } else {
4181 mcp->mb[4] = LSW(size);
4182 mcp->out_mb |= MBX_4;
4183 }
4184
4185 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07004186 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07004187 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004188 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004189
4190 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004191 ql_dbg(ql_dbg_mbx, vha, 0x1008,
4192 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004193 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004194 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007,
4195 "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07004196 }
4197
4198 return rval;
4199}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004200/* 84XX Support **************************************************************/
4201
4202struct cs84xx_mgmt_cmd {
4203 union {
4204 struct verify_chip_entry_84xx req;
4205 struct verify_chip_rsp_84xx rsp;
4206 } p;
4207};
4208
4209int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004210qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004211{
4212 int rval, retry;
4213 struct cs84xx_mgmt_cmd *mn;
4214 dma_addr_t mn_dma;
4215 uint16_t options;
4216 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004217 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004218
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004219 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8,
4220 "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004221
4222 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
4223 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004224 return QLA_MEMORY_ALLOC_FAILED;
4225 }
4226
4227 /* Force Update? */
4228 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
4229 /* Diagnostic firmware? */
4230 /* options |= MENLO_DIAG_FW; */
4231 /* We update the firmware with only one data sequence. */
4232 options |= VCO_END_OF_DATA;
4233
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004234 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07004235 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004236 memset(mn, 0, sizeof(*mn));
4237 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
4238 mn->p.req.entry_count = 1;
4239 mn->p.req.options = cpu_to_le16(options);
4240
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004241 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
4242 "Dump of Verify Request.\n");
4243 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
4244 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004245
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08004246 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004247 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004248 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
4249 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004250 goto verify_done;
4251 }
4252
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004253 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
4254 "Dump of Verify Response.\n");
4255 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
4256 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004257
4258 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
4259 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
4260 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004261 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004262 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004263
4264 if (status[0] != CS_COMPLETE) {
4265 rval = QLA_FUNCTION_FAILED;
4266 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004267 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
4268 "Firmware update failed. Retrying "
4269 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004270 options |= VCO_DONT_UPDATE_FW;
4271 options &= ~VCO_FORCE_UPDATE;
4272 retry = 1;
4273 }
4274 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004275 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004276 "Firmware updated to %x.\n",
4277 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004278
4279 /* NOTE: we only update OP firmware. */
4280 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
4281 ha->cs84xx->op_fw_version =
4282 le32_to_cpu(mn->p.rsp.fw_ver);
4283 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
4284 flags);
4285 }
4286 } while (retry);
4287
4288verify_done:
4289 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
4290
4291 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004292 ql_dbg(ql_dbg_mbx, vha, 0x10d1,
4293 "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004294 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004295 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2,
4296 "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07004297 }
4298
4299 return rval;
4300}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004301
4302int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004303qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004304{
4305 int rval;
4306 unsigned long flags;
4307 mbx_cmd_t mc;
4308 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004309 struct qla_hw_data *ha = vha->hw;
4310
Quinn Tran45235022018-07-18 14:29:53 -07004311 if (!ha->flags.fw_started)
4312 return QLA_SUCCESS;
4313
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004314 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
4315 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004316
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004317 if (IS_SHADOW_REG_CAPABLE(ha))
4318 req->options |= BIT_13;
4319
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004320 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004321 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004322 mcp->mb[2] = MSW(LSD(req->dma));
4323 mcp->mb[3] = LSW(LSD(req->dma));
4324 mcp->mb[6] = MSW(MSD(req->dma));
4325 mcp->mb[7] = LSW(MSD(req->dma));
4326 mcp->mb[5] = req->length;
4327 if (req->rsp)
4328 mcp->mb[10] = req->rsp->id;
4329 mcp->mb[12] = req->qos;
4330 mcp->mb[11] = req->vp_idx;
4331 mcp->mb[13] = req->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004332 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004333 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004334
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004335 mcp->mb[4] = req->id;
4336 /* que in ptr index */
4337 mcp->mb[8] = 0;
4338 /* que out ptr index */
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004339 mcp->mb[9] = *req->out_ptr = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004340 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
4341 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4342 mcp->in_mb = MBX_0;
4343 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004344 mcp->tov = MBX_TOV_SECONDS * 2;
4345
Chad Dupuisf73cb692014-02-26 04:15:06 -05004346 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004347 mcp->in_mb |= MBX_1;
Joe Carnuccioba4828b2014-04-11 16:54:10 -04004348 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004349 mcp->out_mb |= MBX_15;
4350 /* debug q create issue in SR-IOV */
4351 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
4352 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004353
4354 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004355 if (!(req->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004356 WRT_REG_DWORD(req->req_q_in, 0);
Joe Carnuccio29db41c2014-04-11 16:54:09 -04004357 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004358 WRT_REG_DWORD(req->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004359 }
4360 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4361
Anirban Chakraborty17d98632008-12-18 10:06:15 -08004362 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004363 if (rval != QLA_SUCCESS) {
4364 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
4365 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4366 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004367 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5,
4368 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004369 }
4370
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004371 return rval;
4372}
4373
4374int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004375qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004376{
4377 int rval;
4378 unsigned long flags;
4379 mbx_cmd_t mc;
4380 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004381 struct qla_hw_data *ha = vha->hw;
4382
Quinn Tran45235022018-07-18 14:29:53 -07004383 if (!ha->flags.fw_started)
4384 return QLA_SUCCESS;
4385
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004386 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
4387 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004388
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004389 if (IS_SHADOW_REG_CAPABLE(ha))
4390 rsp->options |= BIT_13;
4391
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004392 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004393 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004394 mcp->mb[2] = MSW(LSD(rsp->dma));
4395 mcp->mb[3] = LSW(LSD(rsp->dma));
4396 mcp->mb[6] = MSW(MSD(rsp->dma));
4397 mcp->mb[7] = LSW(MSD(rsp->dma));
4398 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08004399 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004400 mcp->mb[13] = rsp->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004401 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004402 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004403
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004404 mcp->mb[4] = rsp->id;
4405 /* que in ptr index */
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04004406 mcp->mb[8] = *rsp->in_ptr = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004407 /* que out ptr index */
4408 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07004409 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004410 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4411 mcp->in_mb = MBX_0;
4412 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004413 mcp->tov = MBX_TOV_SECONDS * 2;
4414
4415 if (IS_QLA81XX(ha)) {
4416 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
4417 mcp->in_mb |= MBX_1;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004418 } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004419 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
4420 mcp->in_mb |= MBX_1;
4421 /* debug q create issue in SR-IOV */
4422 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
4423 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004424
4425 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08004426 if (!(rsp->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004427 WRT_REG_DWORD(rsp->rsp_q_out, 0);
Himanshu Madhanib20f02e2015-06-10 11:05:18 -04004428 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04004429 WRT_REG_DWORD(rsp->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004430 }
4431
4432 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4433
Anirban Chakraborty17d98632008-12-18 10:06:15 -08004434 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004435 if (rval != QLA_SUCCESS) {
4436 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
4437 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4438 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004439 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8,
4440 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004441 }
4442
Anirban Chakraborty73208df2008-12-09 16:45:39 -08004443 return rval;
4444}
4445
Andrew Vasquez8a659572009-02-08 20:50:12 -08004446int
4447qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
4448{
4449 int rval;
4450 mbx_cmd_t mc;
4451 mbx_cmd_t *mcp = &mc;
4452
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004453 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9,
4454 "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004455
4456 mcp->mb[0] = MBC_IDC_ACK;
4457 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
4458 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4459 mcp->in_mb = MBX_0;
4460 mcp->tov = MBX_TOV_SECONDS;
4461 mcp->flags = 0;
4462 rval = qla2x00_mailbox_command(vha, mcp);
4463
4464 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004465 ql_dbg(ql_dbg_mbx, vha, 0x10da,
4466 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004467 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004468 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db,
4469 "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08004470 }
4471
4472 return rval;
4473}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004474
4475int
4476qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
4477{
4478 int rval;
4479 mbx_cmd_t mc;
4480 mbx_cmd_t *mcp = &mc;
4481
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004482 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc,
4483 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004484
Chad Dupuisf73cb692014-02-26 04:15:06 -05004485 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4486 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004487 return QLA_FUNCTION_FAILED;
4488
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004489 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4490 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
4491 mcp->out_mb = MBX_1|MBX_0;
4492 mcp->in_mb = MBX_1|MBX_0;
4493 mcp->tov = MBX_TOV_SECONDS;
4494 mcp->flags = 0;
4495 rval = qla2x00_mailbox_command(vha, mcp);
4496
4497 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004498 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
4499 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4500 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004501 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004502 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de,
4503 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004504 *sector_size = mcp->mb[1];
4505 }
4506
4507 return rval;
4508}
4509
4510int
4511qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
4512{
4513 int rval;
4514 mbx_cmd_t mc;
4515 mbx_cmd_t *mcp = &mc;
4516
Chad Dupuisf73cb692014-02-26 04:15:06 -05004517 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4518 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004519 return QLA_FUNCTION_FAILED;
4520
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004521 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df,
4522 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004523
4524 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4525 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
4526 FAC_OPT_CMD_WRITE_PROTECT;
4527 mcp->out_mb = MBX_1|MBX_0;
4528 mcp->in_mb = MBX_1|MBX_0;
4529 mcp->tov = MBX_TOV_SECONDS;
4530 mcp->flags = 0;
4531 rval = qla2x00_mailbox_command(vha, mcp);
4532
4533 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004534 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
4535 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4536 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004537 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004538 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1,
4539 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004540 }
4541
4542 return rval;
4543}
4544
4545int
4546qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
4547{
4548 int rval;
4549 mbx_cmd_t mc;
4550 mbx_cmd_t *mcp = &mc;
4551
Chad Dupuisf73cb692014-02-26 04:15:06 -05004552 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4553 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004554 return QLA_FUNCTION_FAILED;
4555
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004556 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,
4557 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004558
4559 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4560 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
4561 mcp->mb[2] = LSW(start);
4562 mcp->mb[3] = MSW(start);
4563 mcp->mb[4] = LSW(finish);
4564 mcp->mb[5] = MSW(finish);
4565 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4566 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4567 mcp->tov = MBX_TOV_SECONDS;
4568 mcp->flags = 0;
4569 rval = qla2x00_mailbox_command(vha, mcp);
4570
4571 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004572 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
4573 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4574 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004575 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004576 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,
4577 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004578 }
4579
4580 return rval;
4581}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004582
4583int
4584qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
4585{
4586 int rval = 0;
4587 mbx_cmd_t mc;
4588 mbx_cmd_t *mcp = &mc;
4589
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004590 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5,
4591 "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004592
4593 mcp->mb[0] = MBC_RESTART_MPI_FW;
4594 mcp->out_mb = MBX_0;
4595 mcp->in_mb = MBX_0|MBX_1;
4596 mcp->tov = MBX_TOV_SECONDS;
4597 mcp->flags = 0;
4598 rval = qla2x00_mailbox_command(vha, mcp);
4599
4600 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004601 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
4602 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4603 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004604 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004605 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7,
4606 "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004607 }
4608
4609 return rval;
4610}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004611
Joe Carnuccioc46e65c2013-08-27 01:37:35 -04004612int
4613qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4614{
4615 int rval;
4616 mbx_cmd_t mc;
4617 mbx_cmd_t *mcp = &mc;
4618 int i;
4619 int len;
4620 uint16_t *str;
4621 struct qla_hw_data *ha = vha->hw;
4622
4623 if (!IS_P3P_TYPE(ha))
4624 return QLA_FUNCTION_FAILED;
4625
4626 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b,
4627 "Entered %s.\n", __func__);
4628
4629 str = (void *)version;
4630 len = strlen(version);
4631
4632 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4633 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8;
4634 mcp->out_mb = MBX_1|MBX_0;
4635 for (i = 4; i < 16 && len; i++, str++, len -= 2) {
4636 mcp->mb[i] = cpu_to_le16p(str);
4637 mcp->out_mb |= 1<<i;
4638 }
4639 for (; i < 16; i++) {
4640 mcp->mb[i] = 0;
4641 mcp->out_mb |= 1<<i;
4642 }
4643 mcp->in_mb = MBX_1|MBX_0;
4644 mcp->tov = MBX_TOV_SECONDS;
4645 mcp->flags = 0;
4646 rval = qla2x00_mailbox_command(vha, mcp);
4647
4648 if (rval != QLA_SUCCESS) {
4649 ql_dbg(ql_dbg_mbx, vha, 0x117c,
4650 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4651 } else {
4652 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d,
4653 "Done %s.\n", __func__);
4654 }
4655
4656 return rval;
4657}
4658
4659int
4660qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4661{
4662 int rval;
4663 mbx_cmd_t mc;
4664 mbx_cmd_t *mcp = &mc;
4665 int len;
4666 uint16_t dwlen;
4667 uint8_t *str;
4668 dma_addr_t str_dma;
4669 struct qla_hw_data *ha = vha->hw;
4670
4671 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) ||
4672 IS_P3P_TYPE(ha))
4673 return QLA_FUNCTION_FAILED;
4674
4675 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e,
4676 "Entered %s.\n", __func__);
4677
4678 str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);
4679 if (!str) {
4680 ql_log(ql_log_warn, vha, 0x117f,
4681 "Failed to allocate driver version param.\n");
4682 return QLA_MEMORY_ALLOC_FAILED;
4683 }
4684
4685 memcpy(str, "\x7\x3\x11\x0", 4);
4686 dwlen = str[0];
4687 len = dwlen * 4 - 4;
4688 memset(str + 4, 0, len);
4689 if (len > strlen(version))
4690 len = strlen(version);
4691 memcpy(str + 4, version, len);
4692
4693 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4694 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;
4695 mcp->mb[2] = MSW(LSD(str_dma));
4696 mcp->mb[3] = LSW(LSD(str_dma));
4697 mcp->mb[6] = MSW(MSD(str_dma));
4698 mcp->mb[7] = LSW(MSD(str_dma));
4699 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4700 mcp->in_mb = MBX_1|MBX_0;
4701 mcp->tov = MBX_TOV_SECONDS;
4702 mcp->flags = 0;
4703 rval = qla2x00_mailbox_command(vha, mcp);
4704
4705 if (rval != QLA_SUCCESS) {
4706 ql_dbg(ql_dbg_mbx, vha, 0x1180,
4707 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4708 } else {
4709 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181,
4710 "Done %s.\n", __func__);
4711 }
4712
4713 dma_pool_free(ha->s_dma_pool, str, str_dma);
4714
4715 return rval;
4716}
4717
Duane Grigsbyedd05de2017-10-13 09:34:06 -07004718int
4719qla24xx_get_port_login_templ(scsi_qla_host_t *vha, dma_addr_t buf_dma,
4720 void *buf, uint16_t bufsiz)
4721{
4722 int rval, i;
4723 mbx_cmd_t mc;
4724 mbx_cmd_t *mcp = &mc;
4725 uint32_t *bp;
4726
4727 if (!IS_FWI2_CAPABLE(vha->hw))
4728 return QLA_FUNCTION_FAILED;
4729
4730 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4731 "Entered %s.\n", __func__);
4732
4733 mcp->mb[0] = MBC_GET_RNID_PARAMS;
4734 mcp->mb[1] = RNID_TYPE_PORT_LOGIN << 8;
4735 mcp->mb[2] = MSW(buf_dma);
4736 mcp->mb[3] = LSW(buf_dma);
4737 mcp->mb[6] = MSW(MSD(buf_dma));
4738 mcp->mb[7] = LSW(MSD(buf_dma));
4739 mcp->mb[8] = bufsiz/4;
4740 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4741 mcp->in_mb = MBX_1|MBX_0;
4742 mcp->tov = MBX_TOV_SECONDS;
4743 mcp->flags = 0;
4744 rval = qla2x00_mailbox_command(vha, mcp);
4745
4746 if (rval != QLA_SUCCESS) {
4747 ql_dbg(ql_dbg_mbx, vha, 0x115a,
4748 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4749 } else {
4750 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4751 "Done %s.\n", __func__);
4752 bp = (uint32_t *) buf;
4753 for (i = 0; i < (bufsiz-4)/4; i++, bp++)
Quinn Tran8777e432018-08-02 13:16:57 -07004754 *bp = le32_to_cpu(*bp);
Duane Grigsbyedd05de2017-10-13 09:34:06 -07004755 }
4756
4757 return rval;
4758}
4759
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004760static int
4761qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
4762{
4763 int rval;
4764 mbx_cmd_t mc;
4765 mbx_cmd_t *mcp = &mc;
4766
4767 if (!IS_FWI2_CAPABLE(vha->hw))
4768 return QLA_FUNCTION_FAILED;
4769
4770 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4771 "Entered %s.\n", __func__);
4772
4773 mcp->mb[0] = MBC_GET_RNID_PARAMS;
4774 mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8;
4775 mcp->out_mb = MBX_1|MBX_0;
4776 mcp->in_mb = MBX_1|MBX_0;
4777 mcp->tov = MBX_TOV_SECONDS;
4778 mcp->flags = 0;
4779 rval = qla2x00_mailbox_command(vha, mcp);
4780 *temp = mcp->mb[1];
4781
4782 if (rval != QLA_SUCCESS) {
4783 ql_dbg(ql_dbg_mbx, vha, 0x115a,
4784 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4785 } else {
4786 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4787 "Done %s.\n", __func__);
4788 }
4789
4790 return rval;
4791}
4792
Joe Carnuccio3a117112013-02-08 01:58:00 -05004793int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004794qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4795 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004796{
4797 int rval;
4798 mbx_cmd_t mc;
4799 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004800 struct qla_hw_data *ha = vha->hw;
4801
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004802 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,
4803 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004804
Joe Carnuccio6766df92011-05-10 11:30:15 -07004805 if (!IS_FWI2_CAPABLE(ha))
4806 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004807
Joe Carnuccio6766df92011-05-10 11:30:15 -07004808 if (len == 1)
4809 opt |= BIT_0;
4810
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004811 mcp->mb[0] = MBC_READ_SFP;
4812 mcp->mb[1] = dev;
4813 mcp->mb[2] = MSW(sfp_dma);
4814 mcp->mb[3] = LSW(sfp_dma);
4815 mcp->mb[6] = MSW(MSD(sfp_dma));
4816 mcp->mb[7] = LSW(MSD(sfp_dma));
4817 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004818 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004819 mcp->mb[10] = opt;
4820 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 -07004821 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004822 mcp->tov = MBX_TOV_SECONDS;
4823 mcp->flags = 0;
4824 rval = qla2x00_mailbox_command(vha, mcp);
4825
4826 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004827 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004828
4829 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004830 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
4831 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Quinn Trane4e3a2c2017-08-23 15:05:07 -07004832 if (mcp->mb[0] == MBS_COMMAND_ERROR &&
4833 mcp->mb[1] == 0x22)
4834 /* sfp is not there */
4835 rval = QLA_INTERFACE_ERROR;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004836 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004837 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
4838 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004839 }
4840
4841 return rval;
4842}
4843
4844int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004845qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4846 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004847{
4848 int rval;
4849 mbx_cmd_t mc;
4850 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004851 struct qla_hw_data *ha = vha->hw;
4852
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004853 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb,
4854 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004855
Joe Carnuccio6766df92011-05-10 11:30:15 -07004856 if (!IS_FWI2_CAPABLE(ha))
4857 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004858
Joe Carnuccio6766df92011-05-10 11:30:15 -07004859 if (len == 1)
4860 opt |= BIT_0;
4861
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004862 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004863 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004864
4865 mcp->mb[0] = MBC_WRITE_SFP;
4866 mcp->mb[1] = dev;
4867 mcp->mb[2] = MSW(sfp_dma);
4868 mcp->mb[3] = LSW(sfp_dma);
4869 mcp->mb[6] = MSW(MSD(sfp_dma));
4870 mcp->mb[7] = LSW(MSD(sfp_dma));
4871 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004872 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004873 mcp->mb[10] = opt;
4874 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 -07004875 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004876 mcp->tov = MBX_TOV_SECONDS;
4877 mcp->flags = 0;
4878 rval = qla2x00_mailbox_command(vha, mcp);
4879
4880 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004881 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
4882 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004883 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004884 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed,
4885 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004886 }
4887
4888 return rval;
4889}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004890
4891int
4892qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
4893 uint16_t size_in_bytes, uint16_t *actual_size)
4894{
4895 int rval;
4896 mbx_cmd_t mc;
4897 mbx_cmd_t *mcp = &mc;
4898
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004899 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee,
4900 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004901
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004902 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004903 return QLA_FUNCTION_FAILED;
4904
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004905 mcp->mb[0] = MBC_GET_XGMAC_STATS;
4906 mcp->mb[2] = MSW(stats_dma);
4907 mcp->mb[3] = LSW(stats_dma);
4908 mcp->mb[6] = MSW(MSD(stats_dma));
4909 mcp->mb[7] = LSW(MSD(stats_dma));
4910 mcp->mb[8] = size_in_bytes >> 2;
4911 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4912 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4913 mcp->tov = MBX_TOV_SECONDS;
4914 mcp->flags = 0;
4915 rval = qla2x00_mailbox_command(vha, mcp);
4916
4917 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004918 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
4919 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4920 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004921 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004922 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0,
4923 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004924
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004925
4926 *actual_size = mcp->mb[2] << 2;
4927 }
4928
4929 return rval;
4930}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004931
4932int
4933qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
4934 uint16_t size)
4935{
4936 int rval;
4937 mbx_cmd_t mc;
4938 mbx_cmd_t *mcp = &mc;
4939
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004940 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1,
4941 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004942
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004943 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004944 return QLA_FUNCTION_FAILED;
4945
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004946 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4947 mcp->mb[1] = 0;
4948 mcp->mb[2] = MSW(tlv_dma);
4949 mcp->mb[3] = LSW(tlv_dma);
4950 mcp->mb[6] = MSW(MSD(tlv_dma));
4951 mcp->mb[7] = LSW(MSD(tlv_dma));
4952 mcp->mb[8] = size;
4953 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4954 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4955 mcp->tov = MBX_TOV_SECONDS;
4956 mcp->flags = 0;
4957 rval = qla2x00_mailbox_command(vha, mcp);
4958
4959 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004960 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
4961 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4962 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004963 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004964 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3,
4965 "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004966 }
4967
4968 return rval;
4969}
Andrew Vasquez18e75552009-06-03 09:55:30 -07004970
4971int
4972qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
4973{
4974 int rval;
4975 mbx_cmd_t mc;
4976 mbx_cmd_t *mcp = &mc;
4977
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004978 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4,
4979 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004980
Andrew Vasquez18e75552009-06-03 09:55:30 -07004981 if (!IS_FWI2_CAPABLE(vha->hw))
4982 return QLA_FUNCTION_FAILED;
4983
Andrew Vasquez18e75552009-06-03 09:55:30 -07004984 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
4985 mcp->mb[1] = LSW(risc_addr);
4986 mcp->mb[8] = MSW(risc_addr);
4987 mcp->out_mb = MBX_8|MBX_1|MBX_0;
4988 mcp->in_mb = MBX_3|MBX_2|MBX_0;
4989 mcp->tov = 30;
4990 mcp->flags = 0;
4991 rval = qla2x00_mailbox_command(vha, mcp);
4992 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004993 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
4994 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004995 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004996 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6,
4997 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004998 *data = mcp->mb[3] << 16 | mcp->mb[2];
4999 }
5000
5001 return rval;
5002}
5003
5004int
Giridhar Malavalia9083012010-04-12 17:59:55 -07005005qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
5006 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005007{
5008 int rval;
5009 mbx_cmd_t mc;
5010 mbx_cmd_t *mcp = &mc;
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005011
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005012 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7,
5013 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005014
5015 memset(mcp->mb, 0 , sizeof(mcp->mb));
5016 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
5017 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
5018
5019 /* transfer count */
5020 mcp->mb[10] = LSW(mreq->transfer_size);
5021 mcp->mb[11] = MSW(mreq->transfer_size);
5022
5023 /* send data address */
5024 mcp->mb[14] = LSW(mreq->send_dma);
5025 mcp->mb[15] = MSW(mreq->send_dma);
5026 mcp->mb[20] = LSW(MSD(mreq->send_dma));
5027 mcp->mb[21] = MSW(MSD(mreq->send_dma));
5028
Lucas De Marchi25985ed2011-03-30 22:57:33 -03005029 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005030 mcp->mb[16] = LSW(mreq->rcv_dma);
5031 mcp->mb[17] = MSW(mreq->rcv_dma);
5032 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
5033 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
5034
5035 /* Iteration count */
Joe Carnuccio1b98b422013-03-28 08:21:26 -04005036 mcp->mb[18] = LSW(mreq->iteration_count);
5037 mcp->mb[19] = MSW(mreq->iteration_count);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005038
5039 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
5040 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 -08005041 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005042 mcp->out_mb |= MBX_2;
5043 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
5044
5045 mcp->buf_size = mreq->transfer_size;
5046 mcp->tov = MBX_TOV_SECONDS;
5047 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5048
5049 rval = qla2x00_mailbox_command(vha, mcp);
5050
5051 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005052 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
5053 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
5054 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
5055 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005056 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005057 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9,
5058 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005059 }
5060
5061 /* Copy mailbox information */
5062 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005063 return rval;
5064}
5065
5066int
Giridhar Malavalia9083012010-04-12 17:59:55 -07005067qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
5068 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005069{
5070 int rval;
5071 mbx_cmd_t mc;
5072 mbx_cmd_t *mcp = &mc;
5073 struct qla_hw_data *ha = vha->hw;
5074
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005075 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa,
5076 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005077
5078 memset(mcp->mb, 0 , sizeof(mcp->mb));
5079 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
Joe Carnuccio1d634962017-05-24 18:06:22 -07005080 /* BIT_6 specifies 64bit address */
5081 mcp->mb[1] = mreq->options | BIT_15 | BIT_6;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005082 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -07005083 mcp->mb[2] = vha->fcoe_fcf_idx;
5084 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005085 mcp->mb[16] = LSW(mreq->rcv_dma);
5086 mcp->mb[17] = MSW(mreq->rcv_dma);
5087 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
5088 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
5089
5090 mcp->mb[10] = LSW(mreq->transfer_size);
5091
5092 mcp->mb[14] = LSW(mreq->send_dma);
5093 mcp->mb[15] = MSW(mreq->send_dma);
5094 mcp->mb[20] = LSW(MSD(mreq->send_dma));
5095 mcp->mb[21] = MSW(MSD(mreq->send_dma));
5096
5097 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
5098 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005099 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005100 mcp->out_mb |= MBX_2;
5101
5102 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005103 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
5104 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005105 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005106 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005107 mcp->in_mb |= MBX_3;
5108
5109 mcp->tov = MBX_TOV_SECONDS;
5110 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5111 mcp->buf_size = mreq->transfer_size;
5112
5113 rval = qla2x00_mailbox_command(vha, mcp);
5114
5115 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005116 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
5117 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5118 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005119 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005120 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc,
5121 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005122 }
5123
5124 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07005125 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005126 return rval;
5127}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07005128
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005129int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005130qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005131{
5132 int rval;
5133 mbx_cmd_t mc;
5134 mbx_cmd_t *mcp = &mc;
5135
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005136 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005137 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005138
5139 mcp->mb[0] = MBC_ISP84XX_RESET;
5140 mcp->mb[1] = enable_diagnostic;
5141 mcp->out_mb = MBX_1|MBX_0;
5142 mcp->in_mb = MBX_1|MBX_0;
5143 mcp->tov = MBX_TOV_SECONDS;
5144 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005145 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005146
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005147 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005148 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005149 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005150 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff,
5151 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08005152
5153 return rval;
5154}
5155
5156int
Andrew Vasquez18e75552009-06-03 09:55:30 -07005157qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
5158{
5159 int rval;
5160 mbx_cmd_t mc;
5161 mbx_cmd_t *mcp = &mc;
5162
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005163 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100,
5164 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005165
Andrew Vasquez18e75552009-06-03 09:55:30 -07005166 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07005167 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07005168
Andrew Vasquez18e75552009-06-03 09:55:30 -07005169 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
5170 mcp->mb[1] = LSW(risc_addr);
5171 mcp->mb[2] = LSW(data);
5172 mcp->mb[3] = MSW(data);
5173 mcp->mb[8] = MSW(risc_addr);
5174 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
5175 mcp->in_mb = MBX_0;
5176 mcp->tov = 30;
5177 mcp->flags = 0;
5178 rval = qla2x00_mailbox_command(vha, mcp);
5179 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005180 ql_dbg(ql_dbg_mbx, vha, 0x1101,
5181 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07005182 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005183 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
5184 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07005185 }
5186
5187 return rval;
5188}
Michael Hernandez3064ff32009-12-15 21:29:44 -08005189
5190int
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005191qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
5192{
5193 int rval;
5194 uint32_t stat, timer;
5195 uint16_t mb0 = 0;
5196 struct qla_hw_data *ha = vha->hw;
5197 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
5198
5199 rval = QLA_SUCCESS;
5200
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005201 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103,
5202 "Entered %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005203
5204 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
5205
5206 /* Write the MBC data to the registers */
5207 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
5208 WRT_REG_WORD(&reg->mailbox1, mb[0]);
5209 WRT_REG_WORD(&reg->mailbox2, mb[1]);
5210 WRT_REG_WORD(&reg->mailbox3, mb[2]);
5211 WRT_REG_WORD(&reg->mailbox4, mb[3]);
5212
5213 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
5214
5215 /* Poll for MBC interrupt */
5216 for (timer = 6000000; timer; timer--) {
5217 /* Check for pending interrupts. */
5218 stat = RD_REG_DWORD(&reg->host_status);
5219 if (stat & HSRX_RISC_INT) {
5220 stat &= 0xff;
5221
5222 if (stat == 0x1 || stat == 0x2 ||
5223 stat == 0x10 || stat == 0x11) {
5224 set_bit(MBX_INTERRUPT,
5225 &ha->mbx_cmd_flags);
5226 mb0 = RD_REG_WORD(&reg->mailbox0);
5227 WRT_REG_DWORD(&reg->hccr,
5228 HCCRX_CLR_RISC_INT);
5229 RD_REG_DWORD(&reg->hccr);
5230 break;
5231 }
5232 }
5233 udelay(5);
5234 }
5235
5236 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
5237 rval = mb0 & MBS_MASK;
5238 else
5239 rval = QLA_FUNCTION_FAILED;
5240
5241 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005242 ql_dbg(ql_dbg_mbx, vha, 0x1104,
5243 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005244 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005245 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105,
5246 "Done %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005247 }
5248
5249 return rval;
5250}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005251
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07005252int
Michael Hernandez3064ff32009-12-15 21:29:44 -08005253qla2x00_get_data_rate(scsi_qla_host_t *vha)
5254{
5255 int rval;
5256 mbx_cmd_t mc;
5257 mbx_cmd_t *mcp = &mc;
5258 struct qla_hw_data *ha = vha->hw;
5259
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005260 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
5261 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005262
Michael Hernandez3064ff32009-12-15 21:29:44 -08005263 if (!IS_FWI2_CAPABLE(ha))
5264 return QLA_FUNCTION_FAILED;
5265
Michael Hernandez3064ff32009-12-15 21:29:44 -08005266 mcp->mb[0] = MBC_DATA_RATE;
5267 mcp->mb[1] = 0;
5268 mcp->out_mb = MBX_1|MBX_0;
5269 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05005270 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005271 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08005272 mcp->tov = MBX_TOV_SECONDS;
5273 mcp->flags = 0;
5274 rval = qla2x00_mailbox_command(vha, mcp);
5275 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005276 ql_dbg(ql_dbg_mbx, vha, 0x1107,
5277 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08005278 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005279 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
5280 "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08005281 if (mcp->mb[1] != 0x7)
5282 ha->link_data_rate = mcp->mb[1];
5283 }
5284
5285 return rval;
5286}
Sarang Radke09ff7012010-03-19 17:03:59 -07005287
5288int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005289qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
5290{
5291 int rval;
5292 mbx_cmd_t mc;
5293 mbx_cmd_t *mcp = &mc;
5294 struct qla_hw_data *ha = vha->hw;
5295
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005296 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
5297 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005298
Chad Dupuisf73cb692014-02-26 04:15:06 -05005299 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) &&
5300 !IS_QLA27XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005301 return QLA_FUNCTION_FAILED;
5302 mcp->mb[0] = MBC_GET_PORT_CONFIG;
5303 mcp->out_mb = MBX_0;
5304 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5305 mcp->tov = MBX_TOV_SECONDS;
5306 mcp->flags = 0;
5307
5308 rval = qla2x00_mailbox_command(vha, mcp);
5309
5310 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005311 ql_dbg(ql_dbg_mbx, vha, 0x110a,
5312 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005313 } else {
5314 /* Copy all bits to preserve original value */
5315 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
5316
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005317 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b,
5318 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005319 }
5320 return rval;
5321}
5322
5323int
5324qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
5325{
5326 int rval;
5327 mbx_cmd_t mc;
5328 mbx_cmd_t *mcp = &mc;
5329
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005330 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c,
5331 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005332
5333 mcp->mb[0] = MBC_SET_PORT_CONFIG;
5334 /* Copy all bits to preserve original setting */
5335 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
5336 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5337 mcp->in_mb = MBX_0;
5338 mcp->tov = MBX_TOV_SECONDS;
5339 mcp->flags = 0;
5340 rval = qla2x00_mailbox_command(vha, mcp);
5341
5342 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005343 ql_dbg(ql_dbg_mbx, vha, 0x110d,
5344 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005345 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005346 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e,
5347 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07005348
5349 return rval;
5350}
5351
5352
5353int
Sarang Radke09ff7012010-03-19 17:03:59 -07005354qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
5355 uint16_t *mb)
5356{
5357 int rval;
5358 mbx_cmd_t mc;
5359 mbx_cmd_t *mcp = &mc;
5360 struct qla_hw_data *ha = vha->hw;
5361
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005362 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f,
5363 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005364
Sarang Radke09ff7012010-03-19 17:03:59 -07005365 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
5366 return QLA_FUNCTION_FAILED;
5367
Sarang Radke09ff7012010-03-19 17:03:59 -07005368 mcp->mb[0] = MBC_PORT_PARAMS;
5369 mcp->mb[1] = loop_id;
5370 if (ha->flags.fcp_prio_enabled)
5371 mcp->mb[2] = BIT_1;
5372 else
5373 mcp->mb[2] = BIT_2;
5374 mcp->mb[4] = priority & 0xf;
5375 mcp->mb[9] = vha->vp_idx;
5376 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5377 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5378 mcp->tov = 30;
5379 mcp->flags = 0;
5380 rval = qla2x00_mailbox_command(vha, mcp);
5381 if (mb != NULL) {
5382 mb[0] = mcp->mb[0];
5383 mb[1] = mcp->mb[1];
5384 mb[3] = mcp->mb[3];
5385 mb[4] = mcp->mb[4];
5386 }
5387
5388 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005389 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07005390 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005391 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc,
5392 "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07005393 }
5394
5395 return rval;
5396}
Giridhar Malavalia9083012010-04-12 17:59:55 -07005397
5398int
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005399qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)
Andrew Vasquez794a5692010-12-21 16:00:21 -08005400{
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005401 int rval = QLA_FUNCTION_FAILED;
Andrew Vasquez794a5692010-12-21 16:00:21 -08005402 struct qla_hw_data *ha = vha->hw;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005403 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08005404
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005405 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) {
5406 ql_dbg(ql_dbg_mbx, vha, 0x1150,
5407 "Thermal not supported by this card.\n");
5408 return rval;
Andrew Vasquez794a5692010-12-21 16:00:21 -08005409 }
Andrew Vasquez794a5692010-12-21 16:00:21 -08005410
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005411 if (IS_QLA25XX(ha)) {
5412 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
5413 ha->pdev->subsystem_device == 0x0175) {
5414 rval = qla2x00_read_sfp(vha, 0, &byte,
5415 0x98, 0x1, 1, BIT_13|BIT_0);
5416 *temp = byte;
5417 return rval;
5418 }
5419 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
5420 ha->pdev->subsystem_device == 0x338e) {
5421 rval = qla2x00_read_sfp(vha, 0, &byte,
5422 0x98, 0x1, 1, BIT_15|BIT_14|BIT_0);
5423 *temp = byte;
5424 return rval;
5425 }
5426 ql_dbg(ql_dbg_mbx, vha, 0x10c9,
5427 "Thermal not supported by this card.\n");
5428 return rval;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005429 }
5430
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005431 if (IS_QLA82XX(ha)) {
5432 *temp = qla82xx_read_temperature(vha);
5433 rval = QLA_SUCCESS;
5434 return rval;
5435 } else if (IS_QLA8044(ha)) {
5436 *temp = qla8044_read_temperature(vha);
5437 rval = QLA_SUCCESS;
5438 return rval;
5439 }
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05005440
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04005441 rval = qla2x00_read_asic_temperature(vha, temp);
Andrew Vasquez794a5692010-12-21 16:00:21 -08005442 return rval;
5443}
5444
5445int
Giridhar Malavalia9083012010-04-12 17:59:55 -07005446qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
5447{
5448 int rval;
5449 struct qla_hw_data *ha = vha->hw;
5450 mbx_cmd_t mc;
5451 mbx_cmd_t *mcp = &mc;
5452
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005453 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017,
5454 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005455
Giridhar Malavalia9083012010-04-12 17:59:55 -07005456 if (!IS_FWI2_CAPABLE(ha))
5457 return QLA_FUNCTION_FAILED;
5458
Giridhar Malavalia9083012010-04-12 17:59:55 -07005459 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05005460 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07005461 mcp->mb[1] = 1;
5462
5463 mcp->out_mb = MBX_1|MBX_0;
5464 mcp->in_mb = MBX_0;
5465 mcp->tov = 30;
5466 mcp->flags = 0;
5467
5468 rval = qla2x00_mailbox_command(vha, mcp);
5469 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005470 ql_dbg(ql_dbg_mbx, vha, 0x1016,
5471 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005472 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005473 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e,
5474 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005475 }
5476
5477 return rval;
5478}
5479
5480int
5481qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
5482{
5483 int rval;
5484 struct qla_hw_data *ha = vha->hw;
5485 mbx_cmd_t mc;
5486 mbx_cmd_t *mcp = &mc;
5487
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005488 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
5489 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005490
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005491 if (!IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -07005492 return QLA_FUNCTION_FAILED;
5493
Giridhar Malavalia9083012010-04-12 17:59:55 -07005494 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05005495 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07005496 mcp->mb[1] = 0;
5497
5498 mcp->out_mb = MBX_1|MBX_0;
5499 mcp->in_mb = MBX_0;
5500 mcp->tov = 30;
5501 mcp->flags = 0;
5502
5503 rval = qla2x00_mailbox_command(vha, mcp);
5504 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07005505 ql_dbg(ql_dbg_mbx, vha, 0x100c,
5506 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005507 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005508 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b,
5509 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07005510 }
5511
5512 return rval;
5513}
Giridhar Malavali08de2842011-08-16 11:31:44 -07005514
5515int
5516qla82xx_md_get_template_size(scsi_qla_host_t *vha)
5517{
5518 struct qla_hw_data *ha = vha->hw;
5519 mbx_cmd_t mc;
5520 mbx_cmd_t *mcp = &mc;
5521 int rval = QLA_FUNCTION_FAILED;
5522
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005523 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f,
5524 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005525
5526 memset(mcp->mb, 0 , sizeof(mcp->mb));
5527 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5528 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5529 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
5530 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
5531
5532 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5533 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
5534 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5535
5536 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5537 mcp->tov = MBX_TOV_SECONDS;
5538 rval = qla2x00_mailbox_command(vha, mcp);
5539
5540 /* Always copy back return mailbox values. */
5541 if (rval != QLA_SUCCESS) {
5542 ql_dbg(ql_dbg_mbx, vha, 0x1120,
5543 "mailbox command FAILED=0x%x, subcode=%x.\n",
5544 (mcp->mb[1] << 16) | mcp->mb[0],
5545 (mcp->mb[3] << 16) | mcp->mb[2]);
5546 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005547 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121,
5548 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005549 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
5550 if (!ha->md_template_size) {
5551 ql_dbg(ql_dbg_mbx, vha, 0x1122,
5552 "Null template size obtained.\n");
5553 rval = QLA_FUNCTION_FAILED;
5554 }
5555 }
5556 return rval;
5557}
5558
5559int
5560qla82xx_md_get_template(scsi_qla_host_t *vha)
5561{
5562 struct qla_hw_data *ha = vha->hw;
5563 mbx_cmd_t mc;
5564 mbx_cmd_t *mcp = &mc;
5565 int rval = QLA_FUNCTION_FAILED;
5566
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005567 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123,
5568 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005569
5570 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
5571 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
5572 if (!ha->md_tmplt_hdr) {
5573 ql_log(ql_log_warn, vha, 0x1124,
5574 "Unable to allocate memory for Minidump template.\n");
5575 return rval;
5576 }
5577
5578 memset(mcp->mb, 0 , sizeof(mcp->mb));
5579 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5580 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5581 mcp->mb[2] = LSW(RQST_TMPLT);
5582 mcp->mb[3] = MSW(RQST_TMPLT);
5583 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
5584 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
5585 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
5586 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
5587 mcp->mb[8] = LSW(ha->md_template_size);
5588 mcp->mb[9] = MSW(ha->md_template_size);
5589
5590 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5591 mcp->tov = MBX_TOV_SECONDS;
5592 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5593 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5594 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5595 rval = qla2x00_mailbox_command(vha, mcp);
5596
5597 if (rval != QLA_SUCCESS) {
5598 ql_dbg(ql_dbg_mbx, vha, 0x1125,
5599 "mailbox command FAILED=0x%x, subcode=%x.\n",
5600 ((mcp->mb[1] << 16) | mcp->mb[0]),
5601 ((mcp->mb[3] << 16) | mcp->mb[2]));
5602 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005603 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126,
5604 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005605 return rval;
5606}
Saurav Kashyap999916d2011-08-16 11:31:45 -07005607
5608int
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005609qla8044_md_get_template(scsi_qla_host_t *vha)
5610{
5611 struct qla_hw_data *ha = vha->hw;
5612 mbx_cmd_t mc;
5613 mbx_cmd_t *mcp = &mc;
5614 int rval = QLA_FUNCTION_FAILED;
5615 int offset = 0, size = MINIDUMP_SIZE_36K;
5616 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,
5617 "Entered %s.\n", __func__);
5618
5619 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
5620 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
5621 if (!ha->md_tmplt_hdr) {
5622 ql_log(ql_log_warn, vha, 0xb11b,
5623 "Unable to allocate memory for Minidump template.\n");
5624 return rval;
5625 }
5626
5627 memset(mcp->mb, 0 , sizeof(mcp->mb));
5628 while (offset < ha->md_template_size) {
5629 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5630 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5631 mcp->mb[2] = LSW(RQST_TMPLT);
5632 mcp->mb[3] = MSW(RQST_TMPLT);
5633 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));
5634 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));
5635 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));
5636 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));
5637 mcp->mb[8] = LSW(size);
5638 mcp->mb[9] = MSW(size);
5639 mcp->mb[10] = offset & 0x0000FFFF;
5640 mcp->mb[11] = offset & 0xFFFF0000;
5641 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5642 mcp->tov = MBX_TOV_SECONDS;
5643 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5644 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5645 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5646 rval = qla2x00_mailbox_command(vha, mcp);
5647
5648 if (rval != QLA_SUCCESS) {
5649 ql_dbg(ql_dbg_mbx, vha, 0xb11c,
5650 "mailbox command FAILED=0x%x, subcode=%x.\n",
5651 ((mcp->mb[1] << 16) | mcp->mb[0]),
5652 ((mcp->mb[3] << 16) | mcp->mb[2]));
5653 return rval;
5654 } else
5655 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,
5656 "Done %s.\n", __func__);
5657 offset = offset + size;
5658 }
5659 return rval;
5660}
5661
5662int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005663qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5664{
5665 int rval;
5666 struct qla_hw_data *ha = vha->hw;
5667 mbx_cmd_t mc;
5668 mbx_cmd_t *mcp = &mc;
5669
5670 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5671 return QLA_FUNCTION_FAILED;
5672
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005673 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133,
5674 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005675
5676 memset(mcp, 0, sizeof(mbx_cmd_t));
5677 mcp->mb[0] = MBC_SET_LED_CONFIG;
5678 mcp->mb[1] = led_cfg[0];
5679 mcp->mb[2] = led_cfg[1];
5680 if (IS_QLA8031(ha)) {
5681 mcp->mb[3] = led_cfg[2];
5682 mcp->mb[4] = led_cfg[3];
5683 mcp->mb[5] = led_cfg[4];
5684 mcp->mb[6] = led_cfg[5];
5685 }
5686
5687 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5688 if (IS_QLA8031(ha))
5689 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5690 mcp->in_mb = MBX_0;
5691 mcp->tov = 30;
5692 mcp->flags = 0;
5693
5694 rval = qla2x00_mailbox_command(vha, mcp);
5695 if (rval != QLA_SUCCESS) {
5696 ql_dbg(ql_dbg_mbx, vha, 0x1134,
5697 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5698 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005699 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135,
5700 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005701 }
5702
5703 return rval;
5704}
5705
5706int
5707qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5708{
5709 int rval;
5710 struct qla_hw_data *ha = vha->hw;
5711 mbx_cmd_t mc;
5712 mbx_cmd_t *mcp = &mc;
5713
5714 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5715 return QLA_FUNCTION_FAILED;
5716
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005717 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136,
5718 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005719
5720 memset(mcp, 0, sizeof(mbx_cmd_t));
5721 mcp->mb[0] = MBC_GET_LED_CONFIG;
5722
5723 mcp->out_mb = MBX_0;
5724 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5725 if (IS_QLA8031(ha))
5726 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5727 mcp->tov = 30;
5728 mcp->flags = 0;
5729
5730 rval = qla2x00_mailbox_command(vha, mcp);
5731 if (rval != QLA_SUCCESS) {
5732 ql_dbg(ql_dbg_mbx, vha, 0x1137,
5733 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5734 } else {
5735 led_cfg[0] = mcp->mb[1];
5736 led_cfg[1] = mcp->mb[2];
5737 if (IS_QLA8031(ha)) {
5738 led_cfg[2] = mcp->mb[3];
5739 led_cfg[3] = mcp->mb[4];
5740 led_cfg[4] = mcp->mb[5];
5741 led_cfg[5] = mcp->mb[6];
5742 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005743 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138,
5744 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005745 }
5746
5747 return rval;
5748}
5749
5750int
Saurav Kashyap999916d2011-08-16 11:31:45 -07005751qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
5752{
5753 int rval;
5754 struct qla_hw_data *ha = vha->hw;
5755 mbx_cmd_t mc;
5756 mbx_cmd_t *mcp = &mc;
5757
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005758 if (!IS_P3P_TYPE(ha))
Saurav Kashyap999916d2011-08-16 11:31:45 -07005759 return QLA_FUNCTION_FAILED;
5760
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005761 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005762 "Entered %s.\n", __func__);
5763
5764 memset(mcp, 0, sizeof(mbx_cmd_t));
5765 mcp->mb[0] = MBC_SET_LED_CONFIG;
5766 if (enable)
5767 mcp->mb[7] = 0xE;
5768 else
5769 mcp->mb[7] = 0xD;
5770
5771 mcp->out_mb = MBX_7|MBX_0;
5772 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005773 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07005774 mcp->flags = 0;
5775
5776 rval = qla2x00_mailbox_command(vha, mcp);
5777 if (rval != QLA_SUCCESS) {
5778 ql_dbg(ql_dbg_mbx, vha, 0x1128,
5779 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5780 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005781 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005782 "Done %s.\n", __func__);
5783 }
5784
5785 return rval;
5786}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005787
5788int
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005789qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005790{
5791 int rval;
5792 struct qla_hw_data *ha = vha->hw;
5793 mbx_cmd_t mc;
5794 mbx_cmd_t *mcp = &mc;
5795
Chad Dupuisf73cb692014-02-26 04:15:06 -05005796 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005797 return QLA_FUNCTION_FAILED;
5798
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005799 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130,
5800 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005801
5802 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
5803 mcp->mb[1] = LSW(reg);
5804 mcp->mb[2] = MSW(reg);
5805 mcp->mb[3] = LSW(data);
5806 mcp->mb[4] = MSW(data);
5807 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5808
5809 mcp->in_mb = MBX_1|MBX_0;
5810 mcp->tov = MBX_TOV_SECONDS;
5811 mcp->flags = 0;
5812 rval = qla2x00_mailbox_command(vha, mcp);
5813
5814 if (rval != QLA_SUCCESS) {
5815 ql_dbg(ql_dbg_mbx, vha, 0x1131,
5816 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5817 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005818 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005819 "Done %s.\n", __func__);
5820 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005821
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005822 return rval;
5823}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005824
5825int
5826qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
5827{
5828 int rval;
5829 struct qla_hw_data *ha = vha->hw;
5830 mbx_cmd_t mc;
5831 mbx_cmd_t *mcp = &mc;
5832
5833 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005834 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b,
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005835 "Implicit LOGO Unsupported.\n");
5836 return QLA_FUNCTION_FAILED;
5837 }
5838
5839
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005840 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c,
5841 "Entering %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005842
5843 /* Perform Implicit LOGO. */
5844 mcp->mb[0] = MBC_PORT_LOGOUT;
5845 mcp->mb[1] = fcport->loop_id;
5846 mcp->mb[10] = BIT_15;
5847 mcp->out_mb = MBX_10|MBX_1|MBX_0;
5848 mcp->in_mb = MBX_0;
5849 mcp->tov = MBX_TOV_SECONDS;
5850 mcp->flags = 0;
5851 rval = qla2x00_mailbox_command(vha, mcp);
5852 if (rval != QLA_SUCCESS)
5853 ql_dbg(ql_dbg_mbx, vha, 0x113d,
5854 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5855 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005856 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e,
5857 "Done %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005858
5859 return rval;
5860}
5861
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005862int
5863qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
5864{
5865 int rval;
5866 mbx_cmd_t mc;
5867 mbx_cmd_t *mcp = &mc;
5868 struct qla_hw_data *ha = vha->hw;
5869 unsigned long retry_max_time = jiffies + (2 * HZ);
5870
Chad Dupuisf73cb692014-02-26 04:15:06 -05005871 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005872 return QLA_FUNCTION_FAILED;
5873
5874 ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
5875
5876retry_rd_reg:
5877 mcp->mb[0] = MBC_READ_REMOTE_REG;
5878 mcp->mb[1] = LSW(reg);
5879 mcp->mb[2] = MSW(reg);
5880 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5881 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5882 mcp->tov = MBX_TOV_SECONDS;
5883 mcp->flags = 0;
5884 rval = qla2x00_mailbox_command(vha, mcp);
5885
5886 if (rval != QLA_SUCCESS) {
5887 ql_dbg(ql_dbg_mbx, vha, 0x114c,
5888 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5889 rval, mcp->mb[0], mcp->mb[1]);
5890 } else {
5891 *data = (mcp->mb[3] | (mcp->mb[4] << 16));
5892 if (*data == QLA8XXX_BAD_VALUE) {
5893 /*
5894 * During soft-reset CAMRAM register reads might
5895 * return 0xbad0bad0. So retry for MAX of 2 sec
5896 * while reading camram registers.
5897 */
5898 if (time_after(jiffies, retry_max_time)) {
5899 ql_dbg(ql_dbg_mbx, vha, 0x1141,
5900 "Failure to read CAMRAM register. "
5901 "data=0x%x.\n", *data);
5902 return QLA_FUNCTION_FAILED;
5903 }
5904 msleep(100);
5905 goto retry_rd_reg;
5906 }
5907 ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
5908 }
5909
5910 return rval;
5911}
5912
5913int
5914qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
5915{
5916 int rval;
5917 mbx_cmd_t mc;
5918 mbx_cmd_t *mcp = &mc;
5919 struct qla_hw_data *ha = vha->hw;
5920
Himanshu Madhanib20f02e2015-06-10 11:05:18 -04005921 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005922 return QLA_FUNCTION_FAILED;
5923
5924 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
5925
5926 mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
5927 mcp->out_mb = MBX_0;
5928 mcp->in_mb = MBX_1|MBX_0;
5929 mcp->tov = MBX_TOV_SECONDS;
5930 mcp->flags = 0;
5931 rval = qla2x00_mailbox_command(vha, mcp);
5932
5933 if (rval != QLA_SUCCESS) {
5934 ql_dbg(ql_dbg_mbx, vha, 0x1144,
5935 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5936 rval, mcp->mb[0], mcp->mb[1]);
5937 ha->isp_ops->fw_dump(vha, 0);
5938 } else {
5939 ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
5940 }
5941
5942 return rval;
5943}
5944
5945int
5946qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
5947 uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
5948{
5949 int rval;
5950 mbx_cmd_t mc;
5951 mbx_cmd_t *mcp = &mc;
5952 uint8_t subcode = (uint8_t)options;
5953 struct qla_hw_data *ha = vha->hw;
5954
5955 if (!IS_QLA8031(ha))
5956 return QLA_FUNCTION_FAILED;
5957
5958 ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
5959
5960 mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
5961 mcp->mb[1] = options;
5962 mcp->out_mb = MBX_1|MBX_0;
5963 if (subcode & BIT_2) {
5964 mcp->mb[2] = LSW(start_addr);
5965 mcp->mb[3] = MSW(start_addr);
5966 mcp->mb[4] = LSW(end_addr);
5967 mcp->mb[5] = MSW(end_addr);
5968 mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
5969 }
5970 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5971 if (!(subcode & (BIT_2 | BIT_5)))
5972 mcp->in_mb |= MBX_4|MBX_3;
5973 mcp->tov = MBX_TOV_SECONDS;
5974 mcp->flags = 0;
5975 rval = qla2x00_mailbox_command(vha, mcp);
5976
5977 if (rval != QLA_SUCCESS) {
5978 ql_dbg(ql_dbg_mbx, vha, 0x1147,
5979 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
5980 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
5981 mcp->mb[4]);
5982 ha->isp_ops->fw_dump(vha, 0);
5983 } else {
5984 if (subcode & BIT_5)
5985 *sector_size = mcp->mb[1];
5986 else if (subcode & (BIT_6 | BIT_7)) {
5987 ql_dbg(ql_dbg_mbx, vha, 0x1148,
5988 "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5989 } else if (subcode & (BIT_3 | BIT_4)) {
5990 ql_dbg(ql_dbg_mbx, vha, 0x1149,
5991 "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5992 }
5993 ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
5994 }
5995
5996 return rval;
5997}
Saurav Kashyap81178772012-08-22 14:21:04 -04005998
5999int
6000qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
6001 uint32_t size)
6002{
6003 int rval;
6004 mbx_cmd_t mc;
6005 mbx_cmd_t *mcp = &mc;
6006
6007 if (!IS_MCTP_CAPABLE(vha->hw))
6008 return QLA_FUNCTION_FAILED;
6009
6010 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,
6011 "Entered %s.\n", __func__);
6012
6013 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
6014 mcp->mb[1] = LSW(addr);
6015 mcp->mb[2] = MSW(req_dma);
6016 mcp->mb[3] = LSW(req_dma);
6017 mcp->mb[4] = MSW(size);
6018 mcp->mb[5] = LSW(size);
6019 mcp->mb[6] = MSW(MSD(req_dma));
6020 mcp->mb[7] = LSW(MSD(req_dma));
6021 mcp->mb[8] = MSW(addr);
6022 /* Setting RAM ID to valid */
6023 mcp->mb[10] |= BIT_7;
6024 /* For MCTP RAM ID is 0x40 */
6025 mcp->mb[10] |= 0x40;
6026
6027 mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
6028 MBX_0;
6029
6030 mcp->in_mb = MBX_0;
6031 mcp->tov = MBX_TOV_SECONDS;
6032 mcp->flags = 0;
6033 rval = qla2x00_mailbox_command(vha, mcp);
6034
6035 if (rval != QLA_SUCCESS) {
6036 ql_dbg(ql_dbg_mbx, vha, 0x114e,
6037 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
6038 } else {
6039 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,
6040 "Done %s.\n", __func__);
6041 }
6042
6043 return rval;
6044}
Joe Carnuccioec891462016-07-06 11:14:26 -04006045
6046int
6047qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
6048 void *dd_buf, uint size, uint options)
6049{
6050 int rval;
6051 mbx_cmd_t mc;
6052 mbx_cmd_t *mcp = &mc;
6053 dma_addr_t dd_dma;
6054
6055 if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
6056 return QLA_FUNCTION_FAILED;
6057
Quinn Tran83548fe2017-06-02 09:12:01 -07006058 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x119f,
Joe Carnuccioec891462016-07-06 11:14:26 -04006059 "Entered %s.\n", __func__);
6060
Joe Carnuccioec891462016-07-06 11:14:26 -04006061 dd_dma = dma_map_single(&vha->hw->pdev->dev,
6062 dd_buf, size, DMA_FROM_DEVICE);
Pan Bian0b2ce192017-08-08 21:55:30 +08006063 if (dma_mapping_error(&vha->hw->pdev->dev, dd_dma)) {
Joe Carnuccioec891462016-07-06 11:14:26 -04006064 ql_log(ql_log_warn, vha, 0x1194, "Failed to map dma buffer.\n");
6065 return QLA_MEMORY_ALLOC_FAILED;
6066 }
6067
6068 memset(dd_buf, 0, size);
6069
6070 mcp->mb[0] = MBC_DPORT_DIAGNOSTICS;
6071 mcp->mb[1] = options;
6072 mcp->mb[2] = MSW(LSD(dd_dma));
6073 mcp->mb[3] = LSW(LSD(dd_dma));
6074 mcp->mb[6] = MSW(MSD(dd_dma));
6075 mcp->mb[7] = LSW(MSD(dd_dma));
6076 mcp->mb[8] = size;
6077 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
6078 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
6079 mcp->buf_size = size;
6080 mcp->flags = MBX_DMA_IN;
6081 mcp->tov = MBX_TOV_SECONDS * 4;
6082 rval = qla2x00_mailbox_command(vha, mcp);
6083
6084 if (rval != QLA_SUCCESS) {
6085 ql_dbg(ql_dbg_mbx, vha, 0x1195, "Failed=%x.\n", rval);
6086 } else {
6087 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1196,
6088 "Done %s.\n", __func__);
6089 }
6090
6091 dma_unmap_single(&vha->hw->pdev->dev, dd_dma,
6092 size, DMA_FROM_DEVICE);
6093
6094 return rval;
6095}
Quinn Tran15f30a52017-03-15 09:48:52 -07006096
6097static void qla2x00_async_mb_sp_done(void *s, int res)
6098{
6099 struct srb *sp = s;
6100
6101 sp->u.iocb_cmd.u.mbx.rc = res;
6102
6103 complete(&sp->u.iocb_cmd.u.mbx.comp);
6104 /* don't free sp here. Let the caller do the free */
6105}
6106
6107/*
6108 * This mailbox uses the iocb interface to send MB command.
6109 * This allows non-critial (non chip setup) command to go
6110 * out in parrallel.
6111 */
6112int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp)
6113{
6114 int rval = QLA_FUNCTION_FAILED;
6115 srb_t *sp;
6116 struct srb_iocb *c;
6117
6118 if (!vha->hw->flags.fw_started)
6119 goto done;
6120
6121 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
6122 if (!sp)
6123 goto done;
6124
6125 sp->type = SRB_MB_IOCB;
6126 sp->name = mb_to_str(mcp->mb[0]);
6127
Quinn Tran15f30a52017-03-15 09:48:52 -07006128 c = &sp->u.iocb_cmd;
6129 c->timeout = qla2x00_async_iocb_timeout;
6130 init_completion(&c->u.mbx.comp);
6131
Ben Hutchingse74e7d92018-03-20 21:36:14 +00006132 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
6133
6134 memcpy(sp->u.iocb_cmd.u.mbx.out_mb, mcp->mb, SIZEOF_IOCB_MB_REG);
6135
Quinn Tran15f30a52017-03-15 09:48:52 -07006136 sp->done = qla2x00_async_mb_sp_done;
6137
6138 rval = qla2x00_start_sp(sp);
6139 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006140 ql_dbg(ql_dbg_mbx, vha, 0x1018,
Quinn Tran15f30a52017-03-15 09:48:52 -07006141 "%s: %s Failed submission. %x.\n",
6142 __func__, sp->name, rval);
6143 goto done_free_sp;
6144 }
6145
Quinn Tran83548fe2017-06-02 09:12:01 -07006146 ql_dbg(ql_dbg_mbx, vha, 0x113f, "MB:%s hndl %x submitted\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006147 sp->name, sp->handle);
6148
6149 wait_for_completion(&c->u.mbx.comp);
6150 memcpy(mcp->mb, sp->u.iocb_cmd.u.mbx.in_mb, SIZEOF_IOCB_MB_REG);
6151
6152 rval = c->u.mbx.rc;
6153 switch (rval) {
6154 case QLA_FUNCTION_TIMEOUT:
Quinn Tran83548fe2017-06-02 09:12:01 -07006155 ql_dbg(ql_dbg_mbx, vha, 0x1140, "%s: %s Timeout. %x.\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006156 __func__, sp->name, rval);
6157 break;
6158 case QLA_SUCCESS:
Quinn Tran83548fe2017-06-02 09:12:01 -07006159 ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006160 __func__, sp->name);
6161 sp->free(sp);
6162 break;
6163 default:
Quinn Tran83548fe2017-06-02 09:12:01 -07006164 ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006165 __func__, sp->name, rval);
6166 sp->free(sp);
6167 break;
6168 }
6169
6170 return rval;
6171
6172done_free_sp:
6173 sp->free(sp);
6174done:
6175 return rval;
6176}
6177
6178/*
6179 * qla24xx_gpdb_wait
6180 * NOTE: Do not call this routine from DPC thread
6181 */
6182int qla24xx_gpdb_wait(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
6183{
6184 int rval = QLA_FUNCTION_FAILED;
6185 dma_addr_t pd_dma;
6186 struct port_database_24xx *pd;
6187 struct qla_hw_data *ha = vha->hw;
6188 mbx_cmd_t mc;
6189
6190 if (!vha->hw->flags.fw_started)
6191 goto done;
6192
Thomas Meyer08eb7f42017-09-21 08:15:26 +02006193 pd = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Quinn Tran15f30a52017-03-15 09:48:52 -07006194 if (pd == NULL) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006195 ql_log(ql_log_warn, vha, 0xd047,
6196 "Failed to allocate port database structure.\n");
Quinn Tran15f30a52017-03-15 09:48:52 -07006197 goto done_free_sp;
6198 }
Quinn Tran15f30a52017-03-15 09:48:52 -07006199
6200 memset(&mc, 0, sizeof(mc));
6201 mc.mb[0] = MBC_GET_PORT_DATABASE;
6202 mc.mb[1] = cpu_to_le16(fcport->loop_id);
6203 mc.mb[2] = MSW(pd_dma);
6204 mc.mb[3] = LSW(pd_dma);
6205 mc.mb[6] = MSW(MSD(pd_dma));
6206 mc.mb[7] = LSW(MSD(pd_dma));
6207 mc.mb[9] = cpu_to_le16(vha->vp_idx);
6208 mc.mb[10] = cpu_to_le16((uint16_t)opt);
6209
6210 rval = qla24xx_send_mb_cmd(vha, &mc);
6211 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006212 ql_dbg(ql_dbg_mbx, vha, 0x1193,
Quinn Tran15f30a52017-03-15 09:48:52 -07006213 "%s: %8phC fail\n", __func__, fcport->port_name);
6214 goto done_free_sp;
6215 }
6216
6217 rval = __qla24xx_parse_gpdb(vha, fcport, pd);
6218
Quinn Tran83548fe2017-06-02 09:12:01 -07006219 ql_dbg(ql_dbg_mbx, vha, 0x1197, "%s: %8phC done\n",
Quinn Tran15f30a52017-03-15 09:48:52 -07006220 __func__, fcport->port_name);
6221
6222done_free_sp:
6223 if (pd)
6224 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
6225done:
6226 return rval;
6227}
6228
6229int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport,
6230 struct port_database_24xx *pd)
6231{
6232 int rval = QLA_SUCCESS;
6233 uint64_t zero = 0;
Duane Grigsbya5d42f42017-06-21 13:48:41 -07006234 u8 current_login_state, last_login_state;
6235
6236 if (fcport->fc4f_nvme) {
6237 current_login_state = pd->current_login_state >> 4;
6238 last_login_state = pd->last_login_state >> 4;
6239 } else {
6240 current_login_state = pd->current_login_state & 0xf;
6241 last_login_state = pd->last_login_state & 0xf;
6242 }
Quinn Tran15f30a52017-03-15 09:48:52 -07006243
6244 /* Check for logged in state. */
Quinn Tran23c64552017-12-04 14:45:08 -08006245 if (current_login_state != PDS_PRLI_COMPLETE) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006246 ql_dbg(ql_dbg_mbx, vha, 0x119a,
6247 "Unable to verify login-state (%x/%x) for loop_id %x.\n",
Duane Grigsbya5d42f42017-06-21 13:48:41 -07006248 current_login_state, last_login_state, fcport->loop_id);
Quinn Tran15f30a52017-03-15 09:48:52 -07006249 rval = QLA_FUNCTION_FAILED;
6250 goto gpd_error_out;
6251 }
6252
6253 if (fcport->loop_id == FC_NO_LOOP_ID ||
6254 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
6255 memcmp(fcport->port_name, pd->port_name, 8))) {
6256 /* We lost the device mid way. */
6257 rval = QLA_NOT_LOGGED_IN;
6258 goto gpd_error_out;
6259 }
6260
6261 /* Names are little-endian. */
6262 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
6263 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
6264
6265 /* Get port_id of device. */
6266 fcport->d_id.b.domain = pd->port_id[0];
6267 fcport->d_id.b.area = pd->port_id[1];
6268 fcport->d_id.b.al_pa = pd->port_id[2];
6269 fcport->d_id.b.rsvd_1 = 0;
6270
Duane Grigsbya5d42f42017-06-21 13:48:41 -07006271 if (fcport->fc4f_nvme) {
6272 fcport->nvme_prli_service_param =
6273 pd->prli_nvme_svc_param_word_3;
6274 fcport->port_type = FCT_NVME;
6275 } else {
6276 /* If not target must be initiator or unknown type. */
6277 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
6278 fcport->port_type = FCT_INITIATOR;
6279 else
6280 fcport->port_type = FCT_TARGET;
6281 }
Quinn Tran15f30a52017-03-15 09:48:52 -07006282 /* Passback COS information. */
6283 fcport->supported_classes = (pd->flags & PDF_CLASS_2) ?
6284 FC_COS_CLASS2 : FC_COS_CLASS3;
6285
6286 if (pd->prli_svc_param_word_3[0] & BIT_7) {
6287 fcport->flags |= FCF_CONF_COMP_SUPPORTED;
6288 fcport->conf_compl_supported = 1;
6289 }
6290
6291gpd_error_out:
6292 return rval;
6293}
6294
6295/*
6296 * qla24xx_gidlist__wait
6297 * NOTE: don't call this routine from DPC thread.
6298 */
6299int qla24xx_gidlist_wait(struct scsi_qla_host *vha,
6300 void *id_list, dma_addr_t id_list_dma, uint16_t *entries)
6301{
6302 int rval = QLA_FUNCTION_FAILED;
6303 mbx_cmd_t mc;
6304
6305 if (!vha->hw->flags.fw_started)
6306 goto done;
6307
6308 memset(&mc, 0, sizeof(mc));
6309 mc.mb[0] = MBC_GET_ID_LIST;
6310 mc.mb[2] = MSW(id_list_dma);
6311 mc.mb[3] = LSW(id_list_dma);
6312 mc.mb[6] = MSW(MSD(id_list_dma));
6313 mc.mb[7] = LSW(MSD(id_list_dma));
6314 mc.mb[8] = 0;
6315 mc.mb[9] = cpu_to_le16(vha->vp_idx);
6316
6317 rval = qla24xx_send_mb_cmd(vha, &mc);
6318 if (rval != QLA_SUCCESS) {
Quinn Tran83548fe2017-06-02 09:12:01 -07006319 ql_dbg(ql_dbg_mbx, vha, 0x119b,
6320 "%s: fail\n", __func__);
Quinn Tran15f30a52017-03-15 09:48:52 -07006321 } else {
6322 *entries = mc.mb[1];
Quinn Tran83548fe2017-06-02 09:12:01 -07006323 ql_dbg(ql_dbg_mbx, vha, 0x119c,
6324 "%s: done\n", __func__);
Quinn Tran15f30a52017-03-15 09:48:52 -07006325 }
6326done:
6327 return rval;
6328}
Duane Grigsbydeeae7a2017-07-21 09:32:25 -07006329
6330int qla27xx_set_zio_threshold(scsi_qla_host_t *vha, uint16_t value)
6331{
6332 int rval;
6333 mbx_cmd_t mc;
6334 mbx_cmd_t *mcp = &mc;
6335
6336 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1200,
6337 "Entered %s\n", __func__);
6338
6339 memset(mcp->mb, 0 , sizeof(mcp->mb));
6340 mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD;
6341 mcp->mb[1] = cpu_to_le16(1);
6342 mcp->mb[2] = cpu_to_le16(value);
6343 mcp->out_mb = MBX_2 | MBX_1 | MBX_0;
6344 mcp->in_mb = MBX_2 | MBX_0;
6345 mcp->tov = MBX_TOV_SECONDS;
6346 mcp->flags = 0;
6347
6348 rval = qla2x00_mailbox_command(vha, mcp);
6349
6350 ql_dbg(ql_dbg_mbx, vha, 0x1201, "%s %x\n",
6351 (rval != QLA_SUCCESS) ? "Failed" : "Done", rval);
6352
6353 return rval;
6354}
6355
6356int qla27xx_get_zio_threshold(scsi_qla_host_t *vha, uint16_t *value)
6357{
6358 int rval;
6359 mbx_cmd_t mc;
6360 mbx_cmd_t *mcp = &mc;
6361
6362 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1203,
6363 "Entered %s\n", __func__);
6364
6365 memset(mcp->mb, 0, sizeof(mcp->mb));
6366 mcp->mb[0] = MBC_GET_SET_ZIO_THRESHOLD;
6367 mcp->mb[1] = cpu_to_le16(0);
6368 mcp->out_mb = MBX_1 | MBX_0;
6369 mcp->in_mb = MBX_2 | MBX_0;
6370 mcp->tov = MBX_TOV_SECONDS;
6371 mcp->flags = 0;
6372
6373 rval = qla2x00_mailbox_command(vha, mcp);
6374 if (rval == QLA_SUCCESS)
6375 *value = mc.mb[2];
6376
6377 ql_dbg(ql_dbg_mbx, vha, 0x1205, "%s %x\n",
6378 (rval != QLA_SUCCESS) ? "Failed" : "Done", rval);
6379
6380 return rval;
6381}
Quinn Trane4e3a2c2017-08-23 15:05:07 -07006382
6383int
6384qla2x00_read_sfp_dev(struct scsi_qla_host *vha, char *buf, int count)
6385{
6386 struct qla_hw_data *ha = vha->hw;
6387 uint16_t iter, addr, offset;
6388 dma_addr_t phys_addr;
6389 int rval, c;
6390 u8 *sfp_data;
6391
6392 memset(ha->sfp_data, 0, SFP_DEV_SIZE);
6393 addr = 0xa0;
6394 phys_addr = ha->sfp_data_dma;
6395 sfp_data = ha->sfp_data;
6396 offset = c = 0;
6397
6398 for (iter = 0; iter < SFP_DEV_SIZE / SFP_BLOCK_SIZE; iter++) {
6399 if (iter == 4) {
6400 /* Skip to next device address. */
6401 addr = 0xa2;
6402 offset = 0;
6403 }
6404
6405 rval = qla2x00_read_sfp(vha, phys_addr, sfp_data,
6406 addr, offset, SFP_BLOCK_SIZE, BIT_1);
6407 if (rval != QLA_SUCCESS) {
6408 ql_log(ql_log_warn, vha, 0x706d,
6409 "Unable to read SFP data (%x/%x/%x).\n", rval,
6410 addr, offset);
6411
6412 return rval;
6413 }
6414
6415 if (buf && (c < count)) {
6416 u16 sz;
6417
6418 if ((count - c) >= SFP_BLOCK_SIZE)
6419 sz = SFP_BLOCK_SIZE;
6420 else
6421 sz = count - c;
6422
6423 memcpy(buf, sfp_data, sz);
6424 buf += SFP_BLOCK_SIZE;
6425 c += sz;
6426 }
6427 phys_addr += SFP_BLOCK_SIZE;
6428 sfp_data += SFP_BLOCK_SIZE;
6429 offset += SFP_BLOCK_SIZE;
6430 }
6431
6432 return rval;
6433}
Quinn Tran94d83e32017-12-28 12:33:23 -08006434
6435int qla24xx_res_count_wait(struct scsi_qla_host *vha,
6436 uint16_t *out_mb, int out_mb_sz)
6437{
6438 int rval = QLA_FUNCTION_FAILED;
6439 mbx_cmd_t mc;
6440
6441 if (!vha->hw->flags.fw_started)
6442 goto done;
6443
6444 memset(&mc, 0, sizeof(mc));
6445 mc.mb[0] = MBC_GET_RESOURCE_COUNTS;
6446
6447 rval = qla24xx_send_mb_cmd(vha, &mc);
6448 if (rval != QLA_SUCCESS) {
6449 ql_dbg(ql_dbg_mbx, vha, 0xffff,
6450 "%s: fail\n", __func__);
6451 } else {
6452 if (out_mb_sz <= SIZEOF_IOCB_MB_REG)
6453 memcpy(out_mb, mc.mb, out_mb_sz);
6454 else
6455 memcpy(out_mb, mc.mb, SIZEOF_IOCB_MB_REG);
6456
6457 ql_dbg(ql_dbg_mbx, vha, 0xffff,
6458 "%s: done\n", __func__);
6459 }
6460done:
6461 return rval;
6462}