blob: 144effd45ddfd6e59f01f1ab25f1fcffe5fd8835 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Andrew Vasquezfa90c542005-10-27 11:10:08 -07002 * QLogic Fibre Channel HBA Driver
Saurav Kashyap1e633952013-02-08 01:57:54 -05003 * Copyright (c) 2003-2013 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{
36 int rval;
37 unsigned long flags = 0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070038 device_reg_t __iomem *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;
Linus Torvalds1da177e2005-04-16 15:20:36 -070046 unsigned long wait_time;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080047 struct qla_hw_data *ha = vha->hw;
48 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070049
Arun Easi5e19ed92012-02-09 11:15:51 -080050 ql_dbg(ql_dbg_mbx, vha, 0x1000, "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -070051
52 if (ha->pdev->error_state > pci_channel_io_frozen) {
Arun Easi5e19ed92012-02-09 11:15:51 -080053 ql_log(ql_log_warn, vha, 0x1001,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070054 "error_state is greater than pci_channel_io_frozen, "
55 "exiting.\n");
Seokmann Jub9b12f72009-03-24 09:08:18 -070056 return QLA_FUNCTION_TIMEOUT;
Saurav Kashyap7c3df132011-07-14 12:00:13 -070057 }
Seokmann Jub9b12f72009-03-24 09:08:18 -070058
Giridhar Malavalia9083012010-04-12 17:59:55 -070059 if (vha->device_flags & DFLG_DEV_FAILED) {
Arun Easi5e19ed92012-02-09 11:15:51 -080060 ql_log(ql_log_warn, vha, 0x1002,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070061 "Device in failed state, exiting.\n");
Giridhar Malavalia9083012010-04-12 17:59:55 -070062 return QLA_FUNCTION_TIMEOUT;
63 }
64
Seokmann Ju2c3dfe32007-07-05 13:16:51 -070065 reg = ha->iobase;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080066 io_lock_on = base_vha->flags.init_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -070067
68 rval = QLA_SUCCESS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -080069 abort_active = test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070071
Andrew Vasquez85880802009-12-15 21:29:46 -080072 if (ha->flags.pci_channel_io_perm_failure) {
Arun Easi5e19ed92012-02-09 11:15:51 -080073 ql_log(ql_log_warn, vha, 0x1003,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070074 "Perm failure on EEH timeout MBX, exiting.\n");
Andrew Vasquez85880802009-12-15 21:29:46 -080075 return QLA_FUNCTION_TIMEOUT;
76 }
77
Santosh Vernekar7d613ac2012-08-22 14:21:03 -040078 if (IS_QLA82XX(ha) && ha->flags.isp82xx_fw_hung) {
Giridhar Malavali862cd012011-02-23 15:27:11 -080079 /* Setting Link-Down error */
80 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
Arun Easi5e19ed92012-02-09 11:15:51 -080081 ql_log(ql_log_warn, vha, 0x1004,
Saurav Kashyap7c3df132011-07-14 12:00:13 -070082 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Andrew Vasquez1806fcd2011-11-18 09:02:15 -080083 return QLA_FUNCTION_TIMEOUT;
Giridhar Malavali862cd012011-02-23 15:27:11 -080084 }
85
Linus Torvalds1da177e2005-04-16 15:20:36 -070086 /*
Andrew Vasquez1c7c6352005-07-06 10:30:57 -070087 * Wait for active mailbox commands to finish by waiting at most tov
88 * seconds. This is to serialize actual issuing of mailbox cmds during
89 * non ISP abort time.
Linus Torvalds1da177e2005-04-16 15:20:36 -070090 */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080091 if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) {
92 /* Timeout occurred. Return error. */
Arun Easi5e19ed92012-02-09 11:15:51 -080093 ql_log(ql_log_warn, vha, 0x1005,
Chad Dupuisd8c0d542012-02-09 11:15:46 -080094 "Cmd access timeout, cmd=0x%x, Exiting.\n",
95 mcp->mb[0]);
Andrew Vasquez8eca3f32009-01-22 09:45:31 -080096 return QLA_FUNCTION_TIMEOUT;
Linus Torvalds1da177e2005-04-16 15:20:36 -070097 }
98
99 ha->flags.mbox_busy = 1;
100 /* Save mailbox command for debug */
101 ha->mcp = mcp;
102
Arun Easi5e19ed92012-02-09 11:15:51 -0800103 ql_dbg(ql_dbg_mbx, vha, 0x1006,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700104 "Prepare to issue mbox cmd=0x%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
106 spin_lock_irqsave(&ha->hardware_lock, flags);
107
108 /* Load mailbox registers. */
Giridhar Malavalia9083012010-04-12 17:59:55 -0700109 if (IS_QLA82XX(ha))
110 optr = (uint16_t __iomem *)&reg->isp82.mailbox_in[0];
111 else if (IS_FWI2_CAPABLE(ha) && !IS_QLA82XX(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700112 optr = (uint16_t __iomem *)&reg->isp24.mailbox0;
113 else
114 optr = (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
116 iptr = mcp->mb;
117 command = mcp->mb[0];
118 mboxes = mcp->out_mb;
119
120 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
121 if (IS_QLA2200(ha) && cnt == 8)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700122 optr =
123 (uint16_t __iomem *)MAILBOX_REG(ha, &reg->isp, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 if (mboxes & BIT_0)
125 WRT_REG_WORD(optr, *iptr);
126
127 mboxes >>= 1;
128 optr++;
129 iptr++;
130 }
131
Arun Easi5e19ed92012-02-09 11:15:51 -0800132 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1111,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700133 "Loaded MBX registers (displayed in bytes) =.\n");
Arun Easi5e19ed92012-02-09 11:15:51 -0800134 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1112,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700135 (uint8_t *)mcp->mb, 16);
Arun Easi5e19ed92012-02-09 11:15:51 -0800136 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1113,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700137 ".\n");
Arun Easi5e19ed92012-02-09 11:15:51 -0800138 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1114,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700139 ((uint8_t *)mcp->mb + 0x10), 16);
Arun Easi5e19ed92012-02-09 11:15:51 -0800140 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1115,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700141 ".\n");
Arun Easi5e19ed92012-02-09 11:15:51 -0800142 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1116,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700143 ((uint8_t *)mcp->mb + 0x20), 8);
Arun Easi5e19ed92012-02-09 11:15:51 -0800144 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1117,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700145 "I/O Address = %p.\n", optr);
Arun Easi5e19ed92012-02-09 11:15:51 -0800146 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x100e);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700147
148 /* Issue set host interrupt command to send cmd out. */
149 ha->flags.mbox_int = 0;
150 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
151
152 /* Unlock mbx registers and wait for interrupt */
Arun Easi5e19ed92012-02-09 11:15:51 -0800153 ql_dbg(ql_dbg_mbx, vha, 0x100f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700154 "Going to unlock irq & waiting for interrupts. "
155 "jiffies=%lx.\n", jiffies);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156
157 /* Wait for mbx cmd completion until timeout */
158
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800159 if ((!abort_active && io_lock_on) || IS_NOPOLLING_TYPE(ha)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
161
Giridhar Malavalia9083012010-04-12 17:59:55 -0700162 if (IS_QLA82XX(ha)) {
163 if (RD_REG_DWORD(&reg->isp82.hint) &
164 HINT_MBX_INT_PENDING) {
165 spin_unlock_irqrestore(&ha->hardware_lock,
166 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800167 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800168 ql_dbg(ql_dbg_mbx, vha, 0x1010,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700169 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700170 rval = QLA_FUNCTION_TIMEOUT;
171 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700172 }
173 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
174 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700175 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
176 else
177 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178 spin_unlock_irqrestore(&ha->hardware_lock, flags);
179
Giridhar Malavali754d1242013-06-25 11:27:16 -0400180 if (!wait_for_completion_timeout(&ha->mbx_intr_comp,
181 mcp->tov * HZ)) {
182 ql_dbg(ql_dbg_mbx, vha, 0x117a,
183 "cmd=%x Timeout.\n", command);
184 spin_lock_irqsave(&ha->hardware_lock, flags);
185 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags);
186 spin_unlock_irqrestore(&ha->hardware_lock, flags);
187 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 } else {
Arun Easi5e19ed92012-02-09 11:15:51 -0800189 ql_dbg(ql_dbg_mbx, vha, 0x1011,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700190 "Cmd=%x Polling Mode.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191
Giridhar Malavalia9083012010-04-12 17:59:55 -0700192 if (IS_QLA82XX(ha)) {
193 if (RD_REG_DWORD(&reg->isp82.hint) &
194 HINT_MBX_INT_PENDING) {
195 spin_unlock_irqrestore(&ha->hardware_lock,
196 flags);
Giridhar Malavali8937f2f2011-11-18 09:02:18 -0800197 ha->flags.mbox_busy = 0;
Arun Easi5e19ed92012-02-09 11:15:51 -0800198 ql_dbg(ql_dbg_mbx, vha, 0x1012,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700199 "Pending mailbox timeout, exiting.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700200 rval = QLA_FUNCTION_TIMEOUT;
201 goto premature_exit;
Giridhar Malavalia9083012010-04-12 17:59:55 -0700202 }
203 WRT_REG_DWORD(&reg->isp82.hint, HINT_MBX_INT_PENDING);
204 } else if (IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700205 WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_SET_HOST_INT);
206 else
207 WRT_REG_WORD(&reg->isp.hccr, HCCR_SET_HOST_INT);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209
210 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */
211 while (!ha->flags.mbox_int) {
212 if (time_after(jiffies, wait_time))
213 break;
214
215 /* Check for pending interrupts. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800216 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217
Andrew Vasquez85880802009-12-15 21:29:46 -0800218 if (!ha->flags.mbox_int &&
219 !(IS_QLA2200(ha) &&
220 command == MBC_LOAD_RISC_RAM_EXTENDED))
andrew.vasquez@qlogic.com59989832006-01-13 17:05:10 -0800221 msleep(10);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 } /* while */
Arun Easi5e19ed92012-02-09 11:15:51 -0800223 ql_dbg(ql_dbg_mbx, vha, 0x1013,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700224 "Waited %d sec.\n",
225 (uint)((jiffies - (wait_time - (mcp->tov * HZ)))/HZ));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 }
227
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 /* Check whether we timed out */
229 if (ha->flags.mbox_int) {
230 uint16_t *iptr2;
231
Arun Easi5e19ed92012-02-09 11:15:51 -0800232 ql_dbg(ql_dbg_mbx, vha, 0x1014,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700233 "Cmd=%x completed.\n", command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234
235 /* Got interrupt. Clear the flag. */
236 ha->flags.mbox_int = 0;
237 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
238
Santosh Vernekar7d613ac2012-08-22 14:21:03 -0400239 if ((IS_QLA82XX(ha) && ha->flags.isp82xx_fw_hung)) {
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700240 ha->flags.mbox_busy = 0;
241 /* Setting Link-Down error */
242 mcp->mb[0] = MBS_LINK_DOWN_ERROR;
243 ha->mcp = NULL;
244 rval = QLA_FUNCTION_FAILED;
Arun Easi5e19ed92012-02-09 11:15:51 -0800245 ql_log(ql_log_warn, vha, 0x1015,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700246 "FW hung = %d.\n", ha->flags.isp82xx_fw_hung);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700247 goto premature_exit;
248 }
249
Andrew Vasquez 354d6b22005-04-23 02:47:27 -0400250 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700251 rval = QLA_FUNCTION_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
253 /* Load return mailbox registers. */
254 iptr2 = mcp->mb;
255 iptr = (uint16_t *)&ha->mailbox_out[0];
256 mboxes = mcp->in_mb;
257 for (cnt = 0; cnt < ha->mbx_count; cnt++) {
258 if (mboxes & BIT_0)
259 *iptr2 = *iptr;
260
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
284 * of the current firmware state
285 */
286 ha->isp_ops->fw_dump(vha, 0);
287
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 rval = QLA_FUNCTION_TIMEOUT;
289 }
290
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 ha->flags.mbox_busy = 0;
292
293 /* Clean up */
294 ha->mcp = NULL;
295
Andrew Vasquez124f85e2009-01-05 11:18:06 -0800296 if ((abort_active || !io_lock_on) && !IS_NOPOLLING_TYPE(ha)) {
Arun Easi5e19ed92012-02-09 11:15:51 -0800297 ql_dbg(ql_dbg_mbx, vha, 0x101a,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700298 "Checking for additional resp interrupt.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299
300 /* polling mode for non isp_abort commands. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800301 qla2x00_poll(ha->rsp_q_map[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302 }
303
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700304 if (rval == QLA_FUNCTION_TIMEOUT &&
305 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) {
Andrew Vasquez85880802009-12-15 21:29:46 -0800306 if (!io_lock_on || (mcp->flags & IOCTL_CMD) ||
307 ha->flags.eeh_busy) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 /* not in dpc. schedule it for dpc to take over. */
Arun Easi5e19ed92012-02-09 11:15:51 -0800309 ql_dbg(ql_dbg_mbx, vha, 0x101b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700310 "Timeout, schedule isp_abort_needed.\n");
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700311
312 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
313 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
314 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800315 if (IS_QLA82XX(ha)) {
316 ql_dbg(ql_dbg_mbx, vha, 0x112a,
317 "disabling pause transmit on port "
318 "0 & 1.\n");
319 qla82xx_wr_32(ha,
320 QLA82XX_CRB_NIU + 0x98,
321 CRB_NIU_XG_PAUSE_CTL_P0|
322 CRB_NIU_XG_PAUSE_CTL_P1);
323 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700324 ql_log(ql_log_info, base_vha, 0x101c,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400325 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800326 "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP "
327 "abort.\n", command, mcp->mb[0],
328 ha->flags.eeh_busy);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700329 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
330 qla2xxx_wake_dpc(vha);
331 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 } else if (!abort_active) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333 /* call abort directly since we are in the DPC thread */
Arun Easi5e19ed92012-02-09 11:15:51 -0800334 ql_dbg(ql_dbg_mbx, vha, 0x101d,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700335 "Timeout, calling abort_isp.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700337 if (!test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) &&
338 !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) &&
339 !test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
Giridhar Malavali63154912011-11-18 09:02:19 -0800340 if (IS_QLA82XX(ha)) {
341 ql_dbg(ql_dbg_mbx, vha, 0x112b,
342 "disabling pause transmit on port "
343 "0 & 1.\n");
344 qla82xx_wr_32(ha,
345 QLA82XX_CRB_NIU + 0x98,
346 CRB_NIU_XG_PAUSE_CTL_P0|
347 CRB_NIU_XG_PAUSE_CTL_P1);
348 }
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700349 ql_log(ql_log_info, base_vha, 0x101e,
Masanari Iida24d9ee82012-05-15 14:34:10 -0400350 "Mailbox cmd timeout occurred, cmd=0x%x, "
Chad Dupuisd8c0d542012-02-09 11:15:46 -0800351 "mb[0]=0x%x. Scheduling ISP abort ",
352 command, mcp->mb[0]);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700353 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
354 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
Giridhar Malavalid3360962012-02-09 11:14:10 -0800355 /* Allow next mbx cmd to come in. */
356 complete(&ha->mbx_cmd_comp);
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700357 if (ha->isp_ops->abort_isp(vha)) {
358 /* Failed. retry later. */
359 set_bit(ISP_ABORT_NEEDED,
360 &vha->dpc_flags);
361 }
362 clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
Arun Easi5e19ed92012-02-09 11:15:51 -0800363 ql_dbg(ql_dbg_mbx, vha, 0x101f,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700364 "Finished abort_isp.\n");
Giridhar Malavalid3360962012-02-09 11:14:10 -0800365 goto mbx_done;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 }
368 }
369
Santosh Vernekarcdbb0a4f2010-05-28 15:08:25 -0700370premature_exit:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 /* Allow next mbx cmd to come in. */
Andrew Vasquez8eca3f32009-01-22 09:45:31 -0800372 complete(&ha->mbx_cmd_comp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
Giridhar Malavalid3360962012-02-09 11:14:10 -0800374mbx_done:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 if (rval) {
Saurav Kashyap09543c02012-08-22 14:20:59 -0400376 ql_log(ql_log_warn, base_vha, 0x1020,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800377 "**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x, cmd=%x ****.\n",
378 mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3], command);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 } else {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700380 ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381 }
382
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 return rval;
384}
385
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800387qla2x00_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 -0800388 uint32_t risc_code_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389{
390 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800391 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 mbx_cmd_t mc;
393 mbx_cmd_t *mcp = &mc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400395 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022,
396 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397
Andrew Vasqueze4289242007-07-19 15:05:56 -0700398 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800399 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED;
400 mcp->mb[8] = MSW(risc_addr);
401 mcp->out_mb = MBX_8|MBX_0;
402 } else {
403 mcp->mb[0] = MBC_LOAD_RISC_RAM;
404 mcp->out_mb = MBX_0;
405 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406 mcp->mb[1] = LSW(risc_addr);
407 mcp->mb[2] = MSW(req_dma);
408 mcp->mb[3] = LSW(req_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 mcp->mb[6] = MSW(MSD(req_dma));
410 mcp->mb[7] = LSW(MSD(req_dma));
andrew.vasquez@qlogic.com590f98e2006-01-13 17:05:37 -0800411 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700412 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700413 mcp->mb[4] = MSW(risc_code_size);
414 mcp->mb[5] = LSW(risc_code_size);
415 mcp->out_mb |= MBX_5|MBX_4;
416 } else {
417 mcp->mb[4] = LSW(risc_code_size);
418 mcp->out_mb |= MBX_4;
419 }
420
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700422 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800424 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700427 ql_dbg(ql_dbg_mbx, vha, 0x1023,
428 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400430 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024,
431 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 }
433
434 return rval;
435}
436
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700437#define EXTENDED_BB_CREDITS BIT_0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438/*
439 * qla2x00_execute_fw
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700440 * Start adapter firmware.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 *
442 * Input:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700443 * ha = adapter block pointer.
444 * TARGET_QUEUE_LOCK must be released.
445 * ADAPTER_STATE_LOCK must be released.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 *
447 * Returns:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700448 * qla2x00 local function return status code.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 *
450 * Context:
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700451 * Kernel context.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 */
453int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800454qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455{
456 int rval;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800457 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 mbx_cmd_t mc;
459 mbx_cmd_t *mcp = &mc;
460
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400461 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,
462 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463
464 mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700465 mcp->out_mb = MBX_0;
466 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -0700467 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700468 mcp->mb[1] = MSW(risc_addr);
469 mcp->mb[2] = LSW(risc_addr);
470 mcp->mb[3] = 0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800471 if (IS_QLA81XX(ha) || IS_QLA83XX(ha)) {
Santosh Vernekarcad454b2010-03-19 16:59:16 -0700472 struct nvram_81xx *nv = ha->nvram;
473 mcp->mb[4] = (nv->enhanced_features &
474 EXTENDED_BB_CREDITS);
475 } else
476 mcp->mb[4] = 0;
Andrew Vasquez8b3253d2007-09-20 14:07:48 -0700477 mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700478 mcp->in_mb |= MBX_1;
479 } else {
480 mcp->mb[1] = LSW(risc_addr);
481 mcp->out_mb |= MBX_1;
482 if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
483 mcp->mb[2] = 0;
484 mcp->out_mb |= MBX_2;
485 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486 }
487
Ravi Anandb93480e2008-04-03 13:13:25 -0700488 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800490 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700492 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700493 ql_dbg(ql_dbg_mbx, vha, 0x1026,
494 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700495 } else {
Andrew Vasqueze4289242007-07-19 15:05:56 -0700496 if (IS_FWI2_CAPABLE(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400497 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1027,
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700498 "Done exchanges=%x.\n", mcp->mb[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700499 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400500 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028,
501 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700502 }
503 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700504
505 return rval;
506}
507
508/*
509 * qla2x00_get_fw_version
510 * Get firmware version.
511 *
512 * Input:
513 * ha: adapter state pointer.
514 * major: pointer for major number.
515 * minor: pointer for minor number.
516 * subminor: pointer for subminor number.
517 *
518 * Returns:
519 * qla2x00 local function return status code.
520 *
521 * Context:
522 * Kernel context.
523 */
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700524int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800525qla2x00_get_fw_version(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526{
527 int rval;
528 mbx_cmd_t mc;
529 mbx_cmd_t *mcp = &mc;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800530 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400532 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029,
533 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700534
535 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION;
536 mcp->out_mb = MBX_0;
537 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800538 if (IS_QLA81XX(vha->hw) || IS_QLA8031(ha))
Andrew Vasquez55a96152009-03-24 09:08:03 -0700539 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
Saurav Kashyapfb0effe2012-08-22 14:21:28 -0400540 if (IS_FWI2_CAPABLE(ha))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800541 mcp->in_mb |= MBX_17|MBX_16|MBX_15;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 mcp->flags = 0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700543 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800544 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700545 if (rval != QLA_SUCCESS)
546 goto failed;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547
548 /* Return mailbox data. */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800549 ha->fw_major_version = mcp->mb[1];
550 ha->fw_minor_version = mcp->mb[2];
551 ha->fw_subminor_version = mcp->mb[3];
552 ha->fw_attributes = mcp->mb[6];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800553 if (IS_QLA2100(vha->hw) || IS_QLA2200(vha->hw))
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800554 ha->fw_memory_size = 0x1FFFF; /* Defaults to 128KB. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 else
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800556 ha->fw_memory_size = (mcp->mb[5] << 16) | mcp->mb[4];
557 if (IS_QLA81XX(vha->hw) || IS_QLA8031(vha->hw)) {
558 ha->mpi_version[0] = mcp->mb[10] & 0xff;
559 ha->mpi_version[1] = mcp->mb[11] >> 8;
560 ha->mpi_version[2] = mcp->mb[11] & 0xff;
561 ha->mpi_capabilities = (mcp->mb[12] << 16) | mcp->mb[13];
562 ha->phy_version[0] = mcp->mb[8] & 0xff;
563 ha->phy_version[1] = mcp->mb[9] >> 8;
564 ha->phy_version[2] = mcp->mb[9] & 0xff;
Andrew Vasquez3a03eb72009-01-05 11:18:11 -0800565 }
Saurav Kashyap81178772012-08-22 14:21:04 -0400566 if (IS_FWI2_CAPABLE(ha)) {
567 ha->fw_attributes_h = mcp->mb[15];
568 ha->fw_attributes_ext[0] = mcp->mb[16];
569 ha->fw_attributes_ext[1] = mcp->mb[17];
570 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139,
571 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n",
572 __func__, mcp->mb[15], mcp->mb[6]);
573 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f,
574 "%s: Ext_FwAttributes Upper: 0x%x, Lower: 0x%x.\n",
575 __func__, mcp->mb[17], mcp->mb[16]);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -0800576 }
577
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700578failed:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 if (rval != QLA_SUCCESS) {
580 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700581 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 } else {
583 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400584 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b,
585 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 }
Andrew Vasquezca9e9c32009-06-03 09:55:20 -0700587 return rval;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588}
589
590/*
591 * qla2x00_get_fw_options
592 * Set firmware options.
593 *
594 * Input:
595 * ha = adapter block pointer.
596 * fwopt = pointer for firmware options.
597 *
598 * Returns:
599 * qla2x00 local function return status code.
600 *
601 * Context:
602 * Kernel context.
603 */
604int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800605qla2x00_get_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606{
607 int rval;
608 mbx_cmd_t mc;
609 mbx_cmd_t *mcp = &mc;
610
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400611 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c,
612 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613
614 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
615 mcp->out_mb = MBX_0;
616 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700617 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800619 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620
621 if (rval != QLA_SUCCESS) {
622 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700623 ql_dbg(ql_dbg_mbx, vha, 0x102d, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700625 fwopts[0] = mcp->mb[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 fwopts[1] = mcp->mb[1];
627 fwopts[2] = mcp->mb[2];
628 fwopts[3] = mcp->mb[3];
629
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400630 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e,
631 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 }
633
634 return rval;
635}
636
637
638/*
639 * qla2x00_set_fw_options
640 * Set firmware options.
641 *
642 * Input:
643 * ha = adapter block pointer.
644 * fwopt = pointer for firmware options.
645 *
646 * Returns:
647 * qla2x00 local function return status code.
648 *
649 * Context:
650 * Kernel context.
651 */
652int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800653qla2x00_set_fw_options(scsi_qla_host_t *vha, uint16_t *fwopts)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654{
655 int rval;
656 mbx_cmd_t mc;
657 mbx_cmd_t *mcp = &mc;
658
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400659 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f,
660 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661
662 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION;
663 mcp->mb[1] = fwopts[1];
664 mcp->mb[2] = fwopts[2];
665 mcp->mb[3] = fwopts[3];
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700666 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800668 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700669 mcp->in_mb |= MBX_1;
670 } else {
671 mcp->mb[10] = fwopts[10];
672 mcp->mb[11] = fwopts[11];
673 mcp->mb[12] = 0; /* Undocumented, but used */
674 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
675 }
Ravi Anandb93480e2008-04-03 13:13:25 -0700676 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700677 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800678 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700680 fwopts[0] = mcp->mb[0];
681
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 if (rval != QLA_SUCCESS) {
683 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700684 ql_dbg(ql_dbg_mbx, vha, 0x1030,
685 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 } else {
687 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400688 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031,
689 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690 }
691
692 return rval;
693}
694
695/*
696 * qla2x00_mbx_reg_test
697 * Mailbox register wrap test.
698 *
699 * Input:
700 * ha = adapter block pointer.
701 * TARGET_QUEUE_LOCK must be released.
702 * ADAPTER_STATE_LOCK must be released.
703 *
704 * Returns:
705 * qla2x00 local function return status code.
706 *
707 * Context:
708 * Kernel context.
709 */
710int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800711qla2x00_mbx_reg_test(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712{
713 int rval;
714 mbx_cmd_t mc;
715 mbx_cmd_t *mcp = &mc;
716
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400717 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032,
718 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719
720 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST;
721 mcp->mb[1] = 0xAAAA;
722 mcp->mb[2] = 0x5555;
723 mcp->mb[3] = 0xAA55;
724 mcp->mb[4] = 0x55AA;
725 mcp->mb[5] = 0xA5A5;
726 mcp->mb[6] = 0x5A5A;
727 mcp->mb[7] = 0x2525;
728 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
729 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 -0700730 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800732 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733
734 if (rval == QLA_SUCCESS) {
735 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 ||
736 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA)
737 rval = QLA_FUNCTION_FAILED;
738 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
739 mcp->mb[7] != 0x2525)
740 rval = QLA_FUNCTION_FAILED;
741 }
742
743 if (rval != QLA_SUCCESS) {
744 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700745 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 } else {
747 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400748 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034,
749 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 }
751
752 return rval;
753}
754
755/*
756 * qla2x00_verify_checksum
757 * Verify firmware checksum.
758 *
759 * Input:
760 * ha = adapter block pointer.
761 * TARGET_QUEUE_LOCK must be released.
762 * ADAPTER_STATE_LOCK must be released.
763 *
764 * Returns:
765 * qla2x00 local function return status code.
766 *
767 * Context:
768 * Kernel context.
769 */
770int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800771qla2x00_verify_checksum(scsi_qla_host_t *vha, uint32_t risc_addr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700772{
773 int rval;
774 mbx_cmd_t mc;
775 mbx_cmd_t *mcp = &mc;
776
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400777 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035,
778 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779
780 mcp->mb[0] = MBC_VERIFY_CHECKSUM;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700781 mcp->out_mb = MBX_0;
782 mcp->in_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800783 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -0700784 mcp->mb[1] = MSW(risc_addr);
785 mcp->mb[2] = LSW(risc_addr);
786 mcp->out_mb |= MBX_2|MBX_1;
787 mcp->in_mb |= MBX_2|MBX_1;
788 } else {
789 mcp->mb[1] = LSW(risc_addr);
790 mcp->out_mb |= MBX_1;
791 mcp->in_mb |= MBX_1;
792 }
793
Ravi Anandb93480e2008-04-03 13:13:25 -0700794 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800796 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797
798 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700799 ql_dbg(ql_dbg_mbx, vha, 0x1036,
800 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ?
801 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400803 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037,
804 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 }
806
807 return rval;
808}
809
810/*
811 * qla2x00_issue_iocb
812 * Issue IOCB using mailbox command
813 *
814 * Input:
815 * ha = adapter state pointer.
816 * buffer = buffer pointer.
817 * phys_addr = physical address of buffer.
818 * size = size of buffer.
819 * TARGET_QUEUE_LOCK must be released.
820 * ADAPTER_STATE_LOCK must be released.
821 *
822 * Returns:
823 * qla2x00 local function return status code.
824 *
825 * Context:
826 * Kernel context.
827 */
Giridhar Malavali6e980162010-03-19 17:03:58 -0700828int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800829qla2x00_issue_iocb_timeout(scsi_qla_host_t *vha, void *buffer,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700830 dma_addr_t phys_addr, size_t size, uint32_t tov)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831{
832 int rval;
833 mbx_cmd_t mc;
834 mbx_cmd_t *mcp = &mc;
835
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400836 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038,
837 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700838
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839 mcp->mb[0] = MBC_IOCB_COMMAND_A64;
840 mcp->mb[1] = 0;
841 mcp->mb[2] = MSW(phys_addr);
842 mcp->mb[3] = LSW(phys_addr);
843 mcp->mb[6] = MSW(MSD(phys_addr));
844 mcp->mb[7] = LSW(MSD(phys_addr));
845 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
846 mcp->in_mb = MBX_2|MBX_0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700847 mcp->tov = tov;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800849 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850
851 if (rval != QLA_SUCCESS) {
852 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700853 ql_dbg(ql_dbg_mbx, vha, 0x1039, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 } else {
Andrew Vasquez8c958a92005-07-06 10:30:47 -0700855 sts_entry_t *sts_entry = (sts_entry_t *) buffer;
856
857 /* Mask reserved bits. */
858 sts_entry->entry_status &=
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800859 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400860 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a,
861 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 }
863
864 return rval;
865}
866
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700867int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800868qla2x00_issue_iocb(scsi_qla_host_t *vha, void *buffer, dma_addr_t phys_addr,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700869 size_t size)
870{
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800871 return qla2x00_issue_iocb_timeout(vha, buffer, phys_addr, size,
Harihara Kadayam4d4df192008-04-03 13:13:26 -0700872 MBX_TOV_SECONDS);
873}
874
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875/*
876 * qla2x00_abort_command
877 * Abort command aborts a specified IOCB.
878 *
879 * Input:
880 * ha = adapter block pointer.
881 * sp = SB structure pointer.
882 *
883 * Returns:
884 * qla2x00 local function return status code.
885 *
886 * Context:
887 * Kernel context.
888 */
889int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700890qla2x00_abort_command(srb_t *sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891{
892 unsigned long flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 int rval;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800894 uint32_t handle = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700895 mbx_cmd_t mc;
896 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700897 fc_port_t *fcport = sp->fcport;
898 scsi_qla_host_t *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800899 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700900 struct req_que *req = vha->req;
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800901 struct scsi_cmnd *cmd = GET_CMD_SP(sp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400903 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b,
904 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700906 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -0500907 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800908 if (req->outstanding_cmds[handle] == sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909 break;
910 }
Andrew Vasquezc9c5ced2008-07-24 08:31:49 -0700911 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912
Chad Dupuis8d93f552013-01-30 03:34:37 -0500913 if (handle == req->num_outstanding_cmds) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914 /* command not found */
915 return QLA_FUNCTION_FAILED;
916 }
917
918 mcp->mb[0] = MBC_ABORT_COMMAND;
919 if (HAS_EXTENDED_IDS(ha))
920 mcp->mb[1] = fcport->loop_id;
921 else
922 mcp->mb[1] = fcport->loop_id << 8;
923 mcp->mb[2] = (uint16_t)handle;
924 mcp->mb[3] = (uint16_t)(handle >> 16);
Giridhar Malavali9ba56b92012-02-09 11:15:36 -0800925 mcp->mb[6] = (uint16_t)cmd->device->lun;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
927 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700928 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800930 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
932 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700933 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400935 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d,
936 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937 }
938
939 return rval;
940}
941
Linus Torvalds1da177e2005-04-16 15:20:36 -0700942int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700943qla2x00_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944{
Andrew Vasquez523ec772008-04-03 13:13:24 -0700945 int rval, rval2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700946 mbx_cmd_t mc;
947 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800948 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800949 struct req_que *req;
950 struct rsp_que *rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700951
Andrew Vasquez523ec772008-04-03 13:13:24 -0700952 l = l;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800953 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700954
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400955 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e,
956 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700957
Giridhar Malavali7e2b8952010-05-28 15:08:17 -0700958 req = vha->hw->req_q_map[0];
959 rsp = req->rsp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960 mcp->mb[0] = MBC_ABORT_TARGET;
Andrew Vasquez523ec772008-04-03 13:13:24 -0700961 mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800962 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963 mcp->mb[1] = fcport->loop_id;
964 mcp->mb[10] = 0;
965 mcp->out_mb |= MBX_10;
966 } else {
967 mcp->mb[1] = fcport->loop_id << 8;
968 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800969 mcp->mb[2] = vha->hw->loop_reset_delay;
970 mcp->mb[9] = vha->vp_idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700971
972 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -0700973 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -0800975 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400977 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f,
978 "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700979 }
980
981 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -0800982 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, 0,
983 MK_SYNC_ID);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700984 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -0700985 ql_dbg(ql_dbg_mbx, vha, 0x1040,
986 "Failed to issue marker IOCB (%x).\n", rval2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -0400988 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041,
989 "Done %s.\n", __func__);
Andrew Vasquez523ec772008-04-03 13:13:24 -0700990 }
991
992 return rval;
993}
994
995int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -0700996qla2x00_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -0700997{
998 int rval, rval2;
999 mbx_cmd_t mc;
1000 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001001 scsi_qla_host_t *vha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001002 struct req_que *req;
1003 struct rsp_que *rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001004
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001005 vha = fcport->vha;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001006
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001007 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042,
1008 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001009
Giridhar Malavali7e2b8952010-05-28 15:08:17 -07001010 req = vha->hw->req_q_map[0];
1011 rsp = req->rsp;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001012 mcp->mb[0] = MBC_LUN_RESET;
1013 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001014 if (HAS_EXTENDED_IDS(vha->hw))
Andrew Vasquez523ec772008-04-03 13:13:24 -07001015 mcp->mb[1] = fcport->loop_id;
1016 else
1017 mcp->mb[1] = fcport->loop_id << 8;
1018 mcp->mb[2] = l;
1019 mcp->mb[3] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001020 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001021
1022 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001023 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez523ec772008-04-03 13:13:24 -07001024 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001025 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001026 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001027 ql_dbg(ql_dbg_mbx, vha, 0x1043, "Failed=%x.\n", rval);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001028 }
1029
1030 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08001031 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
1032 MK_SYNC_ID_LUN);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001033 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001034 ql_dbg(ql_dbg_mbx, vha, 0x1044,
1035 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07001036 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001037 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045,
1038 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 }
1040
1041 return rval;
1042}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001043
1044/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 * qla2x00_get_adapter_id
1046 * Get adapter ID and topology.
1047 *
1048 * Input:
1049 * ha = adapter block pointer.
1050 * id = pointer for loop ID.
1051 * al_pa = pointer for AL_PA.
1052 * area = pointer for area.
1053 * domain = pointer for domain.
1054 * top = pointer for topology.
1055 * TARGET_QUEUE_LOCK must be released.
1056 * ADAPTER_STATE_LOCK must be released.
1057 *
1058 * Returns:
1059 * qla2x00 local function return status code.
1060 *
1061 * Context:
1062 * Kernel context.
1063 */
1064int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001065qla2x00_get_adapter_id(scsi_qla_host_t *vha, uint16_t *id, uint8_t *al_pa,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001066 uint8_t *area, uint8_t *domain, uint16_t *top, uint16_t *sw_cap)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067{
1068 int rval;
1069 mbx_cmd_t mc;
1070 mbx_cmd_t *mcp = &mc;
1071
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001072 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046,
1073 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074
1075 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001076 mcp->mb[9] = vha->vp_idx;
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08001077 mcp->out_mb = MBX_9|MBX_0;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001078 mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001079 if (IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezbad70012009-04-06 22:33:38 -07001080 mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
Ravi Anandb93480e2008-04-03 13:13:25 -07001081 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001083 rval = qla2x00_mailbox_command(vha, mcp);
Ravi Anand33135aa2005-11-08 14:37:20 -08001084 if (mcp->mb[0] == MBS_COMMAND_ERROR)
1085 rval = QLA_COMMAND_ERROR;
Andrew Vasquez42e421b2008-07-10 16:56:01 -07001086 else if (mcp->mb[0] == MBS_INVALID_COMMAND)
1087 rval = QLA_INVALID_COMMAND;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001088
1089 /* Return data. */
1090 *id = mcp->mb[1];
1091 *al_pa = LSB(mcp->mb[2]);
1092 *area = MSB(mcp->mb[2]);
1093 *domain = LSB(mcp->mb[3]);
1094 *top = mcp->mb[6];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001095 *sw_cap = mcp->mb[7];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096
1097 if (rval != QLA_SUCCESS) {
1098 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001099 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001101 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048,
1102 "Done %s.\n", __func__);
Andrew Vasquezbad70012009-04-06 22:33:38 -07001103
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001104 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquezbad70012009-04-06 22:33:38 -07001105 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff;
1106 vha->fcoe_fcf_idx = mcp->mb[10];
1107 vha->fcoe_vn_port_mac[5] = mcp->mb[11] >> 8;
1108 vha->fcoe_vn_port_mac[4] = mcp->mb[11] & 0xff;
1109 vha->fcoe_vn_port_mac[3] = mcp->mb[12] >> 8;
1110 vha->fcoe_vn_port_mac[2] = mcp->mb[12] & 0xff;
1111 vha->fcoe_vn_port_mac[1] = mcp->mb[13] >> 8;
1112 vha->fcoe_vn_port_mac[0] = mcp->mb[13] & 0xff;
1113 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001114 }
1115
1116 return rval;
1117}
1118
1119/*
1120 * qla2x00_get_retry_cnt
1121 * Get current firmware login retry count and delay.
1122 *
1123 * Input:
1124 * ha = adapter block pointer.
1125 * retry_cnt = pointer to login retry count.
1126 * tov = pointer to login timeout value.
1127 *
1128 * Returns:
1129 * qla2x00 local function return status code.
1130 *
1131 * Context:
1132 * Kernel context.
1133 */
1134int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001135qla2x00_get_retry_cnt(scsi_qla_host_t *vha, uint8_t *retry_cnt, uint8_t *tov,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001136 uint16_t *r_a_tov)
1137{
1138 int rval;
1139 uint16_t ratov;
1140 mbx_cmd_t mc;
1141 mbx_cmd_t *mcp = &mc;
1142
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001143 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049,
1144 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001145
1146 mcp->mb[0] = MBC_GET_RETRY_COUNT;
1147 mcp->out_mb = MBX_0;
1148 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001149 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001150 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001151 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152
1153 if (rval != QLA_SUCCESS) {
1154 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001155 ql_dbg(ql_dbg_mbx, vha, 0x104a,
1156 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 } else {
1158 /* Convert returned data and check our values. */
1159 *r_a_tov = mcp->mb[3] / 2;
1160 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */
1161 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) {
1162 /* Update to the larger values */
1163 *retry_cnt = (uint8_t)mcp->mb[1];
1164 *tov = ratov;
1165 }
1166
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001167 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001168 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169 }
1170
1171 return rval;
1172}
1173
1174/*
1175 * qla2x00_init_firmware
1176 * Initialize adapter firmware.
1177 *
1178 * Input:
1179 * ha = adapter block pointer.
1180 * dptr = Initialization control block pointer.
1181 * size = size of initialization control block.
1182 * TARGET_QUEUE_LOCK must be released.
1183 * ADAPTER_STATE_LOCK must be released.
1184 *
1185 * Returns:
1186 * qla2x00 local function return status code.
1187 *
1188 * Context:
1189 * Kernel context.
1190 */
1191int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001192qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193{
1194 int rval;
1195 mbx_cmd_t mc;
1196 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001197 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001198
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001199 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c,
1200 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201
Giridhar Malavalia9083012010-04-12 17:59:55 -07001202 if (IS_QLA82XX(ha) && ql2xdbwr)
1203 qla82xx_wr_32(ha, ha->nxdb_wr_ptr,
1204 (0x04 | (ha->portnum << 5) | (0 << 8) | (0 << 16)));
1205
Andrew Vasqueze6e074f2008-01-31 12:33:53 -08001206 if (ha->flags.npiv_supported)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001207 mcp->mb[0] = MBC_MID_INITIALIZE_FIRMWARE;
1208 else
1209 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
1210
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001211 mcp->mb[1] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 mcp->mb[2] = MSW(ha->init_cb_dma);
1213 mcp->mb[3] = LSW(ha->init_cb_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
1215 mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001216 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001217 if ((IS_QLA81XX(ha) || IS_QLA83XX(ha)) && ha->ex_init_cb->ex_version) {
Andrew Vasquezb64b0e82009-03-24 09:08:01 -07001218 mcp->mb[1] = BIT_0;
1219 mcp->mb[10] = MSW(ha->ex_init_cb_dma);
1220 mcp->mb[11] = LSW(ha->ex_init_cb_dma);
1221 mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
1222 mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
1223 mcp->mb[14] = sizeof(*ha->ex_init_cb);
1224 mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
1225 }
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001226 /* 1 and 2 should normally be captured. */
1227 mcp->in_mb = MBX_2|MBX_1|MBX_0;
1228 if (IS_QLA83XX(ha))
1229 /* mb3 is additional info about the installed SFP. */
1230 mcp->in_mb |= MBX_3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 mcp->buf_size = size;
1232 mcp->flags = MBX_DMA_OUT;
Ravi Anandb93480e2008-04-03 13:13:25 -07001233 mcp->tov = MBX_TOV_SECONDS;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001234 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
1236 if (rval != QLA_SUCCESS) {
1237 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001238 ql_dbg(ql_dbg_mbx, vha, 0x104d,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001239 "Failed=%x mb[0]=%x, mb[1]=%x, mb[2]=%x, mb[3]=%x,.\n",
1240 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 } else {
1242 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001243 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e,
1244 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 }
1246
1247 return rval;
1248}
1249
1250/*
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001251 * qla2x00_get_node_name_list
1252 * Issue get node name list mailbox command, kmalloc()
1253 * and return the resulting list. Caller must kfree() it!
1254 *
1255 * Input:
1256 * ha = adapter state pointer.
1257 * out_data = resulting list
1258 * out_len = length of the resulting list
1259 *
1260 * Returns:
1261 * qla2x00 local function return status code.
1262 *
1263 * Context:
1264 * Kernel context.
1265 */
1266int
1267qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len)
1268{
1269 struct qla_hw_data *ha = vha->hw;
1270 struct qla_port_24xx_data *list = NULL;
1271 void *pmap;
1272 mbx_cmd_t mc;
1273 dma_addr_t pmap_dma;
1274 ulong dma_size;
1275 int rval, left;
1276
1277 left = 1;
1278 while (left > 0) {
1279 dma_size = left * sizeof(*list);
1280 pmap = dma_alloc_coherent(&ha->pdev->dev, dma_size,
1281 &pmap_dma, GFP_KERNEL);
1282 if (!pmap) {
1283 ql_log(ql_log_warn, vha, 0x113f,
1284 "%s(%ld): DMA Alloc failed of %ld\n",
1285 __func__, vha->host_no, dma_size);
1286 rval = QLA_MEMORY_ALLOC_FAILED;
1287 goto out;
1288 }
1289
1290 mc.mb[0] = MBC_PORT_NODE_NAME_LIST;
1291 mc.mb[1] = BIT_1 | BIT_3;
1292 mc.mb[2] = MSW(pmap_dma);
1293 mc.mb[3] = LSW(pmap_dma);
1294 mc.mb[6] = MSW(MSD(pmap_dma));
1295 mc.mb[7] = LSW(MSD(pmap_dma));
1296 mc.mb[8] = dma_size;
1297 mc.out_mb = MBX_0|MBX_1|MBX_2|MBX_3|MBX_6|MBX_7|MBX_8;
1298 mc.in_mb = MBX_0|MBX_1;
1299 mc.tov = 30;
1300 mc.flags = MBX_DMA_IN;
1301
1302 rval = qla2x00_mailbox_command(vha, &mc);
1303 if (rval != QLA_SUCCESS) {
1304 if ((mc.mb[0] == MBS_COMMAND_ERROR) &&
1305 (mc.mb[1] == 0xA)) {
1306 left += le16_to_cpu(mc.mb[2]) /
1307 sizeof(struct qla_port_24xx_data);
1308 goto restart;
1309 }
1310 goto out_free;
1311 }
1312
1313 left = 0;
1314
1315 list = kzalloc(dma_size, GFP_KERNEL);
1316 if (!list) {
1317 ql_log(ql_log_warn, vha, 0x1140,
1318 "%s(%ld): failed to allocate node names list "
1319 "structure.\n", __func__, vha->host_no);
1320 rval = QLA_MEMORY_ALLOC_FAILED;
1321 goto out_free;
1322 }
1323
1324 memcpy(list, pmap, dma_size);
1325restart:
1326 dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
1327 }
1328
1329 *out_data = list;
1330 *out_len = dma_size;
1331
1332out:
1333 return rval;
1334
1335out_free:
1336 dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
1337 return rval;
1338}
1339
1340/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 * qla2x00_get_port_database
1342 * Issue normal/enhanced get port database mailbox command
1343 * and copy device name as necessary.
1344 *
1345 * Input:
1346 * ha = adapter state pointer.
1347 * dev = structure pointer.
1348 * opt = enhanced cmd option byte.
1349 *
1350 * Returns:
1351 * qla2x00 local function return status code.
1352 *
1353 * Context:
1354 * Kernel context.
1355 */
1356int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001357qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358{
1359 int rval;
1360 mbx_cmd_t mc;
1361 mbx_cmd_t *mcp = &mc;
1362 port_database_t *pd;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001363 struct port_database_24xx *pd24;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 dma_addr_t pd_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001365 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001367 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f,
1368 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001370 pd24 = NULL;
1371 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 if (pd == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001373 ql_log(ql_log_warn, vha, 0x1050,
1374 "Failed to allocate port database structure.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 return QLA_MEMORY_ALLOC_FAILED;
1376 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001377 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001379 mcp->mb[0] = MBC_GET_PORT_DATABASE;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001380 if (opt != 0 && !IS_FWI2_CAPABLE(ha))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382 mcp->mb[2] = MSW(pd_dma);
1383 mcp->mb[3] = LSW(pd_dma);
1384 mcp->mb[6] = MSW(MSD(pd_dma));
1385 mcp->mb[7] = LSW(MSD(pd_dma));
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001386 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001387 mcp->out_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001388 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07001389 if (IS_FWI2_CAPABLE(ha)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001390 mcp->mb[1] = fcport->loop_id;
1391 mcp->mb[10] = opt;
1392 mcp->out_mb |= MBX_10|MBX_1;
1393 mcp->in_mb |= MBX_1;
1394 } else if (HAS_EXTENDED_IDS(ha)) {
1395 mcp->mb[1] = fcport->loop_id;
1396 mcp->mb[10] = opt;
1397 mcp->out_mb |= MBX_10|MBX_1;
1398 } else {
1399 mcp->mb[1] = fcport->loop_id << 8 | opt;
1400 mcp->out_mb |= MBX_1;
1401 }
Andrew Vasqueze4289242007-07-19 15:05:56 -07001402 mcp->buf_size = IS_FWI2_CAPABLE(ha) ?
1403 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 mcp->flags = MBX_DMA_IN;
1405 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001406 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 if (rval != QLA_SUCCESS)
1408 goto gpd_error_out;
1409
Andrew Vasqueze4289242007-07-19 15:05:56 -07001410 if (IS_FWI2_CAPABLE(ha)) {
Arun Easi0eba25d2012-02-09 11:15:58 -08001411 uint64_t zero = 0;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001412 pd24 = (struct port_database_24xx *) pd;
1413
1414 /* Check for logged in state. */
1415 if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
1416 pd24->last_login_state != PDS_PRLI_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001417 ql_dbg(ql_dbg_mbx, vha, 0x1051,
1418 "Unable to verify login-state (%x/%x) for "
1419 "loop_id %x.\n", pd24->current_login_state,
1420 pd24->last_login_state, fcport->loop_id);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001421 rval = QLA_FUNCTION_FAILED;
1422 goto gpd_error_out;
1423 }
1424
Arun Easi0eba25d2012-02-09 11:15:58 -08001425 if (fcport->loop_id == FC_NO_LOOP_ID ||
1426 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1427 memcmp(fcport->port_name, pd24->port_name, 8))) {
1428 /* We lost the device mid way. */
1429 rval = QLA_NOT_LOGGED_IN;
1430 goto gpd_error_out;
1431 }
1432
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001433 /* Names are little-endian. */
1434 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE);
1435 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE);
1436
1437 /* Get port_id of device. */
1438 fcport->d_id.b.domain = pd24->port_id[0];
1439 fcport->d_id.b.area = pd24->port_id[1];
1440 fcport->d_id.b.al_pa = pd24->port_id[2];
1441 fcport->d_id.b.rsvd_1 = 0;
1442
1443 /* If not target must be initiator or unknown type. */
1444 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0)
1445 fcport->port_type = FCT_INITIATOR;
1446 else
1447 fcport->port_type = FCT_TARGET;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001448
1449 /* Passback COS information. */
1450 fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ?
1451 FC_COS_CLASS2 : FC_COS_CLASS3;
1452
1453 if (pd24->prli_svc_param_word_3[0] & BIT_7)
1454 fcport->flags |= FCF_CONF_COMP_SUPPORTED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001455 } else {
Arun Easi0eba25d2012-02-09 11:15:58 -08001456 uint64_t zero = 0;
1457
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001458 /* Check for logged in state. */
1459 if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
1460 pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001461 ql_dbg(ql_dbg_mbx, vha, 0x100a,
1462 "Unable to verify login-state (%x/%x) - "
1463 "portid=%02x%02x%02x.\n", pd->master_state,
1464 pd->slave_state, fcport->d_id.b.domain,
1465 fcport->d_id.b.area, fcport->d_id.b.al_pa);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001466 rval = QLA_FUNCTION_FAILED;
1467 goto gpd_error_out;
1468 }
1469
Arun Easi0eba25d2012-02-09 11:15:58 -08001470 if (fcport->loop_id == FC_NO_LOOP_ID ||
1471 (memcmp(fcport->port_name, (uint8_t *)&zero, 8) &&
1472 memcmp(fcport->port_name, pd->port_name, 8))) {
1473 /* We lost the device mid way. */
1474 rval = QLA_NOT_LOGGED_IN;
1475 goto gpd_error_out;
1476 }
1477
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001478 /* Names are little-endian. */
1479 memcpy(fcport->node_name, pd->node_name, WWN_SIZE);
1480 memcpy(fcport->port_name, pd->port_name, WWN_SIZE);
1481
1482 /* Get port_id of device. */
1483 fcport->d_id.b.domain = pd->port_id[0];
1484 fcport->d_id.b.area = pd->port_id[3];
1485 fcport->d_id.b.al_pa = pd->port_id[2];
1486 fcport->d_id.b.rsvd_1 = 0;
1487
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001488 /* If not target must be initiator or unknown type. */
1489 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
1490 fcport->port_type = FCT_INITIATOR;
1491 else
1492 fcport->port_type = FCT_TARGET;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001493
1494 /* Passback COS information. */
1495 fcport->supported_classes = (pd->options & BIT_4) ?
1496 FC_COS_CLASS2: FC_COS_CLASS3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 }
1498
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499gpd_error_out:
1500 dma_pool_free(ha->s_dma_pool, pd, pd_dma);
1501
1502 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001503 ql_dbg(ql_dbg_mbx, vha, 0x1052,
1504 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval,
1505 mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001507 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053,
1508 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 }
1510
1511 return rval;
1512}
1513
1514/*
1515 * qla2x00_get_firmware_state
1516 * Get adapter firmware state.
1517 *
1518 * Input:
1519 * ha = adapter block pointer.
1520 * dptr = pointer for firmware state.
1521 * TARGET_QUEUE_LOCK must be released.
1522 * ADAPTER_STATE_LOCK must be released.
1523 *
1524 * Returns:
1525 * qla2x00 local function return status code.
1526 *
1527 * Context:
1528 * Kernel context.
1529 */
1530int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001531qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532{
1533 int rval;
1534 mbx_cmd_t mc;
1535 mbx_cmd_t *mcp = &mc;
1536
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001537 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054,
1538 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539
1540 mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
1541 mcp->out_mb = MBX_0;
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001542 if (IS_FWI2_CAPABLE(vha->hw))
1543 mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
1544 else
1545 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001546 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001548 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549
Harihara Kadayam4d4df192008-04-03 13:13:26 -07001550 /* Return firmware states. */
1551 states[0] = mcp->mb[1];
Andrew Vasquez9d2683c2009-06-17 10:30:30 -07001552 if (IS_FWI2_CAPABLE(vha->hw)) {
1553 states[1] = mcp->mb[2];
1554 states[2] = mcp->mb[3];
1555 states[3] = mcp->mb[4];
1556 states[4] = mcp->mb[5];
1557 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558
1559 if (rval != QLA_SUCCESS) {
1560 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001561 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 } else {
1563 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001564 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056,
1565 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566 }
1567
1568 return rval;
1569}
1570
1571/*
1572 * qla2x00_get_port_name
1573 * Issue get port name mailbox command.
1574 * Returned name is in big endian format.
1575 *
1576 * Input:
1577 * ha = adapter block pointer.
1578 * loop_id = loop ID of device.
1579 * name = pointer for name.
1580 * TARGET_QUEUE_LOCK must be released.
1581 * ADAPTER_STATE_LOCK must be released.
1582 *
1583 * Returns:
1584 * qla2x00 local function return status code.
1585 *
1586 * Context:
1587 * Kernel context.
1588 */
1589int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001590qla2x00_get_port_name(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591 uint8_t opt)
1592{
1593 int rval;
1594 mbx_cmd_t mc;
1595 mbx_cmd_t *mcp = &mc;
1596
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001597 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057,
1598 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599
1600 mcp->mb[0] = MBC_GET_PORT_NAME;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001601 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07001602 mcp->out_mb = MBX_9|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001603 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 mcp->mb[1] = loop_id;
1605 mcp->mb[10] = opt;
1606 mcp->out_mb |= MBX_10;
1607 } else {
1608 mcp->mb[1] = loop_id << 8 | opt;
1609 }
1610
1611 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001612 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001614 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615
1616 if (rval != QLA_SUCCESS) {
1617 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001618 ql_dbg(ql_dbg_mbx, vha, 0x1058, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 } else {
1620 if (name != NULL) {
1621 /* This function returns name in big endian. */
Richard Lary1196ae02007-03-22 10:53:19 -05001622 name[0] = MSB(mcp->mb[2]);
1623 name[1] = LSB(mcp->mb[2]);
1624 name[2] = MSB(mcp->mb[3]);
1625 name[3] = LSB(mcp->mb[3]);
1626 name[4] = MSB(mcp->mb[6]);
1627 name[5] = LSB(mcp->mb[6]);
1628 name[6] = MSB(mcp->mb[7]);
1629 name[7] = LSB(mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630 }
1631
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001632 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059,
1633 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 }
1635
1636 return rval;
1637}
1638
1639/*
Joe Carnuccio61e1b262013-02-08 01:57:48 -05001640 * qla24xx_link_initialization
1641 * Issue link initialization mailbox command.
1642 *
1643 * Input:
1644 * ha = adapter block pointer.
1645 * TARGET_QUEUE_LOCK must be released.
1646 * ADAPTER_STATE_LOCK must be released.
1647 *
1648 * Returns:
1649 * qla2x00 local function return status code.
1650 *
1651 * Context:
1652 * Kernel context.
1653 */
1654int
1655qla24xx_link_initialize(scsi_qla_host_t *vha)
1656{
1657 int rval;
1658 mbx_cmd_t mc;
1659 mbx_cmd_t *mcp = &mc;
1660
1661 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1152,
1662 "Entered %s.\n", __func__);
1663
1664 if (!IS_FWI2_CAPABLE(vha->hw) || IS_CNA_CAPABLE(vha->hw))
1665 return QLA_FUNCTION_FAILED;
1666
1667 mcp->mb[0] = MBC_LINK_INITIALIZATION;
1668 mcp->mb[1] = BIT_6|BIT_4;
1669 mcp->mb[2] = 0;
1670 mcp->mb[3] = 0;
1671 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1672 mcp->in_mb = MBX_0;
1673 mcp->tov = MBX_TOV_SECONDS;
1674 mcp->flags = 0;
1675 rval = qla2x00_mailbox_command(vha, mcp);
1676
1677 if (rval != QLA_SUCCESS) {
1678 ql_dbg(ql_dbg_mbx, vha, 0x1153, "Failed=%x.\n", rval);
1679 } else {
1680 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1154,
1681 "Done %s.\n", __func__);
1682 }
1683
1684 return rval;
1685}
1686
1687/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 * qla2x00_lip_reset
1689 * Issue LIP reset mailbox command.
1690 *
1691 * Input:
1692 * ha = adapter block pointer.
1693 * TARGET_QUEUE_LOCK must be released.
1694 * ADAPTER_STATE_LOCK must be released.
1695 *
1696 * Returns:
1697 * qla2x00 local function return status code.
1698 *
1699 * Context:
1700 * Kernel context.
1701 */
1702int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001703qla2x00_lip_reset(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704{
1705 int rval;
1706 mbx_cmd_t mc;
1707 mbx_cmd_t *mcp = &mc;
1708
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001709 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a,
1710 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08001712 if (IS_CNA_CAPABLE(vha->hw)) {
Andrew Vasquez3a03eb72009-01-05 11:18:11 -08001713 /* Logout across all FCFs. */
1714 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
1715 mcp->mb[1] = BIT_1;
1716 mcp->mb[2] = 0;
1717 mcp->out_mb = MBX_2|MBX_1|MBX_0;
1718 } else if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001719 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08001720 mcp->mb[1] = BIT_6;
1721 mcp->mb[2] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001722 mcp->mb[3] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001723 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724 } else {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001725 mcp->mb[0] = MBC_LIP_RESET;
1726 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001727 if (HAS_EXTENDED_IDS(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001728 mcp->mb[1] = 0x00ff;
1729 mcp->mb[10] = 0;
1730 mcp->out_mb |= MBX_10;
1731 } else {
1732 mcp->mb[1] = 0xff00;
1733 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001734 mcp->mb[2] = vha->hw->loop_reset_delay;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001735 mcp->mb[3] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07001738 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001740 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741
1742 if (rval != QLA_SUCCESS) {
1743 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001744 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 } else {
1746 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001747 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c,
1748 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 }
1750
1751 return rval;
1752}
1753
1754/*
1755 * qla2x00_send_sns
1756 * Send SNS command.
1757 *
1758 * Input:
1759 * ha = adapter block pointer.
1760 * sns = pointer for command.
1761 * cmd_size = command size.
1762 * buf_size = response/command size.
1763 * TARGET_QUEUE_LOCK must be released.
1764 * ADAPTER_STATE_LOCK must be released.
1765 *
1766 * Returns:
1767 * qla2x00 local function return status code.
1768 *
1769 * Context:
1770 * Kernel context.
1771 */
1772int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001773qla2x00_send_sns(scsi_qla_host_t *vha, dma_addr_t sns_phys_address,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001774 uint16_t cmd_size, size_t buf_size)
1775{
1776 int rval;
1777 mbx_cmd_t mc;
1778 mbx_cmd_t *mcp = &mc;
1779
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001780 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d,
1781 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001783 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001784 "Retry cnt=%d ratov=%d total tov=%d.\n",
1785 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786
1787 mcp->mb[0] = MBC_SEND_SNS_COMMAND;
1788 mcp->mb[1] = cmd_size;
1789 mcp->mb[2] = MSW(sns_phys_address);
1790 mcp->mb[3] = LSW(sns_phys_address);
1791 mcp->mb[6] = MSW(MSD(sns_phys_address));
1792 mcp->mb[7] = LSW(MSD(sns_phys_address));
1793 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
1794 mcp->in_mb = MBX_0|MBX_1;
1795 mcp->buf_size = buf_size;
1796 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001797 mcp->tov = (vha->hw->login_timeout * 2) + (vha->hw->login_timeout / 2);
1798 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799
1800 if (rval != QLA_SUCCESS) {
1801 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001802 ql_dbg(ql_dbg_mbx, vha, 0x105f,
1803 "Failed=%x mb[0]=%x mb[1]=%x.\n",
1804 rval, mcp->mb[0], mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 } else {
1806 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001807 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060,
1808 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 }
1810
1811 return rval;
1812}
1813
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001814int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001815qla24xx_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001816 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1817{
1818 int rval;
1819
1820 struct logio_entry_24xx *lg;
1821 dma_addr_t lg_dma;
1822 uint32_t iop[2];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001823 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001824 struct req_que *req;
1825 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001826
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001827 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061,
1828 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001829
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07001830 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07001831 req = ha->req_q_map[0];
1832 else
1833 req = vha->req;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001834 rsp = req->rsp;
1835
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001836 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
1837 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001838 ql_log(ql_log_warn, vha, 0x1062,
1839 "Failed to allocate login IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001840 return QLA_MEMORY_ALLOC_FAILED;
1841 }
1842 memset(lg, 0, sizeof(struct logio_entry_24xx));
1843
1844 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
1845 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07001846 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001847 lg->nport_handle = cpu_to_le16(loop_id);
1848 lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI);
1849 if (opt & BIT_0)
1850 lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI);
Andrew Vasquez8baa51a2006-06-23 16:10:44 -07001851 if (opt & BIT_1)
1852 lg->control_flags |= __constant_cpu_to_le16(LCF_SKIP_PRLI);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001853 lg->port_id[0] = al_pa;
1854 lg->port_id[1] = area;
1855 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001856 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08001857 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
1858 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001859 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001860 ql_dbg(ql_dbg_mbx, vha, 0x1063,
1861 "Failed to issue login IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001862 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001863 ql_dbg(ql_dbg_mbx, vha, 0x1064,
1864 "Failed to complete IOCB -- error status (%x).\n",
1865 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001866 rval = QLA_FUNCTION_FAILED;
1867 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
1868 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1869 iop[1] = le32_to_cpu(lg->io_parameter[1]);
1870
Saurav Kashyap7c3df132011-07-14 12:00:13 -07001871 ql_dbg(ql_dbg_mbx, vha, 0x1065,
1872 "Failed to complete IOCB -- completion status (%x) "
1873 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
1874 iop[0], iop[1]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001875
1876 switch (iop[0]) {
1877 case LSC_SCODE_PORTID_USED:
1878 mb[0] = MBS_PORT_ID_USED;
1879 mb[1] = LSW(iop[1]);
1880 break;
1881 case LSC_SCODE_NPORT_USED:
1882 mb[0] = MBS_LOOP_ID_USED;
1883 break;
1884 case LSC_SCODE_NOLINK:
1885 case LSC_SCODE_NOIOCB:
1886 case LSC_SCODE_NOXCB:
1887 case LSC_SCODE_CMD_FAILED:
1888 case LSC_SCODE_NOFABRIC:
1889 case LSC_SCODE_FW_NOT_READY:
1890 case LSC_SCODE_NOT_LOGGED_IN:
1891 case LSC_SCODE_NOPCB:
1892 case LSC_SCODE_ELS_REJECT:
1893 case LSC_SCODE_CMD_PARAM_ERR:
1894 case LSC_SCODE_NONPORT:
1895 case LSC_SCODE_LOGGED_IN:
1896 case LSC_SCODE_NOFLOGI_ACC:
1897 default:
1898 mb[0] = MBS_COMMAND_ERROR;
1899 break;
1900 }
1901 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001902 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066,
1903 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001904
1905 iop[0] = le32_to_cpu(lg->io_parameter[0]);
1906
1907 mb[0] = MBS_COMMAND_COMPLETE;
1908 mb[1] = 0;
1909 if (iop[0] & BIT_4) {
1910 if (iop[0] & BIT_8)
1911 mb[1] |= BIT_1;
1912 } else
1913 mb[1] = BIT_0;
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001914
1915 /* Passback COS information. */
1916 mb[10] = 0;
1917 if (lg->io_parameter[7] || lg->io_parameter[8])
1918 mb[10] |= BIT_0; /* Class 2. */
1919 if (lg->io_parameter[9] || lg->io_parameter[10])
1920 mb[10] |= BIT_1; /* Class 3. */
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04001921 if (lg->io_parameter[0] & __constant_cpu_to_le32(BIT_7))
1922 mb[10] |= BIT_7; /* Confirmed Completion
1923 * Allowed
1924 */
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07001925 }
1926
1927 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
1928
1929 return rval;
1930}
1931
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932/*
1933 * qla2x00_login_fabric
1934 * Issue login fabric port mailbox command.
1935 *
1936 * Input:
1937 * ha = adapter block pointer.
1938 * loop_id = device loop ID.
1939 * domain = device domain.
1940 * area = device area.
1941 * al_pa = device AL_PA.
1942 * status = pointer for return status.
1943 * opt = command options.
1944 * TARGET_QUEUE_LOCK must be released.
1945 * ADAPTER_STATE_LOCK must be released.
1946 *
1947 * Returns:
1948 * qla2x00 local function return status code.
1949 *
1950 * Context:
1951 * Kernel context.
1952 */
1953int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001954qla2x00_login_fabric(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt)
1956{
1957 int rval;
1958 mbx_cmd_t mc;
1959 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001960 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04001962 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067,
1963 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964
1965 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT;
1966 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
1967 if (HAS_EXTENDED_IDS(ha)) {
1968 mcp->mb[1] = loop_id;
1969 mcp->mb[10] = opt;
1970 mcp->out_mb |= MBX_10;
1971 } else {
1972 mcp->mb[1] = (loop_id << 8) | opt;
1973 }
1974 mcp->mb[2] = domain;
1975 mcp->mb[3] = area << 8 | al_pa;
1976
1977 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0;
1978 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
1979 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08001980 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981
1982 /* Return mailbox statuses. */
1983 if (mb != NULL) {
1984 mb[0] = mcp->mb[0];
1985 mb[1] = mcp->mb[1];
1986 mb[2] = mcp->mb[2];
1987 mb[6] = mcp->mb[6];
1988 mb[7] = mcp->mb[7];
Andrew Vasquezad3e0ed2005-08-26 19:08:10 -07001989 /* COS retrieved from Get-Port-Database mailbox command. */
1990 mb[10] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001991 }
1992
1993 if (rval != QLA_SUCCESS) {
1994 /* RLU tmp code: need to change main mailbox_command function to
1995 * return ok even when the mailbox completion value is not
1996 * SUCCESS. The caller needs to be responsible to interpret
1997 * the return values of this mailbox command if we're not
1998 * to change too much of the existing code.
1999 */
2000 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 ||
2001 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 ||
2002 mcp->mb[0] == 0x4006)
2003 rval = QLA_SUCCESS;
2004
2005 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002006 ql_dbg(ql_dbg_mbx, vha, 0x1068,
2007 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
2008 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009 } else {
2010 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002011 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069,
2012 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013 }
2014
2015 return rval;
2016}
2017
2018/*
2019 * qla2x00_login_local_device
2020 * Issue login loop port mailbox command.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002021 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002022 * Input:
2023 * ha = adapter block pointer.
2024 * loop_id = device loop ID.
2025 * opt = command options.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002026 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002027 * Returns:
2028 * Return status code.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002029 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002030 * Context:
2031 * Kernel context.
Andrew Vasquezfa2a1ce2005-07-06 10:32:07 -07002032 *
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033 */
2034int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002035qla2x00_login_local_device(scsi_qla_host_t *vha, fc_port_t *fcport,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002036 uint16_t *mb_ret, uint8_t opt)
2037{
2038 int rval;
2039 mbx_cmd_t mc;
2040 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002041 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002042
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002043 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a,
2044 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002045
Andrew Vasqueze4289242007-07-19 15:05:56 -07002046 if (IS_FWI2_CAPABLE(ha))
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002047 return qla24xx_login_fabric(vha, fcport->loop_id,
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08002048 fcport->d_id.b.domain, fcport->d_id.b.area,
2049 fcport->d_id.b.al_pa, mb_ret, opt);
2050
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051 mcp->mb[0] = MBC_LOGIN_LOOP_PORT;
2052 if (HAS_EXTENDED_IDS(ha))
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08002053 mcp->mb[1] = fcport->loop_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002054 else
andrew.vasquez@qlogic.com9a52a572006-03-09 14:27:44 -08002055 mcp->mb[1] = fcport->loop_id << 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002056 mcp->mb[2] = opt;
2057 mcp->out_mb = MBX_2|MBX_1|MBX_0;
2058 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0;
2059 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
2060 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002061 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002062
2063 /* Return mailbox statuses. */
2064 if (mb_ret != NULL) {
2065 mb_ret[0] = mcp->mb[0];
2066 mb_ret[1] = mcp->mb[1];
2067 mb_ret[6] = mcp->mb[6];
2068 mb_ret[7] = mcp->mb[7];
2069 }
2070
2071 if (rval != QLA_SUCCESS) {
2072 /* AV tmp code: need to change main mailbox_command function to
2073 * return ok even when the mailbox completion value is not
2074 * SUCCESS. The caller needs to be responsible to interpret
2075 * the return values of this mailbox command if we're not
2076 * to change too much of the existing code.
2077 */
2078 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006)
2079 rval = QLA_SUCCESS;
2080
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002081 ql_dbg(ql_dbg_mbx, vha, 0x106b,
2082 "Failed=%x mb[0]=%x mb[1]=%x mb[6]=%x mb[7]=%x.\n",
2083 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002084 } else {
2085 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002086 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c,
2087 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002088 }
2089
2090 return (rval);
2091}
2092
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002093int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002094qla24xx_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002095 uint8_t area, uint8_t al_pa)
2096{
2097 int rval;
2098 struct logio_entry_24xx *lg;
2099 dma_addr_t lg_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002100 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002101 struct req_que *req;
2102 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002103
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002104 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d,
2105 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002106
2107 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma);
2108 if (lg == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002109 ql_log(ql_log_warn, vha, 0x106e,
2110 "Failed to allocate logout IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002111 return QLA_MEMORY_ALLOC_FAILED;
2112 }
2113 memset(lg, 0, sizeof(struct logio_entry_24xx));
2114
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002115 if (ql2xmaxqueues > 1)
2116 req = ha->req_q_map[0];
2117 else
2118 req = vha->req;
2119 rsp = req->rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002120 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE;
2121 lg->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002122 lg->handle = MAKE_HANDLE(req->id, lg->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002123 lg->nport_handle = cpu_to_le16(loop_id);
2124 lg->control_flags =
Andrew Vasquezc8d66912011-03-30 11:46:21 -07002125 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
2126 LCF_FREE_NPORT);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002127 lg->port_id[0] = al_pa;
2128 lg->port_id[1] = area;
2129 lg->port_id[2] = domain;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002130 lg->vp_index = vha->vp_idx;
Andrew Vasquez7f45dd02012-02-09 11:15:45 -08002131 rval = qla2x00_issue_iocb_timeout(vha, lg, lg_dma, 0,
2132 (ha->r_a_tov / 10 * 2) + 2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002133 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002134 ql_dbg(ql_dbg_mbx, vha, 0x106f,
2135 "Failed to issue logout IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002136 } else if (lg->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002137 ql_dbg(ql_dbg_mbx, vha, 0x1070,
2138 "Failed to complete IOCB -- error status (%x).\n",
2139 lg->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002140 rval = QLA_FUNCTION_FAILED;
2141 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002142 ql_dbg(ql_dbg_mbx, vha, 0x1071,
2143 "Failed to complete IOCB -- completion status (%x) "
2144 "ioparam=%x/%x.\n", le16_to_cpu(lg->comp_status),
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002145 le32_to_cpu(lg->io_parameter[0]),
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002146 le32_to_cpu(lg->io_parameter[1]));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002147 } else {
2148 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002149 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072,
2150 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002151 }
2152
2153 dma_pool_free(ha->s_dma_pool, lg, lg_dma);
2154
2155 return rval;
2156}
2157
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158/*
2159 * qla2x00_fabric_logout
2160 * Issue logout fabric port mailbox command.
2161 *
2162 * Input:
2163 * ha = adapter block pointer.
2164 * loop_id = device loop ID.
2165 * TARGET_QUEUE_LOCK must be released.
2166 * ADAPTER_STATE_LOCK must be released.
2167 *
2168 * Returns:
2169 * qla2x00 local function return status code.
2170 *
2171 * Context:
2172 * Kernel context.
2173 */
2174int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002175qla2x00_fabric_logout(scsi_qla_host_t *vha, uint16_t loop_id, uint8_t domain,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002176 uint8_t area, uint8_t al_pa)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177{
2178 int rval;
2179 mbx_cmd_t mc;
2180 mbx_cmd_t *mcp = &mc;
2181
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002182 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073,
2183 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002184
2185 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT;
2186 mcp->out_mb = MBX_1|MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002187 if (HAS_EXTENDED_IDS(vha->hw)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002188 mcp->mb[1] = loop_id;
2189 mcp->mb[10] = 0;
2190 mcp->out_mb |= MBX_10;
2191 } else {
2192 mcp->mb[1] = loop_id << 8;
2193 }
2194
2195 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002196 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002198 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199
2200 if (rval != QLA_SUCCESS) {
2201 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002202 ql_dbg(ql_dbg_mbx, vha, 0x1074,
2203 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002204 } else {
2205 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002206 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075,
2207 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002208 }
2209
2210 return rval;
2211}
2212
2213/*
2214 * qla2x00_full_login_lip
2215 * Issue full login LIP mailbox command.
2216 *
2217 * Input:
2218 * ha = adapter block pointer.
2219 * TARGET_QUEUE_LOCK must be released.
2220 * ADAPTER_STATE_LOCK must be released.
2221 *
2222 * Returns:
2223 * qla2x00 local function return status code.
2224 *
2225 * Context:
2226 * Kernel context.
2227 */
2228int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002229qla2x00_full_login_lip(scsi_qla_host_t *vha)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002230{
2231 int rval;
2232 mbx_cmd_t mc;
2233 mbx_cmd_t *mcp = &mc;
2234
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002235 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076,
2236 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002237
2238 mcp->mb[0] = MBC_LIP_FULL_LOGIN;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002239 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0;
Andrew Vasquez0c8c39a2006-12-13 19:20:30 -08002240 mcp->mb[2] = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002241 mcp->mb[3] = 0;
2242 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
2243 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002244 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002245 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002246 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247
2248 if (rval != QLA_SUCCESS) {
2249 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002250 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251 } else {
2252 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002253 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078,
2254 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002255 }
2256
2257 return rval;
2258}
2259
2260/*
2261 * qla2x00_get_id_list
2262 *
2263 * Input:
2264 * ha = adapter block pointer.
2265 *
2266 * Returns:
2267 * qla2x00 local function return status code.
2268 *
2269 * Context:
2270 * Kernel context.
2271 */
2272int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002273qla2x00_get_id_list(scsi_qla_host_t *vha, void *id_list, dma_addr_t id_list_dma,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274 uint16_t *entries)
2275{
2276 int rval;
2277 mbx_cmd_t mc;
2278 mbx_cmd_t *mcp = &mc;
2279
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002280 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079,
2281 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282
2283 if (id_list == NULL)
2284 return QLA_FUNCTION_FAILED;
2285
2286 mcp->mb[0] = MBC_GET_ID_LIST;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002287 mcp->out_mb = MBX_0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002288 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002289 mcp->mb[2] = MSW(id_list_dma);
2290 mcp->mb[3] = LSW(id_list_dma);
2291 mcp->mb[6] = MSW(MSD(id_list_dma));
2292 mcp->mb[7] = LSW(MSD(id_list_dma));
andrew.vasquez@qlogic.com247ec452006-02-07 08:45:40 -08002293 mcp->mb[8] = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002294 mcp->mb[9] = vha->vp_idx;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002295 mcp->out_mb |= MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002296 } else {
2297 mcp->mb[1] = MSW(id_list_dma);
2298 mcp->mb[2] = LSW(id_list_dma);
2299 mcp->mb[3] = MSW(MSD(id_list_dma));
2300 mcp->mb[6] = LSW(MSD(id_list_dma));
2301 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
2302 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002304 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002306 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307
2308 if (rval != QLA_SUCCESS) {
2309 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002310 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002311 } else {
2312 *entries = mcp->mb[1];
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002313 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b,
2314 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002315 }
2316
2317 return rval;
2318}
2319
2320/*
2321 * qla2x00_get_resource_cnts
2322 * Get current firmware resource counts.
2323 *
2324 * Input:
2325 * ha = adapter block pointer.
2326 *
2327 * Returns:
2328 * qla2x00 local function return status code.
2329 *
2330 * Context:
2331 * Kernel context.
2332 */
2333int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002334qla2x00_get_resource_cnts(scsi_qla_host_t *vha, uint16_t *cur_xchg_cnt,
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002335 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt,
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002336 uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports, uint16_t *max_fcfs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337{
2338 int rval;
2339 mbx_cmd_t mc;
2340 mbx_cmd_t *mcp = &mc;
2341
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002342 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c,
2343 "Entered %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344
2345 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
2346 mcp->out_mb = MBX_0;
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002347 mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002348 if (IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw))
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002349 mcp->in_mb |= MBX_12;
Ravi Anandb93480e2008-04-03 13:13:25 -07002350 mcp->tov = MBX_TOV_SECONDS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002351 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002352 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353
2354 if (rval != QLA_SUCCESS) {
2355 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002356 ql_dbg(ql_dbg_mbx, vha, 0x107d,
2357 "Failed mb[0]=%x.\n", mcp->mb[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002358 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002359 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002360 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x "
2361 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2],
2362 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10],
2363 mcp->mb[11], mcp->mb[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002364
2365 if (cur_xchg_cnt)
2366 *cur_xchg_cnt = mcp->mb[3];
2367 if (orig_xchg_cnt)
2368 *orig_xchg_cnt = mcp->mb[6];
2369 if (cur_iocb_cnt)
2370 *cur_iocb_cnt = mcp->mb[7];
2371 if (orig_iocb_cnt)
2372 *orig_iocb_cnt = mcp->mb[10];
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002373 if (vha->hw->flags.npiv_supported && max_npiv_vports)
Seokmann Ju4d0ea242007-09-20 14:07:43 -07002374 *max_npiv_vports = mcp->mb[11];
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002375 if ((IS_QLA81XX(vha->hw) || IS_QLA83XX(vha->hw)) && max_fcfs)
Andrew Vasquezf3a0a772009-10-13 15:16:49 -07002376 *max_fcfs = mcp->mb[12];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002377 }
2378
2379 return (rval);
2380}
2381
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382/*
2383 * qla2x00_get_fcal_position_map
2384 * Get FCAL (LILP) position map using mailbox command
2385 *
2386 * Input:
2387 * ha = adapter state pointer.
2388 * pos_map = buffer pointer (can be NULL).
2389 *
2390 * Returns:
2391 * qla2x00 local function return status code.
2392 *
2393 * Context:
2394 * Kernel context.
2395 */
2396int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002397qla2x00_get_fcal_position_map(scsi_qla_host_t *vha, char *pos_map)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002398{
2399 int rval;
2400 mbx_cmd_t mc;
2401 mbx_cmd_t *mcp = &mc;
2402 char *pmap;
2403 dma_addr_t pmap_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002404 struct qla_hw_data *ha = vha->hw;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002405
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002406 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f,
2407 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002408
Andrew Vasquez4b892582008-09-11 21:22:48 -07002409 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410 if (pmap == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002411 ql_log(ql_log_warn, vha, 0x1080,
2412 "Memory alloc failed.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413 return QLA_MEMORY_ALLOC_FAILED;
2414 }
2415 memset(pmap, 0, FCAL_MAP_SIZE);
2416
2417 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP;
2418 mcp->mb[2] = MSW(pmap_dma);
2419 mcp->mb[3] = LSW(pmap_dma);
2420 mcp->mb[6] = MSW(MSD(pmap_dma));
2421 mcp->mb[7] = LSW(MSD(pmap_dma));
2422 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2423 mcp->in_mb = MBX_1|MBX_0;
2424 mcp->buf_size = FCAL_MAP_SIZE;
2425 mcp->flags = MBX_DMA_IN;
2426 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002427 rval = qla2x00_mailbox_command(vha, mcp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002428
2429 if (rval == QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002430 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002431 "mb0/mb1=%x/%X FC/AL position map size (%x).\n",
2432 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]);
2433 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d,
2434 pmap, pmap[0] + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002435
2436 if (pos_map)
2437 memcpy(pos_map, pmap, FCAL_MAP_SIZE);
2438 }
2439 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma);
2440
2441 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002442 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002443 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002444 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083,
2445 "Done %s.\n", __func__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446 }
2447
2448 return rval;
2449}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002450
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002451/*
2452 * qla2x00_get_link_status
2453 *
2454 * Input:
2455 * ha = adapter block pointer.
2456 * loop_id = device loop ID.
2457 * ret_buf = pointer to link status return buffer.
2458 *
2459 * Returns:
2460 * 0 = success.
2461 * BIT_0 = mem alloc error.
2462 * BIT_1 = mailbox error.
2463 */
2464int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002465qla2x00_get_link_status(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002466 struct link_statistics *stats, dma_addr_t stats_dma)
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002467{
2468 int rval;
2469 mbx_cmd_t mc;
2470 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002471 uint32_t *siter, *diter, dwords;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002472 struct qla_hw_data *ha = vha->hw;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002473
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002474 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084,
2475 "Entered %s.\n", __func__);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002476
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002477 mcp->mb[0] = MBC_GET_LINK_STATUS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002478 mcp->mb[2] = MSW(stats_dma);
2479 mcp->mb[3] = LSW(stats_dma);
2480 mcp->mb[6] = MSW(MSD(stats_dma));
2481 mcp->mb[7] = LSW(MSD(stats_dma));
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002482 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
2483 mcp->in_mb = MBX_0;
Andrew Vasqueze4289242007-07-19 15:05:56 -07002484 if (IS_FWI2_CAPABLE(ha)) {
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002485 mcp->mb[1] = loop_id;
2486 mcp->mb[4] = 0;
2487 mcp->mb[10] = 0;
2488 mcp->out_mb |= MBX_10|MBX_4|MBX_1;
2489 mcp->in_mb |= MBX_1;
2490 } else if (HAS_EXTENDED_IDS(ha)) {
2491 mcp->mb[1] = loop_id;
2492 mcp->mb[10] = 0;
2493 mcp->out_mb |= MBX_10|MBX_1;
2494 } else {
2495 mcp->mb[1] = loop_id << 8;
2496 mcp->out_mb |= MBX_1;
2497 }
Ravi Anandb93480e2008-04-03 13:13:25 -07002498 mcp->tov = MBX_TOV_SECONDS;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002499 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002500 rval = qla2x00_mailbox_command(vha, mcp);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002501
2502 if (rval == QLA_SUCCESS) {
2503 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002504 ql_dbg(ql_dbg_mbx, vha, 0x1085,
2505 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002506 rval = QLA_FUNCTION_FAILED;
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002507 } else {
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002508 /* Copy over data -- firmware data is LE. */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002509 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086,
2510 "Done %s.\n", __func__);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002511 dwords = offsetof(struct link_statistics, unused1) / 4;
2512 siter = diter = &stats->link_fail_cnt;
2513 while (dwords--)
2514 *diter++ = le32_to_cpu(*siter++);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002515 }
2516 } else {
2517 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002518 ql_dbg(ql_dbg_mbx, vha, 0x1087, "Failed=%x.\n", rval);
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002519 }
2520
andrew.vasquez@qlogic.com392e2f62006-01-31 16:05:02 -08002521 return rval;
2522}
2523
2524int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002525qla24xx_get_isp_stats(scsi_qla_host_t *vha, struct link_statistics *stats,
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002526 dma_addr_t stats_dma)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002527{
2528 int rval;
2529 mbx_cmd_t mc;
2530 mbx_cmd_t *mcp = &mc;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002531 uint32_t *siter, *diter, dwords;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002532
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002533 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088,
2534 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002535
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002536 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002537 mcp->mb[2] = MSW(stats_dma);
2538 mcp->mb[3] = LSW(stats_dma);
2539 mcp->mb[6] = MSW(MSD(stats_dma));
2540 mcp->mb[7] = LSW(MSD(stats_dma));
2541 mcp->mb[8] = sizeof(struct link_statistics) / 4;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002542 mcp->mb[9] = vha->vp_idx;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002543 mcp->mb[10] = 0;
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002544 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 -07002545 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002546 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002547 mcp->flags = IOCTL_CMD;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002548 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002549
2550 if (rval == QLA_SUCCESS) {
2551 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002552 ql_dbg(ql_dbg_mbx, vha, 0x1089,
2553 "Failed mb[0]=%x.\n", mcp->mb[0]);
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002554 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002555 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002556 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a,
2557 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002558 /* Copy over data -- firmware data is LE. */
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002559 dwords = sizeof(struct link_statistics) / 4;
2560 siter = diter = &stats->link_fail_cnt;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002561 while (dwords--)
Andrew Vasquez43ef0582008-01-17 09:02:08 -08002562 *diter++ = le32_to_cpu(*siter++);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002563 }
2564 } else {
2565 /* Failed. */
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002566 ql_dbg(ql_dbg_mbx, vha, 0x108b, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002567 }
2568
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002569 return rval;
2570}
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002571
2572int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002573qla24xx_abort_command(srb_t *sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002574{
2575 int rval;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002576 unsigned long flags = 0;
2577
2578 struct abort_entry_24xx *abt;
2579 dma_addr_t abt_dma;
2580 uint32_t handle;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002581 fc_port_t *fcport = sp->fcport;
2582 struct scsi_qla_host *vha = fcport->vha;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002583 struct qla_hw_data *ha = vha->hw;
Anirban Chakraborty67c2e932009-04-06 22:33:42 -07002584 struct req_que *req = vha->req;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002585
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002586 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c,
2587 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002588
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002589 spin_lock_irqsave(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05002590 for (handle = 1; handle < req->num_outstanding_cmds; handle++) {
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002591 if (req->outstanding_cmds[handle] == sp)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002592 break;
2593 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002594 spin_unlock_irqrestore(&ha->hardware_lock, flags);
Chad Dupuis8d93f552013-01-30 03:34:37 -05002595 if (handle == req->num_outstanding_cmds) {
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002596 /* Command not found. */
2597 return QLA_FUNCTION_FAILED;
2598 }
2599
2600 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma);
2601 if (abt == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002602 ql_log(ql_log_warn, vha, 0x108d,
2603 "Failed to allocate abort IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002604 return QLA_MEMORY_ALLOC_FAILED;
2605 }
2606 memset(abt, 0, sizeof(struct abort_entry_24xx));
2607
2608 abt->entry_type = ABORT_IOCB_TYPE;
2609 abt->entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002610 abt->handle = MAKE_HANDLE(req->id, abt->handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002611 abt->nport_handle = cpu_to_le16(fcport->loop_id);
Mike Hernandeza74ec142011-03-30 11:46:20 -07002612 abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002613 abt->port_id[0] = fcport->d_id.b.al_pa;
2614 abt->port_id[1] = fcport->d_id.b.area;
2615 abt->port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04002616 abt->vp_index = fcport->vha->vp_idx;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002617
2618 abt->req_que_no = cpu_to_le16(req->id);
2619
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002620 rval = qla2x00_issue_iocb(vha, abt, abt_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002621 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002622 ql_dbg(ql_dbg_mbx, vha, 0x108e,
2623 "Failed to issue IOCB (%x).\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002624 } else if (abt->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002625 ql_dbg(ql_dbg_mbx, vha, 0x108f,
2626 "Failed to complete IOCB -- error status (%x).\n",
2627 abt->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002628 rval = QLA_FUNCTION_FAILED;
2629 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002630 ql_dbg(ql_dbg_mbx, vha, 0x1090,
2631 "Failed to complete IOCB -- completion status (%x).\n",
2632 le16_to_cpu(abt->nport_handle));
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002633 rval = QLA_FUNCTION_FAILED;
2634 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002635 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
2636 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002637 }
2638
2639 dma_pool_free(ha->s_dma_pool, abt, abt_dma);
2640
2641 return rval;
2642}
2643
2644struct tsk_mgmt_cmd {
2645 union {
2646 struct tsk_mgmt_entry tsk;
2647 struct sts_entry_24xx sts;
2648 } p;
2649};
2650
Andrew Vasquez523ec772008-04-03 13:13:24 -07002651static int
2652__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002653 unsigned int l, int tag)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002654{
Andrew Vasquez523ec772008-04-03 13:13:24 -07002655 int rval, rval2;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002656 struct tsk_mgmt_cmd *tsk;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002657 struct sts_entry_24xx *sts;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002658 dma_addr_t tsk_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002659 scsi_qla_host_t *vha;
2660 struct qla_hw_data *ha;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002661 struct req_que *req;
2662 struct rsp_que *rsp;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002663
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002664 vha = fcport->vha;
2665 ha = vha->hw;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002666 req = vha->req;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002667
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002668 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092,
2669 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002670
Anirban Chakraborty7163ea82009-08-05 09:18:40 -07002671 if (ha->flags.cpu_affinity_enabled)
Anirban Chakraborty68ca9492009-04-06 22:33:41 -07002672 rsp = ha->rsp_q_map[tag + 1];
2673 else
2674 rsp = req->rsp;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002675 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002676 if (tsk == NULL) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002677 ql_log(ql_log_warn, vha, 0x1093,
2678 "Failed to allocate task management IOCB.\n");
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002679 return QLA_MEMORY_ALLOC_FAILED;
2680 }
2681 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd));
2682
2683 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE;
2684 tsk->p.tsk.entry_count = 1;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002685 tsk->p.tsk.handle = MAKE_HANDLE(req->id, tsk->p.tsk.handle);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002686 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
Andrew Vasquez00a537b2008-02-28 14:06:11 -08002687 tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002688 tsk->p.tsk.control_flags = cpu_to_le32(type);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002689 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
2690 tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
2691 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
Joe Carnuccioc6d39e22012-05-15 14:34:20 -04002692 tsk->p.tsk.vp_index = fcport->vha->vp_idx;
Andrew Vasquez523ec772008-04-03 13:13:24 -07002693 if (type == TCF_LUN_RESET) {
2694 int_to_scsilun(l, &tsk->p.tsk.lun);
2695 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
2696 sizeof(tsk->p.tsk.lun));
2697 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07002698
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002699 sts = &tsk->p.sts;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002700 rval = qla2x00_issue_iocb(vha, tsk, tsk_dma, 0);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002701 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002702 ql_dbg(ql_dbg_mbx, vha, 0x1094,
2703 "Failed to issue %s reset IOCB (%x).\n", name, rval);
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002704 } else if (sts->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002705 ql_dbg(ql_dbg_mbx, vha, 0x1095,
2706 "Failed to complete IOCB -- error status (%x).\n",
2707 sts->entry_status);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002708 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002709 } else if (sts->comp_status !=
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002710 __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002711 ql_dbg(ql_dbg_mbx, vha, 0x1096,
2712 "Failed to complete IOCB -- completion status (%x).\n",
2713 le16_to_cpu(sts->comp_status));
Andrew Vasquez9ca1d012009-10-13 15:16:50 -07002714 rval = QLA_FUNCTION_FAILED;
Andrew Vasquez97dec562011-02-23 15:27:14 -08002715 } else if (le16_to_cpu(sts->scsi_status) &
2716 SS_RESPONSE_INFO_LEN_VALID) {
2717 if (le32_to_cpu(sts->rsp_data_len) < 4) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002718 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002719 "Ignoring inconsistent data length -- not enough "
2720 "response info (%d).\n",
2721 le32_to_cpu(sts->rsp_data_len));
Andrew Vasquez97dec562011-02-23 15:27:14 -08002722 } else if (sts->data[3]) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002723 ql_dbg(ql_dbg_mbx, vha, 0x1098,
2724 "Failed to complete IOCB -- response (%x).\n",
2725 sts->data[3]);
Andrew Vasquez97dec562011-02-23 15:27:14 -08002726 rval = QLA_FUNCTION_FAILED;
2727 }
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002728 }
2729
2730 /* Issue marker IOCB. */
Anirban Chakraborty73208df2008-12-09 16:45:39 -08002731 rval2 = qla2x00_marker(vha, req, rsp, fcport->loop_id, l,
Andrew Vasquez523ec772008-04-03 13:13:24 -07002732 type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
2733 if (rval2 != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002734 ql_dbg(ql_dbg_mbx, vha, 0x1099,
2735 "Failed to issue marker IOCB (%x).\n", rval2);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002736 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002737 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a,
2738 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002739 }
2740
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002741 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002742
2743 return rval;
2744}
2745
Andrew Vasquez523ec772008-04-03 13:13:24 -07002746int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002747qla24xx_abort_target(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002748{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002749 struct qla_hw_data *ha = fcport->vha->hw;
2750
2751 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2752 return qla2x00_async_tm_cmd(fcport, TCF_TARGET_RESET, l, tag);
2753
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002754 return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002755}
2756
2757int
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002758qla24xx_lun_reset(struct fc_port *fcport, unsigned int l, int tag)
Andrew Vasquez523ec772008-04-03 13:13:24 -07002759{
Madhuranath Iyengar38222632010-05-04 15:01:29 -07002760 struct qla_hw_data *ha = fcport->vha->hw;
2761
2762 if ((ql2xasynctmfenable) && IS_FWI2_CAPABLE(ha))
2763 return qla2x00_async_tm_cmd(fcport, TCF_LUN_RESET, l, tag);
2764
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07002765 return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l, tag);
Andrew Vasquez523ec772008-04-03 13:13:24 -07002766}
2767
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002768int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002769qla2x00_system_error(scsi_qla_host_t *vha)
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002770{
2771 int rval;
2772 mbx_cmd_t mc;
2773 mbx_cmd_t *mcp = &mc;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002774 struct qla_hw_data *ha = vha->hw;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002775
Andrew Vasquez68af0812008-05-12 22:21:13 -07002776 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha))
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002777 return QLA_FUNCTION_FAILED;
2778
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002779 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b,
2780 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002781
2782 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR;
2783 mcp->out_mb = MBX_0;
2784 mcp->in_mb = MBX_0;
2785 mcp->tov = 5;
2786 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002787 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002788
2789 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002790 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002791 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002792 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d,
2793 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002794 }
2795
2796 return rval;
2797}
2798
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002799/**
2800 * qla2x00_set_serdes_params() -
2801 * @ha: HA context
2802 *
2803 * Returns
2804 */
2805int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002806qla2x00_set_serdes_params(scsi_qla_host_t *vha, uint16_t sw_em_1g,
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002807 uint16_t sw_em_2g, uint16_t sw_em_4g)
2808{
2809 int rval;
2810 mbx_cmd_t mc;
2811 mbx_cmd_t *mcp = &mc;
2812
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002813 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e,
2814 "Entered %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002815
2816 mcp->mb[0] = MBC_SERDES_PARAMS;
2817 mcp->mb[1] = BIT_0;
andrew.vasquez@qlogic.comfdbc6832006-03-09 14:27:29 -08002818 mcp->mb[2] = sw_em_1g | BIT_15;
2819 mcp->mb[3] = sw_em_2g | BIT_15;
2820 mcp->mb[4] = sw_em_4g | BIT_15;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002821 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
2822 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002823 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002824 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002825 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002826
2827 if (rval != QLA_SUCCESS) {
2828 /*EMPTY*/
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002829 ql_dbg(ql_dbg_mbx, vha, 0x109f,
2830 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002831 } else {
2832 /*EMPTY*/
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002833 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0,
2834 "Done %s.\n", __func__);
Andrew Vasquez1c7c6352005-07-06 10:30:57 -07002835 }
2836
2837 return rval;
2838}
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002839
2840int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002841qla2x00_stop_firmware(scsi_qla_host_t *vha)
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002842{
2843 int rval;
2844 mbx_cmd_t mc;
2845 mbx_cmd_t *mcp = &mc;
2846
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002847 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002848 return QLA_FUNCTION_FAILED;
2849
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002850 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1,
2851 "Entered %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002852
2853 mcp->mb[0] = MBC_STOP_FIRMWARE;
Andrew Vasquez4ba988d2012-02-09 11:14:06 -08002854 mcp->mb[1] = 0;
2855 mcp->out_mb = MBX_1|MBX_0;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002856 mcp->in_mb = MBX_0;
2857 mcp->tov = 5;
2858 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002859 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002860
2861 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002862 ql_dbg(ql_dbg_mbx, vha, 0x10a2, "Failed=%x.\n", rval);
Andrew Vasquezb469a7c2009-04-06 22:33:48 -07002863 if (mcp->mb[0] == MBS_INVALID_COMMAND)
2864 rval = QLA_INVALID_COMMAND;
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002865 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002866 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3,
2867 "Done %s.\n", __func__);
Andrew Vasquezf6ef3b12005-08-26 19:10:20 -07002868 }
2869
2870 return rval;
2871}
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002872
2873int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002874qla2x00_enable_eft_trace(scsi_qla_host_t *vha, dma_addr_t eft_dma,
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002875 uint16_t buffers)
2876{
2877 int rval;
2878 mbx_cmd_t mc;
2879 mbx_cmd_t *mcp = &mc;
2880
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002881 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4,
2882 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002883
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002884 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002885 return QLA_FUNCTION_FAILED;
2886
Andrew Vasquez85880802009-12-15 21:29:46 -08002887 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2888 return QLA_FUNCTION_FAILED;
2889
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002890 mcp->mb[0] = MBC_TRACE_CONTROL;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002891 mcp->mb[1] = TC_EFT_ENABLE;
2892 mcp->mb[2] = LSW(eft_dma);
2893 mcp->mb[3] = MSW(eft_dma);
2894 mcp->mb[4] = LSW(MSD(eft_dma));
2895 mcp->mb[5] = MSW(MSD(eft_dma));
2896 mcp->mb[6] = buffers;
2897 mcp->mb[7] = TC_AEN_DISABLE;
2898 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 -07002899 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002900 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002901 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002902 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002903 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002904 ql_dbg(ql_dbg_mbx, vha, 0x10a5,
2905 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2906 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002907 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002908 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6,
2909 "Done %s.\n", __func__);
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002910 }
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002911
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002912 return rval;
2913}
2914
2915int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002916qla2x00_disable_eft_trace(scsi_qla_host_t *vha)
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002917{
2918 int rval;
2919 mbx_cmd_t mc;
2920 mbx_cmd_t *mcp = &mc;
2921
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002922 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7,
2923 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002924
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002925 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002926 return QLA_FUNCTION_FAILED;
2927
Andrew Vasquez85880802009-12-15 21:29:46 -08002928 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2929 return QLA_FUNCTION_FAILED;
2930
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002931 mcp->mb[0] = MBC_TRACE_CONTROL;
2932 mcp->mb[1] = TC_EFT_DISABLE;
2933 mcp->out_mb = MBX_1|MBX_0;
2934 mcp->in_mb = MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002935 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez00b6bd22008-01-17 09:02:16 -08002936 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002937 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002938 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002939 ql_dbg(ql_dbg_mbx, vha, 0x10a8,
2940 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2941 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002942 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002943 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9,
2944 "Done %s.\n", __func__);
Andrew Vasqueza7a167b2006-06-23 16:10:29 -07002945 }
2946
2947 return rval;
2948}
2949
Andrew Vasquez88729e52006-06-23 16:10:50 -07002950int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002951qla2x00_enable_fce_trace(scsi_qla_host_t *vha, dma_addr_t fce_dma,
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002952 uint16_t buffers, uint16_t *mb, uint32_t *dwords)
2953{
2954 int rval;
2955 mbx_cmd_t mc;
2956 mbx_cmd_t *mcp = &mc;
2957
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002958 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa,
2959 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002960
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08002961 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) &&
2962 !IS_QLA83XX(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002963 return QLA_FUNCTION_FAILED;
2964
Andrew Vasquez85880802009-12-15 21:29:46 -08002965 if (unlikely(pci_channel_offline(vha->hw->pdev)))
2966 return QLA_FUNCTION_FAILED;
2967
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002968 mcp->mb[0] = MBC_TRACE_CONTROL;
2969 mcp->mb[1] = TC_FCE_ENABLE;
2970 mcp->mb[2] = LSW(fce_dma);
2971 mcp->mb[3] = MSW(fce_dma);
2972 mcp->mb[4] = LSW(MSD(fce_dma));
2973 mcp->mb[5] = MSW(MSD(fce_dma));
2974 mcp->mb[6] = buffers;
2975 mcp->mb[7] = TC_AEN_DISABLE;
2976 mcp->mb[8] = 0;
2977 mcp->mb[9] = TC_FCE_DEFAULT_RX_SIZE;
2978 mcp->mb[10] = TC_FCE_DEFAULT_TX_SIZE;
2979 mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
2980 MBX_1|MBX_0;
2981 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07002982 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002983 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08002984 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002985 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07002986 ql_dbg(ql_dbg_mbx, vha, 0x10ab,
2987 "Failed=%x mb[0]=%x mb[1]=%x.\n",
2988 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002989 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04002990 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac,
2991 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002992
2993 if (mb)
2994 memcpy(mb, mcp->mb, 8 * sizeof(*mb));
2995 if (dwords)
Andrew Vasquezfa0926d2008-05-12 22:21:12 -07002996 *dwords = buffers;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08002997 }
2998
2999 return rval;
3000}
3001
3002int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003003qla2x00_disable_fce_trace(scsi_qla_host_t *vha, uint64_t *wr, uint64_t *rd)
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003004{
3005 int rval;
3006 mbx_cmd_t mc;
3007 mbx_cmd_t *mcp = &mc;
3008
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003009 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad,
3010 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003011
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003012 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003013 return QLA_FUNCTION_FAILED;
3014
Andrew Vasquez85880802009-12-15 21:29:46 -08003015 if (unlikely(pci_channel_offline(vha->hw->pdev)))
3016 return QLA_FUNCTION_FAILED;
3017
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003018 mcp->mb[0] = MBC_TRACE_CONTROL;
3019 mcp->mb[1] = TC_FCE_DISABLE;
3020 mcp->mb[2] = TC_FCE_DISABLE_TRACE;
3021 mcp->out_mb = MBX_2|MBX_1|MBX_0;
3022 mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
3023 MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003024 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003025 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003026 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003027 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003028 ql_dbg(ql_dbg_mbx, vha, 0x10ae,
3029 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3030 rval, mcp->mb[0], mcp->mb[1]);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003031 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003032 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af,
3033 "Done %s.\n", __func__);
Andrew Vasquezdf613b92008-01-17 09:02:17 -08003034
3035 if (wr)
3036 *wr = (uint64_t) mcp->mb[5] << 48 |
3037 (uint64_t) mcp->mb[4] << 32 |
3038 (uint64_t) mcp->mb[3] << 16 |
3039 (uint64_t) mcp->mb[2];
3040 if (rd)
3041 *rd = (uint64_t) mcp->mb[9] << 48 |
3042 (uint64_t) mcp->mb[8] << 32 |
3043 (uint64_t) mcp->mb[7] << 16 |
3044 (uint64_t) mcp->mb[6];
3045 }
3046
3047 return rval;
3048}
3049
3050int
Giridhar Malavali6e980162010-03-19 17:03:58 -07003051qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
3052 uint16_t *port_speed, uint16_t *mb)
3053{
3054 int rval;
3055 mbx_cmd_t mc;
3056 mbx_cmd_t *mcp = &mc;
3057
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003058 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0,
3059 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003060
Giridhar Malavali6e980162010-03-19 17:03:58 -07003061 if (!IS_IIDMA_CAPABLE(vha->hw))
3062 return QLA_FUNCTION_FAILED;
3063
Giridhar Malavali6e980162010-03-19 17:03:58 -07003064 mcp->mb[0] = MBC_PORT_PARAMS;
3065 mcp->mb[1] = loop_id;
3066 mcp->mb[2] = mcp->mb[3] = 0;
3067 mcp->mb[9] = vha->vp_idx;
3068 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3069 mcp->in_mb = MBX_3|MBX_1|MBX_0;
3070 mcp->tov = MBX_TOV_SECONDS;
3071 mcp->flags = 0;
3072 rval = qla2x00_mailbox_command(vha, mcp);
3073
3074 /* Return mailbox statuses. */
3075 if (mb != NULL) {
3076 mb[0] = mcp->mb[0];
3077 mb[1] = mcp->mb[1];
3078 mb[3] = mcp->mb[3];
3079 }
3080
3081 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003082 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003083 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003084 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2,
3085 "Done %s.\n", __func__);
Giridhar Malavali6e980162010-03-19 17:03:58 -07003086 if (port_speed)
3087 *port_speed = mcp->mb[3];
3088 }
3089
3090 return rval;
3091}
3092
3093int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003094qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003095 uint16_t port_speed, uint16_t *mb)
3096{
3097 int rval;
3098 mbx_cmd_t mc;
3099 mbx_cmd_t *mcp = &mc;
3100
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003101 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3,
3102 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003103
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003104 if (!IS_IIDMA_CAPABLE(vha->hw))
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003105 return QLA_FUNCTION_FAILED;
3106
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003107 mcp->mb[0] = MBC_PORT_PARAMS;
3108 mcp->mb[1] = loop_id;
3109 mcp->mb[2] = BIT_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003110 if (IS_CNA_CAPABLE(vha->hw))
Harish Zunjarrao1bb39542009-06-17 10:30:29 -07003111 mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
3112 else
3113 mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
3114 mcp->mb[9] = vha->vp_idx;
3115 mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
3116 mcp->in_mb = MBX_3|MBX_1|MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003117 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003118 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003119 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003120
3121 /* Return mailbox statuses. */
3122 if (mb != NULL) {
3123 mb[0] = mcp->mb[0];
3124 mb[1] = mcp->mb[1];
3125 mb[3] = mcp->mb[3];
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003126 }
3127
3128 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003129 ql_dbg(ql_dbg_mbx, vha, 0x10b4,
3130 "Failed=%x.\n", rval);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003131 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003132 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5,
3133 "Done %s.\n", __func__);
Andrew Vasquezd8b45212006-10-02 12:00:43 -07003134 }
3135
3136 return rval;
3137}
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003138
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003139void
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003140qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003141 struct vp_rpt_id_entry_24xx *rptid_entry)
3142{
3143 uint8_t vp_idx;
Seokmann Juc6852c42008-04-24 15:21:29 -07003144 uint16_t stat = le16_to_cpu(rptid_entry->vp_idx);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003145 struct qla_hw_data *ha = vha->hw;
3146 scsi_qla_host_t *vp;
Arun Easifeafb7b2010-09-03 14:57:00 -07003147 unsigned long flags;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003148 int found;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003149
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003150 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
3151 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003152
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003153 if (rptid_entry->entry_status != 0)
3154 return;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003155
3156 if (rptid_entry->format == 0) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003157 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003158 "Format 0 : Number of VPs setup %d, number of "
3159 "VPs acquired %d.\n",
3160 MSB(le16_to_cpu(rptid_entry->vp_count)),
3161 LSB(le16_to_cpu(rptid_entry->vp_count)));
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003162 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b8,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003163 "Primary port id %02x%02x%02x.\n",
3164 rptid_entry->port_id[2], rptid_entry->port_id[1],
3165 rptid_entry->port_id[0]);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003166 } else if (rptid_entry->format == 1) {
Seokmann Juc6852c42008-04-24 15:21:29 -07003167 vp_idx = LSB(stat);
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003168 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b9,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003169 "Format 1: VP[%d] enabled - status %d - with "
3170 "port id %02x%02x%02x.\n", vp_idx, MSB(stat),
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003171 rptid_entry->port_id[2], rptid_entry->port_id[1],
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003172 rptid_entry->port_id[0]);
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003173
3174 vp = vha;
3175 if (vp_idx == 0 && (MSB(stat) != 1))
3176 goto reg_needed;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003177
Saurav Kashyap681e0142012-11-21 02:40:28 -05003178 if (MSB(stat) != 0 && MSB(stat) != 2) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003179 ql_dbg(ql_dbg_mbx, vha, 0x10ba,
3180 "Could not acquire ID for VP[%d].\n", vp_idx);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003181 return;
Andrew Vasquez81eb9b42009-06-03 09:55:23 -07003182 }
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003183
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003184 found = 0;
Arun Easifeafb7b2010-09-03 14:57:00 -07003185 spin_lock_irqsave(&ha->vport_slock, flags);
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003186 list_for_each_entry(vp, &ha->vp_list, list) {
3187 if (vp_idx == vp->vp_idx) {
3188 found = 1;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003189 break;
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003190 }
3191 }
Arun Easifeafb7b2010-09-03 14:57:00 -07003192 spin_unlock_irqrestore(&ha->vport_slock, flags);
3193
Andrew Vasquez4ac8d4ca2013-02-08 01:57:58 -05003194 if (!found)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003195 return;
3196
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003197 vp->d_id.b.domain = rptid_entry->port_id[2];
3198 vp->d_id.b.area = rptid_entry->port_id[1];
3199 vp->d_id.b.al_pa = rptid_entry->port_id[0];
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003200
3201 /*
3202 * Cannot configure here as we are still sitting on the
3203 * response queue. Handle it in dpc context.
3204 */
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003205 set_bit(VP_IDX_ACQUIRED, &vp->vp_flags);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003206
Andrew Vasquez531a82d2009-10-13 15:16:51 -07003207reg_needed:
3208 set_bit(REGISTER_FC4_NEEDED, &vp->dpc_flags);
3209 set_bit(REGISTER_FDMI_NEEDED, &vp->dpc_flags);
3210 set_bit(VP_DPC_NEEDED, &vha->dpc_flags);
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003211 qla2xxx_wake_dpc(vha);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003212 }
3213}
3214
3215/*
3216 * qla24xx_modify_vp_config
3217 * Change VP configuration for vha
3218 *
3219 * Input:
3220 * vha = adapter block pointer.
3221 *
3222 * Returns:
3223 * qla2xxx local function return status code.
3224 *
3225 * Context:
3226 * Kernel context.
3227 */
3228int
3229qla24xx_modify_vp_config(scsi_qla_host_t *vha)
3230{
3231 int rval;
3232 struct vp_config_entry_24xx *vpmod;
3233 dma_addr_t vpmod_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003234 struct qla_hw_data *ha = vha->hw;
3235 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003236
3237 /* This can be called by the parent */
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003238
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003239 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb,
3240 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003241
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003242 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003243 if (!vpmod) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003244 ql_log(ql_log_warn, vha, 0x10bc,
3245 "Failed to allocate modify VP IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003246 return QLA_MEMORY_ALLOC_FAILED;
3247 }
3248
3249 memset(vpmod, 0, sizeof(struct vp_config_entry_24xx));
3250 vpmod->entry_type = VP_CONFIG_IOCB_TYPE;
3251 vpmod->entry_count = 1;
3252 vpmod->command = VCT_COMMAND_MOD_ENABLE_VPS;
3253 vpmod->vp_count = 1;
3254 vpmod->vp_index1 = vha->vp_idx;
3255 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5;
Nicholas Bellinger2d70c102012-05-15 14:34:28 -04003256
3257 qlt_modify_vp_config(vha, vpmod);
3258
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003259 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE);
3260 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE);
3261 vpmod->entry_count = 1;
3262
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003263 rval = qla2x00_issue_iocb(base_vha, vpmod, vpmod_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003264 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003265 ql_dbg(ql_dbg_mbx, vha, 0x10bd,
3266 "Failed to issue VP config IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003267 } else if (vpmod->comp_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003268 ql_dbg(ql_dbg_mbx, vha, 0x10be,
3269 "Failed to complete IOCB -- error status (%x).\n",
3270 vpmod->comp_status);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003271 rval = QLA_FUNCTION_FAILED;
3272 } else if (vpmod->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003273 ql_dbg(ql_dbg_mbx, vha, 0x10bf,
3274 "Failed to complete IOCB -- completion status (%x).\n",
3275 le16_to_cpu(vpmod->comp_status));
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003276 rval = QLA_FUNCTION_FAILED;
3277 } else {
3278 /* EMPTY */
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003279 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0,
3280 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003281 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING);
3282 }
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003283 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003284
3285 return rval;
3286}
3287
3288/*
3289 * qla24xx_control_vp
3290 * Enable a virtual port for given host
3291 *
3292 * Input:
3293 * ha = adapter block pointer.
3294 * vhba = virtual adapter (unused)
3295 * index = index number for enabled VP
3296 *
3297 * Returns:
3298 * qla2xxx local function return status code.
3299 *
3300 * Context:
3301 * Kernel context.
3302 */
3303int
3304qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
3305{
3306 int rval;
3307 int map, pos;
3308 struct vp_ctrl_entry_24xx *vce;
3309 dma_addr_t vce_dma;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003310 struct qla_hw_data *ha = vha->hw;
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003311 int vp_index = vha->vp_idx;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003312 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003313
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003314 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c1,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003315 "Entered %s enabling index %d.\n", __func__, vp_index);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003316
Andrew Vasquezeb66dc62007-11-12 10:30:58 -08003317 if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003318 return QLA_PARAMETER_ERROR;
3319
3320 vce = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vce_dma);
3321 if (!vce) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003322 ql_log(ql_log_warn, vha, 0x10c2,
3323 "Failed to allocate VP control IOCB.\n");
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003324 return QLA_MEMORY_ALLOC_FAILED;
3325 }
3326 memset(vce, 0, sizeof(struct vp_ctrl_entry_24xx));
3327
3328 vce->entry_type = VP_CTRL_IOCB_TYPE;
3329 vce->entry_count = 1;
3330 vce->command = cpu_to_le16(cmd);
3331 vce->vp_count = __constant_cpu_to_le16(1);
3332
3333 /* index map in firmware starts with 1; decrement index
3334 * this is ok as we never use index 0
3335 */
3336 map = (vp_index - 1) / 8;
3337 pos = (vp_index - 1) & 7;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003338 mutex_lock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003339 vce->vp_idx_map[map] |= 1 << pos;
matthias@kaehlcke.net6c2f5272008-05-12 22:21:11 -07003340 mutex_unlock(&ha->vport_lock);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003341
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003342 rval = qla2x00_issue_iocb(base_vha, vce, vce_dma, 0);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003343 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003344 ql_dbg(ql_dbg_mbx, vha, 0x10c3,
3345 "Failed to issue VP control IOCB (%x).\n", rval);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003346 } else if (vce->entry_status != 0) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003347 ql_dbg(ql_dbg_mbx, vha, 0x10c4,
3348 "Failed to complete IOCB -- error status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003349 vce->entry_status);
3350 rval = QLA_FUNCTION_FAILED;
3351 } else if (vce->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003352 ql_dbg(ql_dbg_mbx, vha, 0x10c5,
3353 "Failed to complet IOCB -- completion status (%x).\n",
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003354 le16_to_cpu(vce->comp_status));
3355 rval = QLA_FUNCTION_FAILED;
3356 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003357 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c6,
3358 "Done %s.\n", __func__);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003359 }
3360
3361 dma_pool_free(ha->s_dma_pool, vce, vce_dma);
3362
3363 return rval;
3364}
3365
3366/*
3367 * qla2x00_send_change_request
3368 * Receive or disable RSCN request from fabric controller
3369 *
3370 * Input:
3371 * ha = adapter block pointer
3372 * format = registration format:
3373 * 0 - Reserved
3374 * 1 - Fabric detected registration
3375 * 2 - N_port detected registration
3376 * 3 - Full registration
3377 * FF - clear registration
3378 * vp_idx = Virtual port index
3379 *
3380 * Returns:
3381 * qla2x00 local function return status code.
3382 *
3383 * Context:
3384 * Kernel Context
3385 */
3386
3387int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003388qla2x00_send_change_request(scsi_qla_host_t *vha, uint16_t format,
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003389 uint16_t vp_idx)
3390{
3391 int rval;
3392 mbx_cmd_t mc;
3393 mbx_cmd_t *mcp = &mc;
3394
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003395 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7,
3396 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003397
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003398 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST;
3399 mcp->mb[1] = format;
3400 mcp->mb[9] = vp_idx;
3401 mcp->out_mb = MBX_9|MBX_1|MBX_0;
3402 mcp->in_mb = MBX_0|MBX_1;
3403 mcp->tov = MBX_TOV_SECONDS;
3404 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003405 rval = qla2x00_mailbox_command(vha, mcp);
Seokmann Ju2c3dfe32007-07-05 13:16:51 -07003406
3407 if (rval == QLA_SUCCESS) {
3408 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) {
3409 rval = BIT_1;
3410 }
3411 } else
3412 rval = BIT_1;
3413
3414 return rval;
3415}
Andrew Vasquez338c9162007-09-20 14:07:33 -07003416
3417int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003418qla2x00_dump_ram(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
Andrew Vasquez338c9162007-09-20 14:07:33 -07003419 uint32_t size)
3420{
3421 int rval;
3422 mbx_cmd_t mc;
3423 mbx_cmd_t *mcp = &mc;
3424
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003425 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009,
3426 "Entered %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003427
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003428 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003429 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
3430 mcp->mb[8] = MSW(addr);
3431 mcp->out_mb = MBX_8|MBX_0;
3432 } else {
3433 mcp->mb[0] = MBC_DUMP_RISC_RAM;
3434 mcp->out_mb = MBX_0;
3435 }
3436 mcp->mb[1] = LSW(addr);
3437 mcp->mb[2] = MSW(req_dma);
3438 mcp->mb[3] = LSW(req_dma);
3439 mcp->mb[6] = MSW(MSD(req_dma));
3440 mcp->mb[7] = LSW(MSD(req_dma));
3441 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003442 if (IS_FWI2_CAPABLE(vha->hw)) {
Andrew Vasquez338c9162007-09-20 14:07:33 -07003443 mcp->mb[4] = MSW(size);
3444 mcp->mb[5] = LSW(size);
3445 mcp->out_mb |= MBX_5|MBX_4;
3446 } else {
3447 mcp->mb[4] = LSW(size);
3448 mcp->out_mb |= MBX_4;
3449 }
3450
3451 mcp->in_mb = MBX_0;
Ravi Anandb93480e2008-04-03 13:13:25 -07003452 mcp->tov = MBX_TOV_SECONDS;
Andrew Vasquez338c9162007-09-20 14:07:33 -07003453 mcp->flags = 0;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003454 rval = qla2x00_mailbox_command(vha, mcp);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003455
3456 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003457 ql_dbg(ql_dbg_mbx, vha, 0x1008,
3458 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003459 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003460 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007,
3461 "Done %s.\n", __func__);
Andrew Vasquez338c9162007-09-20 14:07:33 -07003462 }
3463
3464 return rval;
3465}
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003466/* 84XX Support **************************************************************/
3467
3468struct cs84xx_mgmt_cmd {
3469 union {
3470 struct verify_chip_entry_84xx req;
3471 struct verify_chip_rsp_84xx rsp;
3472 } p;
3473};
3474
3475int
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003476qla84xx_verify_chip(struct scsi_qla_host *vha, uint16_t *status)
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003477{
3478 int rval, retry;
3479 struct cs84xx_mgmt_cmd *mn;
3480 dma_addr_t mn_dma;
3481 uint16_t options;
3482 unsigned long flags;
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003483 struct qla_hw_data *ha = vha->hw;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003484
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003485 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8,
3486 "Entered %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003487
3488 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
3489 if (mn == NULL) {
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003490 return QLA_MEMORY_ALLOC_FAILED;
3491 }
3492
3493 /* Force Update? */
3494 options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
3495 /* Diagnostic firmware? */
3496 /* options |= MENLO_DIAG_FW; */
3497 /* We update the firmware with only one data sequence. */
3498 options |= VCO_END_OF_DATA;
3499
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003500 do {
Andrew Vasquezc1ec1f12008-04-24 15:21:24 -07003501 retry = 0;
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003502 memset(mn, 0, sizeof(*mn));
3503 mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
3504 mn->p.req.entry_count = 1;
3505 mn->p.req.options = cpu_to_le16(options);
3506
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003507 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111c,
3508 "Dump of Verify Request.\n");
3509 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111e,
3510 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003511
Anirban Chakraborty7b867cf2008-11-06 10:40:19 -08003512 rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003513 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003514 ql_dbg(ql_dbg_mbx, vha, 0x10cb,
3515 "Failed to issue verify IOCB (%x).\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003516 goto verify_done;
3517 }
3518
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003519 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1110,
3520 "Dump of Verify Response.\n");
3521 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1118,
3522 (uint8_t *)mn, sizeof(*mn));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003523
3524 status[0] = le16_to_cpu(mn->p.rsp.comp_status);
3525 status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
3526 le16_to_cpu(mn->p.rsp.failure_code) : 0;
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003527 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003528 "cs=%x fc=%x.\n", status[0], status[1]);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003529
3530 if (status[0] != CS_COMPLETE) {
3531 rval = QLA_FUNCTION_FAILED;
3532 if (!(options & VCO_DONT_UPDATE_FW)) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003533 ql_dbg(ql_dbg_mbx, vha, 0x10cf,
3534 "Firmware update failed. Retrying "
3535 "without update firmware.\n");
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003536 options |= VCO_DONT_UPDATE_FW;
3537 options &= ~VCO_FORCE_UPDATE;
3538 retry = 1;
3539 }
3540 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003541 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003542 "Firmware updated to %x.\n",
3543 le32_to_cpu(mn->p.rsp.fw_ver));
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003544
3545 /* NOTE: we only update OP firmware. */
3546 spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
3547 ha->cs84xx->op_fw_version =
3548 le32_to_cpu(mn->p.rsp.fw_ver);
3549 spin_unlock_irqrestore(&ha->cs84xx->access_lock,
3550 flags);
3551 }
3552 } while (retry);
3553
3554verify_done:
3555 dma_pool_free(ha->s_dma_pool, mn, mn_dma);
3556
3557 if (rval != QLA_SUCCESS) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003558 ql_dbg(ql_dbg_mbx, vha, 0x10d1,
3559 "Failed=%x.\n", rval);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003560 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003561 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2,
3562 "Done %s.\n", __func__);
Harihara Kadayam4d4df192008-04-03 13:13:26 -07003563 }
3564
3565 return rval;
3566}
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003567
3568int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003569qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003570{
3571 int rval;
3572 unsigned long flags;
3573 mbx_cmd_t mc;
3574 mbx_cmd_t *mcp = &mc;
3575 struct device_reg_25xxmq __iomem *reg;
3576 struct qla_hw_data *ha = vha->hw;
3577
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003578 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3,
3579 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003580
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003581 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003582 mcp->mb[1] = req->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003583 mcp->mb[2] = MSW(LSD(req->dma));
3584 mcp->mb[3] = LSW(LSD(req->dma));
3585 mcp->mb[6] = MSW(MSD(req->dma));
3586 mcp->mb[7] = LSW(MSD(req->dma));
3587 mcp->mb[5] = req->length;
3588 if (req->rsp)
3589 mcp->mb[10] = req->rsp->id;
3590 mcp->mb[12] = req->qos;
3591 mcp->mb[11] = req->vp_idx;
3592 mcp->mb[13] = req->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003593 if (IS_QLA83XX(ha))
3594 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003595
Saurav Kashyapfa492632012-11-21 02:40:29 -05003596 reg = (struct device_reg_25xxmq __iomem *)((ha->mqiobase) +
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003597 QLA_QUE_PAGE * req->id);
3598
3599 mcp->mb[4] = req->id;
3600 /* que in ptr index */
3601 mcp->mb[8] = 0;
3602 /* que out ptr index */
3603 mcp->mb[9] = 0;
3604 mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7|
3605 MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3606 mcp->in_mb = MBX_0;
3607 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003608 mcp->tov = MBX_TOV_SECONDS * 2;
3609
3610 if (IS_QLA81XX(ha) || IS_QLA83XX(ha))
3611 mcp->in_mb |= MBX_1;
3612 if (IS_QLA83XX(ha)) {
3613 mcp->out_mb |= MBX_15;
3614 /* debug q create issue in SR-IOV */
3615 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3616 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003617
3618 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003619 if (!(req->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003620 WRT_REG_DWORD(&reg->req_q_in, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003621 if (!IS_QLA83XX(ha))
3622 WRT_REG_DWORD(&reg->req_q_out, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003623 }
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003624 req->req_q_in = &reg->req_q_in;
3625 req->req_q_out = &reg->req_q_out;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003626 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3627
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003628 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003629 if (rval != QLA_SUCCESS) {
3630 ql_dbg(ql_dbg_mbx, vha, 0x10d4,
3631 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3632 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003633 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5,
3634 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003635 }
3636
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003637 return rval;
3638}
3639
3640int
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003641qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp)
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003642{
3643 int rval;
3644 unsigned long flags;
3645 mbx_cmd_t mc;
3646 mbx_cmd_t *mcp = &mc;
3647 struct device_reg_25xxmq __iomem *reg;
3648 struct qla_hw_data *ha = vha->hw;
3649
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003650 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6,
3651 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003652
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003653 mcp->mb[0] = MBC_INITIALIZE_MULTIQ;
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003654 mcp->mb[1] = rsp->options;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003655 mcp->mb[2] = MSW(LSD(rsp->dma));
3656 mcp->mb[3] = LSW(LSD(rsp->dma));
3657 mcp->mb[6] = MSW(MSD(rsp->dma));
3658 mcp->mb[7] = LSW(MSD(rsp->dma));
3659 mcp->mb[5] = rsp->length;
Andrew Vasquez444786d2009-01-05 11:18:10 -08003660 mcp->mb[14] = rsp->msix->entry;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003661 mcp->mb[13] = rsp->rid;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003662 if (IS_QLA83XX(ha))
3663 mcp->mb[15] = 0;
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003664
Saurav Kashyapfa492632012-11-21 02:40:29 -05003665 reg = (struct device_reg_25xxmq __iomem *)((ha->mqiobase) +
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003666 QLA_QUE_PAGE * rsp->id);
3667
3668 mcp->mb[4] = rsp->id;
3669 /* que in ptr index */
3670 mcp->mb[8] = 0;
3671 /* que out ptr index */
3672 mcp->mb[9] = 0;
Anirban Chakraborty2afa19a2009-04-06 22:33:40 -07003673 mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003674 |MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3675 mcp->in_mb = MBX_0;
3676 mcp->flags = MBX_DMA_OUT;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003677 mcp->tov = MBX_TOV_SECONDS * 2;
3678
3679 if (IS_QLA81XX(ha)) {
3680 mcp->out_mb |= MBX_12|MBX_11|MBX_10;
3681 mcp->in_mb |= MBX_1;
3682 } else if (IS_QLA83XX(ha)) {
3683 mcp->out_mb |= MBX_15|MBX_12|MBX_11|MBX_10;
3684 mcp->in_mb |= MBX_1;
3685 /* debug q create issue in SR-IOV */
3686 mcp->in_mb |= MBX_9 | MBX_8 | MBX_7;
3687 }
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003688
3689 spin_lock_irqsave(&ha->hardware_lock, flags);
Anirban Chakraborty618a7522009-02-08 20:50:11 -08003690 if (!(rsp->options & BIT_0)) {
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003691 WRT_REG_DWORD(&reg->rsp_q_out, 0);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003692 if (!IS_QLA83XX(ha))
3693 WRT_REG_DWORD(&reg->rsp_q_in, 0);
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003694 }
3695
3696 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3697
Anirban Chakraborty17d98632008-12-18 10:06:15 -08003698 rval = qla2x00_mailbox_command(vha, mcp);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003699 if (rval != QLA_SUCCESS) {
3700 ql_dbg(ql_dbg_mbx, vha, 0x10d7,
3701 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
3702 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003703 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8,
3704 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003705 }
3706
Anirban Chakraborty73208df2008-12-09 16:45:39 -08003707 return rval;
3708}
3709
Andrew Vasquez8a659572009-02-08 20:50:12 -08003710int
3711qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
3712{
3713 int rval;
3714 mbx_cmd_t mc;
3715 mbx_cmd_t *mcp = &mc;
3716
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003717 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9,
3718 "Entered %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003719
3720 mcp->mb[0] = MBC_IDC_ACK;
3721 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
3722 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3723 mcp->in_mb = MBX_0;
3724 mcp->tov = MBX_TOV_SECONDS;
3725 mcp->flags = 0;
3726 rval = qla2x00_mailbox_command(vha, mcp);
3727
3728 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003729 ql_dbg(ql_dbg_mbx, vha, 0x10da,
3730 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003731 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003732 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db,
3733 "Done %s.\n", __func__);
Andrew Vasquez8a659572009-02-08 20:50:12 -08003734 }
3735
3736 return rval;
3737}
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003738
3739int
3740qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
3741{
3742 int rval;
3743 mbx_cmd_t mc;
3744 mbx_cmd_t *mcp = &mc;
3745
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003746 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc,
3747 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003748
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003749 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003750 return QLA_FUNCTION_FAILED;
3751
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003752 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3753 mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
3754 mcp->out_mb = MBX_1|MBX_0;
3755 mcp->in_mb = MBX_1|MBX_0;
3756 mcp->tov = MBX_TOV_SECONDS;
3757 mcp->flags = 0;
3758 rval = qla2x00_mailbox_command(vha, mcp);
3759
3760 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003761 ql_dbg(ql_dbg_mbx, vha, 0x10dd,
3762 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3763 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003764 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003765 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de,
3766 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003767 *sector_size = mcp->mb[1];
3768 }
3769
3770 return rval;
3771}
3772
3773int
3774qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
3775{
3776 int rval;
3777 mbx_cmd_t mc;
3778 mbx_cmd_t *mcp = &mc;
3779
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003780 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003781 return QLA_FUNCTION_FAILED;
3782
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003783 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df,
3784 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003785
3786 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3787 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
3788 FAC_OPT_CMD_WRITE_PROTECT;
3789 mcp->out_mb = MBX_1|MBX_0;
3790 mcp->in_mb = MBX_1|MBX_0;
3791 mcp->tov = MBX_TOV_SECONDS;
3792 mcp->flags = 0;
3793 rval = qla2x00_mailbox_command(vha, mcp);
3794
3795 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003796 ql_dbg(ql_dbg_mbx, vha, 0x10e0,
3797 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3798 rval, mcp->mb[0], mcp->mb[1]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003799 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003800 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1,
3801 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003802 }
3803
3804 return rval;
3805}
3806
3807int
3808qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
3809{
3810 int rval;
3811 mbx_cmd_t mc;
3812 mbx_cmd_t *mcp = &mc;
3813
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08003814 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw))
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003815 return QLA_FUNCTION_FAILED;
3816
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003817 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2,
3818 "Entered %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003819
3820 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
3821 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
3822 mcp->mb[2] = LSW(start);
3823 mcp->mb[3] = MSW(start);
3824 mcp->mb[4] = LSW(finish);
3825 mcp->mb[5] = MSW(finish);
3826 mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
3827 mcp->in_mb = MBX_2|MBX_1|MBX_0;
3828 mcp->tov = MBX_TOV_SECONDS;
3829 mcp->flags = 0;
3830 rval = qla2x00_mailbox_command(vha, mcp);
3831
3832 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003833 ql_dbg(ql_dbg_mbx, vha, 0x10e3,
3834 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
3835 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003836 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003837 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4,
3838 "Done %s.\n", __func__);
Joe Carnuccio1d2874d2009-03-24 09:08:06 -07003839 }
3840
3841 return rval;
3842}
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003843
3844int
3845qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
3846{
3847 int rval = 0;
3848 mbx_cmd_t mc;
3849 mbx_cmd_t *mcp = &mc;
3850
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003851 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5,
3852 "Entered %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003853
3854 mcp->mb[0] = MBC_RESTART_MPI_FW;
3855 mcp->out_mb = MBX_0;
3856 mcp->in_mb = MBX_0|MBX_1;
3857 mcp->tov = MBX_TOV_SECONDS;
3858 mcp->flags = 0;
3859 rval = qla2x00_mailbox_command(vha, mcp);
3860
3861 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003862 ql_dbg(ql_dbg_mbx, vha, 0x10e6,
3863 "Failed=%x mb[0]=%x mb[1]=%x.\n",
3864 rval, mcp->mb[0], mcp->mb[1]);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003865 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003866 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7,
3867 "Done %s.\n", __func__);
Lalit Chandivade6e181be2009-03-26 08:49:17 -07003868 }
3869
3870 return rval;
3871}
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003872
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05003873static int
3874qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp)
3875{
3876 int rval;
3877 mbx_cmd_t mc;
3878 mbx_cmd_t *mcp = &mc;
3879
3880 if (!IS_FWI2_CAPABLE(vha->hw))
3881 return QLA_FUNCTION_FAILED;
3882
3883 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1159,
3884 "Entered %s.\n", __func__);
3885
3886 mcp->mb[0] = MBC_GET_RNID_PARAMS;
3887 mcp->mb[1] = RNID_TYPE_ASIC_TEMP << 8;
3888 mcp->out_mb = MBX_1|MBX_0;
3889 mcp->in_mb = MBX_1|MBX_0;
3890 mcp->tov = MBX_TOV_SECONDS;
3891 mcp->flags = 0;
3892 rval = qla2x00_mailbox_command(vha, mcp);
3893 *temp = mcp->mb[1];
3894
3895 if (rval != QLA_SUCCESS) {
3896 ql_dbg(ql_dbg_mbx, vha, 0x115a,
3897 "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]);
3898 } else {
3899 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x115b,
3900 "Done %s.\n", __func__);
3901 }
3902
3903 return rval;
3904}
3905
Joe Carnuccio3a117112013-02-08 01:58:00 -05003906int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003907qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3908 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003909{
3910 int rval;
3911 mbx_cmd_t mc;
3912 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003913 struct qla_hw_data *ha = vha->hw;
3914
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003915 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8,
3916 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003917
Joe Carnuccio6766df92011-05-10 11:30:15 -07003918 if (!IS_FWI2_CAPABLE(ha))
3919 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003920
Joe Carnuccio6766df92011-05-10 11:30:15 -07003921 if (len == 1)
3922 opt |= BIT_0;
3923
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003924 mcp->mb[0] = MBC_READ_SFP;
3925 mcp->mb[1] = dev;
3926 mcp->mb[2] = MSW(sfp_dma);
3927 mcp->mb[3] = LSW(sfp_dma);
3928 mcp->mb[6] = MSW(MSD(sfp_dma));
3929 mcp->mb[7] = LSW(MSD(sfp_dma));
3930 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003931 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003932 mcp->mb[10] = opt;
3933 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 -07003934 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003935 mcp->tov = MBX_TOV_SECONDS;
3936 mcp->flags = 0;
3937 rval = qla2x00_mailbox_command(vha, mcp);
3938
3939 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003940 *sfp = mcp->mb[1];
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003941
3942 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003943 ql_dbg(ql_dbg_mbx, vha, 0x10e9,
3944 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003945 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003946 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea,
3947 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003948 }
3949
3950 return rval;
3951}
3952
3953int
Joe Carnuccio6766df92011-05-10 11:30:15 -07003954qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
3955 uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003956{
3957 int rval;
3958 mbx_cmd_t mc;
3959 mbx_cmd_t *mcp = &mc;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003960 struct qla_hw_data *ha = vha->hw;
3961
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003962 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb,
3963 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003964
Joe Carnuccio6766df92011-05-10 11:30:15 -07003965 if (!IS_FWI2_CAPABLE(ha))
3966 return QLA_FUNCTION_FAILED;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003967
Joe Carnuccio6766df92011-05-10 11:30:15 -07003968 if (len == 1)
3969 opt |= BIT_0;
3970
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003971 if (opt & BIT_0)
Joe Carnuccio6766df92011-05-10 11:30:15 -07003972 len = *sfp;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003973
3974 mcp->mb[0] = MBC_WRITE_SFP;
3975 mcp->mb[1] = dev;
3976 mcp->mb[2] = MSW(sfp_dma);
3977 mcp->mb[3] = LSW(sfp_dma);
3978 mcp->mb[6] = MSW(MSD(sfp_dma));
3979 mcp->mb[7] = LSW(MSD(sfp_dma));
3980 mcp->mb[8] = len;
Joe Carnuccio6766df92011-05-10 11:30:15 -07003981 mcp->mb[9] = off;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003982 mcp->mb[10] = opt;
3983 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 -07003984 mcp->in_mb = MBX_1|MBX_0;
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003985 mcp->tov = MBX_TOV_SECONDS;
3986 mcp->flags = 0;
3987 rval = qla2x00_mailbox_command(vha, mcp);
3988
3989 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07003990 ql_dbg(ql_dbg_mbx, vha, 0x10ec,
3991 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003992 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04003993 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed,
3994 "Done %s.\n", __func__);
Joe Carnuccioad0ecd62009-03-24 09:08:12 -07003995 }
3996
3997 return rval;
3998}
Andrew Vasquezce0423f2009-06-03 09:55:13 -07003999
4000int
4001qla2x00_get_xgmac_stats(scsi_qla_host_t *vha, dma_addr_t stats_dma,
4002 uint16_t size_in_bytes, uint16_t *actual_size)
4003{
4004 int rval;
4005 mbx_cmd_t mc;
4006 mbx_cmd_t *mcp = &mc;
4007
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004008 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee,
4009 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004010
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004011 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004012 return QLA_FUNCTION_FAILED;
4013
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004014 mcp->mb[0] = MBC_GET_XGMAC_STATS;
4015 mcp->mb[2] = MSW(stats_dma);
4016 mcp->mb[3] = LSW(stats_dma);
4017 mcp->mb[6] = MSW(MSD(stats_dma));
4018 mcp->mb[7] = LSW(MSD(stats_dma));
4019 mcp->mb[8] = size_in_bytes >> 2;
4020 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
4021 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4022 mcp->tov = MBX_TOV_SECONDS;
4023 mcp->flags = 0;
4024 rval = qla2x00_mailbox_command(vha, mcp);
4025
4026 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004027 ql_dbg(ql_dbg_mbx, vha, 0x10ef,
4028 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4029 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004030 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004031 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0,
4032 "Done %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004033
Andrew Vasquezce0423f2009-06-03 09:55:13 -07004034
4035 *actual_size = mcp->mb[2] << 2;
4036 }
4037
4038 return rval;
4039}
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004040
4041int
4042qla2x00_get_dcbx_params(scsi_qla_host_t *vha, dma_addr_t tlv_dma,
4043 uint16_t size)
4044{
4045 int rval;
4046 mbx_cmd_t mc;
4047 mbx_cmd_t *mcp = &mc;
4048
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004049 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1,
4050 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004051
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004052 if (!IS_CNA_CAPABLE(vha->hw))
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004053 return QLA_FUNCTION_FAILED;
4054
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004055 mcp->mb[0] = MBC_GET_DCBX_PARAMS;
4056 mcp->mb[1] = 0;
4057 mcp->mb[2] = MSW(tlv_dma);
4058 mcp->mb[3] = LSW(tlv_dma);
4059 mcp->mb[6] = MSW(MSD(tlv_dma));
4060 mcp->mb[7] = LSW(MSD(tlv_dma));
4061 mcp->mb[8] = size;
4062 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
4063 mcp->in_mb = MBX_2|MBX_1|MBX_0;
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, 0x10f2,
4070 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n",
4071 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004072 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004073 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3,
4074 "Done %s.\n", __func__);
Andrew Vasquez11bbc1d2009-06-03 09:55:14 -07004075 }
4076
4077 return rval;
4078}
Andrew Vasquez18e75552009-06-03 09:55:30 -07004079
4080int
4081qla2x00_read_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t *data)
4082{
4083 int rval;
4084 mbx_cmd_t mc;
4085 mbx_cmd_t *mcp = &mc;
4086
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004087 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4,
4088 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004089
Andrew Vasquez18e75552009-06-03 09:55:30 -07004090 if (!IS_FWI2_CAPABLE(vha->hw))
4091 return QLA_FUNCTION_FAILED;
4092
Andrew Vasquez18e75552009-06-03 09:55:30 -07004093 mcp->mb[0] = MBC_READ_RAM_EXTENDED;
4094 mcp->mb[1] = LSW(risc_addr);
4095 mcp->mb[8] = MSW(risc_addr);
4096 mcp->out_mb = MBX_8|MBX_1|MBX_0;
4097 mcp->in_mb = MBX_3|MBX_2|MBX_0;
4098 mcp->tov = 30;
4099 mcp->flags = 0;
4100 rval = qla2x00_mailbox_command(vha, mcp);
4101 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004102 ql_dbg(ql_dbg_mbx, vha, 0x10f5,
4103 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004104 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004105 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6,
4106 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004107 *data = mcp->mb[3] << 16 | mcp->mb[2];
4108 }
4109
4110 return rval;
4111}
4112
4113int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004114qla2x00_loopback_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4115 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004116{
4117 int rval;
4118 mbx_cmd_t mc;
4119 mbx_cmd_t *mcp = &mc;
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004120
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004121 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7,
4122 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004123
4124 memset(mcp->mb, 0 , sizeof(mcp->mb));
4125 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK;
4126 mcp->mb[1] = mreq->options | BIT_6; // BIT_6 specifies 64 bit addressing
4127
4128 /* transfer count */
4129 mcp->mb[10] = LSW(mreq->transfer_size);
4130 mcp->mb[11] = MSW(mreq->transfer_size);
4131
4132 /* send data address */
4133 mcp->mb[14] = LSW(mreq->send_dma);
4134 mcp->mb[15] = MSW(mreq->send_dma);
4135 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4136 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4137
Lucas De Marchi25985ed2011-03-30 22:57:33 -03004138 /* receive data address */
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004139 mcp->mb[16] = LSW(mreq->rcv_dma);
4140 mcp->mb[17] = MSW(mreq->rcv_dma);
4141 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4142 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4143
4144 /* Iteration count */
Joe Carnuccio1b98b422013-03-28 08:21:26 -04004145 mcp->mb[18] = LSW(mreq->iteration_count);
4146 mcp->mb[19] = MSW(mreq->iteration_count);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004147
4148 mcp->out_mb = MBX_21|MBX_20|MBX_19|MBX_18|MBX_17|MBX_16|MBX_15|
4149 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 -08004150 if (IS_CNA_CAPABLE(vha->hw))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004151 mcp->out_mb |= MBX_2;
4152 mcp->in_mb = MBX_19|MBX_18|MBX_3|MBX_2|MBX_1|MBX_0;
4153
4154 mcp->buf_size = mreq->transfer_size;
4155 mcp->tov = MBX_TOV_SECONDS;
4156 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4157
4158 rval = qla2x00_mailbox_command(vha, mcp);
4159
4160 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004161 ql_dbg(ql_dbg_mbx, vha, 0x10f8,
4162 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[18]=%x "
4163 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2],
4164 mcp->mb[3], mcp->mb[18], mcp->mb[19]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004165 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004166 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9,
4167 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004168 }
4169
4170 /* Copy mailbox information */
4171 memcpy( mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004172 return rval;
4173}
4174
4175int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004176qla2x00_echo_test(scsi_qla_host_t *vha, struct msg_echo_lb *mreq,
4177 uint16_t *mresp)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004178{
4179 int rval;
4180 mbx_cmd_t mc;
4181 mbx_cmd_t *mcp = &mc;
4182 struct qla_hw_data *ha = vha->hw;
4183
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004184 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa,
4185 "Entered %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004186
4187 memset(mcp->mb, 0 , sizeof(mcp->mb));
4188 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO;
4189 mcp->mb[1] = mreq->options | BIT_6; /* BIT_6 specifies 64bit address */
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004190 if (IS_CNA_CAPABLE(ha)) {
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004191 mcp->mb[1] |= BIT_15;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004192 mcp->mb[2] = vha->fcoe_fcf_idx;
4193 }
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004194 mcp->mb[16] = LSW(mreq->rcv_dma);
4195 mcp->mb[17] = MSW(mreq->rcv_dma);
4196 mcp->mb[6] = LSW(MSD(mreq->rcv_dma));
4197 mcp->mb[7] = MSW(MSD(mreq->rcv_dma));
4198
4199 mcp->mb[10] = LSW(mreq->transfer_size);
4200
4201 mcp->mb[14] = LSW(mreq->send_dma);
4202 mcp->mb[15] = MSW(mreq->send_dma);
4203 mcp->mb[20] = LSW(MSD(mreq->send_dma));
4204 mcp->mb[21] = MSW(MSD(mreq->send_dma));
4205
4206 mcp->out_mb = MBX_21|MBX_20|MBX_17|MBX_16|MBX_15|
4207 MBX_14|MBX_10|MBX_7|MBX_6|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004208 if (IS_CNA_CAPABLE(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004209 mcp->out_mb |= MBX_2;
4210
4211 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004212 if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
4213 IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004214 mcp->in_mb |= MBX_1;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004215 if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha))
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004216 mcp->in_mb |= MBX_3;
4217
4218 mcp->tov = MBX_TOV_SECONDS;
4219 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4220 mcp->buf_size = mreq->transfer_size;
4221
4222 rval = qla2x00_mailbox_command(vha, mcp);
4223
4224 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004225 ql_dbg(ql_dbg_mbx, vha, 0x10fb,
4226 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4227 rval, mcp->mb[0], mcp->mb[1]);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004228 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004229 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc,
4230 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004231 }
4232
4233 /* Copy mailbox information */
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07004234 memcpy(mresp, mcp->mb, 64);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004235 return rval;
4236}
Giridhar Malavali6dbdda42010-09-03 15:20:49 -07004237
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004238int
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004239qla84xx_reset_chip(scsi_qla_host_t *vha, uint16_t enable_diagnostic)
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004240{
4241 int rval;
4242 mbx_cmd_t mc;
4243 mbx_cmd_t *mcp = &mc;
4244
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004245 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd,
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004246 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004247
4248 mcp->mb[0] = MBC_ISP84XX_RESET;
4249 mcp->mb[1] = enable_diagnostic;
4250 mcp->out_mb = MBX_1|MBX_0;
4251 mcp->in_mb = MBX_1|MBX_0;
4252 mcp->tov = MBX_TOV_SECONDS;
4253 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004254 rval = qla2x00_mailbox_command(vha, mcp);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004255
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004256 if (rval != QLA_SUCCESS)
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004257 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004258 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004259 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff,
4260 "Done %s.\n", __func__);
Giridhar Malavali9a069e12010-01-12 13:02:47 -08004261
4262 return rval;
4263}
4264
4265int
Andrew Vasquez18e75552009-06-03 09:55:30 -07004266qla2x00_write_ram_word(scsi_qla_host_t *vha, uint32_t risc_addr, uint32_t data)
4267{
4268 int rval;
4269 mbx_cmd_t mc;
4270 mbx_cmd_t *mcp = &mc;
4271
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004272 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100,
4273 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004274
Andrew Vasquez18e75552009-06-03 09:55:30 -07004275 if (!IS_FWI2_CAPABLE(vha->hw))
Andrew Vasquez6c452a42010-03-19 17:04:02 -07004276 return QLA_FUNCTION_FAILED;
Andrew Vasquez18e75552009-06-03 09:55:30 -07004277
Andrew Vasquez18e75552009-06-03 09:55:30 -07004278 mcp->mb[0] = MBC_WRITE_RAM_WORD_EXTENDED;
4279 mcp->mb[1] = LSW(risc_addr);
4280 mcp->mb[2] = LSW(data);
4281 mcp->mb[3] = MSW(data);
4282 mcp->mb[8] = MSW(risc_addr);
4283 mcp->out_mb = MBX_8|MBX_3|MBX_2|MBX_1|MBX_0;
4284 mcp->in_mb = MBX_0;
4285 mcp->tov = 30;
4286 mcp->flags = 0;
4287 rval = qla2x00_mailbox_command(vha, mcp);
4288 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004289 ql_dbg(ql_dbg_mbx, vha, 0x1101,
4290 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004291 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004292 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102,
4293 "Done %s.\n", __func__);
Andrew Vasquez18e75552009-06-03 09:55:30 -07004294 }
4295
4296 return rval;
4297}
Michael Hernandez3064ff32009-12-15 21:29:44 -08004298
4299int
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004300qla81xx_write_mpi_register(scsi_qla_host_t *vha, uint16_t *mb)
4301{
4302 int rval;
4303 uint32_t stat, timer;
4304 uint16_t mb0 = 0;
4305 struct qla_hw_data *ha = vha->hw;
4306 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
4307
4308 rval = QLA_SUCCESS;
4309
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004310 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103,
4311 "Entered %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004312
4313 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
4314
4315 /* Write the MBC data to the registers */
4316 WRT_REG_WORD(&reg->mailbox0, MBC_WRITE_MPI_REGISTER);
4317 WRT_REG_WORD(&reg->mailbox1, mb[0]);
4318 WRT_REG_WORD(&reg->mailbox2, mb[1]);
4319 WRT_REG_WORD(&reg->mailbox3, mb[2]);
4320 WRT_REG_WORD(&reg->mailbox4, mb[3]);
4321
4322 WRT_REG_DWORD(&reg->hccr, HCCRX_SET_HOST_INT);
4323
4324 /* Poll for MBC interrupt */
4325 for (timer = 6000000; timer; timer--) {
4326 /* Check for pending interrupts. */
4327 stat = RD_REG_DWORD(&reg->host_status);
4328 if (stat & HSRX_RISC_INT) {
4329 stat &= 0xff;
4330
4331 if (stat == 0x1 || stat == 0x2 ||
4332 stat == 0x10 || stat == 0x11) {
4333 set_bit(MBX_INTERRUPT,
4334 &ha->mbx_cmd_flags);
4335 mb0 = RD_REG_WORD(&reg->mailbox0);
4336 WRT_REG_DWORD(&reg->hccr,
4337 HCCRX_CLR_RISC_INT);
4338 RD_REG_DWORD(&reg->hccr);
4339 break;
4340 }
4341 }
4342 udelay(5);
4343 }
4344
4345 if (test_and_clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags))
4346 rval = mb0 & MBS_MASK;
4347 else
4348 rval = QLA_FUNCTION_FAILED;
4349
4350 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004351 ql_dbg(ql_dbg_mbx, vha, 0x1104,
4352 "Failed=%x mb[0]=%x.\n", rval, mb[0]);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004353 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004354 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105,
4355 "Done %s.\n", __func__);
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004356 }
4357
4358 return rval;
4359}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004360
Madhuranath Iyengarb1d46982010-09-03 15:20:54 -07004361int
Michael Hernandez3064ff32009-12-15 21:29:44 -08004362qla2x00_get_data_rate(scsi_qla_host_t *vha)
4363{
4364 int rval;
4365 mbx_cmd_t mc;
4366 mbx_cmd_t *mcp = &mc;
4367 struct qla_hw_data *ha = vha->hw;
4368
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004369 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106,
4370 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004371
Michael Hernandez3064ff32009-12-15 21:29:44 -08004372 if (!IS_FWI2_CAPABLE(ha))
4373 return QLA_FUNCTION_FAILED;
4374
Michael Hernandez3064ff32009-12-15 21:29:44 -08004375 mcp->mb[0] = MBC_DATA_RATE;
4376 mcp->mb[1] = 0;
4377 mcp->out_mb = MBX_1|MBX_0;
4378 mcp->in_mb = MBX_2|MBX_1|MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004379 if (IS_QLA83XX(ha))
4380 mcp->in_mb |= MBX_3;
Michael Hernandez3064ff32009-12-15 21:29:44 -08004381 mcp->tov = MBX_TOV_SECONDS;
4382 mcp->flags = 0;
4383 rval = qla2x00_mailbox_command(vha, mcp);
4384 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004385 ql_dbg(ql_dbg_mbx, vha, 0x1107,
4386 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004387 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004388 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
4389 "Done %s.\n", __func__);
Michael Hernandez3064ff32009-12-15 21:29:44 -08004390 if (mcp->mb[1] != 0x7)
4391 ha->link_data_rate = mcp->mb[1];
4392 }
4393
4394 return rval;
4395}
Sarang Radke09ff7012010-03-19 17:03:59 -07004396
4397int
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004398qla81xx_get_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4399{
4400 int rval;
4401 mbx_cmd_t mc;
4402 mbx_cmd_t *mcp = &mc;
4403 struct qla_hw_data *ha = vha->hw;
4404
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004405 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109,
4406 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004407
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004408 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004409 return QLA_FUNCTION_FAILED;
4410 mcp->mb[0] = MBC_GET_PORT_CONFIG;
4411 mcp->out_mb = MBX_0;
4412 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4413 mcp->tov = MBX_TOV_SECONDS;
4414 mcp->flags = 0;
4415
4416 rval = qla2x00_mailbox_command(vha, mcp);
4417
4418 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004419 ql_dbg(ql_dbg_mbx, vha, 0x110a,
4420 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004421 } else {
4422 /* Copy all bits to preserve original value */
4423 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4);
4424
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004425 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b,
4426 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004427 }
4428 return rval;
4429}
4430
4431int
4432qla81xx_set_port_config(scsi_qla_host_t *vha, uint16_t *mb)
4433{
4434 int rval;
4435 mbx_cmd_t mc;
4436 mbx_cmd_t *mcp = &mc;
4437
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004438 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c,
4439 "Entered %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004440
4441 mcp->mb[0] = MBC_SET_PORT_CONFIG;
4442 /* Copy all bits to preserve original setting */
4443 memcpy(&mcp->mb[1], mb, sizeof(uint16_t) * 4);
4444 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4445 mcp->in_mb = MBX_0;
4446 mcp->tov = MBX_TOV_SECONDS;
4447 mcp->flags = 0;
4448 rval = qla2x00_mailbox_command(vha, mcp);
4449
4450 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004451 ql_dbg(ql_dbg_mbx, vha, 0x110d,
4452 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004453 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004454 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e,
4455 "Done %s.\n", __func__);
Sarang Radke23f2ebd2010-05-28 15:08:21 -07004456
4457 return rval;
4458}
4459
4460
4461int
Sarang Radke09ff7012010-03-19 17:03:59 -07004462qla24xx_set_fcp_prio(scsi_qla_host_t *vha, uint16_t loop_id, uint16_t priority,
4463 uint16_t *mb)
4464{
4465 int rval;
4466 mbx_cmd_t mc;
4467 mbx_cmd_t *mcp = &mc;
4468 struct qla_hw_data *ha = vha->hw;
4469
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004470 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f,
4471 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004472
Sarang Radke09ff7012010-03-19 17:03:59 -07004473 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha))
4474 return QLA_FUNCTION_FAILED;
4475
Sarang Radke09ff7012010-03-19 17:03:59 -07004476 mcp->mb[0] = MBC_PORT_PARAMS;
4477 mcp->mb[1] = loop_id;
4478 if (ha->flags.fcp_prio_enabled)
4479 mcp->mb[2] = BIT_1;
4480 else
4481 mcp->mb[2] = BIT_2;
4482 mcp->mb[4] = priority & 0xf;
4483 mcp->mb[9] = vha->vp_idx;
4484 mcp->out_mb = MBX_9|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4485 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4486 mcp->tov = 30;
4487 mcp->flags = 0;
4488 rval = qla2x00_mailbox_command(vha, mcp);
4489 if (mb != NULL) {
4490 mb[0] = mcp->mb[0];
4491 mb[1] = mcp->mb[1];
4492 mb[3] = mcp->mb[3];
4493 mb[4] = mcp->mb[4];
4494 }
4495
4496 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004497 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval);
Sarang Radke09ff7012010-03-19 17:03:59 -07004498 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004499 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc,
4500 "Done %s.\n", __func__);
Sarang Radke09ff7012010-03-19 17:03:59 -07004501 }
4502
4503 return rval;
4504}
Giridhar Malavalia9083012010-04-12 17:59:55 -07004505
4506int
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004507qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp)
Andrew Vasquez794a5692010-12-21 16:00:21 -08004508{
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004509 int rval = QLA_FUNCTION_FAILED;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004510 struct qla_hw_data *ha = vha->hw;
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004511 uint8_t byte;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004512
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004513 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ca,
4514 "Entered %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004515
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004516 if (ha->thermal_support & THERMAL_SUPPORT_I2C) {
4517 rval = qla2x00_read_sfp(vha, 0, &byte,
4518 0x98, 0x1, 1, BIT_13|BIT_12|BIT_0);
4519 *temp = byte;
4520 if (rval == QLA_SUCCESS)
4521 goto done;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004522
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004523 ql_log(ql_log_warn, vha, 0x10c9,
Joe Carnuccio490b7732013-03-28 08:21:25 -04004524 "Thermal not supported through I2C bus, trying alternate "
4525 "method (ISP access).\n");
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004526 ha->thermal_support &= ~THERMAL_SUPPORT_I2C;
Andrew Vasquez794a5692010-12-21 16:00:21 -08004527 }
Andrew Vasquez794a5692010-12-21 16:00:21 -08004528
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004529 if (ha->thermal_support & THERMAL_SUPPORT_ISP) {
4530 rval = qla2x00_read_asic_temperature(vha, temp);
4531 if (rval == QLA_SUCCESS)
4532 goto done;
4533
4534 ql_log(ql_log_warn, vha, 0x1019,
Joe Carnuccio490b7732013-03-28 08:21:25 -04004535 "Thermal not supported through ISP.\n");
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004536 ha->thermal_support &= ~THERMAL_SUPPORT_ISP;
4537 }
4538
Joe Carnuccio37f489b2013-02-08 01:57:45 -05004539 ql_log(ql_log_warn, vha, 0x1150,
4540 "Thermal not supported by this card "
4541 "(ignoring further requests).\n");
Joe Carnucciofe52f6e2013-02-08 01:58:03 -05004542 return rval;
4543
4544done:
4545 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1018,
4546 "Done %s.\n", __func__);
Andrew Vasquez794a5692010-12-21 16:00:21 -08004547 return rval;
4548}
4549
4550int
Giridhar Malavalia9083012010-04-12 17:59:55 -07004551qla82xx_mbx_intr_enable(scsi_qla_host_t *vha)
4552{
4553 int rval;
4554 struct qla_hw_data *ha = vha->hw;
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, 0x1017,
4559 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004560
Giridhar Malavalia9083012010-04-12 17:59:55 -07004561 if (!IS_FWI2_CAPABLE(ha))
4562 return QLA_FUNCTION_FAILED;
4563
Giridhar Malavalia9083012010-04-12 17:59:55 -07004564 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004565 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004566 mcp->mb[1] = 1;
4567
4568 mcp->out_mb = MBX_1|MBX_0;
4569 mcp->in_mb = MBX_0;
4570 mcp->tov = 30;
4571 mcp->flags = 0;
4572
4573 rval = qla2x00_mailbox_command(vha, mcp);
4574 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004575 ql_dbg(ql_dbg_mbx, vha, 0x1016,
4576 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004577 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004578 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e,
4579 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004580 }
4581
4582 return rval;
4583}
4584
4585int
4586qla82xx_mbx_intr_disable(scsi_qla_host_t *vha)
4587{
4588 int rval;
4589 struct qla_hw_data *ha = vha->hw;
4590 mbx_cmd_t mc;
4591 mbx_cmd_t *mcp = &mc;
4592
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004593 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d,
4594 "Entered %s.\n", __func__);
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004595
Giridhar Malavalia9083012010-04-12 17:59:55 -07004596 if (!IS_QLA82XX(ha))
4597 return QLA_FUNCTION_FAILED;
4598
Giridhar Malavalia9083012010-04-12 17:59:55 -07004599 memset(mcp, 0, sizeof(mbx_cmd_t));
Giridhar Malavali37113332010-07-23 15:28:34 +05004600 mcp->mb[0] = MBC_TOGGLE_INTERRUPT;
Giridhar Malavalia9083012010-04-12 17:59:55 -07004601 mcp->mb[1] = 0;
4602
4603 mcp->out_mb = MBX_1|MBX_0;
4604 mcp->in_mb = MBX_0;
4605 mcp->tov = 30;
4606 mcp->flags = 0;
4607
4608 rval = qla2x00_mailbox_command(vha, mcp);
4609 if (rval != QLA_SUCCESS) {
Saurav Kashyap7c3df132011-07-14 12:00:13 -07004610 ql_dbg(ql_dbg_mbx, vha, 0x100c,
4611 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004612 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004613 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b,
4614 "Done %s.\n", __func__);
Giridhar Malavalia9083012010-04-12 17:59:55 -07004615 }
4616
4617 return rval;
4618}
Giridhar Malavali08de2842011-08-16 11:31:44 -07004619
4620int
4621qla82xx_md_get_template_size(scsi_qla_host_t *vha)
4622{
4623 struct qla_hw_data *ha = vha->hw;
4624 mbx_cmd_t mc;
4625 mbx_cmd_t *mcp = &mc;
4626 int rval = QLA_FUNCTION_FAILED;
4627
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004628 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f,
4629 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004630
4631 memset(mcp->mb, 0 , sizeof(mcp->mb));
4632 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4633 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4634 mcp->mb[2] = LSW(RQST_TMPLT_SIZE);
4635 mcp->mb[3] = MSW(RQST_TMPLT_SIZE);
4636
4637 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4638 mcp->in_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|
4639 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4640
4641 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4642 mcp->tov = MBX_TOV_SECONDS;
4643 rval = qla2x00_mailbox_command(vha, mcp);
4644
4645 /* Always copy back return mailbox values. */
4646 if (rval != QLA_SUCCESS) {
4647 ql_dbg(ql_dbg_mbx, vha, 0x1120,
4648 "mailbox command FAILED=0x%x, subcode=%x.\n",
4649 (mcp->mb[1] << 16) | mcp->mb[0],
4650 (mcp->mb[3] << 16) | mcp->mb[2]);
4651 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004652 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121,
4653 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004654 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]);
4655 if (!ha->md_template_size) {
4656 ql_dbg(ql_dbg_mbx, vha, 0x1122,
4657 "Null template size obtained.\n");
4658 rval = QLA_FUNCTION_FAILED;
4659 }
4660 }
4661 return rval;
4662}
4663
4664int
4665qla82xx_md_get_template(scsi_qla_host_t *vha)
4666{
4667 struct qla_hw_data *ha = vha->hw;
4668 mbx_cmd_t mc;
4669 mbx_cmd_t *mcp = &mc;
4670 int rval = QLA_FUNCTION_FAILED;
4671
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004672 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123,
4673 "Entered %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004674
4675 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev,
4676 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL);
4677 if (!ha->md_tmplt_hdr) {
4678 ql_log(ql_log_warn, vha, 0x1124,
4679 "Unable to allocate memory for Minidump template.\n");
4680 return rval;
4681 }
4682
4683 memset(mcp->mb, 0 , sizeof(mcp->mb));
4684 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4685 mcp->mb[1] = MSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE);
4686 mcp->mb[2] = LSW(RQST_TMPLT);
4687 mcp->mb[3] = MSW(RQST_TMPLT);
4688 mcp->mb[4] = LSW(LSD(ha->md_tmplt_hdr_dma));
4689 mcp->mb[5] = MSW(LSD(ha->md_tmplt_hdr_dma));
4690 mcp->mb[6] = LSW(MSD(ha->md_tmplt_hdr_dma));
4691 mcp->mb[7] = MSW(MSD(ha->md_tmplt_hdr_dma));
4692 mcp->mb[8] = LSW(ha->md_template_size);
4693 mcp->mb[9] = MSW(ha->md_template_size);
4694
4695 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN|IOCTL_CMD;
4696 mcp->tov = MBX_TOV_SECONDS;
4697 mcp->out_mb = MBX_11|MBX_10|MBX_9|MBX_8|
4698 MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4699 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
4700 rval = qla2x00_mailbox_command(vha, mcp);
4701
4702 if (rval != QLA_SUCCESS) {
4703 ql_dbg(ql_dbg_mbx, vha, 0x1125,
4704 "mailbox command FAILED=0x%x, subcode=%x.\n",
4705 ((mcp->mb[1] << 16) | mcp->mb[0]),
4706 ((mcp->mb[3] << 16) | mcp->mb[2]));
4707 } else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004708 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126,
4709 "Done %s.\n", __func__);
Giridhar Malavali08de2842011-08-16 11:31:44 -07004710 return rval;
4711}
Saurav Kashyap999916d2011-08-16 11:31:45 -07004712
4713int
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004714qla81xx_set_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4715{
4716 int rval;
4717 struct qla_hw_data *ha = vha->hw;
4718 mbx_cmd_t mc;
4719 mbx_cmd_t *mcp = &mc;
4720
4721 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4722 return QLA_FUNCTION_FAILED;
4723
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004724 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133,
4725 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004726
4727 memset(mcp, 0, sizeof(mbx_cmd_t));
4728 mcp->mb[0] = MBC_SET_LED_CONFIG;
4729 mcp->mb[1] = led_cfg[0];
4730 mcp->mb[2] = led_cfg[1];
4731 if (IS_QLA8031(ha)) {
4732 mcp->mb[3] = led_cfg[2];
4733 mcp->mb[4] = led_cfg[3];
4734 mcp->mb[5] = led_cfg[4];
4735 mcp->mb[6] = led_cfg[5];
4736 }
4737
4738 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4739 if (IS_QLA8031(ha))
4740 mcp->out_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4741 mcp->in_mb = MBX_0;
4742 mcp->tov = 30;
4743 mcp->flags = 0;
4744
4745 rval = qla2x00_mailbox_command(vha, mcp);
4746 if (rval != QLA_SUCCESS) {
4747 ql_dbg(ql_dbg_mbx, vha, 0x1134,
4748 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4749 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004750 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135,
4751 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004752 }
4753
4754 return rval;
4755}
4756
4757int
4758qla81xx_get_led_config(scsi_qla_host_t *vha, uint16_t *led_cfg)
4759{
4760 int rval;
4761 struct qla_hw_data *ha = vha->hw;
4762 mbx_cmd_t mc;
4763 mbx_cmd_t *mcp = &mc;
4764
4765 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha))
4766 return QLA_FUNCTION_FAILED;
4767
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004768 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136,
4769 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004770
4771 memset(mcp, 0, sizeof(mbx_cmd_t));
4772 mcp->mb[0] = MBC_GET_LED_CONFIG;
4773
4774 mcp->out_mb = MBX_0;
4775 mcp->in_mb = MBX_2|MBX_1|MBX_0;
4776 if (IS_QLA8031(ha))
4777 mcp->in_mb |= MBX_6|MBX_5|MBX_4|MBX_3;
4778 mcp->tov = 30;
4779 mcp->flags = 0;
4780
4781 rval = qla2x00_mailbox_command(vha, mcp);
4782 if (rval != QLA_SUCCESS) {
4783 ql_dbg(ql_dbg_mbx, vha, 0x1137,
4784 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4785 } else {
4786 led_cfg[0] = mcp->mb[1];
4787 led_cfg[1] = mcp->mb[2];
4788 if (IS_QLA8031(ha)) {
4789 led_cfg[2] = mcp->mb[3];
4790 led_cfg[3] = mcp->mb[4];
4791 led_cfg[4] = mcp->mb[5];
4792 led_cfg[5] = mcp->mb[6];
4793 }
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004794 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138,
4795 "Done %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004796 }
4797
4798 return rval;
4799}
4800
4801int
Saurav Kashyap999916d2011-08-16 11:31:45 -07004802qla82xx_mbx_beacon_ctl(scsi_qla_host_t *vha, int enable)
4803{
4804 int rval;
4805 struct qla_hw_data *ha = vha->hw;
4806 mbx_cmd_t mc;
4807 mbx_cmd_t *mcp = &mc;
4808
4809 if (!IS_QLA82XX(ha))
4810 return QLA_FUNCTION_FAILED;
4811
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004812 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127,
Saurav Kashyap999916d2011-08-16 11:31:45 -07004813 "Entered %s.\n", __func__);
4814
4815 memset(mcp, 0, sizeof(mbx_cmd_t));
4816 mcp->mb[0] = MBC_SET_LED_CONFIG;
4817 if (enable)
4818 mcp->mb[7] = 0xE;
4819 else
4820 mcp->mb[7] = 0xD;
4821
4822 mcp->out_mb = MBX_7|MBX_0;
4823 mcp->in_mb = MBX_0;
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004824 mcp->tov = MBX_TOV_SECONDS;
Saurav Kashyap999916d2011-08-16 11:31:45 -07004825 mcp->flags = 0;
4826
4827 rval = qla2x00_mailbox_command(vha, mcp);
4828 if (rval != QLA_SUCCESS) {
4829 ql_dbg(ql_dbg_mbx, vha, 0x1128,
4830 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4831 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004832 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129,
Saurav Kashyap999916d2011-08-16 11:31:45 -07004833 "Done %s.\n", __func__);
4834 }
4835
4836 return rval;
4837}
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004838
4839int
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04004840qla83xx_wr_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t data)
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004841{
4842 int rval;
4843 struct qla_hw_data *ha = vha->hw;
4844 mbx_cmd_t mc;
4845 mbx_cmd_t *mcp = &mc;
4846
4847 if (!IS_QLA83XX(ha))
4848 return QLA_FUNCTION_FAILED;
4849
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004850 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130,
4851 "Entered %s.\n", __func__);
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004852
4853 mcp->mb[0] = MBC_WRITE_REMOTE_REG;
4854 mcp->mb[1] = LSW(reg);
4855 mcp->mb[2] = MSW(reg);
4856 mcp->mb[3] = LSW(data);
4857 mcp->mb[4] = MSW(data);
4858 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
4859
4860 mcp->in_mb = MBX_1|MBX_0;
4861 mcp->tov = MBX_TOV_SECONDS;
4862 mcp->flags = 0;
4863 rval = qla2x00_mailbox_command(vha, mcp);
4864
4865 if (rval != QLA_SUCCESS) {
4866 ql_dbg(ql_dbg_mbx, vha, 0x1131,
4867 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4868 } else {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004869 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132,
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004870 "Done %s.\n", __func__);
4871 }
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004872
Giridhar Malavali6246b8a2012-02-09 11:15:34 -08004873 return rval;
4874}
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004875
4876int
4877qla2x00_port_logout(scsi_qla_host_t *vha, struct fc_port *fcport)
4878{
4879 int rval;
4880 struct qla_hw_data *ha = vha->hw;
4881 mbx_cmd_t mc;
4882 mbx_cmd_t *mcp = &mc;
4883
4884 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004885 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b,
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004886 "Implicit LOGO Unsupported.\n");
4887 return QLA_FUNCTION_FAILED;
4888 }
4889
4890
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004891 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c,
4892 "Entering %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004893
4894 /* Perform Implicit LOGO. */
4895 mcp->mb[0] = MBC_PORT_LOGOUT;
4896 mcp->mb[1] = fcport->loop_id;
4897 mcp->mb[10] = BIT_15;
4898 mcp->out_mb = MBX_10|MBX_1|MBX_0;
4899 mcp->in_mb = MBX_0;
4900 mcp->tov = MBX_TOV_SECONDS;
4901 mcp->flags = 0;
4902 rval = qla2x00_mailbox_command(vha, mcp);
4903 if (rval != QLA_SUCCESS)
4904 ql_dbg(ql_dbg_mbx, vha, 0x113d,
4905 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
4906 else
Saurav Kashyap5f28d2d2012-05-15 14:34:15 -04004907 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e,
4908 "Done %s.\n", __func__);
Andrew Vasquezaf11f642012-02-09 11:15:43 -08004909
4910 return rval;
4911}
4912
Santosh Vernekar7d613ac2012-08-22 14:21:03 -04004913int
4914qla83xx_rd_reg(scsi_qla_host_t *vha, uint32_t reg, uint32_t *data)
4915{
4916 int rval;
4917 mbx_cmd_t mc;
4918 mbx_cmd_t *mcp = &mc;
4919 struct qla_hw_data *ha = vha->hw;
4920 unsigned long retry_max_time = jiffies + (2 * HZ);
4921
4922 if (!IS_QLA83XX(ha))
4923 return QLA_FUNCTION_FAILED;
4924
4925 ql_dbg(ql_dbg_mbx, vha, 0x114b, "Entered %s.\n", __func__);
4926
4927retry_rd_reg:
4928 mcp->mb[0] = MBC_READ_REMOTE_REG;
4929 mcp->mb[1] = LSW(reg);
4930 mcp->mb[2] = MSW(reg);
4931 mcp->out_mb = MBX_2|MBX_1|MBX_0;
4932 mcp->in_mb = MBX_4|MBX_3|MBX_1|MBX_0;
4933 mcp->tov = MBX_TOV_SECONDS;
4934 mcp->flags = 0;
4935 rval = qla2x00_mailbox_command(vha, mcp);
4936
4937 if (rval != QLA_SUCCESS) {
4938 ql_dbg(ql_dbg_mbx, vha, 0x114c,
4939 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4940 rval, mcp->mb[0], mcp->mb[1]);
4941 } else {
4942 *data = (mcp->mb[3] | (mcp->mb[4] << 16));
4943 if (*data == QLA8XXX_BAD_VALUE) {
4944 /*
4945 * During soft-reset CAMRAM register reads might
4946 * return 0xbad0bad0. So retry for MAX of 2 sec
4947 * while reading camram registers.
4948 */
4949 if (time_after(jiffies, retry_max_time)) {
4950 ql_dbg(ql_dbg_mbx, vha, 0x1141,
4951 "Failure to read CAMRAM register. "
4952 "data=0x%x.\n", *data);
4953 return QLA_FUNCTION_FAILED;
4954 }
4955 msleep(100);
4956 goto retry_rd_reg;
4957 }
4958 ql_dbg(ql_dbg_mbx, vha, 0x1142, "Done %s.\n", __func__);
4959 }
4960
4961 return rval;
4962}
4963
4964int
4965qla83xx_restart_nic_firmware(scsi_qla_host_t *vha)
4966{
4967 int rval;
4968 mbx_cmd_t mc;
4969 mbx_cmd_t *mcp = &mc;
4970 struct qla_hw_data *ha = vha->hw;
4971
4972 if (!IS_QLA83XX(ha))
4973 return QLA_FUNCTION_FAILED;
4974
4975 ql_dbg(ql_dbg_mbx, vha, 0x1143, "Entered %s.\n", __func__);
4976
4977 mcp->mb[0] = MBC_RESTART_NIC_FIRMWARE;
4978 mcp->out_mb = MBX_0;
4979 mcp->in_mb = MBX_1|MBX_0;
4980 mcp->tov = MBX_TOV_SECONDS;
4981 mcp->flags = 0;
4982 rval = qla2x00_mailbox_command(vha, mcp);
4983
4984 if (rval != QLA_SUCCESS) {
4985 ql_dbg(ql_dbg_mbx, vha, 0x1144,
4986 "Failed=%x mb[0]=%x mb[1]=%x.\n",
4987 rval, mcp->mb[0], mcp->mb[1]);
4988 ha->isp_ops->fw_dump(vha, 0);
4989 } else {
4990 ql_dbg(ql_dbg_mbx, vha, 0x1145, "Done %s.\n", __func__);
4991 }
4992
4993 return rval;
4994}
4995
4996int
4997qla83xx_access_control(scsi_qla_host_t *vha, uint16_t options,
4998 uint32_t start_addr, uint32_t end_addr, uint16_t *sector_size)
4999{
5000 int rval;
5001 mbx_cmd_t mc;
5002 mbx_cmd_t *mcp = &mc;
5003 uint8_t subcode = (uint8_t)options;
5004 struct qla_hw_data *ha = vha->hw;
5005
5006 if (!IS_QLA8031(ha))
5007 return QLA_FUNCTION_FAILED;
5008
5009 ql_dbg(ql_dbg_mbx, vha, 0x1146, "Entered %s.\n", __func__);
5010
5011 mcp->mb[0] = MBC_SET_ACCESS_CONTROL;
5012 mcp->mb[1] = options;
5013 mcp->out_mb = MBX_1|MBX_0;
5014 if (subcode & BIT_2) {
5015 mcp->mb[2] = LSW(start_addr);
5016 mcp->mb[3] = MSW(start_addr);
5017 mcp->mb[4] = LSW(end_addr);
5018 mcp->mb[5] = MSW(end_addr);
5019 mcp->out_mb |= MBX_5|MBX_4|MBX_3|MBX_2;
5020 }
5021 mcp->in_mb = MBX_2|MBX_1|MBX_0;
5022 if (!(subcode & (BIT_2 | BIT_5)))
5023 mcp->in_mb |= MBX_4|MBX_3;
5024 mcp->tov = MBX_TOV_SECONDS;
5025 mcp->flags = 0;
5026 rval = qla2x00_mailbox_command(vha, mcp);
5027
5028 if (rval != QLA_SUCCESS) {
5029 ql_dbg(ql_dbg_mbx, vha, 0x1147,
5030 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[3]=%x mb[4]=%x.\n",
5031 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3],
5032 mcp->mb[4]);
5033 ha->isp_ops->fw_dump(vha, 0);
5034 } else {
5035 if (subcode & BIT_5)
5036 *sector_size = mcp->mb[1];
5037 else if (subcode & (BIT_6 | BIT_7)) {
5038 ql_dbg(ql_dbg_mbx, vha, 0x1148,
5039 "Driver-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5040 } else if (subcode & (BIT_3 | BIT_4)) {
5041 ql_dbg(ql_dbg_mbx, vha, 0x1149,
5042 "Flash-lock id=%x%x", mcp->mb[4], mcp->mb[3]);
5043 }
5044 ql_dbg(ql_dbg_mbx, vha, 0x114a, "Done %s.\n", __func__);
5045 }
5046
5047 return rval;
5048}
Saurav Kashyap81178772012-08-22 14:21:04 -04005049
5050int
5051qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr,
5052 uint32_t size)
5053{
5054 int rval;
5055 mbx_cmd_t mc;
5056 mbx_cmd_t *mcp = &mc;
5057
5058 if (!IS_MCTP_CAPABLE(vha->hw))
5059 return QLA_FUNCTION_FAILED;
5060
5061 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114f,
5062 "Entered %s.\n", __func__);
5063
5064 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED;
5065 mcp->mb[1] = LSW(addr);
5066 mcp->mb[2] = MSW(req_dma);
5067 mcp->mb[3] = LSW(req_dma);
5068 mcp->mb[4] = MSW(size);
5069 mcp->mb[5] = LSW(size);
5070 mcp->mb[6] = MSW(MSD(req_dma));
5071 mcp->mb[7] = LSW(MSD(req_dma));
5072 mcp->mb[8] = MSW(addr);
5073 /* Setting RAM ID to valid */
5074 mcp->mb[10] |= BIT_7;
5075 /* For MCTP RAM ID is 0x40 */
5076 mcp->mb[10] |= 0x40;
5077
5078 mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|
5079 MBX_0;
5080
5081 mcp->in_mb = MBX_0;
5082 mcp->tov = MBX_TOV_SECONDS;
5083 mcp->flags = 0;
5084 rval = qla2x00_mailbox_command(vha, mcp);
5085
5086 if (rval != QLA_SUCCESS) {
5087 ql_dbg(ql_dbg_mbx, vha, 0x114e,
5088 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
5089 } else {
5090 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x114d,
5091 "Done %s.\n", __func__);
5092 }
5093
5094 return rval;
5095}