[SCSI] qla4xxx: added IPv6 support.
[linux-2.6.git] / drivers / scsi / qla4xxx / ql4_mbx.c
1 /*
2  * QLogic iSCSI HBA Driver
3  * Copyright (c)  2003-2006 QLogic Corporation
4  *
5  * See LICENSE.qla4xxx for copyright and licensing details.
6  */
7
8 #include "ql4_def.h"
9 #include "ql4_glbl.h"
10 #include "ql4_dbg.h"
11 #include "ql4_inline.h"
12
13
14 /**
15  * qla4xxx_mailbox_command - issues mailbox commands
16  * @ha: Pointer to host adapter structure.
17  * @inCount: number of mailbox registers to load.
18  * @outCount: number of mailbox registers to return.
19  * @mbx_cmd: data pointer for mailbox in registers.
20  * @mbx_sts: data pointer for mailbox out registers.
21  *
22  * This routine sssue mailbox commands and waits for completion.
23  * If outCount is 0, this routine completes successfully WITHOUT waiting
24  * for the mailbox command to complete.
25  **/
26 static int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
27                                    uint8_t outCount, uint32_t *mbx_cmd,
28                                    uint32_t *mbx_sts)
29 {
30         int status = QLA_ERROR;
31         uint8_t i;
32         u_long wait_count;
33         uint32_t intr_status;
34         unsigned long flags = 0;
35
36         /* Make sure that pointers are valid */
37         if (!mbx_cmd || !mbx_sts) {
38                 DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts "
39                               "pointer\n", ha->host_no, __func__));
40                 return status;
41         }
42         /* Mailbox code active */
43         wait_count = MBOX_TOV * 100;
44
45         while (wait_count--) {
46                 mutex_lock(&ha->mbox_sem);
47                 if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) {
48                         set_bit(AF_MBOX_COMMAND, &ha->flags);
49                         mutex_unlock(&ha->mbox_sem);
50                         break;
51                 }
52                 mutex_unlock(&ha->mbox_sem);
53                 if (!wait_count) {
54                         DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n",
55                                 ha->host_no, __func__));
56                         return status;
57                 }
58                 msleep(10);
59         }
60
61         /* To prevent overwriting mailbox registers for a command that has
62          * not yet been serviced, check to see if a previously issued
63          * mailbox command is interrupting.
64          * -----------------------------------------------------------------
65          */
66         spin_lock_irqsave(&ha->hardware_lock, flags);
67         intr_status = readl(&ha->reg->ctrl_status);
68         if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
69                 /* Service existing interrupt */
70                 qla4xxx_interrupt_service_routine(ha, intr_status);
71                 clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
72         }
73
74         /* Send the mailbox command to the firmware */
75         ha->mbox_status_count = outCount;
76         for (i = 0; i < outCount; i++)
77                 ha->mbox_status[i] = 0;
78
79         /* Load all mailbox registers, except mailbox 0. */
80         for (i = 1; i < inCount; i++)
81                 writel(mbx_cmd[i], &ha->reg->mailbox[i]);
82
83         /* Wakeup firmware  */
84         writel(mbx_cmd[0], &ha->reg->mailbox[0]);
85         readl(&ha->reg->mailbox[0]);
86         writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
87         readl(&ha->reg->ctrl_status);
88         spin_unlock_irqrestore(&ha->hardware_lock, flags);
89
90         /* Wait for completion */
91
92         /*
93          * If we don't want status, don't wait for the mailbox command to
94          * complete.  For example, MBOX_CMD_RESET_FW doesn't return status,
95          * you must poll the inbound Interrupt Mask for completion.
96          */
97         if (outCount == 0) {
98                 status = QLA_SUCCESS;
99                 goto mbox_exit;
100         }
101         /* Wait for command to complete */
102         wait_count = jiffies + MBOX_TOV * HZ;
103         while (test_bit(AF_MBOX_COMMAND_DONE, &ha->flags) == 0) {
104                 if (time_after_eq(jiffies, wait_count))
105                         break;
106
107                 spin_lock_irqsave(&ha->hardware_lock, flags);
108                 intr_status = readl(&ha->reg->ctrl_status);
109                 if (intr_status & INTR_PENDING) {
110                         /*
111                          * Service the interrupt.
112                          * The ISR will save the mailbox status registers
113                          * to a temporary storage location in the adapter
114                          * structure.
115                          */
116                         ha->mbox_status_count = outCount;
117                         qla4xxx_interrupt_service_routine(ha, intr_status);
118                 }
119                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
120                 msleep(10);
121         }
122
123         /* Check for mailbox timeout. */
124         if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) {
125                 DEBUG2(printk("scsi%ld: Mailbox Cmd 0x%08X timed out ...,"
126                               " Scheduling Adapter Reset\n", ha->host_no,
127                               mbx_cmd[0]));
128                 ha->mailbox_timeout_count++;
129                 mbx_sts[0] = (-1);
130                 set_bit(DPC_RESET_HA, &ha->dpc_flags);
131                 goto mbox_exit;
132         }
133
134         /*
135          * Copy the mailbox out registers to the caller's mailbox in/out
136          * structure.
137          */
138         spin_lock_irqsave(&ha->hardware_lock, flags);
139         for (i = 0; i < outCount; i++)
140                 mbx_sts[i] = ha->mbox_status[i];
141
142         /* Set return status and error flags (if applicable). */
143         switch (ha->mbox_status[0]) {
144         case MBOX_STS_COMMAND_COMPLETE:
145                 status = QLA_SUCCESS;
146                 break;
147
148         case MBOX_STS_INTERMEDIATE_COMPLETION:
149                 status = QLA_SUCCESS;
150                 break;
151
152         case MBOX_STS_BUSY:
153                 DEBUG2( printk("scsi%ld: %s: Cmd = %08X, ISP BUSY\n",
154                                ha->host_no, __func__, mbx_cmd[0]));
155                 ha->mailbox_timeout_count++;
156                 break;
157
158         default:
159                 DEBUG2(printk("scsi%ld: %s: **** FAILED, cmd = %08X, "
160                               "sts = %08X ****\n", ha->host_no, __func__,
161                               mbx_cmd[0], mbx_sts[0]));
162                 break;
163         }
164         spin_unlock_irqrestore(&ha->hardware_lock, flags);
165
166 mbox_exit:
167         mutex_lock(&ha->mbox_sem);
168         clear_bit(AF_MBOX_COMMAND, &ha->flags);
169         mutex_unlock(&ha->mbox_sem);
170         clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
171
172         return status;
173 }
174
175 uint8_t
176 qla4xxx_set_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
177                  uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)
178 {
179         memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
180         memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
181         mbox_cmd[0] = MBOX_CMD_INITIALIZE_FIRMWARE;
182         mbox_cmd[1] = 0;
183         mbox_cmd[2] = LSDW(init_fw_cb_dma);
184         mbox_cmd[3] = MSDW(init_fw_cb_dma);
185         mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
186         mbox_cmd[5] = (IFCB_VER_MAX << 8) | IFCB_VER_MIN;
187
188         if (qla4xxx_mailbox_command(ha, 6, 6, mbox_cmd, mbox_sts) !=
189             QLA_SUCCESS) {
190                 DEBUG2(printk(KERN_WARNING "scsi%ld: %s: "
191                               "MBOX_CMD_INITIALIZE_FIRMWARE"
192                               " failed w/ status %04X\n",
193                               ha->host_no, __func__, mbox_sts[0]));
194                 return QLA_ERROR;
195         }
196         return QLA_SUCCESS;
197 }
198
199 uint8_t
200 qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
201                  uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma)
202 {
203         memset(mbox_cmd, 0, sizeof(mbox_cmd[0]) * MBOX_REG_COUNT);
204         memset(mbox_sts, 0, sizeof(mbox_sts[0]) * MBOX_REG_COUNT);
205         mbox_cmd[0] = MBOX_CMD_GET_INIT_FW_CTRL_BLOCK;
206         mbox_cmd[2] = LSDW(init_fw_cb_dma);
207         mbox_cmd[3] = MSDW(init_fw_cb_dma);
208         mbox_cmd[4] = sizeof(struct addr_ctrl_blk);
209
210         if (qla4xxx_mailbox_command(ha, 5, 5, mbox_cmd, mbox_sts) !=
211             QLA_SUCCESS) {
212                 DEBUG2(printk(KERN_WARNING "scsi%ld: %s: "
213                               "MBOX_CMD_GET_INIT_FW_CTRL_BLOCK"
214                               " failed w/ status %04X\n",
215                               ha->host_no, __func__, mbox_sts[0]));
216                 return QLA_ERROR;
217         }
218         return QLA_SUCCESS;
219 }
220
221 void
222 qla4xxx_update_local_ip(struct scsi_qla_host *ha,
223                          struct addr_ctrl_blk  *init_fw_cb)
224 {
225         /* Save IPv4 Address Info */
226         memcpy(ha->ip_address, init_fw_cb->ipv4_addr,
227                 min(sizeof(ha->ip_address), sizeof(init_fw_cb->ipv4_addr)));
228         memcpy(ha->subnet_mask, init_fw_cb->ipv4_subnet,
229                 min(sizeof(ha->subnet_mask), sizeof(init_fw_cb->ipv4_subnet)));
230         memcpy(ha->gateway, init_fw_cb->ipv4_gw_addr,
231                 min(sizeof(ha->gateway), sizeof(init_fw_cb->ipv4_gw_addr)));
232
233         if (is_ipv6_enabled(ha)) {
234                 /* Save IPv6 Address */
235                 ha->ipv6_link_local_state = init_fw_cb->ipv6_lnk_lcl_addr_state;
236                 ha->ipv6_addr0_state = init_fw_cb->ipv6_addr0_state;
237                 ha->ipv6_addr1_state = init_fw_cb->ipv6_addr1_state;
238                 ha->ipv6_default_router_state = init_fw_cb->ipv6_dflt_rtr_state;
239                 ha->ipv6_link_local_addr.in6_u.u6_addr8[0] = 0xFE;
240                 ha->ipv6_link_local_addr.in6_u.u6_addr8[1] = 0x80;
241
242                 memcpy(&ha->ipv6_link_local_addr.in6_u.u6_addr8[8],
243                         init_fw_cb->ipv6_if_id,
244                         min(sizeof(ha->ipv6_link_local_addr)/2,
245                         sizeof(init_fw_cb->ipv6_if_id)));
246                 memcpy(&ha->ipv6_addr0, init_fw_cb->ipv6_addr0,
247                         min(sizeof(ha->ipv6_addr0),
248                         sizeof(init_fw_cb->ipv6_addr0)));
249                 memcpy(&ha->ipv6_addr1, init_fw_cb->ipv6_addr1,
250                         min(sizeof(ha->ipv6_addr1),
251                         sizeof(init_fw_cb->ipv6_addr1)));
252                 memcpy(&ha->ipv6_default_router_addr,
253                         init_fw_cb->ipv6_dflt_rtr_addr,
254                         min(sizeof(ha->ipv6_default_router_addr),
255                         sizeof(init_fw_cb->ipv6_dflt_rtr_addr)));
256         }
257 }
258
259 uint8_t
260 qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,
261                           uint32_t *mbox_cmd,
262                           uint32_t *mbox_sts,
263                           struct addr_ctrl_blk  *init_fw_cb,
264                           dma_addr_t init_fw_cb_dma)
265 {
266         if (qla4xxx_get_ifcb(ha, mbox_cmd, mbox_sts, init_fw_cb_dma)
267             != QLA_SUCCESS) {
268                 DEBUG2(printk(KERN_WARNING
269                               "scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
270                               ha->host_no, __func__));
271                 return QLA_ERROR;
272         }
273
274         DEBUG2(qla4xxx_dump_buffer(init_fw_cb, sizeof(struct addr_ctrl_blk)));
275
276         /* Save some info in adapter structure. */
277         ha->acb_version = init_fw_cb->acb_version;
278         ha->firmware_options = le16_to_cpu(init_fw_cb->fw_options);
279         ha->tcp_options = le16_to_cpu(init_fw_cb->ipv4_tcp_opts);
280         ha->ipv4_options = le16_to_cpu(init_fw_cb->ipv4_ip_opts);
281         ha->ipv4_addr_state = le16_to_cpu(init_fw_cb->ipv4_addr_state);
282         ha->heartbeat_interval = init_fw_cb->hb_interval;
283         memcpy(ha->name_string, init_fw_cb->iscsi_name,
284                 min(sizeof(ha->name_string),
285                 sizeof(init_fw_cb->iscsi_name)));
286         /*memcpy(ha->alias, init_fw_cb->Alias,
287                min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/
288
289         /* Save Command Line Paramater info */
290         ha->port_down_retry_count = le16_to_cpu(init_fw_cb->conn_ka_timeout);
291         ha->discovery_wait = ql4xdiscoverywait;
292
293         if (ha->acb_version == ACB_SUPPORTED) {
294                 ha->ipv6_options = init_fw_cb->ipv6_opts;
295                 ha->ipv6_addl_options = init_fw_cb->ipv6_addtl_opts;
296         }
297         qla4xxx_update_local_ip(ha, init_fw_cb);
298
299         return QLA_SUCCESS;
300 }
301
302 /**
303  * qla4xxx_initialize_fw_cb - initializes firmware control block.
304  * @ha: Pointer to host adapter structure.
305  **/
306 int qla4xxx_initialize_fw_cb(struct scsi_qla_host * ha)
307 {
308         struct addr_ctrl_blk *init_fw_cb;
309         dma_addr_t init_fw_cb_dma;
310         uint32_t mbox_cmd[MBOX_REG_COUNT];
311         uint32_t mbox_sts[MBOX_REG_COUNT];
312         int status = QLA_ERROR;
313
314         init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
315                                         sizeof(struct addr_ctrl_blk),
316                                         &init_fw_cb_dma, GFP_KERNEL);
317         if (init_fw_cb == NULL) {
318                 DEBUG2(printk("scsi%ld: %s: Unable to alloc init_cb\n",
319                               ha->host_no, __func__));
320                 return 10;
321         }
322         memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk));
323
324         /* Get Initialize Firmware Control Block. */
325         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
326         memset(&mbox_sts, 0, sizeof(mbox_sts));
327
328         if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) !=
329             QLA_SUCCESS) {
330                 dma_free_coherent(&ha->pdev->dev,
331                                   sizeof(struct addr_ctrl_blk),
332                                   init_fw_cb, init_fw_cb_dma);
333                 goto exit_init_fw_cb;
334         }
335
336         /* Initialize request and response queues. */
337         qla4xxx_init_rings(ha);
338
339         /* Fill in the request and response queue information. */
340         init_fw_cb->rqq_consumer_idx = cpu_to_le16(ha->request_out);
341         init_fw_cb->compq_producer_idx = cpu_to_le16(ha->response_in);
342         init_fw_cb->rqq_len = __constant_cpu_to_le16(REQUEST_QUEUE_DEPTH);
343         init_fw_cb->compq_len = __constant_cpu_to_le16(RESPONSE_QUEUE_DEPTH);
344         init_fw_cb->rqq_addr_lo = cpu_to_le32(LSDW(ha->request_dma));
345         init_fw_cb->rqq_addr_hi = cpu_to_le32(MSDW(ha->request_dma));
346         init_fw_cb->compq_addr_lo = cpu_to_le32(LSDW(ha->response_dma));
347         init_fw_cb->compq_addr_hi = cpu_to_le32(MSDW(ha->response_dma));
348         init_fw_cb->shdwreg_addr_lo = cpu_to_le32(LSDW(ha->shadow_regs_dma));
349         init_fw_cb->shdwreg_addr_hi = cpu_to_le32(MSDW(ha->shadow_regs_dma));
350
351         /* Set up required options. */
352         init_fw_cb->fw_options |=
353                 __constant_cpu_to_le16(FWOPT_SESSION_MODE |
354                                        FWOPT_INITIATOR_MODE);
355         init_fw_cb->fw_options &= __constant_cpu_to_le16(~FWOPT_TARGET_MODE);
356
357         if (qla4xxx_set_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma)
358                 != QLA_SUCCESS) {
359                 DEBUG2(printk(KERN_WARNING
360                               "scsi%ld: %s: Failed to set init_fw_ctrl_blk\n",
361                               ha->host_no, __func__));
362                 goto exit_init_fw_cb;
363         }
364
365         if (qla4xxx_update_local_ifcb(ha, &mbox_cmd[0], &mbox_sts[0],
366                 init_fw_cb, init_fw_cb_dma) != QLA_SUCCESS) {
367                 DEBUG2(printk("scsi%ld: %s: Failed to update local ifcb\n",
368                                 ha->host_no, __func__));
369                 goto exit_init_fw_cb;
370         }
371         status = QLA_SUCCESS;
372
373 exit_init_fw_cb:
374         dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),
375                                 init_fw_cb, init_fw_cb_dma);
376
377         return status;
378 }
379
380 /**
381  * qla4xxx_get_dhcp_ip_address - gets HBA ip address via DHCP
382  * @ha: Pointer to host adapter structure.
383  **/
384 int qla4xxx_get_dhcp_ip_address(struct scsi_qla_host * ha)
385 {
386         struct addr_ctrl_blk *init_fw_cb;
387         dma_addr_t init_fw_cb_dma;
388         uint32_t mbox_cmd[MBOX_REG_COUNT];
389         uint32_t mbox_sts[MBOX_REG_COUNT];
390
391         init_fw_cb = dma_alloc_coherent(&ha->pdev->dev,
392                                         sizeof(struct addr_ctrl_blk),
393                                         &init_fw_cb_dma, GFP_KERNEL);
394         if (init_fw_cb == NULL) {
395                 printk("scsi%ld: %s: Unable to alloc init_cb\n", ha->host_no,
396                        __func__);
397                 return 10;
398         }
399
400         /* Get Initialize Firmware Control Block. */
401         memset(init_fw_cb, 0, sizeof(struct addr_ctrl_blk));
402         if (qla4xxx_get_ifcb(ha, &mbox_cmd[0], &mbox_sts[0], init_fw_cb_dma) !=
403             QLA_SUCCESS) {
404                 DEBUG2(printk("scsi%ld: %s: Failed to get init_fw_ctrl_blk\n",
405                               ha->host_no, __func__));
406                 dma_free_coherent(&ha->pdev->dev,
407                                   sizeof(struct addr_ctrl_blk),
408                                   init_fw_cb, init_fw_cb_dma);
409                 return QLA_ERROR;
410         }
411
412         /* Save IP Address. */
413         qla4xxx_update_local_ip(ha, init_fw_cb);
414         dma_free_coherent(&ha->pdev->dev, sizeof(struct addr_ctrl_blk),
415                                 init_fw_cb, init_fw_cb_dma);
416
417         return QLA_SUCCESS;
418 }
419
420 /**
421  * qla4xxx_get_firmware_state - gets firmware state of HBA
422  * @ha: Pointer to host adapter structure.
423  **/
424 int qla4xxx_get_firmware_state(struct scsi_qla_host * ha)
425 {
426         uint32_t mbox_cmd[MBOX_REG_COUNT];
427         uint32_t mbox_sts[MBOX_REG_COUNT];
428
429         /* Get firmware version */
430         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
431         memset(&mbox_sts, 0, sizeof(mbox_sts));
432
433         mbox_cmd[0] = MBOX_CMD_GET_FW_STATE;
434
435         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 4, &mbox_cmd[0], &mbox_sts[0]) !=
436             QLA_SUCCESS) {
437                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATE failed w/ "
438                               "status %04X\n", ha->host_no, __func__,
439                               mbox_sts[0]));
440                 return QLA_ERROR;
441         }
442         ha->firmware_state = mbox_sts[1];
443         ha->board_id = mbox_sts[2];
444         ha->addl_fw_state = mbox_sts[3];
445         DEBUG2(printk("scsi%ld: %s firmware_state=0x%x\n",
446                       ha->host_no, __func__, ha->firmware_state);)
447
448                 return QLA_SUCCESS;
449 }
450
451 /**
452  * qla4xxx_get_firmware_status - retrieves firmware status
453  * @ha: Pointer to host adapter structure.
454  **/
455 int qla4xxx_get_firmware_status(struct scsi_qla_host * ha)
456 {
457         uint32_t mbox_cmd[MBOX_REG_COUNT];
458         uint32_t mbox_sts[MBOX_REG_COUNT];
459
460         /* Get firmware version */
461         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
462         memset(&mbox_sts, 0, sizeof(mbox_sts));
463
464         mbox_cmd[0] = MBOX_CMD_GET_FW_STATUS;
465
466         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=
467             QLA_SUCCESS) {
468                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_FW_STATUS failed w/ "
469                               "status %04X\n", ha->host_no, __func__,
470                               mbox_sts[0]));
471                 return QLA_ERROR;
472         }
473         return QLA_SUCCESS;
474 }
475
476 /**
477  * qla4xxx_get_fwddb_entry - retrieves firmware ddb entry
478  * @ha: Pointer to host adapter structure.
479  * @fw_ddb_index: Firmware's device database index
480  * @fw_ddb_entry: Pointer to firmware's device database entry structure
481  * @num_valid_ddb_entries: Pointer to number of valid ddb entries
482  * @next_ddb_index: Pointer to next valid device database index
483  * @fw_ddb_device_state: Pointer to device state
484  **/
485 int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
486                             uint16_t fw_ddb_index,
487                             struct dev_db_entry *fw_ddb_entry,
488                             dma_addr_t fw_ddb_entry_dma,
489                             uint32_t *num_valid_ddb_entries,
490                             uint32_t *next_ddb_index,
491                             uint32_t *fw_ddb_device_state,
492                             uint32_t *conn_err_detail,
493                             uint16_t *tcp_source_port_num,
494                             uint16_t *connection_id)
495 {
496         int status = QLA_ERROR;
497         uint16_t options;
498         uint32_t mbox_cmd[MBOX_REG_COUNT];
499         uint32_t mbox_sts[MBOX_REG_COUNT];
500
501         /* Make sure the device index is valid */
502         if (fw_ddb_index >= MAX_DDB_ENTRIES) {
503                 DEBUG2(printk("scsi%ld: %s: index [%d] out of range.\n",
504                               ha->host_no, __func__, fw_ddb_index));
505                 goto exit_get_fwddb;
506         }
507         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
508         memset(&mbox_sts, 0, sizeof(mbox_sts));
509
510         mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY;
511         mbox_cmd[1] = (uint32_t) fw_ddb_index;
512         mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
513         mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
514         mbox_cmd[4] = sizeof(struct dev_db_entry);
515
516         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 7, &mbox_cmd[0], &mbox_sts[0]) ==
517             QLA_ERROR) {
518                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_GET_DATABASE_ENTRY failed"
519                               " with status 0x%04X\n", ha->host_no, __func__,
520                               mbox_sts[0]));
521                 goto exit_get_fwddb;
522         }
523         if (fw_ddb_index != mbox_sts[1]) {
524                 DEBUG2(printk("scsi%ld: %s: index mismatch [%d] != [%d].\n",
525                               ha->host_no, __func__, fw_ddb_index,
526                               mbox_sts[1]));
527                 goto exit_get_fwddb;
528         }
529         if (fw_ddb_entry) {
530                 options = le16_to_cpu(fw_ddb_entry->options);
531                 if (options & DDB_OPT_IPV6_DEVICE) {
532                         dev_info(&ha->pdev->dev, "%s: DDB[%d] MB0 %04x Tot %d "
533                                 "Next %d State %04x ConnErr %08x %pI6 "
534                                 ":%04d \"%s\"\n", __func__, fw_ddb_index,
535                                 mbox_sts[0], mbox_sts[2], mbox_sts[3],
536                                 mbox_sts[4], mbox_sts[5],
537                                 fw_ddb_entry->ip_addr,
538                                 le16_to_cpu(fw_ddb_entry->port),
539                                 fw_ddb_entry->iscsi_name);
540                 } else {
541                         dev_info(&ha->pdev->dev, "%s: DDB[%d] MB0 %04x Tot %d "
542                                 "Next %d State %04x ConnErr %08x %pI4 "
543                                 ":%04d \"%s\"\n", __func__, fw_ddb_index,
544                                 mbox_sts[0], mbox_sts[2], mbox_sts[3],
545                                 mbox_sts[4], mbox_sts[5],
546                                 fw_ddb_entry->ip_addr,
547                                 le16_to_cpu(fw_ddb_entry->port),
548                                 fw_ddb_entry->iscsi_name);
549                 }
550         }
551         if (num_valid_ddb_entries)
552                 *num_valid_ddb_entries = mbox_sts[2];
553         if (next_ddb_index)
554                 *next_ddb_index = mbox_sts[3];
555         if (fw_ddb_device_state)
556                 *fw_ddb_device_state = mbox_sts[4];
557
558         /*
559          * RA: This mailbox has been changed to pass connection error and
560          * details.  Its true for ISP4010 as per Version E - Not sure when it
561          * was changed.  Get the time2wait from the fw_dd_entry field :
562          * default_time2wait which we call it as minTime2Wait DEV_DB_ENTRY
563          * struct.
564          */
565         if (conn_err_detail)
566                 *conn_err_detail = mbox_sts[5];
567         if (tcp_source_port_num)
568                 *tcp_source_port_num = (uint16_t) mbox_sts[6] >> 16;
569         if (connection_id)
570                 *connection_id = (uint16_t) mbox_sts[6] & 0x00FF;
571         status = QLA_SUCCESS;
572
573 exit_get_fwddb:
574         return status;
575 }
576
577 /**
578  * qla4xxx_set_fwddb_entry - sets a ddb entry.
579  * @ha: Pointer to host adapter structure.
580  * @fw_ddb_index: Firmware's device database index
581  * @fw_ddb_entry: Pointer to firmware's ddb entry structure, or NULL.
582  *
583  * This routine initializes or updates the adapter's device database
584  * entry for the specified device. It also triggers a login for the
585  * specified device. Therefore, it may also be used as a secondary
586  * login routine when a NULL pointer is specified for the fw_ddb_entry.
587  **/
588 int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
589                           dma_addr_t fw_ddb_entry_dma)
590 {
591         uint32_t mbox_cmd[MBOX_REG_COUNT];
592         uint32_t mbox_sts[MBOX_REG_COUNT];
593
594         /* Do not wait for completion. The firmware will send us an
595          * ASTS_DATABASE_CHANGED (0x8014) to notify us of the login status.
596          */
597         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
598         memset(&mbox_sts, 0, sizeof(mbox_sts));
599
600         mbox_cmd[0] = MBOX_CMD_SET_DATABASE_ENTRY;
601         mbox_cmd[1] = (uint32_t) fw_ddb_index;
602         mbox_cmd[2] = LSDW(fw_ddb_entry_dma);
603         mbox_cmd[3] = MSDW(fw_ddb_entry_dma);
604         mbox_cmd[4] = sizeof(struct dev_db_entry);
605
606         return qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);
607 }
608
609 /**
610  * qla4xxx_get_crash_record - retrieves crash record.
611  * @ha: Pointer to host adapter structure.
612  *
613  * This routine retrieves a crash record from the QLA4010 after an 8002h aen.
614  **/
615 void qla4xxx_get_crash_record(struct scsi_qla_host * ha)
616 {
617         uint32_t mbox_cmd[MBOX_REG_COUNT];
618         uint32_t mbox_sts[MBOX_REG_COUNT];
619         struct crash_record *crash_record = NULL;
620         dma_addr_t crash_record_dma = 0;
621         uint32_t crash_record_size = 0;
622
623         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
624         memset(&mbox_sts, 0, sizeof(mbox_cmd));
625
626         /* Get size of crash record. */
627         mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
628
629         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
630             QLA_SUCCESS) {
631                 DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve size!\n",
632                               ha->host_no, __func__));
633                 goto exit_get_crash_record;
634         }
635         crash_record_size = mbox_sts[4];
636         if (crash_record_size == 0) {
637                 DEBUG2(printk("scsi%ld: %s: ERROR: Crash record size is 0!\n",
638                               ha->host_no, __func__));
639                 goto exit_get_crash_record;
640         }
641
642         /* Alloc Memory for Crash Record. */
643         crash_record = dma_alloc_coherent(&ha->pdev->dev, crash_record_size,
644                                           &crash_record_dma, GFP_KERNEL);
645         if (crash_record == NULL)
646                 goto exit_get_crash_record;
647
648         /* Get Crash Record. */
649         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
650         memset(&mbox_sts, 0, sizeof(mbox_cmd));
651
652         mbox_cmd[0] = MBOX_CMD_GET_CRASH_RECORD;
653         mbox_cmd[2] = LSDW(crash_record_dma);
654         mbox_cmd[3] = MSDW(crash_record_dma);
655         mbox_cmd[4] = crash_record_size;
656
657         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
658             QLA_SUCCESS)
659                 goto exit_get_crash_record;
660
661         /* Dump Crash Record. */
662
663 exit_get_crash_record:
664         if (crash_record)
665                 dma_free_coherent(&ha->pdev->dev, crash_record_size,
666                                   crash_record, crash_record_dma);
667 }
668
669 /**
670  * qla4xxx_get_conn_event_log - retrieves connection event log
671  * @ha: Pointer to host adapter structure.
672  **/
673 void qla4xxx_get_conn_event_log(struct scsi_qla_host * ha)
674 {
675         uint32_t mbox_cmd[MBOX_REG_COUNT];
676         uint32_t mbox_sts[MBOX_REG_COUNT];
677         struct conn_event_log_entry *event_log = NULL;
678         dma_addr_t event_log_dma = 0;
679         uint32_t event_log_size = 0;
680         uint32_t num_valid_entries;
681         uint32_t      oldest_entry = 0;
682         uint32_t        max_event_log_entries;
683         uint8_t         i;
684
685
686         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
687         memset(&mbox_sts, 0, sizeof(mbox_cmd));
688
689         /* Get size of crash record. */
690         mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
691
692         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
693             QLA_SUCCESS)
694                 goto exit_get_event_log;
695
696         event_log_size = mbox_sts[4];
697         if (event_log_size == 0)
698                 goto exit_get_event_log;
699
700         /* Alloc Memory for Crash Record. */
701         event_log = dma_alloc_coherent(&ha->pdev->dev, event_log_size,
702                                        &event_log_dma, GFP_KERNEL);
703         if (event_log == NULL)
704                 goto exit_get_event_log;
705
706         /* Get Crash Record. */
707         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
708         memset(&mbox_sts, 0, sizeof(mbox_cmd));
709
710         mbox_cmd[0] = MBOX_CMD_GET_CONN_EVENT_LOG;
711         mbox_cmd[2] = LSDW(event_log_dma);
712         mbox_cmd[3] = MSDW(event_log_dma);
713
714         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
715             QLA_SUCCESS) {
716                 DEBUG2(printk("scsi%ld: %s: ERROR: Unable to retrieve event "
717                               "log!\n", ha->host_no, __func__));
718                 goto exit_get_event_log;
719         }
720
721         /* Dump Event Log. */
722         num_valid_entries = mbox_sts[1];
723
724         max_event_log_entries = event_log_size /
725                 sizeof(struct conn_event_log_entry);
726
727         if (num_valid_entries > max_event_log_entries)
728                 oldest_entry = num_valid_entries % max_event_log_entries;
729
730         DEBUG3(printk("scsi%ld: Connection Event Log Dump (%d entries):\n",
731                       ha->host_no, num_valid_entries));
732
733         if (ql4xextended_error_logging == 3) {
734                 if (oldest_entry == 0) {
735                         /* Circular Buffer has not wrapped around */
736                         for (i=0; i < num_valid_entries; i++) {
737                                 qla4xxx_dump_buffer((uint8_t *)event_log+
738                                                     (i*sizeof(*event_log)),
739                                                     sizeof(*event_log));
740                         }
741                 }
742                 else {
743                         /* Circular Buffer has wrapped around -
744                          * display accordingly*/
745                         for (i=oldest_entry; i < max_event_log_entries; i++) {
746                                 qla4xxx_dump_buffer((uint8_t *)event_log+
747                                                     (i*sizeof(*event_log)),
748                                                     sizeof(*event_log));
749                         }
750                         for (i=0; i < oldest_entry; i++) {
751                                 qla4xxx_dump_buffer((uint8_t *)event_log+
752                                                     (i*sizeof(*event_log)),
753                                                     sizeof(*event_log));
754                         }
755                 }
756         }
757
758 exit_get_event_log:
759         if (event_log)
760                 dma_free_coherent(&ha->pdev->dev, event_log_size, event_log,
761                                   event_log_dma);
762 }
763
764 /**
765  * qla4xxx_reset_lun - issues LUN Reset
766  * @ha: Pointer to host adapter structure.
767  * @db_entry: Pointer to device database entry
768  * @un_entry: Pointer to lun entry structure
769  *
770  * This routine performs a LUN RESET on the specified target/lun.
771  * The caller must ensure that the ddb_entry and lun_entry pointers
772  * are valid before calling this routine.
773  **/
774 int qla4xxx_reset_lun(struct scsi_qla_host * ha, struct ddb_entry * ddb_entry,
775                       int lun)
776 {
777         uint32_t mbox_cmd[MBOX_REG_COUNT];
778         uint32_t mbox_sts[MBOX_REG_COUNT];
779         int status = QLA_SUCCESS;
780
781         DEBUG2(printk("scsi%ld:%d:%d: lun reset issued\n", ha->host_no,
782                       ddb_entry->os_target_id, lun));
783
784         /*
785          * Send lun reset command to ISP, so that the ISP will return all
786          * outstanding requests with RESET status
787          */
788         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
789         memset(&mbox_sts, 0, sizeof(mbox_sts));
790
791         mbox_cmd[0] = MBOX_CMD_LUN_RESET;
792         mbox_cmd[1] = ddb_entry->fw_ddb_index;
793         mbox_cmd[2] = lun << 8;
794         mbox_cmd[5] = 0x01;     /* Immediate Command Enable */
795
796         qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]);
797         if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
798             mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
799                 status = QLA_ERROR;
800
801         return status;
802 }
803
804 /**
805  * qla4xxx_reset_target - issues target Reset
806  * @ha: Pointer to host adapter structure.
807  * @db_entry: Pointer to device database entry
808  * @un_entry: Pointer to lun entry structure
809  *
810  * This routine performs a TARGET RESET on the specified target.
811  * The caller must ensure that the ddb_entry pointers
812  * are valid before calling this routine.
813  **/
814 int qla4xxx_reset_target(struct scsi_qla_host *ha,
815                          struct ddb_entry *ddb_entry)
816 {
817         uint32_t mbox_cmd[MBOX_REG_COUNT];
818         uint32_t mbox_sts[MBOX_REG_COUNT];
819         int status = QLA_SUCCESS;
820
821         DEBUG2(printk("scsi%ld:%d: target reset issued\n", ha->host_no,
822                       ddb_entry->os_target_id));
823
824         /*
825          * Send target reset command to ISP, so that the ISP will return all
826          * outstanding requests with RESET status
827          */
828         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
829         memset(&mbox_sts, 0, sizeof(mbox_sts));
830
831         mbox_cmd[0] = MBOX_CMD_TARGET_WARM_RESET;
832         mbox_cmd[1] = ddb_entry->fw_ddb_index;
833         mbox_cmd[5] = 0x01;     /* Immediate Command Enable */
834
835         qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0],
836                                 &mbox_sts[0]);
837         if (mbox_sts[0] != MBOX_STS_COMMAND_COMPLETE &&
838             mbox_sts[0] != MBOX_STS_COMMAND_ERROR)
839                 status = QLA_ERROR;
840
841         return status;
842 }
843
844 int qla4xxx_get_flash(struct scsi_qla_host * ha, dma_addr_t dma_addr,
845                       uint32_t offset, uint32_t len)
846 {
847         uint32_t mbox_cmd[MBOX_REG_COUNT];
848         uint32_t mbox_sts[MBOX_REG_COUNT];
849
850         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
851         memset(&mbox_sts, 0, sizeof(mbox_sts));
852
853         mbox_cmd[0] = MBOX_CMD_READ_FLASH;
854         mbox_cmd[1] = LSDW(dma_addr);
855         mbox_cmd[2] = MSDW(dma_addr);
856         mbox_cmd[3] = offset;
857         mbox_cmd[4] = len;
858
859         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], &mbox_sts[0]) !=
860             QLA_SUCCESS) {
861                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_READ_FLASH, failed w/ "
862                     "status %04X %04X, offset %08x, len %08x\n", ha->host_no,
863                     __func__, mbox_sts[0], mbox_sts[1], offset, len));
864                 return QLA_ERROR;
865         }
866         return QLA_SUCCESS;
867 }
868
869 /**
870  * qla4xxx_get_fw_version - gets firmware version
871  * @ha: Pointer to host adapter structure.
872  *
873  * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may
874  * hold an address for data.  Make sure that we write 0 to those mailboxes,
875  * if unused.
876  **/
877 int qla4xxx_get_fw_version(struct scsi_qla_host * ha)
878 {
879         uint32_t mbox_cmd[MBOX_REG_COUNT];
880         uint32_t mbox_sts[MBOX_REG_COUNT];
881
882         /* Get firmware version. */
883         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
884         memset(&mbox_sts, 0, sizeof(mbox_sts));
885
886         mbox_cmd[0] = MBOX_CMD_ABOUT_FW;
887
888         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
889             QLA_SUCCESS) {
890                 DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ "
891                     "status %04X\n", ha->host_no, __func__, mbox_sts[0]));
892                 return QLA_ERROR;
893         }
894
895         /* Save firmware version information. */
896         ha->firmware_version[0] = mbox_sts[1];
897         ha->firmware_version[1] = mbox_sts[2];
898         ha->patch_number = mbox_sts[3];
899         ha->build_number = mbox_sts[4];
900
901         return QLA_SUCCESS;
902 }
903
904 static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha,
905                                    dma_addr_t dma_addr)
906 {
907         uint32_t mbox_cmd[MBOX_REG_COUNT];
908         uint32_t mbox_sts[MBOX_REG_COUNT];
909
910         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
911         memset(&mbox_sts, 0, sizeof(mbox_sts));
912
913         mbox_cmd[0] = MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS;
914         mbox_cmd[2] = LSDW(dma_addr);
915         mbox_cmd[3] = MSDW(dma_addr);
916
917         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 1, &mbox_cmd[0], &mbox_sts[0]) !=
918             QLA_SUCCESS) {
919                 DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
920                      ha->host_no, __func__, mbox_sts[0]));
921                 return QLA_ERROR;
922         }
923         return QLA_SUCCESS;
924 }
925
926 static int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t *ddb_index)
927 {
928         uint32_t mbox_cmd[MBOX_REG_COUNT];
929         uint32_t mbox_sts[MBOX_REG_COUNT];
930
931         memset(&mbox_cmd, 0, sizeof(mbox_cmd));
932         memset(&mbox_sts, 0, sizeof(mbox_sts));
933
934         mbox_cmd[0] = MBOX_CMD_REQUEST_DATABASE_ENTRY;
935         mbox_cmd[1] = MAX_PRST_DEV_DB_ENTRIES;
936
937         if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 3, &mbox_cmd[0], &mbox_sts[0]) !=
938             QLA_SUCCESS) {
939                 if (mbox_sts[0] == MBOX_STS_COMMAND_ERROR) {
940                         *ddb_index = mbox_sts[2];
941                 } else {
942                         DEBUG2(printk("scsi%ld: %s: failed status %04X\n",
943                              ha->host_no, __func__, mbox_sts[0]));
944                         return QLA_ERROR;
945                 }
946         } else {
947                 *ddb_index = MAX_PRST_DEV_DB_ENTRIES;
948         }
949
950         return QLA_SUCCESS;
951 }
952
953
954 int qla4xxx_send_tgts(struct scsi_qla_host *ha, char *ip, uint16_t port)
955 {
956         struct dev_db_entry *fw_ddb_entry;
957         dma_addr_t fw_ddb_entry_dma;
958         uint32_t ddb_index;
959         int ret_val = QLA_SUCCESS;
960
961
962         fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
963                                           sizeof(*fw_ddb_entry),
964                                           &fw_ddb_entry_dma, GFP_KERNEL);
965         if (!fw_ddb_entry) {
966                 DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
967                               ha->host_no, __func__));
968                 ret_val = QLA_ERROR;
969                 goto qla4xxx_send_tgts_exit;
970         }
971
972         ret_val = qla4xxx_get_default_ddb(ha, fw_ddb_entry_dma);
973         if (ret_val != QLA_SUCCESS)
974                 goto qla4xxx_send_tgts_exit;
975
976         ret_val = qla4xxx_req_ddb_entry(ha, &ddb_index);
977         if (ret_val != QLA_SUCCESS)
978                 goto qla4xxx_send_tgts_exit;
979
980         memset(fw_ddb_entry->iscsi_alias, 0,
981                sizeof(fw_ddb_entry->iscsi_alias));
982
983         memset(fw_ddb_entry->iscsi_name, 0,
984                sizeof(fw_ddb_entry->iscsi_name));
985
986         memset(fw_ddb_entry->ip_addr, 0, sizeof(fw_ddb_entry->ip_addr));
987         memset(fw_ddb_entry->tgt_addr, 0,
988                sizeof(fw_ddb_entry->tgt_addr));
989
990         fw_ddb_entry->options = (DDB_OPT_DISC_SESSION | DDB_OPT_TARGET);
991         fw_ddb_entry->port = cpu_to_le16(ntohs(port));
992
993         fw_ddb_entry->ip_addr[0] = *ip;
994         fw_ddb_entry->ip_addr[1] = *(ip + 1);
995         fw_ddb_entry->ip_addr[2] = *(ip + 2);
996         fw_ddb_entry->ip_addr[3] = *(ip + 3);
997
998         ret_val = qla4xxx_set_ddb_entry(ha, ddb_index, fw_ddb_entry_dma);
999
1000 qla4xxx_send_tgts_exit:
1001         dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1002                           fw_ddb_entry, fw_ddb_entry_dma);
1003         return ret_val;
1004 }
1005