blob: 26ca18c3fa6a3c9a687b48bcd3b1117fd0b30687 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
Armen Baloyanbd21eaf2014-04-11 16:54:24 -04003 * Copyright (c) 2003-2014 QLogic Corporation
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
Andrew Vasquezfa90c542005-10-27 11:10:08 -07005 * See LICENSE.qla2xxx for copyright and licensing details.
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 */
7#include "qla_def.h"
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04008#include "qla_target.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -07009
10#include <linux/delay.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090011#include <linux/gfp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070012
Linus Torvalds1da177e2005-04-16 15:20:36 -070013
14/*
15 * qla2x00_mailbox_command
16 * Issue mailbox command and waits for completion.
17 *
18 * Input:
19 * ha = adapter block pointer.
20 * mcp = driver internal mbx struct pointer.
21 *
22 * Output:
23 * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data.
24 *
25 * Returns:
26 * 0 : QLA_SUCCESS = cmd performed success
27 * 1 : QLA_FUNCTION_FAILED (error encountered)
28 * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered)
29 *
30 * Context:
31 * Kernel context.
32 */
33static int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080034qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070035{
Himanshu Madhanid14e72f2015-04-09 15:00:03 -040036 int rval, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 unsigned long flags = 0;
Chad Dupuisf73cb692014-02-26 04:15:06 -050038 device_reg_t *reg;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070039 uint8_t abort_active;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070040 uint8_t io_lock_on;
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -070041 uint16_t command = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070042 uint16_t *iptr;
43 uint16_t __iomem *optr;
44 uint32_t cnt;
45 uint32_t mboxes;
Himanshu Madhanid14e72f2015-04-09 15:00:03 -040046 uint16_t __iomem *mbx_reg;
Linus Torvalds1da177e2005-04-16 15:20:36 -070047 unsigned long wait_time;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080048 struct qla_hw_data *ha = vha->hw;
49 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070050
Himanshu Madhanid14e72f2015-04-09 15:00:03 -040051
Arun Easi5e19ed92012-02-09 11:15:51 -080052 ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -070053
54 if (ha->pdev->error_state > pci_channel_io_frozen) {
Arun Easi5e19ed92012-02-09 11:15:51 -080055 ql_log(ql_log_warn, vha, 0x1001,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070056 "error_state is greater than pci_channel_io_frozen, "
57 "exiting.\n");
Seokmann Jub9b12f72009-03-24 09:08:18 -070058 return QLA_FUNCTION_TIMEOUT;
Saurav Kashyap7c3df132011-07-14 12:00:13 -070059 }
Seokmann Jub9b12f72009-03-24 09:08:18 -070060
Giridhar Malavalia9083012010-04-12 17:59:55 -070061 if (vha->device_flags & DFLG_DEV_FAILED) {
Arun Easi5e19ed92012-02-09 11:15:51 -080062 ql_log(ql_log_warn, vha, 0x1002,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070063 "Device in failed state, exiting.\n");
Giridhar Malavalia9083012010-04-12 17:59:55 -070064 return QLA_FUNCTION_TIMEOUT;
65 }
66
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070067 reg = ha->iobase;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080068 io_lock_on = base_vha->flags.init_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
70 rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080071 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070073
Andrew Vasquez85880802009-12-15 21:29:46 -080074 if (ha->flags.pci_channel_io_perm_failure) {
Arun Easi5e19ed92012-02-09 11:15:51 -080075 ql_log(ql_log_warn, vha, 0x1003,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070076 "Perm failure on EEH timeout MBX, exiting.\n");
Andrew Vasquez85880802009-12-15 21:29:46 -080077 return QLA_FUNCTION_TIMEOUT;
78 }
79
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -040080 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Giridhar Malavali862cd012011-02-23 15:27:11 -080081 /* Setting Link-Down error */
82 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
Arun Easi5e19ed92012-02-09 11:15:51 -080083 ql_log(ql_log_warn, vha, 0x1004,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070084 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Andrew Vasquez1806fcd2011-11-18 09:02:15 -080085 return QLA_FUNCTION_TIMEOUT;
Giridhar Malavali862cd012011-02-23 15:27:11 -080086 }
87
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070089 * Wait for active mailbox commands to finish by waiting at most tov
90 * seconds. This is to serialize actual issuing of mailbox cmds during
91 * non ISP abort time.
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080093 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
94 /* Timeout occurred. Return error. */
Arun Easi5e19ed92012-02-09 11:15:51 -080095 ql_log(ql_log_warn, vha, 0x1005,
Chad Dupuisd8c0d542012-02-09 11:15:46 -080096 "Cmd access timeout, cmd=0x%x, Exiting.\n",
97 mcp->mb[0]);
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080098 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 }
100
101 ha->flags.mbox_busy = 1;
102 /* Save mailbox command for debug */
103 ha->mcp = mcp;
104
Arun Easi5e19ed92012-02-09 11:15:51 -0800105 ql_dbg(ql_dbg_mbx, vha, 0x1006,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700106 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107
108 spin_lock_irqsave(&ha->hardware_lock, flags);
109
110 /* Load mailbox registers. */
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400111 if (IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -0700112 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400113 else if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha)))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700114 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
115 else
116 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117
118 iptr = mcp->mb;
119 command = mcp->mb[0];
120 mboxes = mcp->out_mb;
121
Joe Carnuccio7b711622014-09-25 05:16:43 -0400122 ql_dbg(ql_dbg_mbx, vha, 0x1111,
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700123 "Mailbox registers (OUT):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
125 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700126 optr =
127 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700128 if (mboxes & BIT_0) {
129 ql_dbg(ql_dbg_mbx, vha, 0x1112,
130 "mbox[%d]<-0x%04x\n", cnt, *iptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131 WRT_REG_WORD(optr, *iptr);
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700132 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
134 mboxes >>= 1;
135 optr++;
136 iptr++;
137 }
138
Arun Easi5e19ed92012-02-09 11:15:51 -0800139 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700140 "I/O Address = %p.\n", optr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
142 /* Issue set host interrupt command to send cmd out. */
143 ha->flags.mbox_int = 0;
144 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
145
146 /* Unlock mbx registers and wait for interrupt */
Arun Easi5e19ed92012-02-09 11:15:51 -0800147 ql_dbg(ql_dbg_mbx, vha, 0x100f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700148 "Going to unlock irq & waiting for interrupts. "
149 "jiffies=%lx.\n", jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
151 /* Wait for mbx cmd completion until timeout */
152
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800153 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
155
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400156 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700157 if (RD_REG_DWORD(&reg->isp82.hint) &
158 HINT_MBX_INT_PENDING) {
159 spin_unlock_irqrestore(&ha->hardware_lock,
160 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800161 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800162 ql_dbg(ql_dbg_mbx, vha, 0x1010,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700163 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700164 rval = QLA_FUNCTION_TIMEOUT;
165 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700166 }
167 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
168 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700169 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
170 else
171 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 spin_unlock_irqrestore(&ha->hardware_lock, flags);
173
Giridhar Malavali754d1242013-06-25 11:27:16 -0400174 if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
175 mcp->tov * HZ)) {
176 ql_dbg(ql_dbg_mbx, vha, 0x117a,
177 "cmd=%x Timeout.\n", command);
178 spin_lock_irqsave(&ha->hardware_lock, flags);
179 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
180 spin_unlock_irqrestore(&ha->hardware_lock, flags);
181 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 } else {
Arun Easi5e19ed92012-02-09 11:15:51 -0800183 ql_dbg(ql_dbg_mbx, vha, 0x1011,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700184 "Cmd=%x Polling Mode.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400186 if (IS_P3P_TYPE(ha)) {
Giridhar Malavalia9083012010-04-12 17:59:55 -0700187 if (RD_REG_DWORD(&reg->isp82.hint) &
188 HINT_MBX_INT_PENDING) {
189 spin_unlock_irqrestore(&ha->hardware_lock,
190 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800191 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800192 ql_dbg(ql_dbg_mbx, vha, 0x1012,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700193 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700194 rval = QLA_FUNCTION_TIMEOUT;
195 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700196 }
197 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
198 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700199 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
200 else
201 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
204 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
205 while (!ha->flags.mbox_int) {
206 if (time_after(jiffies, wait_time))
207 break;
208
209 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800210 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211
Andrew Vasquez85880802009-12-15 21:29:46 -0800212 if (!ha->flags.mbox_int &&
213 !(IS_QLA2200(ha) &&
214 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800215 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 } /* while */
Arun Easi5e19ed92012-02-09 11:15:51 -0800217 ql_dbg(ql_dbg_mbx, vha, 0x1013,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700218 "Waited %d sec.\n",
219 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 }
221
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 /* Check whether we timed out */
223 if (ha->flags.mbox_int) {
224 uint16_t *iptr2;
225
Arun Easi5e19ed92012-02-09 11:15:51 -0800226 ql_dbg(ql_dbg_mbx, vha, 0x1014,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700227 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228
229 /* Got interrupt. Clear the flag. */
230 ha->flags.mbox_int = 0;
231 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
232
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400233 if (IS_P3P_TYPE(ha) && ha->flags.isp82xx_fw_hung) {
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700234 ha->flags.mbox_busy = 0;
235 /* Setting Link-Down error */
236 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
237 ha->mcp = NULL;
238 rval = QLA_FUNCTION_FAILED;
Arun Easi5e19ed92012-02-09 11:15:51 -0800239 ql_log(ql_log_warn, vha, 0x1015,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700240 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700241 goto premature_exit;
242 }
243
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400244 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
247 /* Load return mailbox registers. */
248 iptr2 = mcp->mb;
249 iptr = (uint16_t *)&ha->mailbox_out[0];
250 mboxes = mcp->in_mb;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700251
252 ql_dbg(ql_dbg_mbx, vha, 0x1113,
253 "Mailbox registers (IN):\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700255 if (mboxes & BIT_0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256 *iptr2 = *iptr;
Joe Carnuccio0e31a2c2013-08-23 07:25:37 -0700257 ql_dbg(ql_dbg_mbx, vha, 0x1114,
258 "mbox[%d]->0x%04x\n", cnt, *iptr2);
259 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260
261 mboxes >>= 1;
262 iptr2++;
263 iptr++;
264 }
265 } else {
266
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700267 uint16_t mb0;
268 uint32_t ictrl;
269
Andrew Vasqueze4289242007-07-19 15:05:56 -0700270 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700271 mb0 = RD_REG_WORD(&reg->isp24.mailbox0);
272 ictrl = RD_REG_DWORD(&reg->isp24.ictrl);
273 } else {
Andrew Vasquezcca53352005-08-26 19:08:30 -0700274 mb0 = RD_MAILBOX_REG(ha, &reg->isp, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700275 ictrl = RD_REG_WORD(&reg->isp.ictrl);
276 }
Arun Easi5e19ed92012-02-09 11:15:51 -0800277 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119,
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400278 "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx "
279 "mb[0]=0x%x\n", command, ictrl, jiffies, mb0);
Arun Easi5e19ed92012-02-09 11:15:51 -0800280 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800282 /*
283 * Attempt to capture a firmware dump for further analysis
Chad Dupuisb8eb4132013-06-25 11:27:20 -0400284 * of the current firmware state. We do not need to do this
285 * if we are intentionally generating a dump.
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800286 */
Chad Dupuisb8eb4132013-06-25 11:27:20 -0400287 if (mcp->mb[0] != MBC_GEN_SYSTEM_ERROR)
288 ha->isp_ops->fw_dump(vha, 0);
Chad Dupuisf55bfc82012-02-09 11:15:53 -0800289
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 rval = QLA_FUNCTION_TIMEOUT;
291 }
292
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 ha->flags.mbox_busy = 0;
294
295 /* Clean up */
296 ha->mcp = NULL;
297
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800298 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800299 ql_dbg(ql_dbg_mbx, vha, 0x101a,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700300 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301
302 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800303 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 }
305
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700306 if (rval == QLA_FUNCTION_TIMEOUT &&
307 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800308 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
309 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 /* not in dpc. schedule it for dpc to take over. */
Arun Easi5e19ed92012-02-09 11:15:51 -0800311 ql_dbg(ql_dbg_mbx, vha, 0x101b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700312 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700313
314 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
315 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
316 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800317 if (IS_QLA82XX(ha)) {
318 ql_dbg(ql_dbg_mbx, vha, 0x112a,
319 "disabling pause transmit on port "
320 "0 & 1.\n");
321 qla82xx_wr_32(ha,
322 QLA82XX_CRB_NIU + 0x98,
323 CRB_NIU_XG_PAUSE_CTL_P0|
324 CRB_NIU_XG_PAUSE_CTL_P1);
325 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700326 ql_log(ql_log_info, base_vha, 0x101c,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400327 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800328 "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "
329 "abort.\n", command, mcp->mb[0],
330 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700331 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
332 qla2xxx_wake_dpc(vha);
333 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 /* call abort directly since we are in the DPC thread */
Arun Easi5e19ed92012-02-09 11:15:51 -0800336 ql_dbg(ql_dbg_mbx, vha, 0x101d,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700337 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700339 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
340 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
341 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800342 if (IS_QLA82XX(ha)) {
343 ql_dbg(ql_dbg_mbx, vha, 0x112b,
344 "disabling pause transmit on port "
345 "0 & 1.\n");
346 qla82xx_wr_32(ha,
347 QLA82XX_CRB_NIU + 0x98,
348 CRB_NIU_XG_PAUSE_CTL_P0|
349 CRB_NIU_XG_PAUSE_CTL_P1);
350 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700351 ql_log(ql_log_info, base_vha, 0x101e,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400352 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800353 "mb[0]=0x%x. Scheduling ISP abort ",
354 command, mcp->mb[0]);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700355 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
356 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
Giridhar Malavalid3360962012-02-09 11:14:10 -0800357 /* Allow next mbx cmd to come in. */
358 complete(&ha->mbx_cmd_comp);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700359 if (ha->isp_ops->abort_isp(vha)) {
360 /* Failed. retry later. */
361 set_bit(ISP_ABORT_NEEDED,
362 &vha->dpc_flags);
363 }
364 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Arun Easi5e19ed92012-02-09 11:15:51 -0800365 ql_dbg(ql_dbg_mbx, vha, 0x101f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700366 "Finished abort_isp.\n");
Giridhar Malavalid3360962012-02-09 11:14:10 -0800367 goto mbx_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 }
370 }
371
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700372premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800374 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Giridhar Malavalid3360962012-02-09 11:14:10 -0800376mbx_done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 if (rval) {
Chad Dupuis34c58012014-08-08 07:38:08 -0400378 ql_dbg(ql_dbg_disc, base_vha, 0x1020,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800379 "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n",
380 mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command);
Himanshu Madhanid14e72f2015-04-09 15:00:03 -0400381
382 ql_dbg(ql_dbg_disc, vha, 0x1115,
383 "host status: 0x%x, flags:0x%lx, intr ctrl reg:0x%x, intr status:0x%x\n",
384 RD_REG_DWORD(&reg->isp24.host_status),
385 ha->fw_dump_cap_flags,
386 RD_REG_DWORD(&reg->isp24.ictrl),
387 RD_REG_DWORD(&reg->isp24.istatus));
388
389 mbx_reg = &reg->isp24.mailbox0;
390 for (i = 0; i < 6; i++)
391 ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x1116,
392 "mbox[%d] 0x%04x\n", i, RD_REG_WORD(mbx_reg++));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700394 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 }
396
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397 return rval;
398}
399
Linus Torvalds1da177e2005-04-16 15:20:36 -0700400int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800401qla2x00_load_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t risc_addr,
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800402 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403{
404 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800405 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 mbx_cmd_t mc;
407 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400409 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022,
410 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Andrew Vasqueze4289242007-07-19 15:05:56 -0700412 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800413 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
414 mcp->mb[8] = MSW(risc_addr);
415 mcp->out_mb = MBX_8|MBX_0;
416 } else {
417 mcp->mb[0] = MBC_LOAD_RISC_RAM;
418 mcp->out_mb = MBX_0;
419 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420 mcp->mb[1] = LSW(risc_addr);
421 mcp->mb[2] = MSW(req_dma);
422 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 mcp->mb[6] = MSW(MSD(req_dma));
424 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800425 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700426 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700427 mcp->mb[4] = MSW(risc_code_size);
428 mcp->mb[5] = LSW(risc_code_size);
429 mcp->out_mb |= MBX_5|MBX_4;
430 } else {
431 mcp->mb[4] = LSW(risc_code_size);
432 mcp->out_mb |= MBX_4;
433 }
434
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700436 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800438 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700441 ql_dbg(ql_dbg_mbx, vha, 0x1023,
442 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400444 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,
445 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 }
447
448 return rval;
449}
450
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700451#define EXTENDED_BB_CREDITS BIT_0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452/*
453 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700454 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 *
456 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700457 * ha = adapter block pointer.
458 * TARGET_QUEUE_LOCK must be released.
459 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460 *
461 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700462 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 *
464 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700465 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 */
467int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800468qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469{
470 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800471 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 mbx_cmd_t mc;
473 mbx_cmd_t *mcp = &mc;
474
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400475 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,
476 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477
478 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700479 mcp->out_mb = MBX_0;
480 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700481 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700482 mcp->mb[1] = MSW(risc_addr);
483 mcp->mb[2] = LSW(risc_addr);
484 mcp->mb[3] = 0;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500485 if (IS_QLA25XX(ha) || IS_QLA81XX(ha) || IS_QLA83XX(ha) ||
486 IS_QLA27XX(ha)) {
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700487 struct nvram_81xx *nv = ha->nvram;
488 mcp->mb[4] = (nv->enhanced_features &
489 EXTENDED_BB_CREDITS);
490 } else
491 mcp->mb[4] = 0;
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700492 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700493 mcp->in_mb |= MBX_1;
494 } else {
495 mcp->mb[1] = LSW(risc_addr);
496 mcp->out_mb |= MBX_1;
497 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
498 mcp->mb[2] = 0;
499 mcp->out_mb |= MBX_2;
500 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700501 }
502
Ravi Anandb93480e2008-04-03 13:13:25 -0700503 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800505 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700506
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700507 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700508 ql_dbg(ql_dbg_mbx, vha, 0x1026,
509 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700510 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700511 if (IS_FWI2_CAPABLE(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400512 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1027,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700513 "Done exchanges=%x.\n", mcp->mb[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700514 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400515 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
516 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700517 }
518 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
520 return rval;
521}
522
523/*
524 * qla2x00_get_fw_version
525 * Get firmware version.
526 *
527 * Input:
528 * ha: adapter state pointer.
529 * major: pointer for major number.
530 * minor: pointer for minor number.
531 * subminor: pointer for subminor number.
532 *
533 * Returns:
534 * qla2x00 local function return status code.
535 *
536 * Context:
537 * Kernel context.
538 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700539int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800540qla2x00_get_fw_version(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700541{
542 int rval;
543 mbx_cmd_t mc;
544 mbx_cmd_t *mcp = &mc;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800545 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400547 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029,
548 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
550 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
551 mcp->out_mb = MBX_0;
552 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400553 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha) || IS_QLA8044(ha))
Andrew Vasquez55a96152009-03-24 09:08:03 -0700554 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Saurav Kashyapfb0effe2012-08-22 14:21:28 -0400555 if (IS_FWI2_CAPABLE(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800556 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
Chad Dupuisf73cb692014-02-26 04:15:06 -0500557 if (IS_QLA27XX(ha))
558 mcp->in_mb |= MBX_21|MBX_20|MBX_19|MBX_18;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700560 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800561 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700562 if (rval != QLA_SUCCESS)
563 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564
565 /* Return mailbox data. */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800566 ha->fw_major_version = mcp->mb[1];
567 ha->fw_minor_version = mcp->mb[2];
568 ha->fw_subminor_version = mcp->mb[3];
569 ha->fw_attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800570 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800571 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 else
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800573 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -0400574 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw) || IS_QLA8044(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800575 ha->mpi_version[0] = mcp->mb[10] & 0xff;
576 ha->mpi_version[1] = mcp->mb[11] >> 8;
577 ha->mpi_version[2] = mcp->mb[11] & 0xff;
578 ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
579 ha->phy_version[0] = mcp->mb[8] & 0xff;
580 ha->phy_version[1] = mcp->mb[9] >> 8;
581 ha->phy_version[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800582 }
Saurav Kashyap81178772012-08-22 14:21:04 -0400583 if (IS_FWI2_CAPABLE(ha)) {
584 ha->fw_attributes_h = mcp->mb[15];
585 ha->fw_attributes_ext[0] = mcp->mb[16];
586 ha->fw_attributes_ext[1] = mcp->mb[17];
587 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,
588 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
589 __func__, mcp->mb[15], mcp->mb[6]);
590 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
591 "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
592 __func__, mcp->mb[17], mcp->mb[16]);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800593 }
Chad Dupuisf73cb692014-02-26 04:15:06 -0500594 if (IS_QLA27XX(ha)) {
595 ha->fw_shared_ram_start = (mcp->mb[19] << 16) | mcp->mb[18];
596 ha->fw_shared_ram_end = (mcp->mb[21] << 16) | mcp->mb[20];
597 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800598
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700599failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 if (rval != QLA_SUCCESS) {
601 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700602 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 } else {
604 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400605 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b,
606 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700608 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609}
610
611/*
612 * qla2x00_get_fw_options
613 * Set firmware options.
614 *
615 * Input:
616 * ha = adapter block pointer.
617 * fwopt = pointer for firmware options.
618 *
619 * Returns:
620 * qla2x00 local function return status code.
621 *
622 * Context:
623 * Kernel context.
624 */
625int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800626qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627{
628 int rval;
629 mbx_cmd_t mc;
630 mbx_cmd_t *mcp = &mc;
631
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400632 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c,
633 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634
635 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
636 mcp->out_mb = MBX_0;
637 mcp->in_mb = MBX_3|MBX_2|MBX_1|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
642 if (rval != QLA_SUCCESS) {
643 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700644 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700646 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700647 fwopts[1] = mcp->mb[1];
648 fwopts[2] = mcp->mb[2];
649 fwopts[3] = mcp->mb[3];
650
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400651 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e,
652 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653 }
654
655 return rval;
656}
657
658
659/*
660 * qla2x00_set_fw_options
661 * Set firmware options.
662 *
663 * Input:
664 * ha = adapter block pointer.
665 * fwopt = pointer for firmware options.
666 *
667 * Returns:
668 * qla2x00 local function return status code.
669 *
670 * Context:
671 * Kernel context.
672 */
673int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800674qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675{
676 int rval;
677 mbx_cmd_t mc;
678 mbx_cmd_t *mcp = &mc;
679
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400680 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f,
681 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682
683 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
684 mcp->mb[1] = fwopts[1];
685 mcp->mb[2] = fwopts[2];
686 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700687 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800689 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700690 mcp->in_mb |= MBX_1;
691 } else {
692 mcp->mb[10] = fwopts[10];
693 mcp->mb[11] = fwopts[11];
694 mcp->mb[12] = 0; /* Undocumented, but used */
695 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
696 }
Ravi Anandb93480e2008-04-03 13:13:25 -0700697 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800699 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700701 fwopts[0] = mcp->mb[0];
702
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 if (rval != QLA_SUCCESS) {
704 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700705 ql_dbg(ql_dbg_mbx, vha, 0x1030,
706 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 } else {
708 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400709 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031,
710 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 }
712
713 return rval;
714}
715
716/*
717 * qla2x00_mbx_reg_test
718 * Mailbox register wrap test.
719 *
720 * Input:
721 * ha = adapter block pointer.
722 * TARGET_QUEUE_LOCK must be released.
723 * ADAPTER_STATE_LOCK must be released.
724 *
725 * Returns:
726 * qla2x00 local function return status code.
727 *
728 * Context:
729 * Kernel context.
730 */
731int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800732qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733{
734 int rval;
735 mbx_cmd_t mc;
736 mbx_cmd_t *mcp = &mc;
737
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400738 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032,
739 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740
741 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
742 mcp->mb[1] = 0xAAAA;
743 mcp->mb[2] = 0x5555;
744 mcp->mb[3] = 0xAA55;
745 mcp->mb[4] = 0x55AA;
746 mcp->mb[5] = 0xA5A5;
747 mcp->mb[6] = 0x5A5A;
748 mcp->mb[7] = 0x2525;
749 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
750 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 -0700751 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800753 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754
755 if (rval == QLA_SUCCESS) {
756 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
757 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
758 rval = QLA_FUNCTION_FAILED;
759 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
760 mcp->mb[7] != 0x2525)
761 rval = QLA_FUNCTION_FAILED;
762 }
763
764 if (rval != QLA_SUCCESS) {
765 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700766 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700767 } else {
768 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400769 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034,
770 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 }
772
773 return rval;
774}
775
776/*
777 * qla2x00_verify_checksum
778 * Verify firmware checksum.
779 *
780 * Input:
781 * ha = adapter block pointer.
782 * TARGET_QUEUE_LOCK must be released.
783 * ADAPTER_STATE_LOCK must be released.
784 *
785 * Returns:
786 * qla2x00 local function return status code.
787 *
788 * Context:
789 * Kernel context.
790 */
791int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800792qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793{
794 int rval;
795 mbx_cmd_t mc;
796 mbx_cmd_t *mcp = &mc;
797
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400798 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035,
799 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
801 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700802 mcp->out_mb = MBX_0;
803 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800804 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700805 mcp->mb[1] = MSW(risc_addr);
806 mcp->mb[2] = LSW(risc_addr);
807 mcp->out_mb |= MBX_2|MBX_1;
808 mcp->in_mb |= MBX_2|MBX_1;
809 } else {
810 mcp->mb[1] = LSW(risc_addr);
811 mcp->out_mb |= MBX_1;
812 mcp->in_mb |= MBX_1;
813 }
814
Ravi Anandb93480e2008-04-03 13:13:25 -0700815 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800817 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818
819 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700820 ql_dbg(ql_dbg_mbx, vha, 0x1036,
821 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
822 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400824 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037,
825 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700826 }
827
828 return rval;
829}
830
831/*
832 * qla2x00_issue_iocb
833 * Issue IOCB using mailbox command
834 *
835 * Input:
836 * ha = adapter state pointer.
837 * buffer = buffer pointer.
838 * phys_addr = physical address of buffer.
839 * size = size of buffer.
840 * TARGET_QUEUE_LOCK must be released.
841 * ADAPTER_STATE_LOCK must be released.
842 *
843 * Returns:
844 * qla2x00 local function return status code.
845 *
846 * Context:
847 * Kernel context.
848 */
Giridhar Malavali6e980162010-03-19 17:03:58 -0700849int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800850qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700851 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852{
853 int rval;
854 mbx_cmd_t mc;
855 mbx_cmd_t *mcp = &mc;
856
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400857 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038,
858 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700859
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
861 mcp->mb[1] = 0;
862 mcp->mb[2] = MSW(phys_addr);
863 mcp->mb[3] = LSW(phys_addr);
864 mcp->mb[6] = MSW(MSD(phys_addr));
865 mcp->mb[7] = LSW(MSD(phys_addr));
866 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
867 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700868 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800870 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871
872 if (rval != QLA_SUCCESS) {
873 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700874 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700876 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
877
878 /* Mask reserved bits. */
879 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800880 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400881 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a,
882 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 }
884
885 return rval;
886}
887
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700888int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800889qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700890 size_t size)
891{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800892 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700893 MBX_TOV_SECONDS);
894}
895
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896/*
897 * qla2x00_abort_command
898 * Abort command aborts a specified IOCB.
899 *
900 * Input:
901 * ha = adapter block pointer.
902 * sp = SB structure pointer.
903 *
904 * Returns:
905 * qla2x00 local function return status code.
906 *
907 * Context:
908 * Kernel context.
909 */
910int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700911qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912{
913 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800915 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916 mbx_cmd_t mc;
917 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700918 fc_port_t *fcport = sp->fcport;
919 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800920 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700921 struct req_que *req = vha->req;
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800922 struct scsi_cmnd *cmd = GET_CMD_SP(sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400924 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b,
925 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700927 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -0500928 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800929 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930 break;
931 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700932 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700933
Chad Dupuis8d93f552013-01-30 03:34:37 -0500934 if (handle == req->num_outstanding_cmds) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 /* command not found */
936 return QLA_FUNCTION_FAILED;
937 }
938
939 mcp->mb[0] = MBC_ABORT_COMMAND;
940 if (HAS_EXTENDED_IDS(ha))
941 mcp->mb[1] = fcport->loop_id;
942 else
943 mcp->mb[1] = fcport->loop_id << 8;
944 mcp->mb[2] = (uint16_t)handle;
945 mcp->mb[3] = (uint16_t)(handle >> 16);
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800946 mcp->mb[6] = (uint16_t)cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
948 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700949 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800951 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700952
953 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700954 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400956 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d,
957 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 }
959
960 return rval;
961}
962
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +0200964qla2x00_abort_target(struct fc_port *fcport, uint64_t l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700965{
Andrew Vasquez523ec772008-04-03 13:13:24 -0700966 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967 mbx_cmd_t mc;
968 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800969 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800970 struct req_que *req;
971 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972
Andrew Vasquez523ec772008-04-03 13:13:24 -0700973 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800974 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700975
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400976 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e,
977 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700978
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700979 req = vha->hw->req_q_map[0];
980 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700982 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800983 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 mcp->mb[1] = fcport->loop_id;
985 mcp->mb[10] = 0;
986 mcp->out_mb |= MBX_10;
987 } else {
988 mcp->mb[1] = fcport->loop_id << 8;
989 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800990 mcp->mb[2] = vha->hw->loop_reset_delay;
991 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992
993 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700994 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800996 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400998 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f,
999 "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001000 }
1001
1002 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001003 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
1004 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001005 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001006 ql_dbg(ql_dbg_mbx, vha, 0x1040,
1007 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001009 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041,
1010 "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001011 }
1012
1013 return rval;
1014}
1015
1016int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001017qla2x00_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07001018{
1019 int rval, rval2;
1020 mbx_cmd_t mc;
1021 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001022 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001023 struct req_que *req;
1024 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001025
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001026 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001027
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001028 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042,
1029 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001030
Giridhar Malavali7e2b8952010-05-28 15:08:17 -07001031 req = vha->hw->req_q_map[0];
1032 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001033 mcp->mb[0] = MBC_LUN_RESET;
1034 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001035 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -07001036 mcp->mb[1] = fcport->loop_id;
1037 else
1038 mcp->mb[1] = fcport->loop_id << 8;
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02001039 mcp->mb[2] = (u32)l;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001040 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001041 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001042
1043 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001044 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001045 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001046 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001047 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001048 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001049 }
1050
1051 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001052 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1053 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001054 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001055 ql_dbg(ql_dbg_mbx, vha, 0x1044,
1056 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001057 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001058 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045,
1059 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 }
1061
1062 return rval;
1063}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001064
1065/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001066 * qla2x00_get_adapter_id
1067 * Get adapter ID and topology.
1068 *
1069 * Input:
1070 * ha = adapter block pointer.
1071 * id = pointer for loop ID.
1072 * al_pa = pointer for AL_PA.
1073 * area = pointer for area.
1074 * domain = pointer for domain.
1075 * top = pointer for topology.
1076 * TARGET_QUEUE_LOCK must be released.
1077 * ADAPTER_STATE_LOCK must be released.
1078 *
1079 * Returns:
1080 * qla2x00 local function return status code.
1081 *
1082 * Context:
1083 * Kernel context.
1084 */
1085int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001086qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001087 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088{
1089 int rval;
1090 mbx_cmd_t mc;
1091 mbx_cmd_t *mcp = &mc;
1092
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001093 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046,
1094 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095
1096 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001097 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001098 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001099 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001100 if (IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001101 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001102 if (IS_FWI2_CAPABLE(vha->hw))
1103 mcp->in_mb |= MBX_19|MBX_18|MBX_17|MBX_16;
Ravi Anandb93480e2008-04-03 13:13:25 -07001104 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001106 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001107 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1108 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001109 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1110 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111
1112 /* Return data. */
1113 *id = mcp->mb[1];
1114 *al_pa = LSB(mcp->mb[2]);
1115 *area = MSB(mcp->mb[2]);
1116 *domain = LSB(mcp->mb[3]);
1117 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001118 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119
1120 if (rval != QLA_SUCCESS) {
1121 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001122 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001123 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001124 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048,
1125 "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001126
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001127 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001128 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1129 vha->fcoe_fcf_idx = mcp->mb[10];
1130 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1131 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1132 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1133 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1134 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1135 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1136 }
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04001137 /* If FA-WWN supported */
1138 if (mcp->mb[7] & BIT_14) {
1139 vha->port_name[0] = MSB(mcp->mb[16]);
1140 vha->port_name[1] = LSB(mcp->mb[16]);
1141 vha->port_name[2] = MSB(mcp->mb[17]);
1142 vha->port_name[3] = LSB(mcp->mb[17]);
1143 vha->port_name[4] = MSB(mcp->mb[18]);
1144 vha->port_name[5] = LSB(mcp->mb[18]);
1145 vha->port_name[6] = MSB(mcp->mb[19]);
1146 vha->port_name[7] = LSB(mcp->mb[19]);
1147 fc_host_port_name(vha->host) =
1148 wwn_to_u64(vha->port_name);
1149 ql_dbg(ql_dbg_mbx, vha, 0x10ca,
1150 "FA-WWN acquired %016llx\n",
1151 wwn_to_u64(vha->port_name));
1152 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 }
1154
1155 return rval;
1156}
1157
1158/*
1159 * qla2x00_get_retry_cnt
1160 * Get current firmware login retry count and delay.
1161 *
1162 * Input:
1163 * ha = adapter block pointer.
1164 * retry_cnt = pointer to login retry count.
1165 * tov = pointer to login timeout value.
1166 *
1167 * Returns:
1168 * qla2x00 local function return status code.
1169 *
1170 * Context:
1171 * Kernel context.
1172 */
1173int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001174qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 uint16_t *r_a_tov)
1176{
1177 int rval;
1178 uint16_t ratov;
1179 mbx_cmd_t mc;
1180 mbx_cmd_t *mcp = &mc;
1181
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001182 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049,
1183 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184
1185 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1186 mcp->out_mb = MBX_0;
1187 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001188 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001190 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191
1192 if (rval != QLA_SUCCESS) {
1193 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001194 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1195 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 } else {
1197 /* Convert returned data and check our values. */
1198 *r_a_tov = mcp->mb[3] / 2;
1199 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1200 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1201 /* Update to the larger values */
1202 *retry_cnt = (uint8_t)mcp->mb[1];
1203 *tov = ratov;
1204 }
1205
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001206 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001207 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 }
1209
1210 return rval;
1211}
1212
1213/*
1214 * qla2x00_init_firmware
1215 * Initialize adapter firmware.
1216 *
1217 * Input:
1218 * ha = adapter block pointer.
1219 * dptr = Initialization control block pointer.
1220 * size = size of initialization control block.
1221 * TARGET_QUEUE_LOCK must be released.
1222 * ADAPTER_STATE_LOCK must be released.
1223 *
1224 * Returns:
1225 * qla2x00 local function return status code.
1226 *
1227 * Context:
1228 * Kernel context.
1229 */
1230int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001231qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232{
1233 int rval;
1234 mbx_cmd_t mc;
1235 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001236 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001238 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,
1239 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04001241 if (IS_P3P_TYPE(ha) && ql2xdbwr)
Bart Van Assche8dfa4b5a2015-07-09 07:24:50 -07001242 qla82xx_wr_32(ha, (uintptr_t __force)ha->nxdb_wr_ptr,
Giridhar Malavalia9083012010-04-12 17:59:55 -07001243 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1244
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001245 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001246 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1247 else
1248 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1249
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001250 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251 mcp->mb[2] = MSW(ha->init_cb_dma);
1252 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1254 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001255 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Joe Carnuccio4ef21bd2013-10-30 03:38:11 -04001256 if (ha->ex_init_cb && ha->ex_init_cb->ex_version) {
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001257 mcp->mb[1] = BIT_0;
1258 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1259 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1260 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1261 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1262 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1263 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1264 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001265 /* 1 and 2 should normally be captured. */
1266 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05001267 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001268 /* mb3 is additional info about the installed SFP. */
1269 mcp->in_mb |= MBX_3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 mcp->buf_size = size;
1271 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001272 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001273 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274
1275 if (rval != QLA_SUCCESS) {
1276 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001277 ql_dbg(ql_dbg_mbx, vha, 0x104d,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001278 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1279 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280 } else {
1281 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001282 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,
1283 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 }
1285
1286 return rval;
1287}
1288
1289/*
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001290 * qla2x00_get_node_name_list
1291 * Issue get node name list mailbox command, kmalloc()
1292 * and return the resulting list. Caller must kfree() it!
1293 *
1294 * Input:
1295 * ha = adapter state pointer.
1296 * out_data = resulting list
1297 * out_len = length of the resulting list
1298 *
1299 * Returns:
1300 * qla2x00 local function return status code.
1301 *
1302 * Context:
1303 * Kernel context.
1304 */
1305int
1306qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len)
1307{
1308 struct qla_hw_data *ha = vha->hw;
1309 struct qla_port_24xx_data *list = NULL;
1310 void *pmap;
1311 mbx_cmd_t mc;
1312 dma_addr_t pmap_dma;
1313 ulong dma_size;
1314 int rval, left;
1315
1316 left = 1;
1317 while (left > 0) {
1318 dma_size = left * sizeof(*list);
1319 pmap = dma_alloc_coherent(&ha->pdev->dev, dma_size,
1320 &pmap_dma, GFP_KERNEL);
1321 if (!pmap) {
1322 ql_log(ql_log_warn, vha, 0x113f,
1323 "%s(%ld): DMA Alloc failed of %ld\n",
1324 __func__, vha->host_no, dma_size);
1325 rval = QLA_MEMORY_ALLOC_FAILED;
1326 goto out;
1327 }
1328
1329 mc.mb[0] = MBC_PORT_NODE_NAME_LIST;
1330 mc.mb[1] = BIT_1 | BIT_3;
1331 mc.mb[2] = MSW(pmap_dma);
1332 mc.mb[3] = LSW(pmap_dma);
1333 mc.mb[6] = MSW(MSD(pmap_dma));
1334 mc.mb[7] = LSW(MSD(pmap_dma));
1335 mc.mb[8] = dma_size;
1336 mc.out_mb = MBX_0|MBX_1|MBX_2|MBX_3|MBX_6|MBX_7|MBX_8;
1337 mc.in_mb = MBX_0|MBX_1;
1338 mc.tov = 30;
1339 mc.flags = MBX_DMA_IN;
1340
1341 rval = qla2x00_mailbox_command(vha, &mc);
1342 if (rval != QLA_SUCCESS) {
1343 if ((mc.mb[0] == MBS_COMMAND_ERROR) &&
1344 (mc.mb[1] == 0xA)) {
1345 left += le16_to_cpu(mc.mb[2]) /
1346 sizeof(struct qla_port_24xx_data);
1347 goto restart;
1348 }
1349 goto out_free;
1350 }
1351
1352 left = 0;
1353
Benoit Tainec1818f12014-05-26 17:21:16 +02001354 list = kmemdup(pmap, dma_size, GFP_KERNEL);
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001355 if (!list) {
1356 ql_log(ql_log_warn, vha, 0x1140,
1357 "%s(%ld): failed to allocate node names list "
1358 "structure.\n", __func__, vha->host_no);
1359 rval = QLA_MEMORY_ALLOC_FAILED;
1360 goto out_free;
1361 }
1362
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001363restart:
1364 dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
1365 }
1366
1367 *out_data = list;
1368 *out_len = dma_size;
1369
1370out:
1371 return rval;
1372
1373out_free:
1374 dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
1375 return rval;
1376}
1377
1378/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 * qla2x00_get_port_database
1380 * Issue normal/enhanced get port database mailbox command
1381 * and copy device name as necessary.
1382 *
1383 * Input:
1384 * ha = adapter state pointer.
1385 * dev = structure pointer.
1386 * opt = enhanced cmd option byte.
1387 *
1388 * Returns:
1389 * qla2x00 local function return status code.
1390 *
1391 * Context:
1392 * Kernel context.
1393 */
1394int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001395qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396{
1397 int rval;
1398 mbx_cmd_t mc;
1399 mbx_cmd_t *mcp = &mc;
1400 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001401 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001403 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001405 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f,
1406 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001408 pd24 = NULL;
1409 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001411 ql_log(ql_log_warn, vha, 0x1050,
1412 "Failed to allocate port database structure.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001413 return QLA_MEMORY_ALLOC_FAILED;
1414 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001415 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001417 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001418 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420 mcp->mb[2] = MSW(pd_dma);
1421 mcp->mb[3] = LSW(pd_dma);
1422 mcp->mb[6] = MSW(MSD(pd_dma));
1423 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001424 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001425 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001427 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001428 mcp->mb[1] = fcport->loop_id;
1429 mcp->mb[10] = opt;
1430 mcp->out_mb |= MBX_10|MBX_1;
1431 mcp->in_mb |= MBX_1;
1432 } else if (HAS_EXTENDED_IDS(ha)) {
1433 mcp->mb[1] = fcport->loop_id;
1434 mcp->mb[10] = opt;
1435 mcp->out_mb |= MBX_10|MBX_1;
1436 } else {
1437 mcp->mb[1] = fcport->loop_id << 8 | opt;
1438 mcp->out_mb |= MBX_1;
1439 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001440 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1441 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 mcp->flags = MBX_DMA_IN;
1443 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001444 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445 if (rval != QLA_SUCCESS)
1446 goto gpd_error_out;
1447
Andrew Vasqueze4289242007-07-19 15:05:56 -07001448 if (IS_FWI2_CAPABLE(ha)) {
Arun Easi0eba25d2012-02-09 11:15:58 -08001449 uint64_t zero = 0;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001450 pd24 = (struct port_database_24xx *) pd;
1451
1452 /* Check for logged in state. */
1453 if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1454 pd24->last_login_state != PDS_PRLI_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001455 ql_dbg(ql_dbg_mbx, vha, 0x1051,
1456 "Unable to verify login-state (%x/%x) for "
1457 "loop_id %x.\n", pd24->current_login_state,
1458 pd24->last_login_state, fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001459 rval = QLA_FUNCTION_FAILED;
1460 goto gpd_error_out;
1461 }
1462
Arun Easi0eba25d2012-02-09 11:15:58 -08001463 if (fcport->loop_id == FC_NO_LOOP_ID ||
1464 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1465 memcmp(fcport->port_name, pd24->port_name, 8))) {
1466 /* We lost the device mid way. */
1467 rval = QLA_NOT_LOGGED_IN;
1468 goto gpd_error_out;
1469 }
1470
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001471 /* Names are little-endian. */
1472 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1473 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1474
1475 /* Get port_id of device. */
1476 fcport->d_id.b.domain = pd24->port_id[0];
1477 fcport->d_id.b.area = pd24->port_id[1];
1478 fcport->d_id.b.al_pa = pd24->port_id[2];
1479 fcport->d_id.b.rsvd_1 = 0;
1480
1481 /* If not target must be initiator or unknown type. */
1482 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1483 fcport->port_type = FCT_INITIATOR;
1484 else
1485 fcport->port_type = FCT_TARGET;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001486
1487 /* Passback COS information. */
1488 fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ?
1489 FC_COS_CLASS2 : FC_COS_CLASS3;
1490
1491 if (pd24->prli_svc_param_word_3[0] & BIT_7)
1492 fcport->flags |= FCF_CONF_COMP_SUPPORTED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001493 } else {
Arun Easi0eba25d2012-02-09 11:15:58 -08001494 uint64_t zero = 0;
1495
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001496 /* Check for logged in state. */
1497 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1498 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001499 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1500 "Unable to verify login-state (%x/%x) - "
1501 "portid=%02x%02x%02x.\n", pd->master_state,
1502 pd->slave_state, fcport->d_id.b.domain,
1503 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001504 rval = QLA_FUNCTION_FAILED;
1505 goto gpd_error_out;
1506 }
1507
Arun Easi0eba25d2012-02-09 11:15:58 -08001508 if (fcport->loop_id == FC_NO_LOOP_ID ||
1509 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1510 memcmp(fcport->port_name, pd->port_name, 8))) {
1511 /* We lost the device mid way. */
1512 rval = QLA_NOT_LOGGED_IN;
1513 goto gpd_error_out;
1514 }
1515
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001516 /* Names are little-endian. */
1517 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1518 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1519
1520 /* Get port_id of device. */
1521 fcport->d_id.b.domain = pd->port_id[0];
1522 fcport->d_id.b.area = pd->port_id[3];
1523 fcport->d_id.b.al_pa = pd->port_id[2];
1524 fcport->d_id.b.rsvd_1 = 0;
1525
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001526 /* If not target must be initiator or unknown type. */
1527 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1528 fcport->port_type = FCT_INITIATOR;
1529 else
1530 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001531
1532 /* Passback COS information. */
1533 fcport->supported_classes = (pd->options & BIT_4) ?
1534 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535 }
1536
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537gpd_error_out:
1538 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1539
1540 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001541 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1542 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1543 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001545 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053,
1546 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547 }
1548
1549 return rval;
1550}
1551
1552/*
1553 * qla2x00_get_firmware_state
1554 * Get adapter firmware state.
1555 *
1556 * Input:
1557 * ha = adapter block pointer.
1558 * dptr = pointer for firmware state.
1559 * TARGET_QUEUE_LOCK must be released.
1560 * ADAPTER_STATE_LOCK must be released.
1561 *
1562 * Returns:
1563 * qla2x00 local function return status code.
1564 *
1565 * Context:
1566 * Kernel context.
1567 */
1568int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001569qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570{
1571 int rval;
1572 mbx_cmd_t mc;
1573 mbx_cmd_t *mcp = &mc;
1574
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001575 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
1576 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577
1578 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1579 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001580 if (IS_FWI2_CAPABLE(vha->hw))
Joe Carnucciob5a340d2014-09-25 05:16:48 -04001581 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001582 else
1583 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001584 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001586 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001588 /* Return firmware states. */
1589 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001590 if (IS_FWI2_CAPABLE(vha->hw)) {
1591 states[1] = mcp->mb[2];
1592 states[2] = mcp->mb[3];
1593 states[3] = mcp->mb[4];
1594 states[4] = mcp->mb[5];
Joe Carnucciob5a340d2014-09-25 05:16:48 -04001595 states[5] = mcp->mb[6]; /* DPORT status */
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001596 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597
1598 if (rval != QLA_SUCCESS) {
1599 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001600 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 } else {
1602 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001603 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,
1604 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 }
1606
1607 return rval;
1608}
1609
1610/*
1611 * qla2x00_get_port_name
1612 * Issue get port name mailbox command.
1613 * Returned name is in big endian format.
1614 *
1615 * Input:
1616 * ha = adapter block pointer.
1617 * loop_id = loop ID of device.
1618 * name = pointer for name.
1619 * TARGET_QUEUE_LOCK must be released.
1620 * ADAPTER_STATE_LOCK must be released.
1621 *
1622 * Returns:
1623 * qla2x00 local function return status code.
1624 *
1625 * Context:
1626 * Kernel context.
1627 */
1628int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001629qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 uint8_t opt)
1631{
1632 int rval;
1633 mbx_cmd_t mc;
1634 mbx_cmd_t *mcp = &mc;
1635
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001636 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057,
1637 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638
1639 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001640 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001641 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001642 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643 mcp->mb[1] = loop_id;
1644 mcp->mb[10] = opt;
1645 mcp->out_mb |= MBX_10;
1646 } else {
1647 mcp->mb[1] = loop_id << 8 | opt;
1648 }
1649
1650 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001651 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001653 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654
1655 if (rval != QLA_SUCCESS) {
1656 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001657 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 } else {
1659 if (name != NULL) {
1660 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05001661 name[0] = MSB(mcp->mb[2]);
1662 name[1] = LSB(mcp->mb[2]);
1663 name[2] = MSB(mcp->mb[3]);
1664 name[3] = LSB(mcp->mb[3]);
1665 name[4] = MSB(mcp->mb[6]);
1666 name[5] = LSB(mcp->mb[6]);
1667 name[6] = MSB(mcp->mb[7]);
1668 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 }
1670
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001671 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059,
1672 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 }
1674
1675 return rval;
1676}
1677
1678/*
Joe Carnuccio61e1b262013-02-08 01:57:48 -05001679 * qla24xx_link_initialization
1680 * Issue link initialization mailbox command.
1681 *
1682 * Input:
1683 * ha = adapter block pointer.
1684 * TARGET_QUEUE_LOCK must be released.
1685 * ADAPTER_STATE_LOCK must be released.
1686 *
1687 * Returns:
1688 * qla2x00 local function return status code.
1689 *
1690 * Context:
1691 * Kernel context.
1692 */
1693int
1694qla24xx_link_initialize(scsi_qla_host_t *vha)
1695{
1696 int rval;
1697 mbx_cmd_t mc;
1698 mbx_cmd_t *mcp = &mc;
1699
1700 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152,
1701 "Entered %s.\n", __func__);
1702
1703 if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw))
1704 return QLA_FUNCTION_FAILED;
1705
1706 mcp->mb[0] = MBC_LINK_INITIALIZATION;
Joe Carnuccio5a5c27b2013-08-27 01:37:49 -04001707 mcp->mb[1] = BIT_4;
1708 if (vha->hw->operating_mode == LOOP)
1709 mcp->mb[1] |= BIT_6;
1710 else
1711 mcp->mb[1] |= BIT_5;
Joe Carnuccio61e1b262013-02-08 01:57:48 -05001712 mcp->mb[2] = 0;
1713 mcp->mb[3] = 0;
1714 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1715 mcp->in_mb = MBX_0;
1716 mcp->tov = MBX_TOV_SECONDS;
1717 mcp->flags = 0;
1718 rval = qla2x00_mailbox_command(vha, mcp);
1719
1720 if (rval != QLA_SUCCESS) {
1721 ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval);
1722 } else {
1723 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154,
1724 "Done %s.\n", __func__);
1725 }
1726
1727 return rval;
1728}
1729
1730/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 * qla2x00_lip_reset
1732 * Issue LIP reset mailbox command.
1733 *
1734 * Input:
1735 * ha = adapter block pointer.
1736 * TARGET_QUEUE_LOCK must be released.
1737 * ADAPTER_STATE_LOCK must be released.
1738 *
1739 * Returns:
1740 * qla2x00 local function return status code.
1741 *
1742 * Context:
1743 * Kernel context.
1744 */
1745int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001746qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747{
1748 int rval;
1749 mbx_cmd_t mc;
1750 mbx_cmd_t *mcp = &mc;
1751
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001752 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a,
1753 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001755 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001756 /* Logout across all FCFs. */
1757 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1758 mcp->mb[1] = BIT_1;
1759 mcp->mb[2] = 0;
1760 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1761 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001762 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001763 mcp->mb[1] = BIT_6;
1764 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001765 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001766 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001768 mcp->mb[0] = MBC_LIP_RESET;
1769 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001770 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001771 mcp->mb[1] = 0x00ff;
1772 mcp->mb[10] = 0;
1773 mcp->out_mb |= MBX_10;
1774 } else {
1775 mcp->mb[1] = 0xff00;
1776 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001777 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001778 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001781 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001783 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784
1785 if (rval != QLA_SUCCESS) {
1786 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001787 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 } else {
1789 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001790 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c,
1791 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 }
1793
1794 return rval;
1795}
1796
1797/*
1798 * qla2x00_send_sns
1799 * Send SNS command.
1800 *
1801 * Input:
1802 * ha = adapter block pointer.
1803 * sns = pointer for command.
1804 * cmd_size = command size.
1805 * buf_size = response/command size.
1806 * TARGET_QUEUE_LOCK must be released.
1807 * ADAPTER_STATE_LOCK must be released.
1808 *
1809 * Returns:
1810 * qla2x00 local function return status code.
1811 *
1812 * Context:
1813 * Kernel context.
1814 */
1815int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001816qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 uint16_t cmd_size, size_t buf_size)
1818{
1819 int rval;
1820 mbx_cmd_t mc;
1821 mbx_cmd_t *mcp = &mc;
1822
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001823 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d,
1824 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001826 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001827 "Retry cnt=%d ratov=%d total tov=%d.\n",
1828 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
1830 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1831 mcp->mb[1] = cmd_size;
1832 mcp->mb[2] = MSW(sns_phys_address);
1833 mcp->mb[3] = LSW(sns_phys_address);
1834 mcp->mb[6] = MSW(MSD(sns_phys_address));
1835 mcp->mb[7] = LSW(MSD(sns_phys_address));
1836 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1837 mcp->in_mb = MBX_0|MBX_1;
1838 mcp->buf_size = buf_size;
1839 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001840 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1841 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842
1843 if (rval != QLA_SUCCESS) {
1844 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001845 ql_dbg(ql_dbg_mbx, vha, 0x105f,
1846 "Failed=%x mb[0]=%x mb[1]=%x.\n",
1847 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 } else {
1849 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001850 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060,
1851 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 }
1853
1854 return rval;
1855}
1856
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001857int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001858qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001859 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1860{
1861 int rval;
1862
1863 struct logio_entry_24xx *lg;
1864 dma_addr_t lg_dma;
1865 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001866 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001867 struct req_que *req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001868
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001869 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061,
1870 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001871
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07001872 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07001873 req = ha->req_q_map[0];
1874 else
1875 req = vha->req;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001876
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001877 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1878 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001879 ql_log(ql_log_warn, vha, 0x1062,
1880 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001881 return QLA_MEMORY_ALLOC_FAILED;
1882 }
1883 memset(lg, 0, sizeof(struct logio_entry_24xx));
1884
1885 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1886 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001887 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001888 lg->nport_handle = cpu_to_le16(loop_id);
Bart Van Asschead950362015-07-09 07:24:08 -07001889 lg->control_flags = cpu_to_le16(LCF_COMMAND_PLOGI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001890 if (opt & BIT_0)
Bart Van Asschead950362015-07-09 07:24:08 -07001891 lg->control_flags |= cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07001892 if (opt & BIT_1)
Bart Van Asschead950362015-07-09 07:24:08 -07001893 lg->control_flags |= cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001894 lg->port_id[0] = al_pa;
1895 lg->port_id[1] = area;
1896 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001897 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08001898 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
1899 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001900 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001901 ql_dbg(ql_dbg_mbx, vha, 0x1063,
1902 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001903 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001904 ql_dbg(ql_dbg_mbx, vha, 0x1064,
1905 "Failed to complete IOCB -- error status (%x).\n",
1906 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001907 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07001908 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001909 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1910 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1911
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001912 ql_dbg(ql_dbg_mbx, vha, 0x1065,
1913 "Failed to complete IOCB -- completion status (%x) "
1914 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
1915 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001916
1917 switch (iop[0]) {
1918 case LSC_SCODE_PORTID_USED:
1919 mb[0] = MBS_PORT_ID_USED;
1920 mb[1] = LSW(iop[1]);
1921 break;
1922 case LSC_SCODE_NPORT_USED:
1923 mb[0] = MBS_LOOP_ID_USED;
1924 break;
1925 case LSC_SCODE_NOLINK:
1926 case LSC_SCODE_NOIOCB:
1927 case LSC_SCODE_NOXCB:
1928 case LSC_SCODE_CMD_FAILED:
1929 case LSC_SCODE_NOFABRIC:
1930 case LSC_SCODE_FW_NOT_READY:
1931 case LSC_SCODE_NOT_LOGGED_IN:
1932 case LSC_SCODE_NOPCB:
1933 case LSC_SCODE_ELS_REJECT:
1934 case LSC_SCODE_CMD_PARAM_ERR:
1935 case LSC_SCODE_NONPORT:
1936 case LSC_SCODE_LOGGED_IN:
1937 case LSC_SCODE_NOFLOGI_ACC:
1938 default:
1939 mb[0] = MBS_COMMAND_ERROR;
1940 break;
1941 }
1942 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001943 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066,
1944 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001945
1946 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1947
1948 mb[0] = MBS_COMMAND_COMPLETE;
1949 mb[1] = 0;
1950 if (iop[0] & BIT_4) {
1951 if (iop[0] & BIT_8)
1952 mb[1] |= BIT_1;
1953 } else
1954 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001955
1956 /* Passback COS information. */
1957 mb[10] = 0;
1958 if (lg->io_parameter[7] || lg->io_parameter[8])
1959 mb[10] |= BIT_0; /* Class 2. */
1960 if (lg->io_parameter[9] || lg->io_parameter[10])
1961 mb[10] |= BIT_1; /* Class 3. */
Bart Van Asschead950362015-07-09 07:24:08 -07001962 if (lg->io_parameter[0] & cpu_to_le32(BIT_7))
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001963 mb[10] |= BIT_7; /* Confirmed Completion
1964 * Allowed
1965 */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001966 }
1967
1968 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1969
1970 return rval;
1971}
1972
Linus Torvalds1da177e2005-04-16 15:20:36 -07001973/*
1974 * qla2x00_login_fabric
1975 * Issue login fabric port mailbox command.
1976 *
1977 * Input:
1978 * ha = adapter block pointer.
1979 * loop_id = device loop ID.
1980 * domain = device domain.
1981 * area = device area.
1982 * al_pa = device AL_PA.
1983 * status = pointer for return status.
1984 * opt = command options.
1985 * TARGET_QUEUE_LOCK must be released.
1986 * ADAPTER_STATE_LOCK must be released.
1987 *
1988 * Returns:
1989 * qla2x00 local function return status code.
1990 *
1991 * Context:
1992 * Kernel context.
1993 */
1994int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001995qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001996 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1997{
1998 int rval;
1999 mbx_cmd_t mc;
2000 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002001 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002003 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067,
2004 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002005
2006 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
2007 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2008 if (HAS_EXTENDED_IDS(ha)) {
2009 mcp->mb[1] = loop_id;
2010 mcp->mb[10] = opt;
2011 mcp->out_mb |= MBX_10;
2012 } else {
2013 mcp->mb[1] = (loop_id << 8) | opt;
2014 }
2015 mcp->mb[2] = domain;
2016 mcp->mb[3] = area << 8 | al_pa;
2017
2018 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
2019 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2020 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002021 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022
2023 /* Return mailbox statuses. */
2024 if (mb != NULL) {
2025 mb[0] = mcp->mb[0];
2026 mb[1] = mcp->mb[1];
2027 mb[2] = mcp->mb[2];
2028 mb[6] = mcp->mb[6];
2029 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07002030 /* COS retrieved from Get-Port-Database mailbox command. */
2031 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032 }
2033
2034 if (rval != QLA_SUCCESS) {
2035 /* RLU tmp code: need to change main mailbox_command function to
2036 * return ok even when the mailbox completion value is not
2037 * SUCCESS. The caller needs to be responsible to interpret
2038 * the return values of this mailbox command if we're not
2039 * to change too much of the existing code.
2040 */
2041 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
2042 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
2043 mcp->mb[0] == 0x4006)
2044 rval = QLA_SUCCESS;
2045
2046 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002047 ql_dbg(ql_dbg_mbx, vha, 0x1068,
2048 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
2049 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 } else {
2051 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002052 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069,
2053 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054 }
2055
2056 return rval;
2057}
2058
2059/*
2060 * qla2x00_login_local_device
2061 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002062 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002063 * Input:
2064 * ha = adapter block pointer.
2065 * loop_id = device loop ID.
2066 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002067 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002068 * Returns:
2069 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002070 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071 * Context:
2072 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002073 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002074 */
2075int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002076qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002077 uint16_t *mb_ret, uint8_t opt)
2078{
2079 int rval;
2080 mbx_cmd_t mc;
2081 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002082 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002083
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002084 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a,
2085 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002086
Andrew Vasqueze4289242007-07-19 15:05:56 -07002087 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002088 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002089 fcport->d_id.b.domain, fcport->d_id.b.area,
2090 fcport->d_id.b.al_pa, mb_ret, opt);
2091
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
2093 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002094 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002095 else
andrew.vasquez@qlogic.com9a52a57c2006-03-09 14:27:44 -08002096 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097 mcp->mb[2] = opt;
2098 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2099 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
2100 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2101 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002102 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002103
2104 /* Return mailbox statuses. */
2105 if (mb_ret != NULL) {
2106 mb_ret[0] = mcp->mb[0];
2107 mb_ret[1] = mcp->mb[1];
2108 mb_ret[6] = mcp->mb[6];
2109 mb_ret[7] = mcp->mb[7];
2110 }
2111
2112 if (rval != QLA_SUCCESS) {
2113 /* AV tmp code: need to change main mailbox_command function to
2114 * return ok even when the mailbox completion value is not
2115 * SUCCESS. The caller needs to be responsible to interpret
2116 * the return values of this mailbox command if we're not
2117 * to change too much of the existing code.
2118 */
2119 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
2120 rval = QLA_SUCCESS;
2121
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002122 ql_dbg(ql_dbg_mbx, vha, 0x106b,
2123 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
2124 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125 } else {
2126 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002127 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c,
2128 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129 }
2130
2131 return (rval);
2132}
2133
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002134int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002135qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002136 uint8_t area, uint8_t al_pa)
2137{
2138 int rval;
2139 struct logio_entry_24xx *lg;
2140 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002141 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002142 struct req_que *req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002143
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002144 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d,
2145 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002146
2147 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
2148 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002149 ql_log(ql_log_warn, vha, 0x106e,
2150 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002151 return QLA_MEMORY_ALLOC_FAILED;
2152 }
2153 memset(lg, 0, sizeof(struct logio_entry_24xx));
2154
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002155 if (ql2xmaxqueues > 1)
2156 req = ha->req_q_map[0];
2157 else
2158 req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002159 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2160 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002161 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002162 lg->nport_handle = cpu_to_le16(loop_id);
2163 lg->control_flags =
Bart Van Asschead950362015-07-09 07:24:08 -07002164 cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
Andrew Vasquezc8d66912011-03-30 11:46:21 -07002165 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002166 lg->port_id[0] = al_pa;
2167 lg->port_id[1] = area;
2168 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002169 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08002170 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2171 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002172 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002173 ql_dbg(ql_dbg_mbx, vha, 0x106f,
2174 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002175 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002176 ql_dbg(ql_dbg_mbx, vha, 0x1070,
2177 "Failed to complete IOCB -- error status (%x).\n",
2178 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002179 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002180 } else if (lg->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002181 ql_dbg(ql_dbg_mbx, vha, 0x1071,
2182 "Failed to complete IOCB -- completion status (%x) "
2183 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002184 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002185 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002186 } else {
2187 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002188 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072,
2189 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002190 }
2191
2192 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2193
2194 return rval;
2195}
2196
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197/*
2198 * qla2x00_fabric_logout
2199 * Issue logout fabric port mailbox command.
2200 *
2201 * Input:
2202 * ha = adapter block pointer.
2203 * loop_id = device loop ID.
2204 * TARGET_QUEUE_LOCK must be released.
2205 * ADAPTER_STATE_LOCK must be released.
2206 *
2207 * Returns:
2208 * qla2x00 local function return status code.
2209 *
2210 * Context:
2211 * Kernel context.
2212 */
2213int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002214qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002215 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002216{
2217 int rval;
2218 mbx_cmd_t mc;
2219 mbx_cmd_t *mcp = &mc;
2220
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002221 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073,
2222 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002223
2224 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
2225 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002226 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002227 mcp->mb[1] = loop_id;
2228 mcp->mb[10] = 0;
2229 mcp->out_mb |= MBX_10;
2230 } else {
2231 mcp->mb[1] = loop_id << 8;
2232 }
2233
2234 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002235 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002236 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002237 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238
2239 if (rval != QLA_SUCCESS) {
2240 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002241 ql_dbg(ql_dbg_mbx, vha, 0x1074,
2242 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243 } else {
2244 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002245 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075,
2246 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247 }
2248
2249 return rval;
2250}
2251
2252/*
2253 * qla2x00_full_login_lip
2254 * Issue full login LIP mailbox command.
2255 *
2256 * Input:
2257 * ha = adapter block pointer.
2258 * TARGET_QUEUE_LOCK must be released.
2259 * ADAPTER_STATE_LOCK must be released.
2260 *
2261 * Returns:
2262 * qla2x00 local function return status code.
2263 *
2264 * Context:
2265 * Kernel context.
2266 */
2267int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002268qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269{
2270 int rval;
2271 mbx_cmd_t mc;
2272 mbx_cmd_t *mcp = &mc;
2273
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002274 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076,
2275 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276
2277 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002278 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002279 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280 mcp->mb[3] = 0;
2281 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2282 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002283 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002285 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286
2287 if (rval != QLA_SUCCESS) {
2288 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002289 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002290 } else {
2291 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002292 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078,
2293 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294 }
2295
2296 return rval;
2297}
2298
2299/*
2300 * qla2x00_get_id_list
2301 *
2302 * Input:
2303 * ha = adapter block pointer.
2304 *
2305 * Returns:
2306 * qla2x00 local function return status code.
2307 *
2308 * Context:
2309 * Kernel context.
2310 */
2311int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002312qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002313 uint16_t *entries)
2314{
2315 int rval;
2316 mbx_cmd_t mc;
2317 mbx_cmd_t *mcp = &mc;
2318
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002319 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079,
2320 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002321
2322 if (id_list == NULL)
2323 return QLA_FUNCTION_FAILED;
2324
2325 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002326 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002327 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002328 mcp->mb[2] = MSW(id_list_dma);
2329 mcp->mb[3] = LSW(id_list_dma);
2330 mcp->mb[6] = MSW(MSD(id_list_dma));
2331 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002332 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002333 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002334 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002335 } else {
2336 mcp->mb[1] = MSW(id_list_dma);
2337 mcp->mb[2] = LSW(id_list_dma);
2338 mcp->mb[3] = MSW(MSD(id_list_dma));
2339 mcp->mb[6] = LSW(MSD(id_list_dma));
2340 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2341 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002343 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002345 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002346
2347 if (rval != QLA_SUCCESS) {
2348 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002349 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350 } else {
2351 *entries = mcp->mb[1];
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002352 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b,
2353 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002354 }
2355
2356 return rval;
2357}
2358
2359/*
2360 * qla2x00_get_resource_cnts
2361 * Get current firmware resource counts.
2362 *
2363 * Input:
2364 * ha = adapter block pointer.
2365 *
2366 * Returns:
2367 * qla2x00 local function return status code.
2368 *
2369 * Context:
2370 * Kernel context.
2371 */
2372int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002373qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002374 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002375 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376{
2377 int rval;
2378 mbx_cmd_t mc;
2379 mbx_cmd_t *mcp = &mc;
2380
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002381 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c,
2382 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002383
2384 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2385 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002386 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 -05002387 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw) || IS_QLA27XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002388 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002389 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002390 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002391 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002392
2393 if (rval != QLA_SUCCESS) {
2394 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002395 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2396 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002398 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002399 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2400 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2401 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2402 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002403
2404 if (cur_xchg_cnt)
2405 *cur_xchg_cnt = mcp->mb[3];
2406 if (orig_xchg_cnt)
2407 *orig_xchg_cnt = mcp->mb[6];
2408 if (cur_iocb_cnt)
2409 *cur_iocb_cnt = mcp->mb[7];
2410 if (orig_iocb_cnt)
2411 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002412 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002413 *max_npiv_vports = mcp->mb[11];
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002414 if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) && max_fcfs)
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002415 *max_fcfs = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002416 }
2417
2418 return (rval);
2419}
2420
Linus Torvalds1da177e2005-04-16 15:20:36 -07002421/*
2422 * qla2x00_get_fcal_position_map
2423 * Get FCAL (LILP) position map using mailbox command
2424 *
2425 * Input:
2426 * ha = adapter state pointer.
2427 * pos_map = buffer pointer (can be NULL).
2428 *
2429 * Returns:
2430 * qla2x00 local function return status code.
2431 *
2432 * Context:
2433 * Kernel context.
2434 */
2435int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002436qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437{
2438 int rval;
2439 mbx_cmd_t mc;
2440 mbx_cmd_t *mcp = &mc;
2441 char *pmap;
2442 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002443 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002445 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f,
2446 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002447
Andrew Vasquez4b892582008-09-11 21:22:48 -07002448 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002450 ql_log(ql_log_warn, vha, 0x1080,
2451 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002452 return QLA_MEMORY_ALLOC_FAILED;
2453 }
2454 memset(pmap, 0, FCAL_MAP_SIZE);
2455
2456 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2457 mcp->mb[2] = MSW(pmap_dma);
2458 mcp->mb[3] = LSW(pmap_dma);
2459 mcp->mb[6] = MSW(MSD(pmap_dma));
2460 mcp->mb[7] = LSW(MSD(pmap_dma));
2461 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2462 mcp->in_mb = MBX_1|MBX_0;
2463 mcp->buf_size = FCAL_MAP_SIZE;
2464 mcp->flags = MBX_DMA_IN;
2465 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002466 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002467
2468 if (rval == QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002469 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002470 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2471 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2472 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2473 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002474
2475 if (pos_map)
2476 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2477 }
2478 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2479
2480 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002481 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002483 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083,
2484 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485 }
2486
2487 return rval;
2488}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002489
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002490/*
2491 * qla2x00_get_link_status
2492 *
2493 * Input:
2494 * ha = adapter block pointer.
2495 * loop_id = device loop ID.
2496 * ret_buf = pointer to link status return buffer.
2497 *
2498 * Returns:
2499 * 0 = success.
2500 * BIT_0 = mem alloc error.
2501 * BIT_1 = mailbox error.
2502 */
2503int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002504qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002505 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002506{
2507 int rval;
2508 mbx_cmd_t mc;
2509 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002510 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002511 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002512
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002513 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084,
2514 "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002515
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002516 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002517 mcp->mb[2] = MSW(stats_dma);
2518 mcp->mb[3] = LSW(stats_dma);
2519 mcp->mb[6] = MSW(MSD(stats_dma));
2520 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002521 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2522 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002523 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002524 mcp->mb[1] = loop_id;
2525 mcp->mb[4] = 0;
2526 mcp->mb[10] = 0;
2527 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2528 mcp->in_mb |= MBX_1;
2529 } else if (HAS_EXTENDED_IDS(ha)) {
2530 mcp->mb[1] = loop_id;
2531 mcp->mb[10] = 0;
2532 mcp->out_mb |= MBX_10|MBX_1;
2533 } else {
2534 mcp->mb[1] = loop_id << 8;
2535 mcp->out_mb |= MBX_1;
2536 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002537 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002538 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002539 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002540
2541 if (rval == QLA_SUCCESS) {
2542 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002543 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2544 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002545 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002546 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002547 /* Copy over data -- firmware data is LE. */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002548 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086,
2549 "Done %s.\n", __func__);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002550 dwords = offsetof(struct link_statistics, unused1) / 4;
2551 siter = diter = &stats->link_fail_cnt;
2552 while (dwords--)
2553 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002554 }
2555 } else {
2556 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002557 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002558 }
2559
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002560 return rval;
2561}
2562
2563int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002564qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002565 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002566{
2567 int rval;
2568 mbx_cmd_t mc;
2569 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002570 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002571
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002572 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,
2573 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002574
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002575 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002576 mcp->mb[2] = MSW(stats_dma);
2577 mcp->mb[3] = LSW(stats_dma);
2578 mcp->mb[6] = MSW(MSD(stats_dma));
2579 mcp->mb[7] = LSW(MSD(stats_dma));
2580 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002581 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002582 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002583 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002584 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002585 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002586 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002587 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002588
2589 if (rval == QLA_SUCCESS) {
2590 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002591 ql_dbg(ql_dbg_mbx, vha, 0x1089,
2592 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002593 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002594 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002595 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a,
2596 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002597 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002598 dwords = sizeof(struct link_statistics) / 4;
2599 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002600 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002601 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002602 }
2603 } else {
2604 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002605 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002606 }
2607
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002608 return rval;
2609}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002610
2611int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002612qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002613{
2614 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002615 unsigned long flags = 0;
2616
2617 struct abort_entry_24xx *abt;
2618 dma_addr_t abt_dma;
2619 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002620 fc_port_t *fcport = sp->fcport;
2621 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002622 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07002623 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002624
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002625 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,
2626 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002627
Armen Baloyan4440e462014-02-26 04:15:18 -05002628 if (ql2xasynctmfenable)
2629 return qla24xx_async_abort_command(sp);
2630
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002631 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05002632 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002633 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002634 break;
2635 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002636 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05002637 if (handle == req->num_outstanding_cmds) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002638 /* Command not found. */
2639 return QLA_FUNCTION_FAILED;
2640 }
2641
2642 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2643 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002644 ql_log(ql_log_warn, vha, 0x108d,
2645 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002646 return QLA_MEMORY_ALLOC_FAILED;
2647 }
2648 memset(abt, 0, sizeof(struct abort_entry_24xx));
2649
2650 abt->entry_type = ABORT_IOCB_TYPE;
2651 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002652 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002653 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07002654 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002655 abt->port_id[0] = fcport->d_id.b.al_pa;
2656 abt->port_id[1] = fcport->d_id.b.area;
2657 abt->port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04002658 abt->vp_index = fcport->vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002659
2660 abt->req_que_no = cpu_to_le16(req->id);
2661
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002662 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002663 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002664 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2665 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002666 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002667 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2668 "Failed to complete IOCB -- error status (%x).\n",
2669 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002670 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002671 } else if (abt->nport_handle != cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002672 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2673 "Failed to complete IOCB -- completion status (%x).\n",
2674 le16_to_cpu(abt->nport_handle));
Chad Dupuisf934c9d2014-04-11 16:54:31 -04002675 if (abt->nport_handle == CS_IOCB_ERROR)
2676 rval = QLA_FUNCTION_PARAMETER_ERROR;
2677 else
2678 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002679 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002680 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
2681 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002682 }
2683
2684 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2685
2686 return rval;
2687}
2688
2689struct tsk_mgmt_cmd {
2690 union {
2691 struct tsk_mgmt_entry tsk;
2692 struct sts_entry_24xx sts;
2693 } p;
2694};
2695
Andrew Vasquez523ec772008-04-03 13:13:24 -07002696static int
2697__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02002698 uint64_t l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002699{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002700 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002701 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002702 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002703 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002704 scsi_qla_host_t *vha;
2705 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002706 struct req_que *req;
2707 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002708
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002709 vha = fcport->vha;
2710 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002711 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002712
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002713 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092,
2714 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002715
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002716 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002717 rsp = ha->rsp_q_map[tag + 1];
2718 else
2719 rsp = req->rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002720 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002721 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002722 ql_log(ql_log_warn, vha, 0x1093,
2723 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002724 return QLA_MEMORY_ALLOC_FAILED;
2725 }
2726 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2727
2728 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2729 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002730 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002731 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002732 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002733 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002734 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2735 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2736 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04002737 tsk->p.tsk.vp_index = fcport->vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002738 if (type == TCF_LUN_RESET) {
2739 int_to_scsilun(l, &tsk->p.tsk.lun);
2740 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2741 sizeof(tsk->p.tsk.lun));
2742 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002743
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002744 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002745 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002746 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002747 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2748 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002749 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002750 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2751 "Failed to complete IOCB -- error status (%x).\n",
2752 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002753 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07002754 } else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002755 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2756 "Failed to complete IOCB -- completion status (%x).\n",
2757 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002758 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08002759 } else if (le16_to_cpu(sts->scsi_status) &
2760 SS_RESPONSE_INFO_LEN_VALID) {
2761 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002762 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002763 "Ignoring inconsistent data length -- not enough "
2764 "response info (%d).\n",
2765 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08002766 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002767 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2768 "Failed to complete IOCB -- response (%x).\n",
2769 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08002770 rval = QLA_FUNCTION_FAILED;
2771 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002772 }
2773
2774 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002775 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002776 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2777 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002778 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2779 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002780 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002781 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a,
2782 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002783 }
2784
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002785 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002786
2787 return rval;
2788}
2789
Andrew Vasquez523ec772008-04-03 13:13:24 -07002790int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02002791qla24xx_abort_target(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002792{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002793 struct qla_hw_data *ha = fcport->vha->hw;
2794
2795 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2796 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2797
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002798 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002799}
2800
2801int
Hannes Reinecke9cb78c12014-06-25 15:27:36 +02002802qla24xx_lun_reset(struct fc_port *fcport, uint64_t l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002803{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002804 struct qla_hw_data *ha = fcport->vha->hw;
2805
2806 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2807 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2808
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002809 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002810}
2811
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002812int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002813qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002814{
2815 int rval;
2816 mbx_cmd_t mc;
2817 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002818 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002819
Andrew Vasquez68af0812008-05-12 22:21:13 -07002820 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002821 return QLA_FUNCTION_FAILED;
2822
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002823 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b,
2824 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002825
2826 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2827 mcp->out_mb = MBX_0;
2828 mcp->in_mb = MBX_0;
2829 mcp->tov = 5;
2830 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002831 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002832
2833 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002834 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002835 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002836 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d,
2837 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002838 }
2839
2840 return rval;
2841}
2842
Joe Carnucciodb64e932013-10-30 03:38:18 -04002843int
2844qla2x00_write_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t data)
2845{
2846 int rval;
2847 mbx_cmd_t mc;
2848 mbx_cmd_t *mcp = &mc;
2849
Andrew Vasquez064135e2015-04-09 15:00:02 -04002850 if (!IS_QLA2031(vha->hw) && !IS_QLA27XX(vha->hw))
Joe Carnucciodb64e932013-10-30 03:38:18 -04002851 return QLA_FUNCTION_FAILED;
2852
2853 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1182,
2854 "Entered %s.\n", __func__);
2855
2856 mcp->mb[0] = MBC_WRITE_SERDES;
2857 mcp->mb[1] = addr;
Andrew Vasquez064135e2015-04-09 15:00:02 -04002858 if (IS_QLA2031(vha->hw))
2859 mcp->mb[2] = data & 0xff;
2860 else
2861 mcp->mb[2] = data;
2862
Joe Carnucciodb64e932013-10-30 03:38:18 -04002863 mcp->mb[3] = 0;
2864 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2865 mcp->in_mb = MBX_0;
2866 mcp->tov = MBX_TOV_SECONDS;
2867 mcp->flags = 0;
2868 rval = qla2x00_mailbox_command(vha, mcp);
2869
2870 if (rval != QLA_SUCCESS) {
2871 ql_dbg(ql_dbg_mbx, vha, 0x1183,
2872 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
2873 } else {
2874 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1184,
2875 "Done %s.\n", __func__);
2876 }
2877
2878 return rval;
2879}
2880
2881int
2882qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data)
2883{
2884 int rval;
2885 mbx_cmd_t mc;
2886 mbx_cmd_t *mcp = &mc;
2887
Andrew Vasquez064135e2015-04-09 15:00:02 -04002888 if (!IS_QLA2031(vha->hw) && !IS_QLA27XX(vha->hw))
Joe Carnucciodb64e932013-10-30 03:38:18 -04002889 return QLA_FUNCTION_FAILED;
2890
2891 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1185,
2892 "Entered %s.\n", __func__);
2893
2894 mcp->mb[0] = MBC_READ_SERDES;
2895 mcp->mb[1] = addr;
2896 mcp->mb[3] = 0;
2897 mcp->out_mb = MBX_3|MBX_1|MBX_0;
2898 mcp->in_mb = MBX_1|MBX_0;
2899 mcp->tov = MBX_TOV_SECONDS;
2900 mcp->flags = 0;
2901 rval = qla2x00_mailbox_command(vha, mcp);
2902
Andrew Vasquez064135e2015-04-09 15:00:02 -04002903 if (IS_QLA2031(vha->hw))
2904 *data = mcp->mb[1] & 0xff;
2905 else
2906 *data = mcp->mb[1];
Joe Carnucciodb64e932013-10-30 03:38:18 -04002907
2908 if (rval != QLA_SUCCESS) {
2909 ql_dbg(ql_dbg_mbx, vha, 0x1186,
2910 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
2911 } else {
2912 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1187,
2913 "Done %s.\n", __func__);
2914 }
2915
2916 return rval;
2917}
2918
Joe Carnuccioe8887c52014-04-11 16:54:17 -04002919int
2920qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)
2921{
2922 int rval;
2923 mbx_cmd_t mc;
2924 mbx_cmd_t *mcp = &mc;
2925
2926 if (!IS_QLA8044(vha->hw))
2927 return QLA_FUNCTION_FAILED;
2928
2929 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1186,
2930 "Entered %s.\n", __func__);
2931
2932 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
2933 mcp->mb[1] = HCS_WRITE_SERDES;
2934 mcp->mb[3] = LSW(addr);
2935 mcp->mb[4] = MSW(addr);
2936 mcp->mb[5] = LSW(data);
2937 mcp->mb[6] = MSW(data);
2938 mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
2939 mcp->in_mb = MBX_0;
2940 mcp->tov = MBX_TOV_SECONDS;
2941 mcp->flags = 0;
2942 rval = qla2x00_mailbox_command(vha, mcp);
2943
2944 if (rval != QLA_SUCCESS) {
2945 ql_dbg(ql_dbg_mbx, vha, 0x1187,
2946 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
2947 } else {
2948 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188,
2949 "Done %s.\n", __func__);
2950 }
2951
2952 return rval;
2953}
2954
2955int
2956qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
2957{
2958 int rval;
2959 mbx_cmd_t mc;
2960 mbx_cmd_t *mcp = &mc;
2961
2962 if (!IS_QLA8044(vha->hw))
2963 return QLA_FUNCTION_FAILED;
2964
2965 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189,
2966 "Entered %s.\n", __func__);
2967
2968 mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG;
2969 mcp->mb[1] = HCS_READ_SERDES;
2970 mcp->mb[3] = LSW(addr);
2971 mcp->mb[4] = MSW(addr);
2972 mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0;
2973 mcp->in_mb = MBX_2|MBX_1|MBX_0;
2974 mcp->tov = MBX_TOV_SECONDS;
2975 mcp->flags = 0;
2976 rval = qla2x00_mailbox_command(vha, mcp);
2977
2978 *data = mcp->mb[2] << 16 | mcp->mb[1];
2979
2980 if (rval != QLA_SUCCESS) {
2981 ql_dbg(ql_dbg_mbx, vha, 0x118a,
2982 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
2983 } else {
2984 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b,
2985 "Done %s.\n", __func__);
2986 }
2987
2988 return rval;
2989}
2990
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002991/**
2992 * qla2x00_set_serdes_params() -
2993 * @ha: HA context
2994 *
2995 * Returns
2996 */
2997int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002998qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002999 uint16_t sw_em_2g, uint16_t sw_em_4g)
3000{
3001 int rval;
3002 mbx_cmd_t mc;
3003 mbx_cmd_t *mcp = &mc;
3004
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003005 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e,
3006 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003007
3008 mcp->mb[0] = MBC_SERDES_PARAMS;
3009 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08003010 mcp->mb[2] = sw_em_1g | BIT_15;
3011 mcp->mb[3] = sw_em_2g | BIT_15;
3012 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003013 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3014 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003015 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003016 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003017 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003018
3019 if (rval != QLA_SUCCESS) {
3020 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003021 ql_dbg(ql_dbg_mbx, vha, 0x109f,
3022 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003023 } else {
3024 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003025 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0,
3026 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07003027 }
3028
3029 return rval;
3030}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003031
3032int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003033qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003034{
3035 int rval;
3036 mbx_cmd_t mc;
3037 mbx_cmd_t *mcp = &mc;
3038
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003039 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003040 return QLA_FUNCTION_FAILED;
3041
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003042 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1,
3043 "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003044
3045 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08003046 mcp->mb[1] = 0;
3047 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003048 mcp->in_mb = MBX_0;
3049 mcp->tov = 5;
3050 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003051 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003052
3053 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003054 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07003055 if (mcp->mb[0] == MBS_INVALID_COMMAND)
3056 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003057 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003058 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3,
3059 "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07003060 }
3061
3062 return rval;
3063}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003064
3065int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003066qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003067 uint16_t buffers)
3068{
3069 int rval;
3070 mbx_cmd_t mc;
3071 mbx_cmd_t *mcp = &mc;
3072
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003073 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4,
3074 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003075
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003076 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003077 return QLA_FUNCTION_FAILED;
3078
Andrew Vasquez85880802009-12-15 21:29:46 -08003079 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3080 return QLA_FUNCTION_FAILED;
3081
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003082 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003083 mcp->mb[1] = TC_EFT_ENABLE;
3084 mcp->mb[2] = LSW(eft_dma);
3085 mcp->mb[3] = MSW(eft_dma);
3086 mcp->mb[4] = LSW(MSD(eft_dma));
3087 mcp->mb[5] = MSW(MSD(eft_dma));
3088 mcp->mb[6] = buffers;
3089 mcp->mb[7] = TC_AEN_DISABLE;
3090 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 -07003091 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003092 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003093 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003094 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003095 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003096 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
3097 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3098 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003099 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003100 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6,
3101 "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003102 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003103
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003104 return rval;
3105}
3106
3107int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003108qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003109{
3110 int rval;
3111 mbx_cmd_t mc;
3112 mbx_cmd_t *mcp = &mc;
3113
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003114 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7,
3115 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003116
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003117 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003118 return QLA_FUNCTION_FAILED;
3119
Andrew Vasquez85880802009-12-15 21:29:46 -08003120 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3121 return QLA_FUNCTION_FAILED;
3122
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003123 mcp->mb[0] = MBC_TRACE_CONTROL;
3124 mcp->mb[1] = TC_EFT_DISABLE;
3125 mcp->out_mb = MBX_1|MBX_0;
3126 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003127 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08003128 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003129 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003130 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003131 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
3132 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3133 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003134 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003135 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9,
3136 "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07003137 }
3138
3139 return rval;
3140}
3141
Andrew Vasquez88729e52006-06-23 16:10:50 -07003142int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003143qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003144 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
3145{
3146 int rval;
3147 mbx_cmd_t mc;
3148 mbx_cmd_t *mcp = &mc;
3149
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003150 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa,
3151 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003152
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003153 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
Chad Dupuisf73cb692014-02-26 04:15:06 -05003154 !IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003155 return QLA_FUNCTION_FAILED;
3156
Andrew Vasquez85880802009-12-15 21:29:46 -08003157 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3158 return QLA_FUNCTION_FAILED;
3159
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003160 mcp->mb[0] = MBC_TRACE_CONTROL;
3161 mcp->mb[1] = TC_FCE_ENABLE;
3162 mcp->mb[2] = LSW(fce_dma);
3163 mcp->mb[3] = MSW(fce_dma);
3164 mcp->mb[4] = LSW(MSD(fce_dma));
3165 mcp->mb[5] = MSW(MSD(fce_dma));
3166 mcp->mb[6] = buffers;
3167 mcp->mb[7] = TC_AEN_DISABLE;
3168 mcp->mb[8] = 0;
3169 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
3170 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
3171 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3172 MBX_1|MBX_0;
3173 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003174 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003175 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003176 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003177 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003178 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
3179 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3180 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003181 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003182 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac,
3183 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003184
3185 if (mb)
3186 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
3187 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07003188 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003189 }
3190
3191 return rval;
3192}
3193
3194int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003195qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003196{
3197 int rval;
3198 mbx_cmd_t mc;
3199 mbx_cmd_t *mcp = &mc;
3200
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003201 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad,
3202 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003203
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003204 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003205 return QLA_FUNCTION_FAILED;
3206
Andrew Vasquez85880802009-12-15 21:29:46 -08003207 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3208 return QLA_FUNCTION_FAILED;
3209
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003210 mcp->mb[0] = MBC_TRACE_CONTROL;
3211 mcp->mb[1] = TC_FCE_DISABLE;
3212 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
3213 mcp->out_mb = MBX_2|MBX_1|MBX_0;
3214 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3215 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003216 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003217 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003218 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003219 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003220 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
3221 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3222 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003223 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003224 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af,
3225 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003226
3227 if (wr)
3228 *wr = (uint64_t) mcp->mb[5] << 48 |
3229 (uint64_t) mcp->mb[4] << 32 |
3230 (uint64_t) mcp->mb[3] << 16 |
3231 (uint64_t) mcp->mb[2];
3232 if (rd)
3233 *rd = (uint64_t) mcp->mb[9] << 48 |
3234 (uint64_t) mcp->mb[8] << 32 |
3235 (uint64_t) mcp->mb[7] << 16 |
3236 (uint64_t) mcp->mb[6];
3237 }
3238
3239 return rval;
3240}
3241
3242int
Giridhar Malavali6e980162010-03-19 17:03:58 -07003243qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
3244 uint16_t *port_speed, uint16_t *mb)
3245{
3246 int rval;
3247 mbx_cmd_t mc;
3248 mbx_cmd_t *mcp = &mc;
3249
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003250 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0,
3251 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003252
Giridhar Malavali6e980162010-03-19 17:03:58 -07003253 if (!IS_IIDMA_CAPABLE(vha->hw))
3254 return QLA_FUNCTION_FAILED;
3255
Giridhar Malavali6e980162010-03-19 17:03:58 -07003256 mcp->mb[0] = MBC_PORT_PARAMS;
3257 mcp->mb[1] = loop_id;
3258 mcp->mb[2] = mcp->mb[3] = 0;
3259 mcp->mb[9] = vha->vp_idx;
3260 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3261 mcp->in_mb = MBX_3|MBX_1|MBX_0;
3262 mcp->tov = MBX_TOV_SECONDS;
3263 mcp->flags = 0;
3264 rval = qla2x00_mailbox_command(vha, mcp);
3265
3266 /* Return mailbox statuses. */
3267 if (mb != NULL) {
3268 mb[0] = mcp->mb[0];
3269 mb[1] = mcp->mb[1];
3270 mb[3] = mcp->mb[3];
3271 }
3272
3273 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003274 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003275 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003276 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2,
3277 "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003278 if (port_speed)
3279 *port_speed = mcp->mb[3];
3280 }
3281
3282 return rval;
3283}
3284
3285int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003286qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003287 uint16_t port_speed, uint16_t *mb)
3288{
3289 int rval;
3290 mbx_cmd_t mc;
3291 mbx_cmd_t *mcp = &mc;
3292
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003293 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3,
3294 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003295
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003296 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003297 return QLA_FUNCTION_FAILED;
3298
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003299 mcp->mb[0] = MBC_PORT_PARAMS;
3300 mcp->mb[1] = loop_id;
3301 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003302 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07003303 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
3304 else
3305 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
3306 mcp->mb[9] = vha->vp_idx;
3307 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3308 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003309 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003310 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003311 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003312
3313 /* Return mailbox statuses. */
3314 if (mb != NULL) {
3315 mb[0] = mcp->mb[0];
3316 mb[1] = mcp->mb[1];
3317 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003318 }
3319
3320 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003321 ql_dbg(ql_dbg_mbx, vha, 0x10b4,
3322 "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003323 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003324 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5,
3325 "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003326 }
3327
3328 return rval;
3329}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003330
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003331void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003332qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003333 struct vp_rpt_id_entry_24xx *rptid_entry)
3334{
3335 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07003336 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003337 struct qla_hw_data *ha = vha->hw;
3338 scsi_qla_host_t *vp;
Arun Easifeafb7b2010-09-03 14:57:00 -07003339 unsigned long flags;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003340 int found;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003341
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003342 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
3343 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003344
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003345 if (rptid_entry->entry_status != 0)
3346 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003347
3348 if (rptid_entry->format == 0) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003349 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003350 "Format 0 : Number of VPs setup %d, number of "
3351 "VPs acquired %d.\n",
3352 MSB(le16_to_cpu(rptid_entry->vp_count)),
3353 LSB(le16_to_cpu(rptid_entry->vp_count)));
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003354 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b8,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003355 "Primary port id %02x%02x%02x.\n",
3356 rptid_entry->port_id[2], rptid_entry->port_id[1],
3357 rptid_entry->port_id[0]);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003358 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07003359 vp_idx = LSB(stat);
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003360 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b9,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003361 "Format 1: VP[%d] enabled - status %d - with "
3362 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003363 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003364 rptid_entry->port_id[0]);
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003365
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04003366 /* FA-WWN is only for physical port */
3367 if (!vp_idx) {
3368 void *wwpn = ha->init_cb->port_name;
3369
3370 if (!MSB(stat)) {
3371 if (rptid_entry->vp_idx_map[1] & BIT_6)
3372 wwpn = rptid_entry->reserved_4 + 8;
3373 }
3374 memcpy(vha->port_name, wwpn, WWN_SIZE);
3375 fc_host_port_name(vha->host) =
3376 wwn_to_u64(vha->port_name);
3377 ql_dbg(ql_dbg_mbx, vha, 0x1018,
3378 "FA-WWN portname %016llx (%x)\n",
3379 fc_host_port_name(vha->host), MSB(stat));
3380 }
3381
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003382 vp = vha;
Joe Carnuccio7c9c4762014-09-25 05:16:47 -04003383 if (vp_idx == 0)
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003384 goto reg_needed;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003385
Saurav Kashyap681e0142012-11-21 02:40:28 -05003386 if (MSB(stat) != 0 && MSB(stat) != 2) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003387 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
3388 "Could not acquire ID for VP[%d].\n", vp_idx);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003389 return;
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07003390 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003391
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003392 found = 0;
Arun Easifeafb7b2010-09-03 14:57:00 -07003393 spin_lock_irqsave(&ha->vport_slock, flags);
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003394 list_for_each_entry(vp, &ha->vp_list, list) {
3395 if (vp_idx == vp->vp_idx) {
3396 found = 1;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003397 break;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003398 }
3399 }
Arun Easifeafb7b2010-09-03 14:57:00 -07003400 spin_unlock_irqrestore(&ha->vport_slock, flags);
3401
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003402 if (!found)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003403 return;
3404
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003405 vp->d_id.b.domain = rptid_entry->port_id[2];
3406 vp->d_id.b.area = rptid_entry->port_id[1];
3407 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003408
3409 /*
3410 * Cannot configure here as we are still sitting on the
3411 * response queue. Handle it in dpc context.
3412 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003413 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003414
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003415reg_needed:
3416 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
3417 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
3418 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003419 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003420 }
3421}
3422
3423/*
3424 * qla24xx_modify_vp_config
3425 * Change VP configuration for vha
3426 *
3427 * Input:
3428 * vha = adapter block pointer.
3429 *
3430 * Returns:
3431 * qla2xxx local function return status code.
3432 *
3433 * Context:
3434 * Kernel context.
3435 */
3436int
3437qla24xx_modify_vp_config(scsi_qla_host_t *vha)
3438{
3439 int rval;
3440 struct vp_config_entry_24xx *vpmod;
3441 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003442 struct qla_hw_data *ha = vha->hw;
3443 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003444
3445 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003446
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003447 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb,
3448 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003449
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003450 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003451 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003452 ql_log(ql_log_warn, vha, 0x10bc,
3453 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003454 return QLA_MEMORY_ALLOC_FAILED;
3455 }
3456
3457 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
3458 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
3459 vpmod->entry_count = 1;
3460 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
3461 vpmod->vp_count = 1;
3462 vpmod->vp_index1 = vha->vp_idx;
3463 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04003464
3465 qlt_modify_vp_config(vha, vpmod);
3466
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003467 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
3468 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
3469 vpmod->entry_count = 1;
3470
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003471 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003472 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003473 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
3474 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003475 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003476 ql_dbg(ql_dbg_mbx, vha, 0x10be,
3477 "Failed to complete IOCB -- error status (%x).\n",
3478 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003479 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07003480 } else if (vpmod->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003481 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3482 "Failed to complete IOCB -- completion status (%x).\n",
3483 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003484 rval = QLA_FUNCTION_FAILED;
3485 } else {
3486 /* EMPTY */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003487 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0,
3488 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003489 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3490 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003491 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003492
3493 return rval;
3494}
3495
3496/*
3497 * qla24xx_control_vp
3498 * Enable a virtual port for given host
3499 *
3500 * Input:
3501 * ha = adapter block pointer.
3502 * vhba = virtual adapter (unused)
3503 * index = index number for enabled VP
3504 *
3505 * Returns:
3506 * qla2xxx local function return status code.
3507 *
3508 * Context:
3509 * Kernel context.
3510 */
3511int
3512qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
3513{
3514 int rval;
3515 int map, pos;
3516 struct vp_ctrl_entry_24xx *vce;
3517 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003518 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003519 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003520 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003521
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003522 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c1,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003523 "Entered %s enabling index %d.\n", __func__, vp_index);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003524
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08003525 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003526 return QLA_PARAMETER_ERROR;
3527
3528 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3529 if (!vce) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003530 ql_log(ql_log_warn, vha, 0x10c2,
3531 "Failed to allocate VP control IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003532 return QLA_MEMORY_ALLOC_FAILED;
3533 }
3534 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3535
3536 vce->entry_type = VP_CTRL_IOCB_TYPE;
3537 vce->entry_count = 1;
3538 vce->command = cpu_to_le16(cmd);
Bart Van Asschead950362015-07-09 07:24:08 -07003539 vce->vp_count = cpu_to_le16(1);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003540
3541 /* index map in firmware starts with 1; decrement index
3542 * this is ok as we never use index 0
3543 */
3544 map = (vp_index - 1) / 8;
3545 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003546 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003547 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003548 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003549
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003550 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003551 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003552 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3553 "Failed to issue VP control IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003554 } else if (vce->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003555 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3556 "Failed to complete IOCB -- error status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003557 vce->entry_status);
3558 rval = QLA_FUNCTION_FAILED;
Bart Van Asschead950362015-07-09 07:24:08 -07003559 } else if (vce->comp_status != cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003560 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3561 "Failed to complet IOCB -- completion status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003562 le16_to_cpu(vce->comp_status));
3563 rval = QLA_FUNCTION_FAILED;
3564 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003565 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c6,
3566 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003567 }
3568
3569 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3570
3571 return rval;
3572}
3573
3574/*
3575 * qla2x00_send_change_request
3576 * Receive or disable RSCN request from fabric controller
3577 *
3578 * Input:
3579 * ha = adapter block pointer
3580 * format = registration format:
3581 * 0 - Reserved
3582 * 1 - Fabric detected registration
3583 * 2 - N_port detected registration
3584 * 3 - Full registration
3585 * FF - clear registration
3586 * vp_idx = Virtual port index
3587 *
3588 * Returns:
3589 * qla2x00 local function return status code.
3590 *
3591 * Context:
3592 * Kernel Context
3593 */
3594
3595int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003596qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003597 uint16_t vp_idx)
3598{
3599 int rval;
3600 mbx_cmd_t mc;
3601 mbx_cmd_t *mcp = &mc;
3602
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003603 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7,
3604 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003605
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003606 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3607 mcp->mb[1] = format;
3608 mcp->mb[9] = vp_idx;
3609 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3610 mcp->in_mb = MBX_0|MBX_1;
3611 mcp->tov = MBX_TOV_SECONDS;
3612 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003613 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003614
3615 if (rval == QLA_SUCCESS) {
3616 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3617 rval = BIT_1;
3618 }
3619 } else
3620 rval = BIT_1;
3621
3622 return rval;
3623}
Andrew Vasquez338c9162007-09-20 14:07:33 -07003624
3625int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003626qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07003627 uint32_t size)
3628{
3629 int rval;
3630 mbx_cmd_t mc;
3631 mbx_cmd_t *mcp = &mc;
3632
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003633 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009,
3634 "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003635
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003636 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003637 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3638 mcp->mb[8] = MSW(addr);
3639 mcp->out_mb = MBX_8|MBX_0;
3640 } else {
3641 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3642 mcp->out_mb = MBX_0;
3643 }
3644 mcp->mb[1] = LSW(addr);
3645 mcp->mb[2] = MSW(req_dma);
3646 mcp->mb[3] = LSW(req_dma);
3647 mcp->mb[6] = MSW(MSD(req_dma));
3648 mcp->mb[7] = LSW(MSD(req_dma));
3649 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003650 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003651 mcp->mb[4] = MSW(size);
3652 mcp->mb[5] = LSW(size);
3653 mcp->out_mb |= MBX_5|MBX_4;
3654 } else {
3655 mcp->mb[4] = LSW(size);
3656 mcp->out_mb |= MBX_4;
3657 }
3658
3659 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003660 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07003661 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003662 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003663
3664 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003665 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3666 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003667 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003668 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007,
3669 "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003670 }
3671
3672 return rval;
3673}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003674/* 84XX Support **************************************************************/
3675
3676struct cs84xx_mgmt_cmd {
3677 union {
3678 struct verify_chip_entry_84xx req;
3679 struct verify_chip_rsp_84xx rsp;
3680 } p;
3681};
3682
3683int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003684qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003685{
3686 int rval, retry;
3687 struct cs84xx_mgmt_cmd *mn;
3688 dma_addr_t mn_dma;
3689 uint16_t options;
3690 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003691 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003692
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003693 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8,
3694 "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003695
3696 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3697 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003698 return QLA_MEMORY_ALLOC_FAILED;
3699 }
3700
3701 /* Force Update? */
3702 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3703 /* Diagnostic firmware? */
3704 /* options |= MENLO_DIAG_FW; */
3705 /* We update the firmware with only one data sequence. */
3706 options |= VCO_END_OF_DATA;
3707
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003708 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003709 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003710 memset(mn, 0, sizeof(*mn));
3711 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3712 mn->p.req.entry_count = 1;
3713 mn->p.req.options = cpu_to_le16(options);
3714
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003715 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3716 "Dump of Verify Request.\n");
3717 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3718 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003719
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003720 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003721 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003722 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3723 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003724 goto verify_done;
3725 }
3726
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003727 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3728 "Dump of Verify Response.\n");
3729 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3730 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003731
3732 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3733 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3734 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003735 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003736 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003737
3738 if (status[0] != CS_COMPLETE) {
3739 rval = QLA_FUNCTION_FAILED;
3740 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003741 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3742 "Firmware update failed. Retrying "
3743 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003744 options |= VCO_DONT_UPDATE_FW;
3745 options &= ~VCO_FORCE_UPDATE;
3746 retry = 1;
3747 }
3748 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003749 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003750 "Firmware updated to %x.\n",
3751 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003752
3753 /* NOTE: we only update OP firmware. */
3754 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3755 ha->cs84xx->op_fw_version =
3756 le32_to_cpu(mn->p.rsp.fw_ver);
3757 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3758 flags);
3759 }
3760 } while (retry);
3761
3762verify_done:
3763 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3764
3765 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003766 ql_dbg(ql_dbg_mbx, vha, 0x10d1,
3767 "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003768 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003769 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2,
3770 "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003771 }
3772
3773 return rval;
3774}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003775
3776int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003777qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003778{
3779 int rval;
3780 unsigned long flags;
3781 mbx_cmd_t mc;
3782 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003783 struct qla_hw_data *ha = vha->hw;
3784
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003785 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
3786 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003787
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04003788 if (IS_SHADOW_REG_CAPABLE(ha))
3789 req->options |= BIT_13;
3790
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003791 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003792 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003793 mcp->mb[2] = MSW(LSD(req->dma));
3794 mcp->mb[3] = LSW(LSD(req->dma));
3795 mcp->mb[6] = MSW(MSD(req->dma));
3796 mcp->mb[7] = LSW(MSD(req->dma));
3797 mcp->mb[5] = req->length;
3798 if (req->rsp)
3799 mcp->mb[10] = req->rsp->id;
3800 mcp->mb[12] = req->qos;
3801 mcp->mb[11] = req->vp_idx;
3802 mcp->mb[13] = req->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003803 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003804 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003805
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003806 mcp->mb[4] = req->id;
3807 /* que in ptr index */
3808 mcp->mb[8] = 0;
3809 /* que out ptr index */
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04003810 mcp->mb[9] = *req->out_ptr = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003811 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3812 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3813 mcp->in_mb = MBX_0;
3814 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003815 mcp->tov = MBX_TOV_SECONDS * 2;
3816
Chad Dupuisf73cb692014-02-26 04:15:06 -05003817 if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003818 mcp->in_mb |= MBX_1;
Joe Carnuccioba4828b2014-04-11 16:54:10 -04003819 if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003820 mcp->out_mb |= MBX_15;
3821 /* debug q create issue in SR-IOV */
3822 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3823 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003824
3825 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003826 if (!(req->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003827 WRT_REG_DWORD(req->req_q_in, 0);
Joe Carnuccio29db41c2014-04-11 16:54:09 -04003828 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003829 WRT_REG_DWORD(req->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003830 }
3831 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3832
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003833 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003834 if (rval != QLA_SUCCESS) {
3835 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3836 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3837 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003838 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5,
3839 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003840 }
3841
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003842 return rval;
3843}
3844
3845int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003846qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003847{
3848 int rval;
3849 unsigned long flags;
3850 mbx_cmd_t mc;
3851 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003852 struct qla_hw_data *ha = vha->hw;
3853
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003854 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
3855 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003856
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04003857 if (IS_SHADOW_REG_CAPABLE(ha))
3858 rsp->options |= BIT_13;
3859
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003860 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003861 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003862 mcp->mb[2] = MSW(LSD(rsp->dma));
3863 mcp->mb[3] = LSW(LSD(rsp->dma));
3864 mcp->mb[6] = MSW(MSD(rsp->dma));
3865 mcp->mb[7] = LSW(MSD(rsp->dma));
3866 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003867 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003868 mcp->mb[13] = rsp->rid;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003869 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003870 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003871
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003872 mcp->mb[4] = rsp->id;
3873 /* que in ptr index */
Joe Carnuccio7c6300e2014-04-11 16:54:37 -04003874 mcp->mb[8] = *rsp->in_ptr = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003875 /* que out ptr index */
3876 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003877 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003878 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3879 mcp->in_mb = MBX_0;
3880 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003881 mcp->tov = MBX_TOV_SECONDS * 2;
3882
3883 if (IS_QLA81XX(ha)) {
3884 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
3885 mcp->in_mb |= MBX_1;
Chad Dupuisf73cb692014-02-26 04:15:06 -05003886 } else if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003887 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
3888 mcp->in_mb |= MBX_1;
3889 /* debug q create issue in SR-IOV */
3890 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3891 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003892
3893 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003894 if (!(rsp->options & BIT_0)) {
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003895 WRT_REG_DWORD(rsp->rsp_q_out, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003896 if (!IS_QLA83XX(ha))
Andrew Vasquezda9b1d52013-08-27 01:37:30 -04003897 WRT_REG_DWORD(rsp->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003898 }
3899
3900 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3901
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003902 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003903 if (rval != QLA_SUCCESS) {
3904 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
3905 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3906 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003907 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8,
3908 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003909 }
3910
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003911 return rval;
3912}
3913
Andrew Vasquez8a659572009-02-08 20:50:12 -08003914int
3915qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3916{
3917 int rval;
3918 mbx_cmd_t mc;
3919 mbx_cmd_t *mcp = &mc;
3920
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003921 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9,
3922 "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003923
3924 mcp->mb[0] = MBC_IDC_ACK;
3925 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3926 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3927 mcp->in_mb = MBX_0;
3928 mcp->tov = MBX_TOV_SECONDS;
3929 mcp->flags = 0;
3930 rval = qla2x00_mailbox_command(vha, mcp);
3931
3932 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003933 ql_dbg(ql_dbg_mbx, vha, 0x10da,
3934 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003935 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003936 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db,
3937 "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003938 }
3939
3940 return rval;
3941}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003942
3943int
3944qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3945{
3946 int rval;
3947 mbx_cmd_t mc;
3948 mbx_cmd_t *mcp = &mc;
3949
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003950 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc,
3951 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003952
Chad Dupuisf73cb692014-02-26 04:15:06 -05003953 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
3954 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003955 return QLA_FUNCTION_FAILED;
3956
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003957 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3958 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3959 mcp->out_mb = MBX_1|MBX_0;
3960 mcp->in_mb = MBX_1|MBX_0;
3961 mcp->tov = MBX_TOV_SECONDS;
3962 mcp->flags = 0;
3963 rval = qla2x00_mailbox_command(vha, mcp);
3964
3965 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003966 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
3967 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3968 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003969 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003970 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de,
3971 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003972 *sector_size = mcp->mb[1];
3973 }
3974
3975 return rval;
3976}
3977
3978int
3979qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3980{
3981 int rval;
3982 mbx_cmd_t mc;
3983 mbx_cmd_t *mcp = &mc;
3984
Chad Dupuisf73cb692014-02-26 04:15:06 -05003985 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
3986 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003987 return QLA_FUNCTION_FAILED;
3988
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003989 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df,
3990 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003991
3992 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3993 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3994 FAC_OPT_CMD_WRITE_PROTECT;
3995 mcp->out_mb = MBX_1|MBX_0;
3996 mcp->in_mb = MBX_1|MBX_0;
3997 mcp->tov = MBX_TOV_SECONDS;
3998 mcp->flags = 0;
3999 rval = qla2x00_mailbox_command(vha, mcp);
4000
4001 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004002 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
4003 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4004 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004005 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004006 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1,
4007 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004008 }
4009
4010 return rval;
4011}
4012
4013int
4014qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
4015{
4016 int rval;
4017 mbx_cmd_t mc;
4018 mbx_cmd_t *mcp = &mc;
4019
Chad Dupuisf73cb692014-02-26 04:15:06 -05004020 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw) &&
4021 !IS_QLA27XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004022 return QLA_FUNCTION_FAILED;
4023
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004024 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,
4025 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004026
4027 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
4028 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
4029 mcp->mb[2] = LSW(start);
4030 mcp->mb[3] = MSW(start);
4031 mcp->mb[4] = LSW(finish);
4032 mcp->mb[5] = MSW(finish);
4033 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4034 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4035 mcp->tov = MBX_TOV_SECONDS;
4036 mcp->flags = 0;
4037 rval = qla2x00_mailbox_command(vha, mcp);
4038
4039 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004040 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
4041 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4042 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004043 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004044 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,
4045 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07004046 }
4047
4048 return rval;
4049}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004050
4051int
4052qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
4053{
4054 int rval = 0;
4055 mbx_cmd_t mc;
4056 mbx_cmd_t *mcp = &mc;
4057
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004058 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5,
4059 "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004060
4061 mcp->mb[0] = MBC_RESTART_MPI_FW;
4062 mcp->out_mb = MBX_0;
4063 mcp->in_mb = MBX_0|MBX_1;
4064 mcp->tov = MBX_TOV_SECONDS;
4065 mcp->flags = 0;
4066 rval = qla2x00_mailbox_command(vha, mcp);
4067
4068 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004069 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
4070 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4071 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004072 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004073 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7,
4074 "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07004075 }
4076
4077 return rval;
4078}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004079
Joe Carnuccioc46e65c2013-08-27 01:37:35 -04004080int
4081qla82xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4082{
4083 int rval;
4084 mbx_cmd_t mc;
4085 mbx_cmd_t *mcp = &mc;
4086 int i;
4087 int len;
4088 uint16_t *str;
4089 struct qla_hw_data *ha = vha->hw;
4090
4091 if (!IS_P3P_TYPE(ha))
4092 return QLA_FUNCTION_FAILED;
4093
4094 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117b,
4095 "Entered %s.\n", __func__);
4096
4097 str = (void *)version;
4098 len = strlen(version);
4099
4100 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4101 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8;
4102 mcp->out_mb = MBX_1|MBX_0;
4103 for (i = 4; i < 16 && len; i++, str++, len -= 2) {
4104 mcp->mb[i] = cpu_to_le16p(str);
4105 mcp->out_mb |= 1<<i;
4106 }
4107 for (; i < 16; i++) {
4108 mcp->mb[i] = 0;
4109 mcp->out_mb |= 1<<i;
4110 }
4111 mcp->in_mb = MBX_1|MBX_0;
4112 mcp->tov = MBX_TOV_SECONDS;
4113 mcp->flags = 0;
4114 rval = qla2x00_mailbox_command(vha, mcp);
4115
4116 if (rval != QLA_SUCCESS) {
4117 ql_dbg(ql_dbg_mbx, vha, 0x117c,
4118 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4119 } else {
4120 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117d,
4121 "Done %s.\n", __func__);
4122 }
4123
4124 return rval;
4125}
4126
4127int
4128qla25xx_set_driver_version(scsi_qla_host_t *vha, char *version)
4129{
4130 int rval;
4131 mbx_cmd_t mc;
4132 mbx_cmd_t *mcp = &mc;
4133 int len;
4134 uint16_t dwlen;
4135 uint8_t *str;
4136 dma_addr_t str_dma;
4137 struct qla_hw_data *ha = vha->hw;
4138
4139 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha) ||
4140 IS_P3P_TYPE(ha))
4141 return QLA_FUNCTION_FAILED;
4142
4143 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x117e,
4144 "Entered %s.\n", __func__);
4145
4146 str = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &str_dma);
4147 if (!str) {
4148 ql_log(ql_log_warn, vha, 0x117f,
4149 "Failed to allocate driver version param.\n");
4150 return QLA_MEMORY_ALLOC_FAILED;
4151 }
4152
4153 memcpy(str, "\x7\x3\x11\x0", 4);
4154 dwlen = str[0];
4155 len = dwlen * 4 - 4;
4156 memset(str + 4, 0, len);
4157 if (len > strlen(version))
4158 len = strlen(version);
4159 memcpy(str + 4, version, len);
4160
4161 mcp->mb[0] = MBC_SET_RNID_PARAMS;
4162 mcp->mb[1] = RNID_TYPE_SET_VERSION << 8 | dwlen;
4163 mcp->mb[2] = MSW(LSD(str_dma));
4164 mcp->mb[3] = LSW(LSD(str_dma));
4165 mcp->mb[6] = MSW(MSD(str_dma));
4166 mcp->mb[7] = LSW(MSD(str_dma));
4167 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4168 mcp->in_mb = MBX_1|MBX_0;
4169 mcp->tov = MBX_TOV_SECONDS;
4170 mcp->flags = 0;
4171 rval = qla2x00_mailbox_command(vha, mcp);
4172
4173 if (rval != QLA_SUCCESS) {
4174 ql_dbg(ql_dbg_mbx, vha, 0x1180,
4175 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4176 } else {
4177 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1181,
4178 "Done %s.\n", __func__);
4179 }
4180
4181 dma_pool_free(ha->s_dma_pool, str, str_dma);
4182
4183 return rval;
4184}
4185
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004186static int
4187qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
4188{
4189 int rval;
4190 mbx_cmd_t mc;
4191 mbx_cmd_t *mcp = &mc;
4192
4193 if (!IS_FWI2_CAPABLE(vha->hw))
4194 return QLA_FUNCTION_FAILED;
4195
4196 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
4197 "Entered %s.\n", __func__);
4198
4199 mcp->mb[0] = MBC_GET_RNID_PARAMS;
4200 mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8;
4201 mcp->out_mb = MBX_1|MBX_0;
4202 mcp->in_mb = MBX_1|MBX_0;
4203 mcp->tov = MBX_TOV_SECONDS;
4204 mcp->flags = 0;
4205 rval = qla2x00_mailbox_command(vha, mcp);
4206 *temp = mcp->mb[1];
4207
4208 if (rval != QLA_SUCCESS) {
4209 ql_dbg(ql_dbg_mbx, vha, 0x115a,
4210 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
4211 } else {
4212 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
4213 "Done %s.\n", __func__);
4214 }
4215
4216 return rval;
4217}
4218
Joe Carnuccio3a117112013-02-08 01:58:00 -05004219int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004220qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4221 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004222{
4223 int rval;
4224 mbx_cmd_t mc;
4225 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004226 struct qla_hw_data *ha = vha->hw;
4227
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004228 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,
4229 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004230
Joe Carnuccio6766df92011-05-10 11:30:15 -07004231 if (!IS_FWI2_CAPABLE(ha))
4232 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004233
Joe Carnuccio6766df92011-05-10 11:30:15 -07004234 if (len == 1)
4235 opt |= BIT_0;
4236
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004237 mcp->mb[0] = MBC_READ_SFP;
4238 mcp->mb[1] = dev;
4239 mcp->mb[2] = MSW(sfp_dma);
4240 mcp->mb[3] = LSW(sfp_dma);
4241 mcp->mb[6] = MSW(MSD(sfp_dma));
4242 mcp->mb[7] = LSW(MSD(sfp_dma));
4243 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004244 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004245 mcp->mb[10] = opt;
4246 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 -07004247 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004248 mcp->tov = MBX_TOV_SECONDS;
4249 mcp->flags = 0;
4250 rval = qla2x00_mailbox_command(vha, mcp);
4251
4252 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004253 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004254
4255 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004256 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
4257 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004258 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004259 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
4260 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004261 }
4262
4263 return rval;
4264}
4265
4266int
Joe Carnuccio6766df92011-05-10 11:30:15 -07004267qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
4268 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004269{
4270 int rval;
4271 mbx_cmd_t mc;
4272 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004273 struct qla_hw_data *ha = vha->hw;
4274
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004275 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb,
4276 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004277
Joe Carnuccio6766df92011-05-10 11:30:15 -07004278 if (!IS_FWI2_CAPABLE(ha))
4279 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004280
Joe Carnuccio6766df92011-05-10 11:30:15 -07004281 if (len == 1)
4282 opt |= BIT_0;
4283
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004284 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07004285 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004286
4287 mcp->mb[0] = MBC_WRITE_SFP;
4288 mcp->mb[1] = dev;
4289 mcp->mb[2] = MSW(sfp_dma);
4290 mcp->mb[3] = LSW(sfp_dma);
4291 mcp->mb[6] = MSW(MSD(sfp_dma));
4292 mcp->mb[7] = LSW(MSD(sfp_dma));
4293 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07004294 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004295 mcp->mb[10] = opt;
4296 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 -07004297 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004298 mcp->tov = MBX_TOV_SECONDS;
4299 mcp->flags = 0;
4300 rval = qla2x00_mailbox_command(vha, mcp);
4301
4302 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004303 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
4304 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004305 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004306 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed,
4307 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07004308 }
4309
4310 return rval;
4311}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004312
4313int
4314qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
4315 uint16_t size_in_bytes, uint16_t *actual_size)
4316{
4317 int rval;
4318 mbx_cmd_t mc;
4319 mbx_cmd_t *mcp = &mc;
4320
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004321 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee,
4322 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004323
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004324 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004325 return QLA_FUNCTION_FAILED;
4326
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004327 mcp->mb[0] = MBC_GET_XGMAC_STATS;
4328 mcp->mb[2] = MSW(stats_dma);
4329 mcp->mb[3] = LSW(stats_dma);
4330 mcp->mb[6] = MSW(MSD(stats_dma));
4331 mcp->mb[7] = LSW(MSD(stats_dma));
4332 mcp->mb[8] = size_in_bytes >> 2;
4333 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4334 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4335 mcp->tov = MBX_TOV_SECONDS;
4336 mcp->flags = 0;
4337 rval = qla2x00_mailbox_command(vha, mcp);
4338
4339 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004340 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
4341 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4342 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004343 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004344 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0,
4345 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004346
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004347
4348 *actual_size = mcp->mb[2] << 2;
4349 }
4350
4351 return rval;
4352}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004353
4354int
4355qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
4356 uint16_t size)
4357{
4358 int rval;
4359 mbx_cmd_t mc;
4360 mbx_cmd_t *mcp = &mc;
4361
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004362 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1,
4363 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004364
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004365 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004366 return QLA_FUNCTION_FAILED;
4367
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004368 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4369 mcp->mb[1] = 0;
4370 mcp->mb[2] = MSW(tlv_dma);
4371 mcp->mb[3] = LSW(tlv_dma);
4372 mcp->mb[6] = MSW(MSD(tlv_dma));
4373 mcp->mb[7] = LSW(MSD(tlv_dma));
4374 mcp->mb[8] = size;
4375 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4376 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4377 mcp->tov = MBX_TOV_SECONDS;
4378 mcp->flags = 0;
4379 rval = qla2x00_mailbox_command(vha, mcp);
4380
4381 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004382 ql_dbg(ql_dbg_mbx, vha, 0x10f2,
4383 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4384 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004385 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004386 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3,
4387 "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004388 }
4389
4390 return rval;
4391}
Andrew Vasquez18e75552009-06-03 09:55:30 -07004392
4393int
4394qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
4395{
4396 int rval;
4397 mbx_cmd_t mc;
4398 mbx_cmd_t *mcp = &mc;
4399
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004400 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4,
4401 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004402
Andrew Vasquez18e75552009-06-03 09:55:30 -07004403 if (!IS_FWI2_CAPABLE(vha->hw))
4404 return QLA_FUNCTION_FAILED;
4405
Andrew Vasquez18e75552009-06-03 09:55:30 -07004406 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
4407 mcp->mb[1] = LSW(risc_addr);
4408 mcp->mb[8] = MSW(risc_addr);
4409 mcp->out_mb = MBX_8|MBX_1|MBX_0;
4410 mcp->in_mb = MBX_3|MBX_2|MBX_0;
4411 mcp->tov = 30;
4412 mcp->flags = 0;
4413 rval = qla2x00_mailbox_command(vha, mcp);
4414 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004415 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
4416 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004417 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004418 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6,
4419 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004420 *data = mcp->mb[3] << 16 | mcp->mb[2];
4421 }
4422
4423 return rval;
4424}
4425
4426int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004427qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4428 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004429{
4430 int rval;
4431 mbx_cmd_t mc;
4432 mbx_cmd_t *mcp = &mc;
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004433
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004434 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7,
4435 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004436
4437 memset(mcp->mb, 0 , sizeof(mcp->mb));
4438 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
4439 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
4440
4441 /* transfer count */
4442 mcp->mb[10] = LSW(mreq->transfer_size);
4443 mcp->mb[11] = MSW(mreq->transfer_size);
4444
4445 /* send data address */
4446 mcp->mb[14] = LSW(mreq->send_dma);
4447 mcp->mb[15] = MSW(mreq->send_dma);
4448 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4449 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4450
Lucas De Marchi25985ed2011-03-30 22:57:33 -03004451 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004452 mcp->mb[16] = LSW(mreq->rcv_dma);
4453 mcp->mb[17] = MSW(mreq->rcv_dma);
4454 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4455 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4456
4457 /* Iteration count */
Joe Carnuccio1b98b422013-03-28 08:21:26 -04004458 mcp->mb[18] = LSW(mreq->iteration_count);
4459 mcp->mb[19] = MSW(mreq->iteration_count);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004460
4461 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
4462 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 -08004463 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004464 mcp->out_mb |= MBX_2;
4465 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
4466
4467 mcp->buf_size = mreq->transfer_size;
4468 mcp->tov = MBX_TOV_SECONDS;
4469 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4470
4471 rval = qla2x00_mailbox_command(vha, mcp);
4472
4473 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004474 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
4475 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
4476 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
4477 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004478 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004479 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9,
4480 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004481 }
4482
4483 /* Copy mailbox information */
4484 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004485 return rval;
4486}
4487
4488int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004489qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4490 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004491{
4492 int rval;
4493 mbx_cmd_t mc;
4494 mbx_cmd_t *mcp = &mc;
4495 struct qla_hw_data *ha = vha->hw;
4496
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004497 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa,
4498 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004499
4500 memset(mcp->mb, 0 , sizeof(mcp->mb));
4501 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
4502 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004503 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004504 mcp->mb[1] |= BIT_15;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004505 mcp->mb[2] = vha->fcoe_fcf_idx;
4506 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004507 mcp->mb[16] = LSW(mreq->rcv_dma);
4508 mcp->mb[17] = MSW(mreq->rcv_dma);
4509 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4510 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4511
4512 mcp->mb[10] = LSW(mreq->transfer_size);
4513
4514 mcp->mb[14] = LSW(mreq->send_dma);
4515 mcp->mb[15] = MSW(mreq->send_dma);
4516 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4517 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4518
4519 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
4520 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004521 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004522 mcp->out_mb |= MBX_2;
4523
4524 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004525 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
4526 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004527 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004528 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004529 mcp->in_mb |= MBX_3;
4530
4531 mcp->tov = MBX_TOV_SECONDS;
4532 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4533 mcp->buf_size = mreq->transfer_size;
4534
4535 rval = qla2x00_mailbox_command(vha, mcp);
4536
4537 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004538 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
4539 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4540 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004541 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004542 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc,
4543 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004544 }
4545
4546 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07004547 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004548 return rval;
4549}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07004550
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004551int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004552qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004553{
4554 int rval;
4555 mbx_cmd_t mc;
4556 mbx_cmd_t *mcp = &mc;
4557
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004558 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004559 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004560
4561 mcp->mb[0] = MBC_ISP84XX_RESET;
4562 mcp->mb[1] = enable_diagnostic;
4563 mcp->out_mb = MBX_1|MBX_0;
4564 mcp->in_mb = MBX_1|MBX_0;
4565 mcp->tov = MBX_TOV_SECONDS;
4566 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004567 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004568
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004569 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004570 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004571 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004572 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff,
4573 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004574
4575 return rval;
4576}
4577
4578int
Andrew Vasquez18e75552009-06-03 09:55:30 -07004579qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
4580{
4581 int rval;
4582 mbx_cmd_t mc;
4583 mbx_cmd_t *mcp = &mc;
4584
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004585 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100,
4586 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004587
Andrew Vasquez18e75552009-06-03 09:55:30 -07004588 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07004589 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07004590
Andrew Vasquez18e75552009-06-03 09:55:30 -07004591 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
4592 mcp->mb[1] = LSW(risc_addr);
4593 mcp->mb[2] = LSW(data);
4594 mcp->mb[3] = MSW(data);
4595 mcp->mb[8] = MSW(risc_addr);
4596 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
4597 mcp->in_mb = MBX_0;
4598 mcp->tov = 30;
4599 mcp->flags = 0;
4600 rval = qla2x00_mailbox_command(vha, mcp);
4601 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004602 ql_dbg(ql_dbg_mbx, vha, 0x1101,
4603 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004604 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004605 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
4606 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004607 }
4608
4609 return rval;
4610}
Michael Hernandez3064ff32009-12-15 21:29:44 -08004611
4612int
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004613qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
4614{
4615 int rval;
4616 uint32_t stat, timer;
4617 uint16_t mb0 = 0;
4618 struct qla_hw_data *ha = vha->hw;
4619 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
4620
4621 rval = QLA_SUCCESS;
4622
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004623 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103,
4624 "Entered %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004625
4626 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
4627
4628 /* Write the MBC data to the registers */
4629 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
4630 WRT_REG_WORD(&reg->mailbox1, mb[0]);
4631 WRT_REG_WORD(&reg->mailbox2, mb[1]);
4632 WRT_REG_WORD(&reg->mailbox3, mb[2]);
4633 WRT_REG_WORD(&reg->mailbox4, mb[3]);
4634
4635 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
4636
4637 /* Poll for MBC interrupt */
4638 for (timer = 6000000; timer; timer--) {
4639 /* Check for pending interrupts. */
4640 stat = RD_REG_DWORD(&reg->host_status);
4641 if (stat & HSRX_RISC_INT) {
4642 stat &= 0xff;
4643
4644 if (stat == 0x1 || stat == 0x2 ||
4645 stat == 0x10 || stat == 0x11) {
4646 set_bit(MBX_INTERRUPT,
4647 &ha->mbx_cmd_flags);
4648 mb0 = RD_REG_WORD(&reg->mailbox0);
4649 WRT_REG_DWORD(&reg->hccr,
4650 HCCRX_CLR_RISC_INT);
4651 RD_REG_DWORD(&reg->hccr);
4652 break;
4653 }
4654 }
4655 udelay(5);
4656 }
4657
4658 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
4659 rval = mb0 & MBS_MASK;
4660 else
4661 rval = QLA_FUNCTION_FAILED;
4662
4663 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004664 ql_dbg(ql_dbg_mbx, vha, 0x1104,
4665 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004666 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004667 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105,
4668 "Done %s.\n", __func__);
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004669 }
4670
4671 return rval;
4672}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004673
Madhuranath Iyengarb1d469892010-09-03 15:20:54 -07004674int
Michael Hernandez3064ff32009-12-15 21:29:44 -08004675qla2x00_get_data_rate(scsi_qla_host_t *vha)
4676{
4677 int rval;
4678 mbx_cmd_t mc;
4679 mbx_cmd_t *mcp = &mc;
4680 struct qla_hw_data *ha = vha->hw;
4681
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004682 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
4683 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004684
Michael Hernandez3064ff32009-12-15 21:29:44 -08004685 if (!IS_FWI2_CAPABLE(ha))
4686 return QLA_FUNCTION_FAILED;
4687
Michael Hernandez3064ff32009-12-15 21:29:44 -08004688 mcp->mb[0] = MBC_DATA_RATE;
4689 mcp->mb[1] = 0;
4690 mcp->out_mb = MBX_1|MBX_0;
4691 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Chad Dupuisf73cb692014-02-26 04:15:06 -05004692 if (IS_QLA83XX(ha) || IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004693 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08004694 mcp->tov = MBX_TOV_SECONDS;
4695 mcp->flags = 0;
4696 rval = qla2x00_mailbox_command(vha, mcp);
4697 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004698 ql_dbg(ql_dbg_mbx, vha, 0x1107,
4699 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004700 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004701 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
4702 "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004703 if (mcp->mb[1] != 0x7)
4704 ha->link_data_rate = mcp->mb[1];
4705 }
4706
4707 return rval;
4708}
Sarang Radke09ff7012010-03-19 17:03:59 -07004709
4710int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004711qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4712{
4713 int rval;
4714 mbx_cmd_t mc;
4715 mbx_cmd_t *mcp = &mc;
4716 struct qla_hw_data *ha = vha->hw;
4717
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004718 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
4719 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004720
Chad Dupuisf73cb692014-02-26 04:15:06 -05004721 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) && !IS_QLA8044(ha) &&
4722 !IS_QLA27XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004723 return QLA_FUNCTION_FAILED;
4724 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4725 mcp->out_mb = MBX_0;
4726 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4727 mcp->tov = MBX_TOV_SECONDS;
4728 mcp->flags = 0;
4729
4730 rval = qla2x00_mailbox_command(vha, mcp);
4731
4732 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004733 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4734 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004735 } else {
4736 /* Copy all bits to preserve original value */
4737 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4738
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004739 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b,
4740 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004741 }
4742 return rval;
4743}
4744
4745int
4746qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4747{
4748 int rval;
4749 mbx_cmd_t mc;
4750 mbx_cmd_t *mcp = &mc;
4751
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004752 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c,
4753 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004754
4755 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4756 /* Copy all bits to preserve original setting */
4757 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4758 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4759 mcp->in_mb = MBX_0;
4760 mcp->tov = MBX_TOV_SECONDS;
4761 mcp->flags = 0;
4762 rval = qla2x00_mailbox_command(vha, mcp);
4763
4764 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004765 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4766 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004767 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004768 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e,
4769 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004770
4771 return rval;
4772}
4773
4774
4775int
Sarang Radke09ff7012010-03-19 17:03:59 -07004776qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4777 uint16_t *mb)
4778{
4779 int rval;
4780 mbx_cmd_t mc;
4781 mbx_cmd_t *mcp = &mc;
4782 struct qla_hw_data *ha = vha->hw;
4783
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004784 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f,
4785 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004786
Sarang Radke09ff7012010-03-19 17:03:59 -07004787 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4788 return QLA_FUNCTION_FAILED;
4789
Sarang Radke09ff7012010-03-19 17:03:59 -07004790 mcp->mb[0] = MBC_PORT_PARAMS;
4791 mcp->mb[1] = loop_id;
4792 if (ha->flags.fcp_prio_enabled)
4793 mcp->mb[2] = BIT_1;
4794 else
4795 mcp->mb[2] = BIT_2;
4796 mcp->mb[4] = priority & 0xf;
4797 mcp->mb[9] = vha->vp_idx;
4798 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4799 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4800 mcp->tov = 30;
4801 mcp->flags = 0;
4802 rval = qla2x00_mailbox_command(vha, mcp);
4803 if (mb != NULL) {
4804 mb[0] = mcp->mb[0];
4805 mb[1] = mcp->mb[1];
4806 mb[3] = mcp->mb[3];
4807 mb[4] = mcp->mb[4];
4808 }
4809
4810 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004811 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07004812 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004813 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc,
4814 "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07004815 }
4816
4817 return rval;
4818}
Giridhar Malavalia9083012010-04-12 17:59:55 -07004819
4820int
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004821qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)
Andrew Vasquez794a5692010-12-21 16:00:21 -08004822{
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004823 int rval = QLA_FUNCTION_FAILED;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004824 struct qla_hw_data *ha = vha->hw;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004825 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004826
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004827 if (!IS_FWI2_CAPABLE(ha) || IS_QLA24XX_TYPE(ha) || IS_QLA81XX(ha)) {
4828 ql_dbg(ql_dbg_mbx, vha, 0x1150,
4829 "Thermal not supported by this card.\n");
4830 return rval;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004831 }
Andrew Vasquez794a5692010-12-21 16:00:21 -08004832
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004833 if (IS_QLA25XX(ha)) {
4834 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_QLOGIC &&
4835 ha->pdev->subsystem_device == 0x0175) {
4836 rval = qla2x00_read_sfp(vha, 0, &byte,
4837 0x98, 0x1, 1, BIT_13|BIT_0);
4838 *temp = byte;
4839 return rval;
4840 }
4841 if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
4842 ha->pdev->subsystem_device == 0x338e) {
4843 rval = qla2x00_read_sfp(vha, 0, &byte,
4844 0x98, 0x1, 1, BIT_15|BIT_14|BIT_0);
4845 *temp = byte;
4846 return rval;
4847 }
4848 ql_dbg(ql_dbg_mbx, vha, 0x10c9,
4849 "Thermal not supported by this card.\n");
4850 return rval;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004851 }
4852
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004853 if (IS_QLA82XX(ha)) {
4854 *temp = qla82xx_read_temperature(vha);
4855 rval = QLA_SUCCESS;
4856 return rval;
4857 } else if (IS_QLA8044(ha)) {
4858 *temp = qla8044_read_temperature(vha);
4859 rval = QLA_SUCCESS;
4860 return rval;
4861 }
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004862
Joe Carnuccio1ae47cf2013-08-27 01:37:36 -04004863 rval = qla2x00_read_asic_temperature(vha, temp);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004864 return rval;
4865}
4866
4867int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004868qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
4869{
4870 int rval;
4871 struct qla_hw_data *ha = vha->hw;
4872 mbx_cmd_t mc;
4873 mbx_cmd_t *mcp = &mc;
4874
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004875 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017,
4876 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004877
Giridhar Malavalia9083012010-04-12 17:59:55 -07004878 if (!IS_FWI2_CAPABLE(ha))
4879 return QLA_FUNCTION_FAILED;
4880
Giridhar Malavalia9083012010-04-12 17:59:55 -07004881 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004882 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004883 mcp->mb[1] = 1;
4884
4885 mcp->out_mb = MBX_1|MBX_0;
4886 mcp->in_mb = MBX_0;
4887 mcp->tov = 30;
4888 mcp->flags = 0;
4889
4890 rval = qla2x00_mailbox_command(vha, mcp);
4891 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004892 ql_dbg(ql_dbg_mbx, vha, 0x1016,
4893 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004894 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004895 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e,
4896 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004897 }
4898
4899 return rval;
4900}
4901
4902int
4903qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4904{
4905 int rval;
4906 struct qla_hw_data *ha = vha->hw;
4907 mbx_cmd_t mc;
4908 mbx_cmd_t *mcp = &mc;
4909
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004910 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
4911 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004912
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04004913 if (!IS_P3P_TYPE(ha))
Giridhar Malavalia9083012010-04-12 17:59:55 -07004914 return QLA_FUNCTION_FAILED;
4915
Giridhar Malavalia9083012010-04-12 17:59:55 -07004916 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004917 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004918 mcp->mb[1] = 0;
4919
4920 mcp->out_mb = MBX_1|MBX_0;
4921 mcp->in_mb = MBX_0;
4922 mcp->tov = 30;
4923 mcp->flags = 0;
4924
4925 rval = qla2x00_mailbox_command(vha, mcp);
4926 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004927 ql_dbg(ql_dbg_mbx, vha, 0x100c,
4928 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004929 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004930 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b,
4931 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004932 }
4933
4934 return rval;
4935}
Giridhar Malavali08de2842011-08-16 11:31:44 -07004936
4937int
4938qla82xx_md_get_template_size(scsi_qla_host_t *vha)
4939{
4940 struct qla_hw_data *ha = vha->hw;
4941 mbx_cmd_t mc;
4942 mbx_cmd_t *mcp = &mc;
4943 int rval = QLA_FUNCTION_FAILED;
4944
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004945 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f,
4946 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004947
4948 memset(mcp->mb, 0 , sizeof(mcp->mb));
4949 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4950 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4951 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
4952 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
4953
4954 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4955 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
4956 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4957
4958 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4959 mcp->tov = MBX_TOV_SECONDS;
4960 rval = qla2x00_mailbox_command(vha, mcp);
4961
4962 /* Always copy back return mailbox values. */
4963 if (rval != QLA_SUCCESS) {
4964 ql_dbg(ql_dbg_mbx, vha, 0x1120,
4965 "mailbox command FAILED=0x%x, subcode=%x.\n",
4966 (mcp->mb[1] << 16) | mcp->mb[0],
4967 (mcp->mb[3] << 16) | mcp->mb[2]);
4968 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004969 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121,
4970 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004971 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
4972 if (!ha->md_template_size) {
4973 ql_dbg(ql_dbg_mbx, vha, 0x1122,
4974 "Null template size obtained.\n");
4975 rval = QLA_FUNCTION_FAILED;
4976 }
4977 }
4978 return rval;
4979}
4980
4981int
4982qla82xx_md_get_template(scsi_qla_host_t *vha)
4983{
4984 struct qla_hw_data *ha = vha->hw;
4985 mbx_cmd_t mc;
4986 mbx_cmd_t *mcp = &mc;
4987 int rval = QLA_FUNCTION_FAILED;
4988
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004989 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123,
4990 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004991
4992 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4993 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4994 if (!ha->md_tmplt_hdr) {
4995 ql_log(ql_log_warn, vha, 0x1124,
4996 "Unable to allocate memory for Minidump template.\n");
4997 return rval;
4998 }
4999
5000 memset(mcp->mb, 0 , sizeof(mcp->mb));
5001 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5002 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5003 mcp->mb[2] = LSW(RQST_TMPLT);
5004 mcp->mb[3] = MSW(RQST_TMPLT);
5005 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
5006 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
5007 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
5008 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
5009 mcp->mb[8] = LSW(ha->md_template_size);
5010 mcp->mb[9] = MSW(ha->md_template_size);
5011
5012 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5013 mcp->tov = MBX_TOV_SECONDS;
5014 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5015 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5016 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5017 rval = qla2x00_mailbox_command(vha, mcp);
5018
5019 if (rval != QLA_SUCCESS) {
5020 ql_dbg(ql_dbg_mbx, vha, 0x1125,
5021 "mailbox command FAILED=0x%x, subcode=%x.\n",
5022 ((mcp->mb[1] << 16) | mcp->mb[0]),
5023 ((mcp->mb[3] << 16) | mcp->mb[2]));
5024 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005025 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126,
5026 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07005027 return rval;
5028}
Saurav Kashyap999916d2011-08-16 11:31:45 -07005029
5030int
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005031qla8044_md_get_template(scsi_qla_host_t *vha)
5032{
5033 struct qla_hw_data *ha = vha->hw;
5034 mbx_cmd_t mc;
5035 mbx_cmd_t *mcp = &mc;
5036 int rval = QLA_FUNCTION_FAILED;
5037 int offset = 0, size = MINIDUMP_SIZE_36K;
5038 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11f,
5039 "Entered %s.\n", __func__);
5040
5041 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
5042 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
5043 if (!ha->md_tmplt_hdr) {
5044 ql_log(ql_log_warn, vha, 0xb11b,
5045 "Unable to allocate memory for Minidump template.\n");
5046 return rval;
5047 }
5048
5049 memset(mcp->mb, 0 , sizeof(mcp->mb));
5050 while (offset < ha->md_template_size) {
5051 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5052 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
5053 mcp->mb[2] = LSW(RQST_TMPLT);
5054 mcp->mb[3] = MSW(RQST_TMPLT);
5055 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma + offset));
5056 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma + offset));
5057 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma + offset));
5058 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma + offset));
5059 mcp->mb[8] = LSW(size);
5060 mcp->mb[9] = MSW(size);
5061 mcp->mb[10] = offset & 0x0000FFFF;
5062 mcp->mb[11] = offset & 0xFFFF0000;
5063 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
5064 mcp->tov = MBX_TOV_SECONDS;
5065 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
5066 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5067 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
5068 rval = qla2x00_mailbox_command(vha, mcp);
5069
5070 if (rval != QLA_SUCCESS) {
5071 ql_dbg(ql_dbg_mbx, vha, 0xb11c,
5072 "mailbox command FAILED=0x%x, subcode=%x.\n",
5073 ((mcp->mb[1] << 16) | mcp->mb[0]),
5074 ((mcp->mb[3] << 16) | mcp->mb[2]));
5075 return rval;
5076 } else
5077 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0xb11d,
5078 "Done %s.\n", __func__);
5079 offset = offset + size;
5080 }
5081 return rval;
5082}
5083
5084int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005085qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5086{
5087 int rval;
5088 struct qla_hw_data *ha = vha->hw;
5089 mbx_cmd_t mc;
5090 mbx_cmd_t *mcp = &mc;
5091
5092 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5093 return QLA_FUNCTION_FAILED;
5094
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005095 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133,
5096 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005097
5098 memset(mcp, 0, sizeof(mbx_cmd_t));
5099 mcp->mb[0] = MBC_SET_LED_CONFIG;
5100 mcp->mb[1] = led_cfg[0];
5101 mcp->mb[2] = led_cfg[1];
5102 if (IS_QLA8031(ha)) {
5103 mcp->mb[3] = led_cfg[2];
5104 mcp->mb[4] = led_cfg[3];
5105 mcp->mb[5] = led_cfg[4];
5106 mcp->mb[6] = led_cfg[5];
5107 }
5108
5109 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5110 if (IS_QLA8031(ha))
5111 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5112 mcp->in_mb = MBX_0;
5113 mcp->tov = 30;
5114 mcp->flags = 0;
5115
5116 rval = qla2x00_mailbox_command(vha, mcp);
5117 if (rval != QLA_SUCCESS) {
5118 ql_dbg(ql_dbg_mbx, vha, 0x1134,
5119 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5120 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005121 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135,
5122 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005123 }
5124
5125 return rval;
5126}
5127
5128int
5129qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
5130{
5131 int rval;
5132 struct qla_hw_data *ha = vha->hw;
5133 mbx_cmd_t mc;
5134 mbx_cmd_t *mcp = &mc;
5135
5136 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
5137 return QLA_FUNCTION_FAILED;
5138
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005139 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136,
5140 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005141
5142 memset(mcp, 0, sizeof(mbx_cmd_t));
5143 mcp->mb[0] = MBC_GET_LED_CONFIG;
5144
5145 mcp->out_mb = MBX_0;
5146 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5147 if (IS_QLA8031(ha))
5148 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
5149 mcp->tov = 30;
5150 mcp->flags = 0;
5151
5152 rval = qla2x00_mailbox_command(vha, mcp);
5153 if (rval != QLA_SUCCESS) {
5154 ql_dbg(ql_dbg_mbx, vha, 0x1137,
5155 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5156 } else {
5157 led_cfg[0] = mcp->mb[1];
5158 led_cfg[1] = mcp->mb[2];
5159 if (IS_QLA8031(ha)) {
5160 led_cfg[2] = mcp->mb[3];
5161 led_cfg[3] = mcp->mb[4];
5162 led_cfg[4] = mcp->mb[5];
5163 led_cfg[5] = mcp->mb[6];
5164 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005165 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138,
5166 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005167 }
5168
5169 return rval;
5170}
5171
5172int
Saurav Kashyap999916d2011-08-16 11:31:45 -07005173qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
5174{
5175 int rval;
5176 struct qla_hw_data *ha = vha->hw;
5177 mbx_cmd_t mc;
5178 mbx_cmd_t *mcp = &mc;
5179
Atul Deshmukh7ec0eff2013-08-27 01:37:28 -04005180 if (!IS_P3P_TYPE(ha))
Saurav Kashyap999916d2011-08-16 11:31:45 -07005181 return QLA_FUNCTION_FAILED;
5182
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005183 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005184 "Entered %s.\n", __func__);
5185
5186 memset(mcp, 0, sizeof(mbx_cmd_t));
5187 mcp->mb[0] = MBC_SET_LED_CONFIG;
5188 if (enable)
5189 mcp->mb[7] = 0xE;
5190 else
5191 mcp->mb[7] = 0xD;
5192
5193 mcp->out_mb = MBX_7|MBX_0;
5194 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005195 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07005196 mcp->flags = 0;
5197
5198 rval = qla2x00_mailbox_command(vha, mcp);
5199 if (rval != QLA_SUCCESS) {
5200 ql_dbg(ql_dbg_mbx, vha, 0x1128,
5201 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5202 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005203 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129,
Saurav Kashyap999916d2011-08-16 11:31:45 -07005204 "Done %s.\n", __func__);
5205 }
5206
5207 return rval;
5208}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005209
5210int
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005211qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005212{
5213 int rval;
5214 struct qla_hw_data *ha = vha->hw;
5215 mbx_cmd_t mc;
5216 mbx_cmd_t *mcp = &mc;
5217
Chad Dupuisf73cb692014-02-26 04:15:06 -05005218 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005219 return QLA_FUNCTION_FAILED;
5220
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005221 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130,
5222 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005223
5224 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
5225 mcp->mb[1] = LSW(reg);
5226 mcp->mb[2] = MSW(reg);
5227 mcp->mb[3] = LSW(data);
5228 mcp->mb[4] = MSW(data);
5229 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
5230
5231 mcp->in_mb = MBX_1|MBX_0;
5232 mcp->tov = MBX_TOV_SECONDS;
5233 mcp->flags = 0;
5234 rval = qla2x00_mailbox_command(vha, mcp);
5235
5236 if (rval != QLA_SUCCESS) {
5237 ql_dbg(ql_dbg_mbx, vha, 0x1131,
5238 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5239 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005240 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005241 "Done %s.\n", __func__);
5242 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005243
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08005244 return rval;
5245}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005246
5247int
5248qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
5249{
5250 int rval;
5251 struct qla_hw_data *ha = vha->hw;
5252 mbx_cmd_t mc;
5253 mbx_cmd_t *mcp = &mc;
5254
5255 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005256 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b,
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005257 "Implicit LOGO Unsupported.\n");
5258 return QLA_FUNCTION_FAILED;
5259 }
5260
5261
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005262 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c,
5263 "Entering %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005264
5265 /* Perform Implicit LOGO. */
5266 mcp->mb[0] = MBC_PORT_LOGOUT;
5267 mcp->mb[1] = fcport->loop_id;
5268 mcp->mb[10] = BIT_15;
5269 mcp->out_mb = MBX_10|MBX_1|MBX_0;
5270 mcp->in_mb = MBX_0;
5271 mcp->tov = MBX_TOV_SECONDS;
5272 mcp->flags = 0;
5273 rval = qla2x00_mailbox_command(vha, mcp);
5274 if (rval != QLA_SUCCESS)
5275 ql_dbg(ql_dbg_mbx, vha, 0x113d,
5276 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5277 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04005278 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e,
5279 "Done %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08005280
5281 return rval;
5282}
5283
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005284int
5285qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
5286{
5287 int rval;
5288 mbx_cmd_t mc;
5289 mbx_cmd_t *mcp = &mc;
5290 struct qla_hw_data *ha = vha->hw;
5291 unsigned long retry_max_time = jiffies + (2 * HZ);
5292
Chad Dupuisf73cb692014-02-26 04:15:06 -05005293 if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha))
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04005294 return QLA_FUNCTION_FAILED;
5295
5296 ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
5297
5298retry_rd_reg:
5299 mcp->mb[0] = MBC_READ_REMOTE_REG;
5300 mcp->mb[1] = LSW(reg);
5301 mcp->mb[2] = MSW(reg);
5302 mcp->out_mb = MBX_2|MBX_1|MBX_0;
5303 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
5304 mcp->tov = MBX_TOV_SECONDS;
5305 mcp->flags = 0;
5306 rval = qla2x00_mailbox_command(vha, mcp);
5307
5308 if (rval != QLA_SUCCESS) {
5309 ql_dbg(ql_dbg_mbx, vha, 0x114c,
5310 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5311 rval, mcp->mb[0], mcp->mb[1]);
5312 } else {
5313 *data = (mcp->mb[3] | (mcp->mb[4] << 16));
5314 if (*data == QLA8XXX_BAD_VALUE) {
5315 /*
5316 * During soft-reset CAMRAM register reads might
5317 * return 0xbad0bad0. So retry for MAX of 2 sec
5318 * while reading camram registers.
5319 */
5320 if (time_after(jiffies, retry_max_time)) {
5321 ql_dbg(ql_dbg_mbx, vha, 0x1141,
5322 "Failure to read CAMRAM register. "
5323 "data=0x%x.\n", *data);
5324 return QLA_FUNCTION_FAILED;
5325 }
5326 msleep(100);
5327 goto retry_rd_reg;
5328 }
5329 ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
5330 }
5331
5332 return rval;
5333}
5334
5335int
5336qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
5337{
5338 int rval;
5339 mbx_cmd_t mc;
5340 mbx_cmd_t *mcp = &mc;
5341 struct qla_hw_data *ha = vha->hw;
5342
5343 if (!IS_QLA83XX(ha))
5344 return QLA_FUNCTION_FAILED;
5345
5346 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
5347
5348 mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
5349 mcp->out_mb = MBX_0;
5350 mcp->in_mb = MBX_1|MBX_0;
5351 mcp->tov = MBX_TOV_SECONDS;
5352 mcp->flags = 0;
5353 rval = qla2x00_mailbox_command(vha, mcp);
5354
5355 if (rval != QLA_SUCCESS) {
5356 ql_dbg(ql_dbg_mbx, vha, 0x1144,
5357 "Failed=%x mb[0]=%x mb[1]=%x.\n",
5358 rval, mcp->mb[0], mcp->mb[1]);
5359 ha->isp_ops->fw_dump(vha, 0);
5360 } else {
5361 ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
5362 }
5363
5364 return rval;
5365}
5366
5367int
5368qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
5369 uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
5370{
5371 int rval;
5372 mbx_cmd_t mc;
5373 mbx_cmd_t *mcp = &mc;
5374 uint8_t subcode = (uint8_t)options;
5375 struct qla_hw_data *ha = vha->hw;
5376
5377 if (!IS_QLA8031(ha))
5378 return QLA_FUNCTION_FAILED;
5379
5380 ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
5381
5382 mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
5383 mcp->mb[1] = options;
5384 mcp->out_mb = MBX_1|MBX_0;
5385 if (subcode & BIT_2) {
5386 mcp->mb[2] = LSW(start_addr);
5387 mcp->mb[3] = MSW(start_addr);
5388 mcp->mb[4] = LSW(end_addr);
5389 mcp->mb[5] = MSW(end_addr);
5390 mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
5391 }
5392 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5393 if (!(subcode & (BIT_2 | BIT_5)))
5394 mcp->in_mb |= MBX_4|MBX_3;
5395 mcp->tov = MBX_TOV_SECONDS;
5396 mcp->flags = 0;
5397 rval = qla2x00_mailbox_command(vha, mcp);
5398
5399 if (rval != QLA_SUCCESS) {
5400 ql_dbg(ql_dbg_mbx, vha, 0x1147,
5401 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
5402 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
5403 mcp->mb[4]);
5404 ha->isp_ops->fw_dump(vha, 0);
5405 } else {
5406 if (subcode & BIT_5)
5407 *sector_size = mcp->mb[1];
5408 else if (subcode & (BIT_6 | BIT_7)) {
5409 ql_dbg(ql_dbg_mbx, vha, 0x1148,
5410 "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5411 } else if (subcode & (BIT_3 | BIT_4)) {
5412 ql_dbg(ql_dbg_mbx, vha, 0x1149,
5413 "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5414 }
5415 ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
5416 }
5417
5418 return rval;
5419}
Saurav Kashyap81178772012-08-22 14:21:04 -04005420
5421int
5422qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
5423 uint32_t size)
5424{
5425 int rval;
5426 mbx_cmd_t mc;
5427 mbx_cmd_t *mcp = &mc;
5428
5429 if (!IS_MCTP_CAPABLE(vha->hw))
5430 return QLA_FUNCTION_FAILED;
5431
5432 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,
5433 "Entered %s.\n", __func__);
5434
5435 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
5436 mcp->mb[1] = LSW(addr);
5437 mcp->mb[2] = MSW(req_dma);
5438 mcp->mb[3] = LSW(req_dma);
5439 mcp->mb[4] = MSW(size);
5440 mcp->mb[5] = LSW(size);
5441 mcp->mb[6] = MSW(MSD(req_dma));
5442 mcp->mb[7] = LSW(MSD(req_dma));
5443 mcp->mb[8] = MSW(addr);
5444 /* Setting RAM ID to valid */
5445 mcp->mb[10] |= BIT_7;
5446 /* For MCTP RAM ID is 0x40 */
5447 mcp->mb[10] |= 0x40;
5448
5449 mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
5450 MBX_0;
5451
5452 mcp->in_mb = MBX_0;
5453 mcp->tov = MBX_TOV_SECONDS;
5454 mcp->flags = 0;
5455 rval = qla2x00_mailbox_command(vha, mcp);
5456
5457 if (rval != QLA_SUCCESS) {
5458 ql_dbg(ql_dbg_mbx, vha, 0x114e,
5459 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5460 } else {
5461 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,
5462 "Done %s.\n", __func__);
5463 }
5464
5465 return rval;
5466}