]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/scsi/qla4xxx/ql4_mbx.c
[SCSI] qla4xxx: Added support for ISP8042
[karo-tx-linux.git] / drivers / scsi / qla4xxx / ql4_mbx.c
1 /*
2  * QLogic iSCSI HBA Driver
3  * Copyright (c)  2003-2012 QLogic Corporation
4  *
5  * See LICENSE.qla4xxx for copyright and licensing details.
6  */
7
8 #include <linux/ctype.h>
9 #include "ql4_def.h"
10 #include "ql4_glbl.h"
11 #include "ql4_dbg.h"
12 #include "ql4_inline.h"
13 #include "ql4_version.h"
14
15 void qla4xxx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
16                             int in_count)
17 {
18         int i;
19
20         /* Load all mailbox registers, except mailbox 0. */
21         for (i = 1; i < in_count; i++)
22                 writel(mbx_cmd[i], &ha->reg->mailbox[i]);
23
24         /* Wakeup firmware  */
25         writel(mbx_cmd[0], &ha->reg->mailbox[0]);
26         readl(&ha->reg->mailbox[0]);
27         writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
28         readl(&ha->reg->ctrl_status);
29 }
30
31 void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)
32 {
33         int intr_status;
34
35         intr_status = readl(&ha->reg->ctrl_status);
36         if (intr_status & INTR_PENDING) {
37                 /*
38                  * Service the interrupt.
39                  * The ISR will save the mailbox status registers
40                  * to a temporary storage location in the adapter structure.
41                  */
42                 ha->mbox_status_count = out_count;
43                 ha->isp_ops->interrupt_service_routine(ha, intr_status);
44         }
45 }
46
47 /**
48  * qla4xxx_is_intr_poll_mode – Are we allowed to poll for interrupts?
49  * @ha: Pointer to host adapter structure.
50  * @ret: 1=polling mode, 0=non-polling mode
51  **/
52 static int qla4xxx_is_intr_poll_mode(struct scsi_qla_host *ha)
53 {
54         int rval = 1;
55
56         if (is_qla8032(ha) || is_qla8042(ha)) {
57                 if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
58                     test_bit(AF_83XX_MBOX_INTR_ON, &ha->flags))
59                         rval = 0;
60         } else {
61                 if (test_bit(AF_IRQ_ATTACHED, &ha->flags) &&
62                     test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
63                     test_bit(AF_ONLINE, &ha->flags) &&
64                     !test_bit(AF_HA_REMOVAL, &ha->flags))
65                         rval = 0;
66         }
67
68         return rval;
69 }
70
71 /**
72  * qla4xxx_mailbox_command - issues mailbox commands
73  * @ha: Pointer to host adapter structure.
74  * @inCount: number of mailbox registers to load.
75  * @outCount: number of mailbox registers to return.
76  * @mbx_cmd: data pointer for mailbox in registers.
77  * @mbx_sts: data pointer for mailbox out registers.
78  *
79  * This routine issue mailbox commands and waits for completion.
80  * If outCount is 0, this routine completes successfully WITHOUT waiting
81  * for the mailbox command to complete.
82  **/
83 int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
84                             uint8_t outCount, uint32_t *mbx_cmd,
85                             uint32_t *mbx_sts)
86 {
87         int status = QLA_ERROR;
88         uint8_t i;
89         u_long wait_count;
90         unsigned long flags = 0;
91         uint32_t dev_state;
92
93         /* Make sure that pointers are valid */
94         if (!mbx_cmd || !mbx_sts) {
95                 DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts "
96                               "pointer\n", ha->host_no, __func__));
97                 return status;
98         }
99
100         if (is_qla40XX(ha)) {
101                 if (test_bit(AF_HA_REMOVAL, &ha->flags)) {
102                         DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: "
103                                           "prematurely completing mbx cmd as "
104                                           "adapter removal detected\n",
105                                           ha->host_no, __func__));
106                         return status;
107                 }
108         }
109
110         if ((is_aer_supported(ha)) &&
111             (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) {
112                 DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, "
113                     "timeout MBX Exiting.\n", ha->host_no, __func__));
114                 return status;
115         }
116
117         /* Mailbox code active */
118         wait_count = MBOX_TOV * 100;
119
120         while (wait_count--) {
121                 mutex_lock(&ha->mbox_sem);
122                 if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) {
123                         set_bit(AF_MBOX_COMMAND, &ha->flags);
124                         mutex_unlock(&ha->mbox_sem);
125                         break;
126                 }
127                 mutex_unlock(&ha->mbox_sem);
128                 if (!wait_count) {
129                         DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n",
130                                 ha->host_no, __func__));
131                         return status;
132                 }
133                 msleep(10);
134         }
135
136         if (is_qla80XX(ha)) {
137                 if (test_bit(AF_FW_RECOVERY, &ha->flags)) {
138                         DEBUG2(ql4_printk(KERN_WARNING, ha,
139                                           "scsi%ld: %s: prematurely completing mbx cmd as firmware recovery detected\n",
140                                           ha->host_no, __func__));
141                         goto mbox_exit;
142                 }
143                 /* Do not send any mbx cmd if h/w is in failed state*/
144                 ha->isp_ops->idc_lock(ha);
145                 dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
146                 ha->isp_ops->idc_unlock(ha);
147                 if (dev_state == QLA8XXX_DEV_FAILED) {
148                         ql4_printk(KERN_WARNING, ha,
149                                    "scsi%ld: %s: H/W is in failed state, do not send any mailbox commands\n",
150                                    ha->host_no, __func__);
151                         goto mbox_exit;
152                 }
153         }
154
155         spin_lock_irqsave(&ha->hardware_lock, flags);
156
157         ha->mbox_status_count = outCount;
158         for (i = 0; i < outCount; i++)
159                 ha->mbox_status[i] = 0;
160
161         /* Queue the mailbox command to the firmware */
162         ha->isp_ops->queue_mailbox_command(ha, mbx_cmd, inCount);
163
164         spin_unlock_irqrestore(&ha->hardware_lock, flags);
165
166         /* Wait for completion */
167
168         /*
169          * If we don't want status, don't wait for the mailbox command to
170          * complete.  For example, MBOX_CMD_RESET_FW doesn't return status,
171          * you must poll the inbound Interrupt Mask for completion.
172          */
173         if (outCount == 0) {
174                 status = QLA_SUCCESS;
175                 goto mbox_exit;
176         }
177
178         /*
179          * Wait for completion: Poll or completion queue
180          */
181         if (qla4xxx_is_intr_poll_mode(ha)) {
182                 /* Poll for command to complete */
183                 wait_count = jiffies + MBOX_TOV * HZ;
184                 while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) {
185                         if (time_after_eq(jiffies, wait_count))
186                                 break;
187                         /*
188                          * Service the interrupt.
189                          * The ISR will save the mailbox status registers
190                          * to a temporary storage location in the adapter
191                          * structure.
192                          */
193                         spin_lock_irqsave(&ha->hardware_lock, flags);
194                         ha->isp_ops->process_mailbox_interrupt(ha, outCount);
195                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
196                         msleep(10);
197                 }
198         } else {
199                 /* Do not poll for completion. Use completion queue */
200                 set_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
201                 wait_for_completion_timeout(&ha->mbx_intr_comp, MBOX_TOV * HZ);
202                 clear_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags);
203         }
204
205         /* Check for mailbox timeout. */
206         if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {
207                 if (is_qla80XX(ha) &&
208                     test_bit(AF_FW_RECOVERY, &ha->flags)) {
209                         DEBUG2(ql4_printk(KERN_INFO, ha,
210                             "scsi%ld: %s: prematurely completing mbx cmd as "
211                             "firmware recovery detected\n",
212                             ha->host_no, __func__));
213                         goto mbox_exit;
214                 }
215                 DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...,"
216                               " Scheduling Adapter Reset\n", ha->host_no,
217                               mbx_cmd[0]));
218                 ha->mailbox_timeout_count++;
219                 mbx_sts[0] = (-1);
220                 set_bit(DPC_RESET_HA, &ha->dpc_flags);
221                 if (is_qla8022(ha)) {
222                         ql4_printk(KERN_INFO, ha,
223                                    "disabling pause transmit on port 0 & 1.\n");
224                         qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
225                                         CRB_NIU_XG_PAUSE_CTL_P0 |
226                                         CRB_NIU_XG_PAUSE_CTL_P1);
227                 } else if (is_qla8032(ha) || is_qla8042(ha)) {
228                         ql4_printk(KERN_INFO, ha, " %s: disabling pause transmit on port 0 & 1.\n",
229                                    __func__);
230                         qla4_83xx_disable_pause(ha);
231                 }
232                 goto mbox_exit;
233         }
234
235         /*
236          * Copy the mailbox out registers to the caller's mailbox in/out
237          * structure.
238          */
239         spin_lock_irqsave(&ha->hardware_lock, flags);
240         for (i = 0; i < outCount; i++)
241                 mbx_sts[i] = ha->mbox_status[i];
242
243         /* Set return status and error flags (if applicable). */
244         switch (ha->mbox_status[0]) {
245         case MBOX_STS_COMMAND_COMPLETE:
246                 status = QLA_SUCCESS;
247                 break;
248
249         case MBOX_STS_INTERMEDIATE_COMPLETION:
250                 status = QLA_SUCCESS;
251                 break;
252
253         case MBOX_STS_BUSY:
254                 DEBUG2( printk("scsi%ld: %s: Cmd = %08X, ISP BUSY\n",
255                                ha->host_no, __func__, mbx_cmd[0]));
256                 ha->mailbox_timeout_count++;
257                 break;
258
259         default:
260                 DEBUG2(printk("scsi%ld: %s: **** FAILED, cmd = %08X, "
261                               "sts = %08X ****\n", ha->host_no, __func__,
262                               mbx_cmd[0], mbx_sts[0]));
263                 break;
264         }
265         spin_unlock_irqrestore(&ha->hardware_lock, flags);
266
267 mbox_exit:
268         mutex_lock(&ha->mbox_sem);
269         clear_bit(AF_MBOX_COMMAND, &ha->flags);
270         mutex_unlock(&ha->mbox_sem);
271         clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
272
273         return status;
274 }
275
276 /**
277  * qla4xxx_get_minidump_template - Get the firmware template
278  * @ha: Pointer to host adapter structure.
279  * @phys_addr: dma address for template
280  *
281  * Obtain the minidump template from firmware during initialization
282  * as it may not be available when minidump is desired.
283  **/
284 int qla4xxx_get_minidump_template(struct scsi_qla_host *ha,
285                                   dma_addr_t phys_addr)
286 {
287         uint32_t mbox_cmd[MBOX_REG_COUNT];
288         uint32_t mbox_sts[MBOX_REG_COUNT];
289         int status;
290
291         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
292         memset(&mbox_sts, 0, sizeof(mbox_sts));
293
294         mbox_cmd[0] = MBOX_CMD_MINIDUMP;
295         mbox_cmd[1] = MINIDUMP_GET_TMPLT_SUBCOMMAND;
296         mbox_cmd[2] = LSDW(phys_addr);
297         mbox_cmd[3] = MSDW(phys_addr);
298         mbox_cmd[4] = ha->fw_dump_tmplt_size;
299         mbox_cmd[5] = 0;
300
301         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0],
302                                          &mbox_sts[0]);
303         if (status != QLA_SUCCESS) {
304                 DEBUG2(ql4_printk(KERN_INFO, ha,
305                                   "scsi%ld: %s: Cmd = %08X, mbx[0] = 0x%04x, mbx[1] = 0x%04x\n",
306                                   ha->host_no, __func__, mbox_cmd[0],
307                                   mbox_sts[0], mbox_sts[1]));
308         }
309         return status;
310 }
311
312 /**
313  * qla4xxx_req_template_size - Get minidump template size from firmware.
314  * @ha: Pointer to host adapter structure.
315  **/
316 int qla4xxx_req_template_size(struct scsi_qla_host *ha)
317 {
318         uint32_t mbox_cmd[MBOX_REG_COUNT];
319         uint32_t mbox_sts[MBOX_REG_COUNT];
320         int status;
321
322         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
323         memset(&mbox_sts, 0, sizeof(mbox_sts));
324
325         mbox_cmd[0] = MBOX_CMD_MINIDUMP;
326         mbox_cmd[1] = MINIDUMP_GET_SIZE_SUBCOMMAND;
327
328         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0],
329                                          &mbox_sts[0]);
330         if (status == QLA_SUCCESS) {
331                 ha->fw_dump_tmplt_size = mbox_sts[1];
332                 DEBUG2(ql4_printk(KERN_INFO, ha,
333                                   "%s: sts[0]=0x%04x, template  size=0x%04x, size_cm_02=0x%04x, size_cm_04=0x%04x, size_cm_08=0x%04x, size_cm_10=0x%04x, size_cm_FF=0x%04x, version=0x%04x\n",
334                                   __func__, mbox_sts[0], mbox_sts[1],
335                                   mbox_sts[2], mbox_sts[3], mbox_sts[4],
336                                   mbox_sts[5], mbox_sts[6], mbox_sts[7]));
337                 if (ha->fw_dump_tmplt_size == 0)
338                         status = QLA_ERROR;
339         } else {
340                 ql4_printk(KERN_WARNING, ha,
341                            "%s: Error sts[0]=0x%04x, mbx[1]=0x%04x\n",
342                            __func__, mbox_sts[0], mbox_sts[1]);
343                 status = QLA_ERROR;
344         }
345
346         return status;
347 }
348
349 void qla4xxx_mailbox_premature_completion(struct scsi_qla_host *ha)
350 {
351         set_bit(AF_FW_RECOVERY, &ha->flags);
352         ql4_printk(KERN_INFO, ha, "scsi%ld: %s: set FW RECOVERY!\n",
353             ha->host_no, __func__);
354
355         if (test_bit(AF_MBOX_COMMAND, &ha->flags)) {
356                 if (test_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags)) {
357                         complete(&ha->mbx_intr_comp);
358                         ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw "
359                             "recovery, doing premature completion of "
360                             "mbx cmd\n", ha->host_no, __func__);
361
362                 } else {
363                         set_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
364                         ql4_printk(KERN_INFO, ha, "scsi%ld: %s: Due to fw "
365                             "recovery, doing premature completion of "
366                             "polling mbx cmd\n", ha->host_no, __func__);
367                 }
368         }
369 }
370
371 static uint8_t
372 qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
373                  uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)
374 {
375         memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
376         memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
377
378         if (is_qla8022(ha))
379                 qla4_82xx_wr_32(ha, ha->nx_db_wr_ptr, 0);
380
381         mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
382         mbox_cmd[1] = 0;
383         mbox_cmd[2] = LSDW(init_fw_cb_dma);
384         mbox_cmd[3] = MSDW(init_fw_cb_dma);
385         mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
386         mbox_cmd[5] = (IFCB_VER_MAX << 8) | IFCB_VER_MIN;
387
388         if (qla4xxx_mailbox_command(ha, 6, 6, mbox_cmd, mbox_sts) !=
389             QLA_SUCCESS) {
390                 DEBUG2(printk(KERN_WARNING "scsi%ld: %s: "
391                               "MBOX_CMD_INITIALIZE_FIRMWARE"
392                               " failed w/ status %04X\n",
393                               ha->host_no, __func__, mbox_sts[0]));
394                 return QLA_ERROR;
395         }
396         return QLA_SUCCESS;
397 }
398
399 uint8_t
400 qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
401                  uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)
402 {
403         memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
404         memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
405         mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
406         mbox_cmd[2] = LSDW(init_fw_cb_dma);
407         mbox_cmd[3] = MSDW(init_fw_cb_dma);
408         mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
409
410         if (qla4xxx_mailbox_command(ha, 5, 5, mbox_cmd, mbox_sts) !=
411             QLA_SUCCESS) {
412                 DEBUG2(printk(KERN_WARNING "scsi%ld: %s: "
413                               "MBOX_CMD_GET_INIT_FW_CTRL_BLOCK"
414                               " failed w/ status %04X\n",
415                               ha->host_no, __func__, mbox_sts[0]));
416                 return QLA_ERROR;
417         }
418         return QLA_SUCCESS;
419 }
420
421 static void
422 qla4xxx_update_local_ip(struct scsi_qla_host *ha,
423                         struct addr_ctrl_blk *init_fw_cb)
424 {
425         ha->ip_config.tcp_options = le16_to_cpu(init_fw_cb->ipv4_tcp_opts);
426         ha->ip_config.ipv4_options = le16_to_cpu(init_fw_cb->ipv4_ip_opts);
427         ha->ip_config.ipv4_addr_state =
428                                 le16_to_cpu(init_fw_cb->ipv4_addr_state);
429         ha->ip_config.eth_mtu_size =
430                                 le16_to_cpu(init_fw_cb->eth_mtu_size);
431         ha->ip_config.ipv4_port = le16_to_cpu(init_fw_cb->ipv4_port);
432
433         if (ha->acb_version == ACB_SUPPORTED) {
434                 ha->ip_config.ipv6_options = le16_to_cpu(init_fw_cb->ipv6_opts);
435                 ha->ip_config.ipv6_addl_options =
436                                 le16_to_cpu(init_fw_cb->ipv6_addtl_opts);
437         }
438
439         /* Save IPv4 Address Info */
440         memcpy(ha->ip_config.ip_address, init_fw_cb->ipv4_addr,
441                min(sizeof(ha->ip_config.ip_address),
442                    sizeof(init_fw_cb->ipv4_addr)));
443         memcpy(ha->ip_config.subnet_mask, init_fw_cb->ipv4_subnet,
444                min(sizeof(ha->ip_config.subnet_mask),
445                    sizeof(init_fw_cb->ipv4_subnet)));
446         memcpy(ha->ip_config.gateway, init_fw_cb->ipv4_gw_addr,
447                min(sizeof(ha->ip_config.gateway),
448                    sizeof(init_fw_cb->ipv4_gw_addr)));
449
450         ha->ip_config.ipv4_vlan_tag = be16_to_cpu(init_fw_cb->ipv4_vlan_tag);
451
452         if (is_ipv6_enabled(ha)) {
453                 /* Save IPv6 Address */
454                 ha->ip_config.ipv6_link_local_state =
455                         le16_to_cpu(init_fw_cb->ipv6_lnk_lcl_addr_state);
456                 ha->ip_config.ipv6_addr0_state =
457                                 le16_to_cpu(init_fw_cb->ipv6_addr0_state);
458                 ha->ip_config.ipv6_addr1_state =
459                                 le16_to_cpu(init_fw_cb->ipv6_addr1_state);
460                 ha->ip_config.ipv6_default_router_state =
461                                 le16_to_cpu(init_fw_cb->ipv6_dflt_rtr_state);
462                 ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[0] = 0xFE;
463                 ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[1] = 0x80;
464
465                 memcpy(&ha->ip_config.ipv6_link_local_addr.in6_u.u6_addr8[8],
466                        init_fw_cb->ipv6_if_id,
467                        min(sizeof(ha->ip_config.ipv6_link_local_addr)/2,
468                            sizeof(init_fw_cb->ipv6_if_id)));
469                 memcpy(&ha->ip_config.ipv6_addr0, init_fw_cb->ipv6_addr0,
470                        min(sizeof(ha->ip_config.ipv6_addr0),
471                            sizeof(init_fw_cb->ipv6_addr0)));
472                 memcpy(&ha->ip_config.ipv6_addr1, init_fw_cb->ipv6_addr1,
473                        min(sizeof(ha->ip_config.ipv6_addr1),
474                            sizeof(init_fw_cb->ipv6_addr1)));
475                 memcpy(&ha->ip_config.ipv6_default_router_addr,
476                        init_fw_cb->ipv6_dflt_rtr_addr,
477                        min(sizeof(ha->ip_config.ipv6_default_router_addr),
478                            sizeof(init_fw_cb->ipv6_dflt_rtr_addr)));
479                 ha->ip_config.ipv6_vlan_tag =
480                                 be16_to_cpu(init_fw_cb->ipv6_vlan_tag);
481                 ha->ip_config.ipv6_port = le16_to_cpu(init_fw_cb->ipv6_port);
482         }
483 }
484
485 uint8_t
486 qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,
487                           uint32_t *mbox_cmd,
488                           uint32_t *mbox_sts,
489                           struct addr_ctrl_blk  *init_fw_cb,
490                           dma_addr_t init_fw_cb_dma)
491 {
492         if (qla4xxx_get_ifcb(ha, mbox_cmd, mbox_sts, init_fw_cb_dma)
493             != QLA_SUCCESS) {
494                 DEBUG2(printk(KERN_WARNING
495                               "scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
496                               ha->host_no, __func__));
497                 return QLA_ERROR;
498         }
499
500         DEBUG2(qla4xxx_dump_buffer(init_fw_cb, sizeof(struct addr_ctrl_blk)));
501
502         /* Save some info in adapter structure. */
503         ha->acb_version = init_fw_cb->acb_version;
504         ha->firmware_options = le16_to_cpu(init_fw_cb->fw_options);
505         ha->heartbeat_interval = init_fw_cb->hb_interval;
506         memcpy(ha->name_string, init_fw_cb->iscsi_name,
507                 min(sizeof(ha->name_string),
508                 sizeof(init_fw_cb->iscsi_name)));
509         ha->def_timeout = le16_to_cpu(init_fw_cb->def_timeout);
510         /*memcpy(ha->alias, init_fw_cb->Alias,
511                min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/
512
513         qla4xxx_update_local_ip(ha, init_fw_cb);
514
515         return QLA_SUCCESS;
516 }
517
518 /**
519  * qla4xxx_initialize_fw_cb - initializes firmware control block.
520  * @ha: Pointer to host adapter structure.
521  **/
522 int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
523 {
524         struct addr_ctrl_blk *init_fw_cb;
525         dma_addr_t init_fw_cb_dma;
526         uint32_t mbox_cmd[MBOX_REG_COUNT];
527         uint32_t mbox_sts[MBOX_REG_COUNT];
528         int status = QLA_ERROR;
529
530         init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
531                                         sizeof(struct addr_ctrl_blk),
532                                         &init_fw_cb_dma, GFP_KERNEL);
533         if (init_fw_cb == NULL) {
534                 DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n",
535                               ha->host_no, __func__));
536                 goto exit_init_fw_cb_no_free;
537         }
538         memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk));
539
540         /* Get Initialize Firmware Control Block. */
541         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
542         memset(&mbox_sts, 0, sizeof(mbox_sts));
543
544         if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) !=
545             QLA_SUCCESS) {
546                 dma_free_coherent(&ha->pdev->dev,
547                                   sizeof(struct addr_ctrl_blk),
548                                   init_fw_cb, init_fw_cb_dma);
549                 goto exit_init_fw_cb;
550         }
551
552         /* Initialize request and response queues. */
553         qla4xxx_init_rings(ha);
554
555         /* Fill in the request and response queue information. */
556         init_fw_cb->rqq_consumer_idx = cpu_to_le16(ha->request_out);
557         init_fw_cb->compq_producer_idx = cpu_to_le16(ha->response_in);
558         init_fw_cb->rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH);
559         init_fw_cb->compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH);
560         init_fw_cb->rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma));
561         init_fw_cb->rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma));
562         init_fw_cb->compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma));
563         init_fw_cb->compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma));
564         init_fw_cb->shdwreg_addr_lo = cpu_to_le32(LSDW(ha->shadow_regs_dma));
565         init_fw_cb->shdwreg_addr_hi = cpu_to_le32(MSDW(ha->shadow_regs_dma));
566
567         /* Set up required options. */
568         init_fw_cb->fw_options |=
569                 __constant_cpu_to_le16(FWOPT_SESSION_MODE |
570                                        FWOPT_INITIATOR_MODE);
571
572         if (is_qla80XX(ha))
573                 init_fw_cb->fw_options |=
574                     __constant_cpu_to_le16(FWOPT_ENABLE_CRBDB);
575
576         init_fw_cb->fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE);
577
578         init_fw_cb->add_fw_options = 0;
579         init_fw_cb->add_fw_options |=
580                         __constant_cpu_to_le16(ADFWOPT_SERIALIZE_TASK_MGMT);
581         init_fw_cb->add_fw_options |=
582                         __constant_cpu_to_le16(ADFWOPT_AUTOCONN_DISABLE);
583
584         if (qla4xxx_set_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma)
585                 != QLA_SUCCESS) {
586                 DEBUG2(printk(KERN_WARNING
587                               "scsi%ld: %s: Failed to set init_fw_ctrl_blk\n",
588                               ha->host_no, __func__));
589                 goto exit_init_fw_cb;
590         }
591
592         if (qla4xxx_update_local_ifcb(ha, &mbox_cmd[0], &mbox_sts[0],
593                 init_fw_cb, init_fw_cb_dma) != QLA_SUCCESS) {
594                 DEBUG2(printk("scsi%ld: %s: Failed to update local ifcb\n",
595                                 ha->host_no, __func__));
596                 goto exit_init_fw_cb;
597         }
598         status = QLA_SUCCESS;
599
600 exit_init_fw_cb:
601         dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),
602                                 init_fw_cb, init_fw_cb_dma);
603 exit_init_fw_cb_no_free:
604         return status;
605 }
606
607 /**
608  * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP
609  * @ha: Pointer to host adapter structure.
610  **/
611 int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha)
612 {
613         struct addr_ctrl_blk *init_fw_cb;
614         dma_addr_t init_fw_cb_dma;
615         uint32_t mbox_cmd[MBOX_REG_COUNT];
616         uint32_t mbox_sts[MBOX_REG_COUNT];
617
618         init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
619                                         sizeof(struct addr_ctrl_blk),
620                                         &init_fw_cb_dma, GFP_KERNEL);
621         if (init_fw_cb == NULL) {
622                 printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no,
623                        __func__);
624                 return QLA_ERROR;
625         }
626
627         /* Get Initialize Firmware Control Block. */
628         memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk));
629         if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) !=
630             QLA_SUCCESS) {
631                 DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
632                               ha->host_no, __func__));
633                 dma_free_coherent(&ha->pdev->dev,
634                                   sizeof(struct addr_ctrl_blk),
635                                   init_fw_cb, init_fw_cb_dma);
636                 return QLA_ERROR;
637         }
638
639         /* Save IP Address. */
640         qla4xxx_update_local_ip(ha, init_fw_cb);
641         dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),
642                                 init_fw_cb, init_fw_cb_dma);
643
644         return QLA_SUCCESS;
645 }
646
647 /**
648  * qla4xxx_get_firmware_state - gets firmware state of HBA
649  * @ha: Pointer to host adapter structure.
650  **/
651 int qla4xxx_get_firmware_state(struct scsi_qla_host * ha)
652 {
653         uint32_t mbox_cmd[MBOX_REG_COUNT];
654         uint32_t mbox_sts[MBOX_REG_COUNT];
655
656         /* Get firmware version */
657         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
658         memset(&mbox_sts, 0, sizeof(mbox_sts));
659
660         mbox_cmd[0] = MBOX_CMD_GET_FW_STATE;
661
662         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 4, &mbox_cmd[0], &mbox_sts[0]) !=
663             QLA_SUCCESS) {
664                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ "
665                               "status %04X\n", ha->host_no, __func__,
666                               mbox_sts[0]));
667                 return QLA_ERROR;
668         }
669         ha->firmware_state = mbox_sts[1];
670         ha->board_id = mbox_sts[2];
671         ha->addl_fw_state = mbox_sts[3];
672         DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n",
673                       ha->host_no, __func__, ha->firmware_state);)
674
675         return QLA_SUCCESS;
676 }
677
678 /**
679  * qla4xxx_get_firmware_status - retrieves firmware status
680  * @ha: Pointer to host adapter structure.
681  **/
682 int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
683 {
684         uint32_t mbox_cmd[MBOX_REG_COUNT];
685         uint32_t mbox_sts[MBOX_REG_COUNT];
686
687         /* Get firmware version */
688         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
689         memset(&mbox_sts, 0, sizeof(mbox_sts));
690
691         mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS;
692
693         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=
694             QLA_SUCCESS) {
695                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ "
696                               "status %04X\n", ha->host_no, __func__,
697                               mbox_sts[0]));
698                 return QLA_ERROR;
699         }
700
701         /* High-water mark of IOCBs */
702         ha->iocb_hiwat = mbox_sts[2];
703         DEBUG2(ql4_printk(KERN_INFO, ha,
704                           "%s: firmware IOCBs available = %d\n", __func__,
705                           ha->iocb_hiwat));
706
707         if (ha->iocb_hiwat > IOCB_HIWAT_CUSHION)
708                 ha->iocb_hiwat -= IOCB_HIWAT_CUSHION;
709
710         /* Ideally, we should not enter this code, as the # of firmware
711          * IOCBs is hard-coded in the firmware. We set a default
712          * iocb_hiwat here just in case */
713         if (ha->iocb_hiwat == 0) {
714                 ha->iocb_hiwat = REQUEST_QUEUE_DEPTH / 4;
715                 DEBUG2(ql4_printk(KERN_WARNING, ha,
716                                   "%s: Setting IOCB's to = %d\n", __func__,
717                                   ha->iocb_hiwat));
718         }
719
720         return QLA_SUCCESS;
721 }
722
723 /**
724  * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry
725  * @ha: Pointer to host adapter structure.
726  * @fw_ddb_index: Firmware's device database index
727  * @fw_ddb_entry: Pointer to firmware's device database entry structure
728  * @num_valid_ddb_entries: Pointer to number of valid ddb entries
729  * @next_ddb_index: Pointer to next valid device database index
730  * @fw_ddb_device_state: Pointer to device state
731  **/
732 int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
733                             uint16_t fw_ddb_index,
734                             struct dev_db_entry *fw_ddb_entry,
735                             dma_addr_t fw_ddb_entry_dma,
736                             uint32_t *num_valid_ddb_entries,
737                             uint32_t *next_ddb_index,
738                             uint32_t *fw_ddb_device_state,
739                             uint32_t *conn_err_detail,
740                             uint16_t *tcp_source_port_num,
741                             uint16_t *connection_id)
742 {
743         int status = QLA_ERROR;
744         uint16_t options;
745         uint32_t mbox_cmd[MBOX_REG_COUNT];
746         uint32_t mbox_sts[MBOX_REG_COUNT];
747
748         /* Make sure the device index is valid */
749         if (fw_ddb_index >= MAX_DDB_ENTRIES) {
750                 DEBUG2(printk("scsi%ld: %s: ddb [%d] out of range.\n",
751                               ha->host_no, __func__, fw_ddb_index));
752                 goto exit_get_fwddb;
753         }
754         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
755         memset(&mbox_sts, 0, sizeof(mbox_sts));
756         if (fw_ddb_entry)
757                 memset(fw_ddb_entry, 0, sizeof(struct dev_db_entry));
758
759         mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY;
760         mbox_cmd[1] = (uint32_t) fw_ddb_index;
761         mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
762         mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
763         mbox_cmd[4] = sizeof(struct dev_db_entry);
764
765         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 7, &mbox_cmd[0], &mbox_sts[0]) ==
766             QLA_ERROR) {
767                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed"
768                               " with status 0x%04X\n", ha->host_no, __func__,
769                               mbox_sts[0]));
770                 goto exit_get_fwddb;
771         }
772         if (fw_ddb_index != mbox_sts[1]) {
773                 DEBUG2(printk("scsi%ld: %s: ddb mismatch [%d] != [%d].\n",
774                               ha->host_no, __func__, fw_ddb_index,
775                               mbox_sts[1]));
776                 goto exit_get_fwddb;
777         }
778         if (fw_ddb_entry) {
779                 options = le16_to_cpu(fw_ddb_entry->options);
780                 if (options & DDB_OPT_IPV6_DEVICE) {
781                         ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d "
782                                 "Next %d State %04x ConnErr %08x %pI6 "
783                                 ":%04d \"%s\"\n", __func__, fw_ddb_index,
784                                 mbox_sts[0], mbox_sts[2], mbox_sts[3],
785                                 mbox_sts[4], mbox_sts[5],
786                                 fw_ddb_entry->ip_addr,
787                                 le16_to_cpu(fw_ddb_entry->port),
788                                 fw_ddb_entry->iscsi_name);
789                 } else {
790                         ql4_printk(KERN_INFO, ha, "%s: DDB[%d] MB0 %04x Tot %d "
791                                 "Next %d State %04x ConnErr %08x %pI4 "
792                                 ":%04d \"%s\"\n", __func__, fw_ddb_index,
793                                 mbox_sts[0], mbox_sts[2], mbox_sts[3],
794                                 mbox_sts[4], mbox_sts[5],
795                                 fw_ddb_entry->ip_addr,
796                                 le16_to_cpu(fw_ddb_entry->port),
797                                 fw_ddb_entry->iscsi_name);
798                 }
799         }
800         if (num_valid_ddb_entries)
801                 *num_valid_ddb_entries = mbox_sts[2];
802         if (next_ddb_index)
803                 *next_ddb_index = mbox_sts[3];
804         if (fw_ddb_device_state)
805                 *fw_ddb_device_state = mbox_sts[4];
806
807         /*
808          * RA: This mailbox has been changed to pass connection error and
809          * details.  Its true for ISP4010 as per Version E - Not sure when it
810          * was changed.  Get the time2wait from the fw_dd_entry field :
811          * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY
812          * struct.
813          */
814         if (conn_err_detail)
815                 *conn_err_detail = mbox_sts[5];
816         if (tcp_source_port_num)
817                 *tcp_source_port_num = (uint16_t) (mbox_sts[6] >> 16);
818         if (connection_id)
819                 *connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
820         status = QLA_SUCCESS;
821
822 exit_get_fwddb:
823         return status;
824 }
825
826 int qla4xxx_conn_open(struct scsi_qla_host *ha, uint16_t fw_ddb_index)
827 {
828         uint32_t mbox_cmd[MBOX_REG_COUNT];
829         uint32_t mbox_sts[MBOX_REG_COUNT];
830         int status;
831
832         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
833         memset(&mbox_sts, 0, sizeof(mbox_sts));
834
835         mbox_cmd[0] = MBOX_CMD_CONN_OPEN;
836         mbox_cmd[1] = fw_ddb_index;
837
838         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0],
839                                          &mbox_sts[0]);
840         DEBUG2(ql4_printk(KERN_INFO, ha,
841                           "%s: status = %d mbx0 = 0x%x mbx1 = 0x%x\n",
842                           __func__, status, mbox_sts[0], mbox_sts[1]));
843         return status;
844 }
845
846 /**
847  * qla4xxx_set_fwddb_entry - sets a ddb entry.
848  * @ha: Pointer to host adapter structure.
849  * @fw_ddb_index: Firmware's device database index
850  * @fw_ddb_entry_dma: dma address of ddb entry
851  * @mbx_sts: mailbox 0 to be returned or NULL
852  *
853  * This routine initializes or updates the adapter's device database
854  * entry for the specified device.
855  **/
856 int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
857                           dma_addr_t fw_ddb_entry_dma, uint32_t *mbx_sts)
858 {
859         uint32_t mbox_cmd[MBOX_REG_COUNT];
860         uint32_t mbox_sts[MBOX_REG_COUNT];
861         int status;
862
863         /* Do not wait for completion. The firmware will send us an
864          * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.
865          */
866         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
867         memset(&mbox_sts, 0, sizeof(mbox_sts));
868
869         mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY;
870         mbox_cmd[1] = (uint32_t) fw_ddb_index;
871         mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
872         mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
873         mbox_cmd[4] = sizeof(struct dev_db_entry);
874
875         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0],
876                                          &mbox_sts[0]);
877         if (mbx_sts)
878                 *mbx_sts = mbox_sts[0];
879         DEBUG2(printk("scsi%ld: %s: status=%d mbx0=0x%x mbx4=0x%x\n",
880             ha->host_no, __func__, status, mbox_sts[0], mbox_sts[4]);)
881
882         return status;
883 }
884
885 int qla4xxx_session_logout_ddb(struct scsi_qla_host *ha,
886                                struct ddb_entry *ddb_entry, int options)
887 {
888         int status;
889         uint32_t mbox_cmd[MBOX_REG_COUNT];
890         uint32_t mbox_sts[MBOX_REG_COUNT];
891
892         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
893         memset(&mbox_sts, 0, sizeof(mbox_sts));
894
895         mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT;
896         mbox_cmd[1] = ddb_entry->fw_ddb_index;
897         mbox_cmd[3] = options;
898
899         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0],
900                                          &mbox_sts[0]);
901         if (status != QLA_SUCCESS) {
902                 DEBUG2(ql4_printk(KERN_INFO, ha,
903                                   "%s: MBOX_CMD_CONN_CLOSE_SESS_LOGOUT "
904                                   "failed sts %04X %04X", __func__,
905                                   mbox_sts[0], mbox_sts[1]));
906         }
907
908         return status;
909 }
910
911 /**
912  * qla4xxx_get_crash_record - retrieves crash record.
913  * @ha: Pointer to host adapter structure.
914  *
915  * This routine retrieves a crash record from the QLA4010 after an 8002h aen.
916  **/
917 void qla4xxx_get_crash_record(struct scsi_qla_host * ha)
918 {
919         uint32_t mbox_cmd[MBOX_REG_COUNT];
920         uint32_t mbox_sts[MBOX_REG_COUNT];
921         struct crash_record *crash_record = NULL;
922         dma_addr_t crash_record_dma = 0;
923         uint32_t crash_record_size = 0;
924
925         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
926         memset(&mbox_sts, 0, sizeof(mbox_cmd));
927
928         /* Get size of crash record. */
929         mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
930
931         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
932             QLA_SUCCESS) {
933                 DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n",
934                               ha->host_no, __func__));
935                 goto exit_get_crash_record;
936         }
937         crash_record_size = mbox_sts[4];
938         if (crash_record_size == 0) {
939                 DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n",
940                               ha->host_no, __func__));
941                 goto exit_get_crash_record;
942         }
943
944         /* Alloc Memory for Crash Record. */
945         crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size,
946                                           &crash_record_dma, GFP_KERNEL);
947         if (crash_record == NULL)
948                 goto exit_get_crash_record;
949
950         /* Get Crash Record. */
951         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
952         memset(&mbox_sts, 0, sizeof(mbox_cmd));
953
954         mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
955         mbox_cmd[2] = LSDW(crash_record_dma);
956         mbox_cmd[3] = MSDW(crash_record_dma);
957         mbox_cmd[4] = crash_record_size;
958
959         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
960             QLA_SUCCESS)
961                 goto exit_get_crash_record;
962
963         /* Dump Crash Record. */
964
965 exit_get_crash_record:
966         if (crash_record)
967                 dma_free_coherent(&ha->pdev->dev, crash_record_size,
968                                   crash_record, crash_record_dma);
969 }
970
971 /**
972  * qla4xxx_get_conn_event_log - retrieves connection event log
973  * @ha: Pointer to host adapter structure.
974  **/
975 void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha)
976 {
977         uint32_t mbox_cmd[MBOX_REG_COUNT];
978         uint32_t mbox_sts[MBOX_REG_COUNT];
979         struct conn_event_log_entry *event_log = NULL;
980         dma_addr_t event_log_dma = 0;
981         uint32_t event_log_size = 0;
982         uint32_t num_valid_entries;
983         uint32_t      oldest_entry = 0;
984         uint32_t        max_event_log_entries;
985         uint8_t         i;
986
987         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
988         memset(&mbox_sts, 0, sizeof(mbox_cmd));
989
990         /* Get size of crash record. */
991         mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
992
993         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
994             QLA_SUCCESS)
995                 goto exit_get_event_log;
996
997         event_log_size = mbox_sts[4];
998         if (event_log_size == 0)
999                 goto exit_get_event_log;
1000
1001         /* Alloc Memory for Crash Record. */
1002         event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size,
1003                                        &event_log_dma, GFP_KERNEL);
1004         if (event_log == NULL)
1005                 goto exit_get_event_log;
1006
1007         /* Get Crash Record. */
1008         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1009         memset(&mbox_sts, 0, sizeof(mbox_cmd));
1010
1011         mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
1012         mbox_cmd[2] = LSDW(event_log_dma);
1013         mbox_cmd[3] = MSDW(event_log_dma);
1014
1015         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
1016             QLA_SUCCESS) {
1017                 DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event "
1018                               "log!\n", ha->host_no, __func__));
1019                 goto exit_get_event_log;
1020         }
1021
1022         /* Dump Event Log. */
1023         num_valid_entries = mbox_sts[1];
1024
1025         max_event_log_entries = event_log_size /
1026                 sizeof(struct conn_event_log_entry);
1027
1028         if (num_valid_entries > max_event_log_entries)
1029                 oldest_entry = num_valid_entries % max_event_log_entries;
1030
1031         DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n",
1032                       ha->host_no, num_valid_entries));
1033
1034         if (ql4xextended_error_logging == 3) {
1035                 if (oldest_entry == 0) {
1036                         /* Circular Buffer has not wrapped around */
1037                         for (i=0; i < num_valid_entries; i++) {
1038                                 qla4xxx_dump_buffer((uint8_t *)event_log+
1039                                                     (i*sizeof(*event_log)),
1040                                                     sizeof(*event_log));
1041                         }
1042                 }
1043                 else {
1044                         /* Circular Buffer has wrapped around -
1045                          * display accordingly*/
1046                         for (i=oldest_entry; i < max_event_log_entries; i++) {
1047                                 qla4xxx_dump_buffer((uint8_t *)event_log+
1048                                                     (i*sizeof(*event_log)),
1049                                                     sizeof(*event_log));
1050                         }
1051                         for (i=0; i < oldest_entry; i++) {
1052                                 qla4xxx_dump_buffer((uint8_t *)event_log+
1053                                                     (i*sizeof(*event_log)),
1054                                                     sizeof(*event_log));
1055                         }
1056                 }
1057         }
1058
1059 exit_get_event_log:
1060         if (event_log)
1061                 dma_free_coherent(&ha->pdev->dev, event_log_size, event_log,
1062                                   event_log_dma);
1063 }
1064
1065 /**
1066  * qla4xxx_abort_task - issues Abort Task
1067  * @ha: Pointer to host adapter structure.
1068  * @srb: Pointer to srb entry
1069  *
1070  * This routine performs a LUN RESET on the specified target/lun.
1071  * The caller must ensure that the ddb_entry and lun_entry pointers
1072  * are valid before calling this routine.
1073  **/
1074 int qla4xxx_abort_task(struct scsi_qla_host *ha, struct srb *srb)
1075 {
1076         uint32_t mbox_cmd[MBOX_REG_COUNT];
1077         uint32_t mbox_sts[MBOX_REG_COUNT];
1078         struct scsi_cmnd *cmd = srb->cmd;
1079         int status = QLA_SUCCESS;
1080         unsigned long flags = 0;
1081         uint32_t index;
1082
1083         /*
1084          * Send abort task command to ISP, so that the ISP will return
1085          * request with ABORT status
1086          */
1087         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1088         memset(&mbox_sts, 0, sizeof(mbox_sts));
1089
1090         spin_lock_irqsave(&ha->hardware_lock, flags);
1091         index = (unsigned long)(unsigned char *)cmd->host_scribble;
1092         spin_unlock_irqrestore(&ha->hardware_lock, flags);
1093
1094         /* Firmware already posted completion on response queue */
1095         if (index == MAX_SRBS)
1096                 return status;
1097
1098         mbox_cmd[0] = MBOX_CMD_ABORT_TASK;
1099         mbox_cmd[1] = srb->ddb->fw_ddb_index;
1100         mbox_cmd[2] = index;
1101         /* Immediate Command Enable */
1102         mbox_cmd[5] = 0x01;
1103
1104         qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0],
1105             &mbox_sts[0]);
1106         if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE) {
1107                 status = QLA_ERROR;
1108
1109                 DEBUG2(printk(KERN_WARNING "scsi%ld:%d:%d: abort task FAILED: "
1110                     "mbx0=%04X, mb1=%04X, mb2=%04X, mb3=%04X, mb4=%04X\n",
1111                     ha->host_no, cmd->device->id, cmd->device->lun, mbox_sts[0],
1112                     mbox_sts[1], mbox_sts[2], mbox_sts[3], mbox_sts[4]));
1113         }
1114
1115         return status;
1116 }
1117
1118 /**
1119  * qla4xxx_reset_lun - issues LUN Reset
1120  * @ha: Pointer to host adapter structure.
1121  * @ddb_entry: Pointer to device database entry
1122  * @lun: lun number
1123  *
1124  * This routine performs a LUN RESET on the specified target/lun.
1125  * The caller must ensure that the ddb_entry and lun_entry pointers
1126  * are valid before calling this routine.
1127  **/
1128 int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
1129                       int lun)
1130 {
1131         uint32_t mbox_cmd[MBOX_REG_COUNT];
1132         uint32_t mbox_sts[MBOX_REG_COUNT];
1133         uint32_t scsi_lun[2];
1134         int status = QLA_SUCCESS;
1135
1136         DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no,
1137                       ddb_entry->fw_ddb_index, lun));
1138
1139         /*
1140          * Send lun reset command to ISP, so that the ISP will return all
1141          * outstanding requests with RESET status
1142          */
1143         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1144         memset(&mbox_sts, 0, sizeof(mbox_sts));
1145         int_to_scsilun(lun, (struct scsi_lun *) scsi_lun);
1146
1147         mbox_cmd[0] = MBOX_CMD_LUN_RESET;
1148         mbox_cmd[1] = ddb_entry->fw_ddb_index;
1149         /* FW expects LUN bytes 0-3 in Incoming Mailbox 2
1150          * (LUN byte 0 is LSByte, byte 3 is MSByte) */
1151         mbox_cmd[2] = cpu_to_le32(scsi_lun[0]);
1152         /* FW expects LUN bytes 4-7 in Incoming Mailbox 3
1153          * (LUN byte 4 is LSByte, byte 7 is MSByte) */
1154         mbox_cmd[3] = cpu_to_le32(scsi_lun[1]);
1155         mbox_cmd[5] = 0x01;     /* Immediate Command Enable */
1156
1157         qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);
1158         if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
1159             mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
1160                 status = QLA_ERROR;
1161
1162         return status;
1163 }
1164
1165 /**
1166  * qla4xxx_reset_target - issues target Reset
1167  * @ha: Pointer to host adapter structure.
1168  * @db_entry: Pointer to device database entry
1169  * @un_entry: Pointer to lun entry structure
1170  *
1171  * This routine performs a TARGET RESET on the specified target.
1172  * The caller must ensure that the ddb_entry pointers
1173  * are valid before calling this routine.
1174  **/
1175 int qla4xxx_reset_target(struct scsi_qla_host *ha,
1176                          struct ddb_entry *ddb_entry)
1177 {
1178         uint32_t mbox_cmd[MBOX_REG_COUNT];
1179         uint32_t mbox_sts[MBOX_REG_COUNT];
1180         int status = QLA_SUCCESS;
1181
1182         DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no,
1183                       ddb_entry->fw_ddb_index));
1184
1185         /*
1186          * Send target reset command to ISP, so that the ISP will return all
1187          * outstanding requests with RESET status
1188          */
1189         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1190         memset(&mbox_sts, 0, sizeof(mbox_sts));
1191
1192         mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET;
1193         mbox_cmd[1] = ddb_entry->fw_ddb_index;
1194         mbox_cmd[5] = 0x01;     /* Immediate Command Enable */
1195
1196         qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
1197                                 &mbox_sts[0]);
1198         if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
1199             mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
1200                 status = QLA_ERROR;
1201
1202         return status;
1203 }
1204
1205 int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,
1206                       uint32_t offset, uint32_t len)
1207 {
1208         uint32_t mbox_cmd[MBOX_REG_COUNT];
1209         uint32_t mbox_sts[MBOX_REG_COUNT];
1210
1211         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1212         memset(&mbox_sts, 0, sizeof(mbox_sts));
1213
1214         mbox_cmd[0] = MBOX_CMD_READ_FLASH;
1215         mbox_cmd[1] = LSDW(dma_addr);
1216         mbox_cmd[2] = MSDW(dma_addr);
1217         mbox_cmd[3] = offset;
1218         mbox_cmd[4] = len;
1219
1220         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], &mbox_sts[0]) !=
1221             QLA_SUCCESS) {
1222                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ "
1223                     "status %04X %04X, offset %08x, len %08x\n", ha->host_no,
1224                     __func__, mbox_sts[0], mbox_sts[1], offset, len));
1225                 return QLA_ERROR;
1226         }
1227         return QLA_SUCCESS;
1228 }
1229
1230 /**
1231  * qla4xxx_about_firmware - gets FW, iscsi draft and boot loader version
1232  * @ha: Pointer to host adapter structure.
1233  *
1234  * Retrieves the FW version, iSCSI draft version & bootloader version of HBA.
1235  * Mailboxes 2 & 3 may hold an address for data. Make sure that we write 0 to
1236  * those mailboxes, if unused.
1237  **/
1238 int qla4xxx_about_firmware(struct scsi_qla_host *ha)
1239 {
1240         struct about_fw_info *about_fw = NULL;
1241         dma_addr_t about_fw_dma;
1242         uint32_t mbox_cmd[MBOX_REG_COUNT];
1243         uint32_t mbox_sts[MBOX_REG_COUNT];
1244         int status = QLA_ERROR;
1245
1246         about_fw = dma_alloc_coherent(&ha->pdev->dev,
1247                                       sizeof(struct about_fw_info),
1248                                       &about_fw_dma, GFP_KERNEL);
1249         if (!about_fw) {
1250                 DEBUG2(ql4_printk(KERN_ERR, ha, "%s: Unable to alloc memory "
1251                                   "for about_fw\n", __func__));
1252                 return status;
1253         }
1254
1255         memset(about_fw, 0, sizeof(struct about_fw_info));
1256         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1257         memset(&mbox_sts, 0, sizeof(mbox_sts));
1258
1259         mbox_cmd[0] = MBOX_CMD_ABOUT_FW;
1260         mbox_cmd[2] = LSDW(about_fw_dma);
1261         mbox_cmd[3] = MSDW(about_fw_dma);
1262         mbox_cmd[4] = sizeof(struct about_fw_info);
1263
1264         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,
1265                                          &mbox_cmd[0], &mbox_sts[0]);
1266         if (status != QLA_SUCCESS) {
1267                 DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_ABOUT_FW "
1268                                   "failed w/ status %04X\n", __func__,
1269                                   mbox_sts[0]));
1270                 goto exit_about_fw;
1271         }
1272
1273         /* Save version information. */
1274         ha->fw_info.fw_major = le16_to_cpu(about_fw->fw_major);
1275         ha->fw_info.fw_minor = le16_to_cpu(about_fw->fw_minor);
1276         ha->fw_info.fw_patch = le16_to_cpu(about_fw->fw_patch);
1277         ha->fw_info.fw_build = le16_to_cpu(about_fw->fw_build);
1278         memcpy(ha->fw_info.fw_build_date, about_fw->fw_build_date,
1279                sizeof(about_fw->fw_build_date));
1280         memcpy(ha->fw_info.fw_build_time, about_fw->fw_build_time,
1281                sizeof(about_fw->fw_build_time));
1282         strcpy((char *)ha->fw_info.fw_build_user,
1283                skip_spaces((char *)about_fw->fw_build_user));
1284         ha->fw_info.fw_load_source = le16_to_cpu(about_fw->fw_load_source);
1285         ha->fw_info.iscsi_major = le16_to_cpu(about_fw->iscsi_major);
1286         ha->fw_info.iscsi_minor = le16_to_cpu(about_fw->iscsi_minor);
1287         ha->fw_info.bootload_major = le16_to_cpu(about_fw->bootload_major);
1288         ha->fw_info.bootload_minor = le16_to_cpu(about_fw->bootload_minor);
1289         ha->fw_info.bootload_patch = le16_to_cpu(about_fw->bootload_patch);
1290         ha->fw_info.bootload_build = le16_to_cpu(about_fw->bootload_build);
1291         strcpy((char *)ha->fw_info.extended_timestamp,
1292                skip_spaces((char *)about_fw->extended_timestamp));
1293
1294         ha->fw_uptime_secs = le32_to_cpu(mbox_sts[5]);
1295         ha->fw_uptime_msecs = le32_to_cpu(mbox_sts[6]);
1296         status = QLA_SUCCESS;
1297
1298 exit_about_fw:
1299         dma_free_coherent(&ha->pdev->dev, sizeof(struct about_fw_info),
1300                           about_fw, about_fw_dma);
1301         return status;
1302 }
1303
1304 int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,
1305                             dma_addr_t dma_addr)
1306 {
1307         uint32_t mbox_cmd[MBOX_REG_COUNT];
1308         uint32_t mbox_sts[MBOX_REG_COUNT];
1309
1310         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1311         memset(&mbox_sts, 0, sizeof(mbox_sts));
1312
1313         mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS;
1314         mbox_cmd[1] = options;
1315         mbox_cmd[2] = LSDW(dma_addr);
1316         mbox_cmd[3] = MSDW(dma_addr);
1317
1318         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
1319             QLA_SUCCESS) {
1320                 DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
1321                      ha->host_no, __func__, mbox_sts[0]));
1322                 return QLA_ERROR;
1323         }
1324         return QLA_SUCCESS;
1325 }
1326
1327 int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t ddb_index,
1328                           uint32_t *mbx_sts)
1329 {
1330         int status;
1331         uint32_t mbox_cmd[MBOX_REG_COUNT];
1332         uint32_t mbox_sts[MBOX_REG_COUNT];
1333
1334         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1335         memset(&mbox_sts, 0, sizeof(mbox_sts));
1336
1337         mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY;
1338         mbox_cmd[1] = ddb_index;
1339
1340         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
1341                                          &mbox_sts[0]);
1342         if (status != QLA_SUCCESS) {
1343                 DEBUG2(ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n",
1344                                    __func__, mbox_sts[0]));
1345         }
1346
1347         *mbx_sts = mbox_sts[0];
1348         return status;
1349 }
1350
1351 int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t ddb_index)
1352 {
1353         int status;
1354         uint32_t mbox_cmd[MBOX_REG_COUNT];
1355         uint32_t mbox_sts[MBOX_REG_COUNT];
1356
1357         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1358         memset(&mbox_sts, 0, sizeof(mbox_sts));
1359
1360         mbox_cmd[0] = MBOX_CMD_CLEAR_DATABASE_ENTRY;
1361         mbox_cmd[1] = ddb_index;
1362
1363         status = qla4xxx_mailbox_command(ha, 2, 1, &mbox_cmd[0],
1364                                          &mbox_sts[0]);
1365         if (status != QLA_SUCCESS) {
1366                 DEBUG2(ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n",
1367                                    __func__, mbox_sts[0]));
1368         }
1369
1370         return status;
1371 }
1372
1373 int qla4xxx_set_flash(struct scsi_qla_host *ha, dma_addr_t dma_addr,
1374                       uint32_t offset, uint32_t length, uint32_t options)
1375 {
1376         uint32_t mbox_cmd[MBOX_REG_COUNT];
1377         uint32_t mbox_sts[MBOX_REG_COUNT];
1378         int status = QLA_SUCCESS;
1379
1380         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1381         memset(&mbox_sts, 0, sizeof(mbox_sts));
1382
1383         mbox_cmd[0] = MBOX_CMD_WRITE_FLASH;
1384         mbox_cmd[1] = LSDW(dma_addr);
1385         mbox_cmd[2] = MSDW(dma_addr);
1386         mbox_cmd[3] = offset;
1387         mbox_cmd[4] = length;
1388         mbox_cmd[5] = options;
1389
1390         status = qla4xxx_mailbox_command(ha, 6, 2, &mbox_cmd[0], &mbox_sts[0]);
1391         if (status != QLA_SUCCESS) {
1392                 DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_WRITE_FLASH "
1393                                   "failed w/ status %04X, mbx1 %04X\n",
1394                                   __func__, mbox_sts[0], mbox_sts[1]));
1395         }
1396         return status;
1397 }
1398
1399 int qla4xxx_bootdb_by_index(struct scsi_qla_host *ha,
1400                             struct dev_db_entry *fw_ddb_entry,
1401                             dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index)
1402 {
1403         uint32_t dev_db_start_offset = FLASH_OFFSET_DB_INFO;
1404         uint32_t dev_db_end_offset;
1405         int status = QLA_ERROR;
1406
1407         memset(fw_ddb_entry, 0, sizeof(*fw_ddb_entry));
1408
1409         dev_db_start_offset += (ddb_index * sizeof(*fw_ddb_entry));
1410         dev_db_end_offset = FLASH_OFFSET_DB_END;
1411
1412         if (dev_db_start_offset > dev_db_end_offset) {
1413                 DEBUG2(ql4_printk(KERN_ERR, ha,
1414                                   "%s:Invalid DDB index %d", __func__,
1415                                   ddb_index));
1416                 goto exit_bootdb_failed;
1417         }
1418
1419         if (qla4xxx_get_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,
1420                               sizeof(*fw_ddb_entry)) != QLA_SUCCESS) {
1421                 ql4_printk(KERN_ERR, ha, "scsi%ld: %s: Get Flash"
1422                            "failed\n", ha->host_no, __func__);
1423                 goto exit_bootdb_failed;
1424         }
1425
1426         if (fw_ddb_entry->cookie == DDB_VALID_COOKIE)
1427                 status = QLA_SUCCESS;
1428
1429 exit_bootdb_failed:
1430         return status;
1431 }
1432
1433 int qla4xxx_flashdb_by_index(struct scsi_qla_host *ha,
1434                              struct dev_db_entry *fw_ddb_entry,
1435                              dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index)
1436 {
1437         uint32_t dev_db_start_offset;
1438         uint32_t dev_db_end_offset;
1439         int status = QLA_ERROR;
1440
1441         memset(fw_ddb_entry, 0, sizeof(*fw_ddb_entry));
1442
1443         if (is_qla40XX(ha)) {
1444                 dev_db_start_offset = FLASH_OFFSET_DB_INFO;
1445                 dev_db_end_offset = FLASH_OFFSET_DB_END;
1446         } else {
1447                 dev_db_start_offset = FLASH_RAW_ACCESS_ADDR +
1448                                       (ha->hw.flt_region_ddb << 2);
1449                 /* flt_ddb_size is DDB table size for both ports
1450                  * so divide it by 2 to calculate the offset for second port
1451                  */
1452                 if (ha->port_num == 1)
1453                         dev_db_start_offset += (ha->hw.flt_ddb_size / 2);
1454
1455                 dev_db_end_offset = dev_db_start_offset +
1456                                     (ha->hw.flt_ddb_size / 2);
1457         }
1458
1459         dev_db_start_offset += (ddb_index * sizeof(*fw_ddb_entry));
1460
1461         if (dev_db_start_offset > dev_db_end_offset) {
1462                 DEBUG2(ql4_printk(KERN_ERR, ha,
1463                                   "%s:Invalid DDB index %d", __func__,
1464                                   ddb_index));
1465                 goto exit_fdb_failed;
1466         }
1467
1468         if (qla4xxx_get_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,
1469                               sizeof(*fw_ddb_entry)) != QLA_SUCCESS) {
1470                 ql4_printk(KERN_ERR, ha, "scsi%ld: %s: Get Flash failed\n",
1471                            ha->host_no, __func__);
1472                 goto exit_fdb_failed;
1473         }
1474
1475         if (fw_ddb_entry->cookie == DDB_VALID_COOKIE)
1476                 status = QLA_SUCCESS;
1477
1478 exit_fdb_failed:
1479         return status;
1480 }
1481
1482 int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password,
1483                      uint16_t idx)
1484 {
1485         int ret = 0;
1486         int rval = QLA_ERROR;
1487         uint32_t offset = 0, chap_size;
1488         struct ql4_chap_table *chap_table;
1489         dma_addr_t chap_dma;
1490
1491         chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);
1492         if (chap_table == NULL)
1493                 return -ENOMEM;
1494
1495         chap_size = sizeof(struct ql4_chap_table);
1496         memset(chap_table, 0, chap_size);
1497
1498         if (is_qla40XX(ha))
1499                 offset = FLASH_CHAP_OFFSET | (idx * chap_size);
1500         else {
1501                 offset = FLASH_RAW_ACCESS_ADDR + (ha->hw.flt_region_chap << 2);
1502                 /* flt_chap_size is CHAP table size for both ports
1503                  * so divide it by 2 to calculate the offset for second port
1504                  */
1505                 if (ha->port_num == 1)
1506                         offset += (ha->hw.flt_chap_size / 2);
1507                 offset += (idx * chap_size);
1508         }
1509
1510         rval = qla4xxx_get_flash(ha, chap_dma, offset, chap_size);
1511         if (rval != QLA_SUCCESS) {
1512                 ret = -EINVAL;
1513                 goto exit_get_chap;
1514         }
1515
1516         DEBUG2(ql4_printk(KERN_INFO, ha, "Chap Cookie: x%x\n",
1517                 __le16_to_cpu(chap_table->cookie)));
1518
1519         if (__le16_to_cpu(chap_table->cookie) != CHAP_VALID_COOKIE) {
1520                 ql4_printk(KERN_ERR, ha, "No valid chap entry found\n");
1521                 goto exit_get_chap;
1522         }
1523
1524         strncpy(password, chap_table->secret, QL4_CHAP_MAX_SECRET_LEN);
1525         strncpy(username, chap_table->name, QL4_CHAP_MAX_NAME_LEN);
1526         chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE);
1527
1528 exit_get_chap:
1529         dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma);
1530         return ret;
1531 }
1532
1533 static int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username,
1534                             char *password, uint16_t idx, int bidi)
1535 {
1536         int ret = 0;
1537         int rval = QLA_ERROR;
1538         uint32_t offset = 0;
1539         struct ql4_chap_table *chap_table;
1540         dma_addr_t chap_dma;
1541
1542         chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);
1543         if (chap_table == NULL) {
1544                 ret =  -ENOMEM;
1545                 goto exit_set_chap;
1546         }
1547
1548         memset(chap_table, 0, sizeof(struct ql4_chap_table));
1549         if (bidi)
1550                 chap_table->flags |= BIT_6; /* peer */
1551         else
1552                 chap_table->flags |= BIT_7; /* local */
1553         chap_table->secret_len = strlen(password);
1554         strncpy(chap_table->secret, password, MAX_CHAP_SECRET_LEN);
1555         strncpy(chap_table->name, username, MAX_CHAP_NAME_LEN);
1556         chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE);
1557         offset = FLASH_CHAP_OFFSET | (idx * sizeof(struct ql4_chap_table));
1558         rval = qla4xxx_set_flash(ha, chap_dma, offset,
1559                                 sizeof(struct ql4_chap_table),
1560                                 FLASH_OPT_RMW_COMMIT);
1561
1562         if (rval == QLA_SUCCESS && ha->chap_list) {
1563                 /* Update ha chap_list cache */
1564                 memcpy((struct ql4_chap_table *)ha->chap_list + idx,
1565                        chap_table, sizeof(struct ql4_chap_table));
1566         }
1567         dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma);
1568         if (rval != QLA_SUCCESS)
1569                 ret =  -EINVAL;
1570
1571 exit_set_chap:
1572         return ret;
1573 }
1574
1575
1576 int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username,
1577                                   char *password, uint16_t chap_index)
1578 {
1579         int rval = QLA_ERROR;
1580         struct ql4_chap_table *chap_table = NULL;
1581         int max_chap_entries;
1582
1583         if (!ha->chap_list) {
1584                 ql4_printk(KERN_ERR, ha, "Do not have CHAP table cache\n");
1585                 rval = QLA_ERROR;
1586                 goto exit_uni_chap;
1587         }
1588
1589         if (!username || !password) {
1590                 ql4_printk(KERN_ERR, ha, "No memory for username & secret\n");
1591                 rval = QLA_ERROR;
1592                 goto exit_uni_chap;
1593         }
1594
1595         if (is_qla80XX(ha))
1596                 max_chap_entries = (ha->hw.flt_chap_size / 2) /
1597                                    sizeof(struct ql4_chap_table);
1598         else
1599                 max_chap_entries = MAX_CHAP_ENTRIES_40XX;
1600
1601         if (chap_index > max_chap_entries) {
1602                 ql4_printk(KERN_ERR, ha, "Invalid Chap index\n");
1603                 rval = QLA_ERROR;
1604                 goto exit_uni_chap;
1605         }
1606
1607         mutex_lock(&ha->chap_sem);
1608         chap_table = (struct ql4_chap_table *)ha->chap_list + chap_index;
1609         if (chap_table->cookie != __constant_cpu_to_le16(CHAP_VALID_COOKIE)) {
1610                 rval = QLA_ERROR;
1611                 goto exit_unlock_uni_chap;
1612         }
1613
1614         if (!(chap_table->flags & BIT_6)) {
1615                 ql4_printk(KERN_ERR, ha, "Unidirectional entry not set\n");
1616                 rval = QLA_ERROR;
1617                 goto exit_unlock_uni_chap;
1618         }
1619
1620         strncpy(password, chap_table->secret, MAX_CHAP_SECRET_LEN);
1621         strncpy(username, chap_table->name, MAX_CHAP_NAME_LEN);
1622
1623         rval = QLA_SUCCESS;
1624
1625 exit_unlock_uni_chap:
1626         mutex_unlock(&ha->chap_sem);
1627 exit_uni_chap:
1628         return rval;
1629 }
1630
1631 /**
1632  * qla4xxx_get_chap_index - Get chap index given username and secret
1633  * @ha: pointer to adapter structure
1634  * @username: CHAP username to be searched
1635  * @password: CHAP password to be searched
1636  * @bidi: Is this a BIDI CHAP
1637  * @chap_index: CHAP index to be returned
1638  *
1639  * Match the username and password in the chap_list, return the index if a
1640  * match is found. If a match is not found then add the entry in FLASH and
1641  * return the index at which entry is written in the FLASH.
1642  **/
1643 int qla4xxx_get_chap_index(struct scsi_qla_host *ha, char *username,
1644                            char *password, int bidi, uint16_t *chap_index)
1645 {
1646         int i, rval;
1647         int free_index = -1;
1648         int found_index = 0;
1649         int max_chap_entries = 0;
1650         struct ql4_chap_table *chap_table;
1651
1652         if (is_qla80XX(ha))
1653                 max_chap_entries = (ha->hw.flt_chap_size / 2) /
1654                                                 sizeof(struct ql4_chap_table);
1655         else
1656                 max_chap_entries = MAX_CHAP_ENTRIES_40XX;
1657
1658         if (!ha->chap_list) {
1659                 ql4_printk(KERN_ERR, ha, "Do not have CHAP table cache\n");
1660                 return QLA_ERROR;
1661         }
1662
1663         if (!username || !password) {
1664                 ql4_printk(KERN_ERR, ha, "Do not have username and psw\n");
1665                 return QLA_ERROR;
1666         }
1667
1668         mutex_lock(&ha->chap_sem);
1669         for (i = 0; i < max_chap_entries; i++) {
1670                 chap_table = (struct ql4_chap_table *)ha->chap_list + i;
1671                 if (chap_table->cookie !=
1672                     __constant_cpu_to_le16(CHAP_VALID_COOKIE)) {
1673                         if (i > MAX_RESRV_CHAP_IDX && free_index == -1)
1674                                 free_index = i;
1675                         continue;
1676                 }
1677                 if (bidi) {
1678                         if (chap_table->flags & BIT_7)
1679                                 continue;
1680                 } else {
1681                         if (chap_table->flags & BIT_6)
1682                                 continue;
1683                 }
1684                 if (!strncmp(chap_table->secret, password,
1685                              MAX_CHAP_SECRET_LEN) &&
1686                     !strncmp(chap_table->name, username,
1687                              MAX_CHAP_NAME_LEN)) {
1688                         *chap_index = i;
1689                         found_index = 1;
1690                         break;
1691                 }
1692         }
1693
1694         /* If chap entry is not present and a free index is available then
1695          * write the entry in flash
1696          */
1697         if (!found_index && free_index != -1) {
1698                 rval = qla4xxx_set_chap(ha, username, password,
1699                                         free_index, bidi);
1700                 if (!rval) {
1701                         *chap_index = free_index;
1702                         found_index = 1;
1703                 }
1704         }
1705
1706         mutex_unlock(&ha->chap_sem);
1707
1708         if (found_index)
1709                 return QLA_SUCCESS;
1710         return QLA_ERROR;
1711 }
1712
1713 int qla4xxx_conn_close_sess_logout(struct scsi_qla_host *ha,
1714                                    uint16_t fw_ddb_index,
1715                                    uint16_t connection_id,
1716                                    uint16_t option)
1717 {
1718         uint32_t mbox_cmd[MBOX_REG_COUNT];
1719         uint32_t mbox_sts[MBOX_REG_COUNT];
1720         int status = QLA_SUCCESS;
1721
1722         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1723         memset(&mbox_sts, 0, sizeof(mbox_sts));
1724
1725         mbox_cmd[0] = MBOX_CMD_CONN_CLOSE_SESS_LOGOUT;
1726         mbox_cmd[1] = fw_ddb_index;
1727         mbox_cmd[2] = connection_id;
1728         mbox_cmd[3] = option;
1729
1730         status = qla4xxx_mailbox_command(ha, 4, 2, &mbox_cmd[0], &mbox_sts[0]);
1731         if (status != QLA_SUCCESS) {
1732                 DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_CONN_CLOSE "
1733                                   "option %04x failed w/ status %04X %04X\n",
1734                                   __func__, option, mbox_sts[0], mbox_sts[1]));
1735         }
1736         return status;
1737 }
1738
1739 int qla4xxx_disable_acb(struct scsi_qla_host *ha)
1740 {
1741         uint32_t mbox_cmd[MBOX_REG_COUNT];
1742         uint32_t mbox_sts[MBOX_REG_COUNT];
1743         int status = QLA_SUCCESS;
1744
1745         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1746         memset(&mbox_sts, 0, sizeof(mbox_sts));
1747
1748         mbox_cmd[0] = MBOX_CMD_DISABLE_ACB;
1749
1750         status = qla4xxx_mailbox_command(ha, 8, 5, &mbox_cmd[0], &mbox_sts[0]);
1751         if (status != QLA_SUCCESS) {
1752                 DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_DISABLE_ACB "
1753                                   "failed w/ status %04X %04X %04X", __func__,
1754                                   mbox_sts[0], mbox_sts[1], mbox_sts[2]));
1755         }
1756         return status;
1757 }
1758
1759 int qla4xxx_get_acb(struct scsi_qla_host *ha, dma_addr_t acb_dma,
1760                     uint32_t acb_type, uint32_t len)
1761 {
1762         uint32_t mbox_cmd[MBOX_REG_COUNT];
1763         uint32_t mbox_sts[MBOX_REG_COUNT];
1764         int status = QLA_SUCCESS;
1765
1766         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
1767         memset(&mbox_sts, 0, sizeof(mbox_sts));
1768
1769         mbox_cmd[0] = MBOX_CMD_GET_ACB;
1770         mbox_cmd[1] = acb_type;
1771         mbox_cmd[2] = LSDW(acb_dma);
1772         mbox_cmd[3] = MSDW(acb_dma);
1773         mbox_cmd[4] = len;
1774
1775         status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]);
1776         if (status != QLA_SUCCESS) {
1777                 DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_GET_ACB "
1778                                   "failed w/ status %04X\n", __func__,
1779                                   mbox_sts[0]));
1780         }
1781         return status;
1782 }
1783
1784 int qla4xxx_set_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
1785                     uint32_t *mbox_sts, dma_addr_t acb_dma)
1786 {
1787         int status = QLA_SUCCESS;
1788
1789         memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
1790         memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
1791         mbox_cmd[0] = MBOX_CMD_SET_ACB;
1792         mbox_cmd[1] = 0; /* Primary ACB */
1793         mbox_cmd[2] = LSDW(acb_dma);
1794         mbox_cmd[3] = MSDW(acb_dma);
1795         mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
1796
1797         status = qla4xxx_mailbox_command(ha, 5, 5, &mbox_cmd[0], &mbox_sts[0]);
1798         if (status != QLA_SUCCESS) {
1799                 DEBUG2(ql4_printk(KERN_WARNING, ha,  "%s: MBOX_CMD_SET_ACB "
1800                                   "failed w/ status %04X\n", __func__,
1801                                   mbox_sts[0]));
1802         }
1803         return status;
1804 }
1805
1806 int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha,
1807                                struct ddb_entry *ddb_entry,
1808                                struct iscsi_cls_conn *cls_conn,
1809                                uint32_t *mbx_sts)
1810 {
1811         struct dev_db_entry *fw_ddb_entry;
1812         struct iscsi_conn *conn;
1813         struct iscsi_session *sess;
1814         struct qla_conn *qla_conn;
1815         struct sockaddr *dst_addr;
1816         dma_addr_t fw_ddb_entry_dma;
1817         int status = QLA_SUCCESS;
1818         int rval = 0;
1819         struct sockaddr_in *addr;
1820         struct sockaddr_in6 *addr6;
1821         char *ip;
1822         uint16_t iscsi_opts = 0;
1823         uint32_t options = 0;
1824         uint16_t idx, *ptid;
1825
1826         fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1827                                           &fw_ddb_entry_dma, GFP_KERNEL);
1828         if (!fw_ddb_entry) {
1829                 DEBUG2(ql4_printk(KERN_ERR, ha,
1830                                   "%s: Unable to allocate dma buffer.\n",
1831                                   __func__));
1832                 rval = -ENOMEM;
1833                 goto exit_set_param_no_free;
1834         }
1835
1836         conn = cls_conn->dd_data;
1837         qla_conn = conn->dd_data;
1838         sess = conn->session;
1839         dst_addr = (struct sockaddr *)&qla_conn->qla_ep->dst_addr;
1840
1841         if (dst_addr->sa_family == AF_INET6)
1842                 options |= IPV6_DEFAULT_DDB_ENTRY;
1843
1844         status = qla4xxx_get_default_ddb(ha, options, fw_ddb_entry_dma);
1845         if (status == QLA_ERROR) {
1846                 rval = -EINVAL;
1847                 goto exit_set_param;
1848         }
1849
1850         ptid = (uint16_t *)&fw_ddb_entry->isid[1];
1851         *ptid = cpu_to_le16((uint16_t)ddb_entry->sess->target_id);
1852
1853         DEBUG2(ql4_printk(KERN_INFO, ha, "ISID [%02x%02x%02x%02x%02x%02x]\n",
1854                           fw_ddb_entry->isid[5], fw_ddb_entry->isid[4],
1855                           fw_ddb_entry->isid[3], fw_ddb_entry->isid[2],
1856                           fw_ddb_entry->isid[1], fw_ddb_entry->isid[0]));
1857
1858         iscsi_opts = le16_to_cpu(fw_ddb_entry->iscsi_options);
1859         memset(fw_ddb_entry->iscsi_alias, 0, sizeof(fw_ddb_entry->iscsi_alias));
1860
1861         memset(fw_ddb_entry->iscsi_name, 0, sizeof(fw_ddb_entry->iscsi_name));
1862
1863         if (sess->targetname != NULL) {
1864                 memcpy(fw_ddb_entry->iscsi_name, sess->targetname,
1865                        min(strlen(sess->targetname),
1866                        sizeof(fw_ddb_entry->iscsi_name)));
1867         }
1868
1869         memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr));
1870         memset(fw_ddb_entry->tgt_addr, 0, sizeof(fw_ddb_entry->tgt_addr));
1871
1872         fw_ddb_entry->options =  DDB_OPT_TARGET | DDB_OPT_AUTO_SENDTGTS_DISABLE;
1873
1874         if (dst_addr->sa_family == AF_INET) {
1875                 addr = (struct sockaddr_in *)dst_addr;
1876                 ip = (char *)&addr->sin_addr;
1877                 memcpy(fw_ddb_entry->ip_addr, ip, IP_ADDR_LEN);
1878                 fw_ddb_entry->port = cpu_to_le16(ntohs(addr->sin_port));
1879                 DEBUG2(ql4_printk(KERN_INFO, ha,
1880                                   "%s: Destination Address [%pI4]: index [%d]\n",
1881                                    __func__, fw_ddb_entry->ip_addr,
1882                                   ddb_entry->fw_ddb_index));
1883         } else if (dst_addr->sa_family == AF_INET6) {
1884                 addr6 = (struct sockaddr_in6 *)dst_addr;
1885                 ip = (char *)&addr6->sin6_addr;
1886                 memcpy(fw_ddb_entry->ip_addr, ip, IPv6_ADDR_LEN);
1887                 fw_ddb_entry->port = cpu_to_le16(ntohs(addr6->sin6_port));
1888                 fw_ddb_entry->options |= DDB_OPT_IPV6_DEVICE;
1889                 DEBUG2(ql4_printk(KERN_INFO, ha,
1890                                   "%s: Destination Address [%pI6]: index [%d]\n",
1891                                    __func__, fw_ddb_entry->ip_addr,
1892                                   ddb_entry->fw_ddb_index));
1893         } else {
1894                 ql4_printk(KERN_ERR, ha,
1895                            "%s: Failed to get IP Address\n",
1896                            __func__);
1897                 rval = -EINVAL;
1898                 goto exit_set_param;
1899         }
1900
1901         /* CHAP */
1902         if (sess->username != NULL && sess->password != NULL) {
1903                 if (strlen(sess->username) && strlen(sess->password)) {
1904                         iscsi_opts |= BIT_7;
1905
1906                         rval = qla4xxx_get_chap_index(ha, sess->username,
1907                                                 sess->password,
1908                                                 LOCAL_CHAP, &idx);
1909                         if (rval)
1910                                 goto exit_set_param;
1911
1912                         fw_ddb_entry->chap_tbl_idx = cpu_to_le16(idx);
1913                 }
1914         }
1915
1916         if (sess->username_in != NULL && sess->password_in != NULL) {
1917                 /* Check if BIDI CHAP */
1918                 if (strlen(sess->username_in) && strlen(sess->password_in)) {
1919                         iscsi_opts |= BIT_4;
1920
1921                         rval = qla4xxx_get_chap_index(ha, sess->username_in,
1922                                                       sess->password_in,
1923                                                       BIDI_CHAP, &idx);
1924                         if (rval)
1925                                 goto exit_set_param;
1926                 }
1927         }
1928
1929         if (sess->initial_r2t_en)
1930                 iscsi_opts |= BIT_10;
1931
1932         if (sess->imm_data_en)
1933                 iscsi_opts |= BIT_11;
1934
1935         fw_ddb_entry->iscsi_options = cpu_to_le16(iscsi_opts);
1936
1937         if (conn->max_recv_dlength)
1938                 fw_ddb_entry->iscsi_max_rcv_data_seg_len =
1939                   __constant_cpu_to_le16((conn->max_recv_dlength / BYTE_UNITS));
1940
1941         if (sess->max_r2t)
1942                 fw_ddb_entry->iscsi_max_outsnd_r2t = cpu_to_le16(sess->max_r2t);
1943
1944         if (sess->first_burst)
1945                 fw_ddb_entry->iscsi_first_burst_len =
1946                        __constant_cpu_to_le16((sess->first_burst / BYTE_UNITS));
1947
1948         if (sess->max_burst)
1949                 fw_ddb_entry->iscsi_max_burst_len =
1950                         __constant_cpu_to_le16((sess->max_burst / BYTE_UNITS));
1951
1952         if (sess->time2wait)
1953                 fw_ddb_entry->iscsi_def_time2wait =
1954                         cpu_to_le16(sess->time2wait);
1955
1956         if (sess->time2retain)
1957                 fw_ddb_entry->iscsi_def_time2retain =
1958                         cpu_to_le16(sess->time2retain);
1959
1960         status = qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index,
1961                                        fw_ddb_entry_dma, mbx_sts);
1962
1963         if (status != QLA_SUCCESS)
1964                 rval = -EINVAL;
1965 exit_set_param:
1966         dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1967                           fw_ddb_entry, fw_ddb_entry_dma);
1968 exit_set_param_no_free:
1969         return rval;
1970 }
1971
1972 int qla4xxx_get_mgmt_data(struct scsi_qla_host *ha, uint16_t fw_ddb_index,
1973                           uint16_t stats_size, dma_addr_t stats_dma)
1974 {
1975         int status = QLA_SUCCESS;
1976         uint32_t mbox_cmd[MBOX_REG_COUNT];
1977         uint32_t mbox_sts[MBOX_REG_COUNT];
1978
1979         memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
1980         memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
1981         mbox_cmd[0] = MBOX_CMD_GET_MANAGEMENT_DATA;
1982         mbox_cmd[1] = fw_ddb_index;
1983         mbox_cmd[2] = LSDW(stats_dma);
1984         mbox_cmd[3] = MSDW(stats_dma);
1985         mbox_cmd[4] = stats_size;
1986
1987         status = qla4xxx_mailbox_command(ha, 5, 1, &mbox_cmd[0], &mbox_sts[0]);
1988         if (status != QLA_SUCCESS) {
1989                 DEBUG2(ql4_printk(KERN_WARNING, ha,
1990                                   "%s: MBOX_CMD_GET_MANAGEMENT_DATA "
1991                                   "failed w/ status %04X\n", __func__,
1992                                   mbox_sts[0]));
1993         }
1994         return status;
1995 }
1996
1997 int qla4xxx_get_ip_state(struct scsi_qla_host *ha, uint32_t acb_idx,
1998                          uint32_t ip_idx, uint32_t *sts)
1999 {
2000         uint32_t mbox_cmd[MBOX_REG_COUNT];
2001         uint32_t mbox_sts[MBOX_REG_COUNT];
2002         int status = QLA_SUCCESS;
2003
2004         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
2005         memset(&mbox_sts, 0, sizeof(mbox_sts));
2006         mbox_cmd[0] = MBOX_CMD_GET_IP_ADDR_STATE;
2007         mbox_cmd[1] = acb_idx;
2008         mbox_cmd[2] = ip_idx;
2009
2010         status = qla4xxx_mailbox_command(ha, 3, 8, &mbox_cmd[0], &mbox_sts[0]);
2011         if (status != QLA_SUCCESS) {
2012                 DEBUG2(ql4_printk(KERN_WARNING, ha,  "%s: "
2013                                   "MBOX_CMD_GET_IP_ADDR_STATE failed w/ "
2014                                   "status %04X\n", __func__, mbox_sts[0]));
2015         }
2016         memcpy(sts, mbox_sts, sizeof(mbox_sts));
2017         return status;
2018 }
2019
2020 int qla4xxx_get_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma,
2021                       uint32_t offset, uint32_t size)
2022 {
2023         int status = QLA_SUCCESS;
2024         uint32_t mbox_cmd[MBOX_REG_COUNT];
2025         uint32_t mbox_sts[MBOX_REG_COUNT];
2026
2027         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
2028         memset(&mbox_sts, 0, sizeof(mbox_sts));
2029
2030         mbox_cmd[0] = MBOX_CMD_GET_NVRAM;
2031         mbox_cmd[1] = LSDW(nvram_dma);
2032         mbox_cmd[2] = MSDW(nvram_dma);
2033         mbox_cmd[3] = offset;
2034         mbox_cmd[4] = size;
2035
2036         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
2037                                          &mbox_sts[0]);
2038         if (status != QLA_SUCCESS) {
2039                 DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "
2040                                   "status %04X\n", ha->host_no, __func__,
2041                                   mbox_sts[0]));
2042         }
2043         return status;
2044 }
2045
2046 int qla4xxx_set_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma,
2047                       uint32_t offset, uint32_t size)
2048 {
2049         int status = QLA_SUCCESS;
2050         uint32_t mbox_cmd[MBOX_REG_COUNT];
2051         uint32_t mbox_sts[MBOX_REG_COUNT];
2052
2053         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
2054         memset(&mbox_sts, 0, sizeof(mbox_sts));
2055
2056         mbox_cmd[0] = MBOX_CMD_SET_NVRAM;
2057         mbox_cmd[1] = LSDW(nvram_dma);
2058         mbox_cmd[2] = MSDW(nvram_dma);
2059         mbox_cmd[3] = offset;
2060         mbox_cmd[4] = size;
2061
2062         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
2063                                          &mbox_sts[0]);
2064         if (status != QLA_SUCCESS) {
2065                 DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "
2066                                   "status %04X\n", ha->host_no, __func__,
2067                                   mbox_sts[0]));
2068         }
2069         return status;
2070 }
2071
2072 int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha,
2073                                      uint32_t region, uint32_t field0,
2074                                      uint32_t field1)
2075 {
2076         int status = QLA_SUCCESS;
2077         uint32_t mbox_cmd[MBOX_REG_COUNT];
2078         uint32_t mbox_sts[MBOX_REG_COUNT];
2079
2080         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
2081         memset(&mbox_sts, 0, sizeof(mbox_sts));
2082
2083         mbox_cmd[0] = MBOX_CMD_RESTORE_FACTORY_DEFAULTS;
2084         mbox_cmd[3] = region;
2085         mbox_cmd[4] = field0;
2086         mbox_cmd[5] = field1;
2087
2088         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0],
2089                                          &mbox_sts[0]);
2090         if (status != QLA_SUCCESS) {
2091                 DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "
2092                                   "status %04X\n", ha->host_no, __func__,
2093                                   mbox_sts[0]));
2094         }
2095         return status;
2096 }
2097
2098 /**
2099  * qla4_8xxx_set_param - set driver version in firmware.
2100  * @ha: Pointer to host adapter structure.
2101  * @param: Parameter to set i.e driver version
2102  **/
2103 int qla4_8xxx_set_param(struct scsi_qla_host *ha, int param)
2104 {
2105         uint32_t mbox_cmd[MBOX_REG_COUNT];
2106         uint32_t mbox_sts[MBOX_REG_COUNT];
2107         uint32_t status;
2108
2109         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
2110         memset(&mbox_sts, 0, sizeof(mbox_sts));
2111
2112         mbox_cmd[0] = MBOX_CMD_SET_PARAM;
2113         if (param == SET_DRVR_VERSION) {
2114                 mbox_cmd[1] = SET_DRVR_VERSION;
2115                 strncpy((char *)&mbox_cmd[2], QLA4XXX_DRIVER_VERSION,
2116                         MAX_DRVR_VER_LEN);
2117         } else {
2118                 ql4_printk(KERN_ERR, ha, "%s: invalid parameter 0x%x\n",
2119                            __func__, param);
2120                 status = QLA_ERROR;
2121                 goto exit_set_param;
2122         }
2123
2124         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, mbox_cmd,
2125                                          mbox_sts);
2126         if (status == QLA_ERROR)
2127                 ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n",
2128                            __func__, mbox_sts[0]);
2129
2130 exit_set_param:
2131         return status;
2132 }
2133
2134 /**
2135  * qla4_83xx_post_idc_ack - post IDC ACK
2136  * @ha: Pointer to host adapter structure.
2137  *
2138  * Posts IDC ACK for IDC Request Notification AEN.
2139  **/
2140 int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha)
2141 {
2142         uint32_t mbox_cmd[MBOX_REG_COUNT];
2143         uint32_t mbox_sts[MBOX_REG_COUNT];
2144         int status;
2145
2146         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
2147         memset(&mbox_sts, 0, sizeof(mbox_sts));
2148
2149         mbox_cmd[0] = MBOX_CMD_IDC_ACK;
2150         mbox_cmd[1] = ha->idc_info.request_desc;
2151         mbox_cmd[2] = ha->idc_info.info1;
2152         mbox_cmd[3] = ha->idc_info.info2;
2153         mbox_cmd[4] = ha->idc_info.info3;
2154
2155         status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,
2156                                          mbox_cmd, mbox_sts);
2157         if (status == QLA_ERROR)
2158                 ql4_printk(KERN_ERR, ha, "%s: failed status %04X\n", __func__,
2159                            mbox_sts[0]);
2160         else
2161                DEBUG2(ql4_printk(KERN_INFO, ha, "%s: IDC ACK posted\n",
2162                                  __func__));
2163
2164         return status;
2165 }