blob: ffce0163cb5dc60c9b27dc455726dffbaa4ce2ad [file] [log] [blame]
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04001/*
2 * QLogic iSCSI HBA Driver
Vikas Chaudhary4a4f51e2013-08-16 07:03:04 -04003 * Copyright (c) 2003-2013 QLogic Corporation
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04004 *
5 * See LICENSE.qla4xxx for copyright and licensing details.
6 */
7
8#include <linux/ratelimit.h>
9
10#include "ql4_def.h"
11#include "ql4_version.h"
12#include "ql4_glbl.h"
13#include "ql4_dbg.h"
14#include "ql4_inline.h"
15
16uint32_t qla4_83xx_rd_reg(struct scsi_qla_host *ha, ulong addr)
17{
18 return readl((void __iomem *)(ha->nx_pcibase + addr));
19}
20
21void qla4_83xx_wr_reg(struct scsi_qla_host *ha, ulong addr, uint32_t val)
22{
23 writel(val, (void __iomem *)(ha->nx_pcibase + addr));
24}
25
26static int qla4_83xx_set_win_base(struct scsi_qla_host *ha, uint32_t addr)
27{
28 uint32_t val;
29 int ret_val = QLA_SUCCESS;
30
31 qla4_83xx_wr_reg(ha, QLA83XX_CRB_WIN_FUNC(ha->func_num), addr);
32 val = qla4_83xx_rd_reg(ha, QLA83XX_CRB_WIN_FUNC(ha->func_num));
33 if (val != addr) {
34 ql4_printk(KERN_ERR, ha, "%s: Failed to set register window : addr written 0x%x, read 0x%x!\n",
35 __func__, addr, val);
36 ret_val = QLA_ERROR;
37 }
38
39 return ret_val;
40}
41
42int qla4_83xx_rd_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
43 uint32_t *data)
44{
45 int ret_val;
46
47 ret_val = qla4_83xx_set_win_base(ha, addr);
48
49 if (ret_val == QLA_SUCCESS)
50 *data = qla4_83xx_rd_reg(ha, QLA83XX_WILDCARD);
51 else
52 ql4_printk(KERN_ERR, ha, "%s: failed read of addr 0x%x!\n",
53 __func__, addr);
54
55 return ret_val;
56}
57
58int qla4_83xx_wr_reg_indirect(struct scsi_qla_host *ha, uint32_t addr,
59 uint32_t data)
60{
61 int ret_val;
62
63 ret_val = qla4_83xx_set_win_base(ha, addr);
64
65 if (ret_val == QLA_SUCCESS)
66 qla4_83xx_wr_reg(ha, QLA83XX_WILDCARD, data);
67 else
68 ql4_printk(KERN_ERR, ha, "%s: failed wrt to addr 0x%x, data 0x%x\n",
69 __func__, addr, data);
70
71 return ret_val;
72}
73
74static int qla4_83xx_flash_lock(struct scsi_qla_host *ha)
75{
76 int lock_owner;
77 int timeout = 0;
78 uint32_t lock_status = 0;
79 int ret_val = QLA_SUCCESS;
80
81 while (lock_status == 0) {
82 lock_status = qla4_83xx_rd_reg(ha, QLA83XX_FLASH_LOCK);
83 if (lock_status)
84 break;
85
86 if (++timeout >= QLA83XX_FLASH_LOCK_TIMEOUT / 20) {
87 lock_owner = qla4_83xx_rd_reg(ha,
88 QLA83XX_FLASH_LOCK_ID);
89 ql4_printk(KERN_ERR, ha, "%s: flash lock by func %d failed, held by func %d\n",
90 __func__, ha->func_num, lock_owner);
91 ret_val = QLA_ERROR;
92 break;
93 }
94 msleep(20);
95 }
96
97 qla4_83xx_wr_reg(ha, QLA83XX_FLASH_LOCK_ID, ha->func_num);
98 return ret_val;
99}
100
101static void qla4_83xx_flash_unlock(struct scsi_qla_host *ha)
102{
103 /* Reading FLASH_UNLOCK register unlocks the Flash */
104 qla4_83xx_wr_reg(ha, QLA83XX_FLASH_LOCK_ID, 0xFF);
105 qla4_83xx_rd_reg(ha, QLA83XX_FLASH_UNLOCK);
106}
107
108int qla4_83xx_flash_read_u32(struct scsi_qla_host *ha, uint32_t flash_addr,
109 uint8_t *p_data, int u32_word_count)
110{
111 int i;
112 uint32_t u32_word;
113 uint32_t addr = flash_addr;
114 int ret_val = QLA_SUCCESS;
115
116 ret_val = qla4_83xx_flash_lock(ha);
117 if (ret_val == QLA_ERROR)
118 goto exit_lock_error;
119
120 if (addr & 0x03) {
121 ql4_printk(KERN_ERR, ha, "%s: Illegal addr = 0x%x\n",
122 __func__, addr);
123 ret_val = QLA_ERROR;
124 goto exit_flash_read;
125 }
126
127 for (i = 0; i < u32_word_count; i++) {
128 ret_val = qla4_83xx_wr_reg_indirect(ha,
129 QLA83XX_FLASH_DIRECT_WINDOW,
130 (addr & 0xFFFF0000));
131 if (ret_val == QLA_ERROR) {
132 ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW\n!",
133 __func__, addr);
134 goto exit_flash_read;
135 }
136
137 ret_val = qla4_83xx_rd_reg_indirect(ha,
138 QLA83XX_FLASH_DIRECT_DATA(addr),
139 &u32_word);
140 if (ret_val == QLA_ERROR) {
141 ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
142 __func__, addr);
143 goto exit_flash_read;
144 }
145
146 *(__le32 *)p_data = le32_to_cpu(u32_word);
147 p_data = p_data + 4;
148 addr = addr + 4;
149 }
150
151exit_flash_read:
152 qla4_83xx_flash_unlock(ha);
153
154exit_lock_error:
155 return ret_val;
156}
157
158int qla4_83xx_lockless_flash_read_u32(struct scsi_qla_host *ha,
159 uint32_t flash_addr, uint8_t *p_data,
160 int u32_word_count)
161{
162 uint32_t i;
163 uint32_t u32_word;
164 uint32_t flash_offset;
165 uint32_t addr = flash_addr;
166 int ret_val = QLA_SUCCESS;
167
168 flash_offset = addr & (QLA83XX_FLASH_SECTOR_SIZE - 1);
169
170 if (addr & 0x3) {
171 ql4_printk(KERN_ERR, ha, "%s: Illegal addr = 0x%x\n",
172 __func__, addr);
173 ret_val = QLA_ERROR;
174 goto exit_lockless_read;
175 }
176
177 ret_val = qla4_83xx_wr_reg_indirect(ha, QLA83XX_FLASH_DIRECT_WINDOW,
178 addr);
179 if (ret_val == QLA_ERROR) {
180 ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW!\n",
181 __func__, addr);
182 goto exit_lockless_read;
183 }
184
185 /* Check if data is spread across multiple sectors */
186 if ((flash_offset + (u32_word_count * sizeof(uint32_t))) >
187 (QLA83XX_FLASH_SECTOR_SIZE - 1)) {
188
189 /* Multi sector read */
190 for (i = 0; i < u32_word_count; i++) {
191 ret_val = qla4_83xx_rd_reg_indirect(ha,
192 QLA83XX_FLASH_DIRECT_DATA(addr),
193 &u32_word);
194 if (ret_val == QLA_ERROR) {
195 ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
196 __func__, addr);
197 goto exit_lockless_read;
198 }
199
200 *(__le32 *)p_data = le32_to_cpu(u32_word);
201 p_data = p_data + 4;
202 addr = addr + 4;
203 flash_offset = flash_offset + 4;
204
205 if (flash_offset > (QLA83XX_FLASH_SECTOR_SIZE - 1)) {
206 /* This write is needed once for each sector */
207 ret_val = qla4_83xx_wr_reg_indirect(ha,
208 QLA83XX_FLASH_DIRECT_WINDOW,
209 addr);
210 if (ret_val == QLA_ERROR) {
211 ql4_printk(KERN_ERR, ha, "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW!\n",
212 __func__, addr);
213 goto exit_lockless_read;
214 }
215 flash_offset = 0;
216 }
217 }
218 } else {
219 /* Single sector read */
220 for (i = 0; i < u32_word_count; i++) {
221 ret_val = qla4_83xx_rd_reg_indirect(ha,
222 QLA83XX_FLASH_DIRECT_DATA(addr),
223 &u32_word);
224 if (ret_val == QLA_ERROR) {
225 ql4_printk(KERN_ERR, ha, "%s: failed to read addr 0x%x!\n",
226 __func__, addr);
227 goto exit_lockless_read;
228 }
229
230 *(__le32 *)p_data = le32_to_cpu(u32_word);
231 p_data = p_data + 4;
232 addr = addr + 4;
233 }
234 }
235
236exit_lockless_read:
237 return ret_val;
238}
239
240void qla4_83xx_rom_lock_recovery(struct scsi_qla_host *ha)
241{
242 if (qla4_83xx_flash_lock(ha))
243 ql4_printk(KERN_INFO, ha, "%s: Resetting rom lock\n", __func__);
244
245 /*
246 * We got the lock, or someone else is holding the lock
247 * since we are restting, forcefully unlock
248 */
249 qla4_83xx_flash_unlock(ha);
250}
251
252/**
Tej Parkash3c3cab12014-02-24 22:07:00 -0500253 * qla4_8xxx_ms_mem_write_128b - Writes data to MS/off-chip memory
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -0400254 * @ha: Pointer to adapter structure
255 * @addr: Flash address to write to
256 * @data: Data to be written
257 * @count: word_count to be written
258 *
259 * Return: On success return QLA_SUCCESS
260 * On error return QLA_ERROR
261 **/
Tej Parkash3c3cab12014-02-24 22:07:00 -0500262int qla4_8xxx_ms_mem_write_128b(struct scsi_qla_host *ha, uint64_t addr,
Santosh Vernekar41f79bd2013-08-23 03:40:18 -0400263 uint32_t *data, uint32_t count)
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -0400264{
265 int i, j;
266 uint32_t agt_ctrl;
267 unsigned long flags;
268 int ret_val = QLA_SUCCESS;
269
270 /* Only 128-bit aligned access */
271 if (addr & 0xF) {
272 ret_val = QLA_ERROR;
273 goto exit_ms_mem_write;
274 }
275
276 write_lock_irqsave(&ha->hw_lock, flags);
277
278 /* Write address */
Tej Parkash3c3cab12014-02-24 22:07:00 -0500279 ret_val = ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_HI, 0);
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -0400280 if (ret_val == QLA_ERROR) {
281 ql4_printk(KERN_ERR, ha, "%s: write to AGT_ADDR_HI failed\n",
282 __func__);
283 goto exit_ms_mem_write_unlock;
284 }
285
286 for (i = 0; i < count; i++, addr += 16) {
287 if (!((QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_QDR_NET,
288 QLA8XXX_ADDR_QDR_NET_MAX)) ||
289 (QLA8XXX_ADDR_IN_RANGE(addr, QLA8XXX_ADDR_DDR_NET,
290 QLA8XXX_ADDR_DDR_NET_MAX)))) {
291 ret_val = QLA_ERROR;
292 goto exit_ms_mem_write_unlock;
293 }
294
Tej Parkash3c3cab12014-02-24 22:07:00 -0500295 ret_val = ha->isp_ops->wr_reg_indirect(ha,
296 MD_MIU_TEST_AGT_ADDR_LO,
297 addr);
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -0400298 /* Write data */
Tej Parkash3c3cab12014-02-24 22:07:00 -0500299 ret_val |= ha->isp_ops->wr_reg_indirect(ha,
300 MD_MIU_TEST_AGT_WRDATA_LO,
301 *data++);
302 ret_val |= ha->isp_ops->wr_reg_indirect(ha,
303 MD_MIU_TEST_AGT_WRDATA_HI,
304 *data++);
305 ret_val |= ha->isp_ops->wr_reg_indirect(ha,
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -0400306 MD_MIU_TEST_AGT_WRDATA_ULO,
307 *data++);
Tej Parkash3c3cab12014-02-24 22:07:00 -0500308 ret_val |= ha->isp_ops->wr_reg_indirect(ha,
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -0400309 MD_MIU_TEST_AGT_WRDATA_UHI,
310 *data++);
311 if (ret_val == QLA_ERROR) {
312 ql4_printk(KERN_ERR, ha, "%s: write to AGT_WRDATA failed\n",
313 __func__);
314 goto exit_ms_mem_write_unlock;
315 }
316
317 /* Check write status */
Tej Parkash3c3cab12014-02-24 22:07:00 -0500318 ret_val = ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
319 MIU_TA_CTL_WRITE_ENABLE);
320 ret_val |= ha->isp_ops->wr_reg_indirect(ha,
321 MD_MIU_TEST_AGT_CTRL,
322 MIU_TA_CTL_WRITE_START);
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -0400323 if (ret_val == QLA_ERROR) {
324 ql4_printk(KERN_ERR, ha, "%s: write to AGT_CTRL failed\n",
325 __func__);
326 goto exit_ms_mem_write_unlock;
327 }
328
329 for (j = 0; j < MAX_CTL_CHECK; j++) {
Tej Parkash3c3cab12014-02-24 22:07:00 -0500330 ret_val = ha->isp_ops->rd_reg_indirect(ha,
331 MD_MIU_TEST_AGT_CTRL,
332 &agt_ctrl);
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -0400333 if (ret_val == QLA_ERROR) {
334 ql4_printk(KERN_ERR, ha, "%s: failed to read MD_MIU_TEST_AGT_CTRL\n",
335 __func__);
336 goto exit_ms_mem_write_unlock;
337 }
338 if ((agt_ctrl & MIU_TA_CTL_BUSY) == 0)
339 break;
340 }
341
342 /* Status check failed */
343 if (j >= MAX_CTL_CHECK) {
344 printk_ratelimited(KERN_ERR "%s: MS memory write failed!\n",
345 __func__);
346 ret_val = QLA_ERROR;
347 goto exit_ms_mem_write_unlock;
348 }
349 }
350
351exit_ms_mem_write_unlock:
352 write_unlock_irqrestore(&ha->hw_lock, flags);
353
354exit_ms_mem_write:
355 return ret_val;
356}
357
358#define INTENT_TO_RECOVER 0x01
359#define PROCEED_TO_RECOVER 0x02
360
361static int qla4_83xx_lock_recovery(struct scsi_qla_host *ha)
362{
363
364 uint32_t lock = 0, lockid;
365 int ret_val = QLA_ERROR;
366
367 lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY);
368
369 /* Check for other Recovery in progress, go wait */
370 if ((lockid & 0x3) != 0)
371 goto exit_lock_recovery;
372
373 /* Intent to Recover */
374 ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY,
375 (ha->func_num << 2) | INTENT_TO_RECOVER);
376
377 msleep(200);
378
379 /* Check Intent to Recover is advertised */
380 lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY);
381 if ((lockid & 0x3C) != (ha->func_num << 2))
382 goto exit_lock_recovery;
383
384 ql4_printk(KERN_INFO, ha, "%s: IDC Lock recovery initiated for func %d\n",
385 __func__, ha->func_num);
386
387 /* Proceed to Recover */
388 ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY,
389 (ha->func_num << 2) | PROCEED_TO_RECOVER);
390
391 /* Force Unlock */
392 ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCK_ID, 0xFF);
393 ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_UNLOCK);
394
395 /* Clear bits 0-5 in IDC_RECOVERY register*/
396 ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCKRECOVERY, 0);
397
398 /* Get lock */
399 lock = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCK);
400 if (lock) {
401 lockid = ha->isp_ops->rd_reg_direct(ha, QLA83XX_DRV_LOCK_ID);
402 lockid = ((lockid + (1 << 8)) & ~0xFF) | ha->func_num;
403 ha->isp_ops->wr_reg_direct(ha, QLA83XX_DRV_LOCK_ID, lockid);
404 ret_val = QLA_SUCCESS;
405 }
406
407exit_lock_recovery:
408 return ret_val;
409}
410
411#define QLA83XX_DRV_LOCK_MSLEEP 200
412
413int qla4_83xx_drv_lock(struct scsi_qla_host *ha)
414{
415 int timeout = 0;
416 uint32_t status = 0;
417 int ret_val = QLA_SUCCESS;
418 uint32_t first_owner = 0;
419 uint32_t tmo_owner = 0;
420 uint32_t lock_id;
421 uint32_t func_num;
422 uint32_t lock_cnt;
423
424 while (status == 0) {
425 status = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK);
426 if (status) {
427 /* Increment Counter (8-31) and update func_num (0-7) on
428 * getting a successful lock */
429 lock_id = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);
430 lock_id = ((lock_id + (1 << 8)) & ~0xFF) | ha->func_num;
431 qla4_83xx_wr_reg(ha, QLA83XX_DRV_LOCK_ID, lock_id);
432 break;
433 }
434
435 if (timeout == 0)
436 /* Save counter + ID of function holding the lock for
437 * first failure */
438 first_owner = ha->isp_ops->rd_reg_direct(ha,
439 QLA83XX_DRV_LOCK_ID);
440
441 if (++timeout >=
442 (QLA83XX_DRV_LOCK_TIMEOUT / QLA83XX_DRV_LOCK_MSLEEP)) {
443 tmo_owner = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);
444 func_num = tmo_owner & 0xFF;
445 lock_cnt = tmo_owner >> 8;
446 ql4_printk(KERN_INFO, ha, "%s: Lock by func %d failed after 2s, lock held by func %d, lock count %d, first_owner %d\n",
447 __func__, ha->func_num, func_num, lock_cnt,
448 (first_owner & 0xFF));
449
450 if (first_owner != tmo_owner) {
451 /* Some other driver got lock, OR same driver
452 * got lock again (counter value changed), when
453 * we were waiting for lock.
454 * Retry for another 2 sec */
455 ql4_printk(KERN_INFO, ha, "%s: IDC lock failed for func %d\n",
456 __func__, ha->func_num);
457 timeout = 0;
458 } else {
459 /* Same driver holding lock > 2sec.
460 * Force Recovery */
461 ret_val = qla4_83xx_lock_recovery(ha);
462 if (ret_val == QLA_SUCCESS) {
463 /* Recovered and got lock */
464 ql4_printk(KERN_INFO, ha, "%s: IDC lock Recovery by %d successful\n",
465 __func__, ha->func_num);
466 break;
467 }
468 /* Recovery Failed, some other function
469 * has the lock, wait for 2secs and retry */
Masanari Iida8faaaea2014-01-07 21:58:06 +0900470 ql4_printk(KERN_INFO, ha, "%s: IDC lock Recovery by %d failed, Retrying timeout\n",
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -0400471 __func__, ha->func_num);
472 timeout = 0;
473 }
474 }
475 msleep(QLA83XX_DRV_LOCK_MSLEEP);
476 }
477
478 return ret_val;
479}
480
481void qla4_83xx_drv_unlock(struct scsi_qla_host *ha)
482{
483 int id;
484
485 id = qla4_83xx_rd_reg(ha, QLA83XX_DRV_LOCK_ID);
486
487 if ((id & 0xFF) != ha->func_num) {
488 ql4_printk(KERN_ERR, ha, "%s: IDC Unlock by %d failed, lock owner is %d\n",
489 __func__, ha->func_num, (id & 0xFF));
490 return;
491 }
492
493 /* Keep lock counter value, update the ha->func_num to 0xFF */
494 qla4_83xx_wr_reg(ha, QLA83XX_DRV_LOCK_ID, (id | 0xFF));
495 qla4_83xx_rd_reg(ha, QLA83XX_DRV_UNLOCK);
496}
497
498void qla4_83xx_set_idc_dontreset(struct scsi_qla_host *ha)
499{
500 uint32_t idc_ctrl;
501
502 idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
503 idc_ctrl |= DONTRESET_BIT0;
504 qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL, idc_ctrl);
505 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: idc_ctrl = %d\n", __func__,
506 idc_ctrl));
507}
508
509void qla4_83xx_clear_idc_dontreset(struct scsi_qla_host *ha)
510{
511 uint32_t idc_ctrl;
512
513 idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
514 idc_ctrl &= ~DONTRESET_BIT0;
515 qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL, idc_ctrl);
516 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: idc_ctrl = %d\n", __func__,
517 idc_ctrl));
518}
519
520int qla4_83xx_idc_dontreset(struct scsi_qla_host *ha)
521{
522 uint32_t idc_ctrl;
523
524 idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
525 return idc_ctrl & DONTRESET_BIT0;
526}
527
528/*-------------------------IDC State Machine ---------------------*/
529
530enum {
531 UNKNOWN_CLASS = 0,
532 NIC_CLASS,
533 FCOE_CLASS,
534 ISCSI_CLASS
535};
536
537struct device_info {
538 int func_num;
539 int device_type;
540 int port_num;
541};
542
Vikas Chaudhary9661975f2013-01-20 23:51:02 -0500543int qla4_83xx_can_perform_reset(struct scsi_qla_host *ha)
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -0400544{
545 uint32_t drv_active;
546 uint32_t dev_part, dev_part1, dev_part2;
547 int i;
548 struct device_info device_map[16];
549 int func_nibble;
550 int nibble;
551 int nic_present = 0;
552 int iscsi_present = 0;
553 int iscsi_func_low = 0;
554
555 /* Use the dev_partition register to determine the PCI function number
556 * and then check drv_active register to see which driver is loaded */
557 dev_part1 = qla4_83xx_rd_reg(ha,
558 ha->reg_tbl[QLA8XXX_CRB_DEV_PART_INFO]);
559 dev_part2 = qla4_83xx_rd_reg(ha, QLA83XX_CRB_DEV_PART_INFO2);
560 drv_active = qla4_83xx_rd_reg(ha, ha->reg_tbl[QLA8XXX_CRB_DRV_ACTIVE]);
561
562 /* Each function has 4 bits in dev_partition Info register,
563 * Lower 2 bits - device type, Upper 2 bits - physical port number */
564 dev_part = dev_part1;
565 for (i = nibble = 0; i <= 15; i++, nibble++) {
566 func_nibble = dev_part & (0xF << (nibble * 4));
567 func_nibble >>= (nibble * 4);
568 device_map[i].func_num = i;
569 device_map[i].device_type = func_nibble & 0x3;
570 device_map[i].port_num = func_nibble & 0xC;
571
572 if (device_map[i].device_type == NIC_CLASS) {
573 if (drv_active & (1 << device_map[i].func_num)) {
574 nic_present++;
575 break;
576 }
577 } else if (device_map[i].device_type == ISCSI_CLASS) {
578 if (drv_active & (1 << device_map[i].func_num)) {
579 if (!iscsi_present ||
580 (iscsi_present &&
581 (iscsi_func_low > device_map[i].func_num)))
582 iscsi_func_low = device_map[i].func_num;
583
584 iscsi_present++;
585 }
586 }
587
588 /* For function_num[8..15] get info from dev_part2 register */
589 if (nibble == 7) {
590 nibble = 0;
591 dev_part = dev_part2;
592 }
593 }
594
595 /* NIC, iSCSI and FCOE are the Reset owners based on order, NIC gets
596 * precedence over iSCSI and FCOE and iSCSI over FCOE, based on drivers
597 * present. */
598 if (!nic_present && (ha->func_num == iscsi_func_low)) {
599 DEBUG2(ql4_printk(KERN_INFO, ha,
600 "%s: can reset - NIC not present and lower iSCSI function is %d\n",
601 __func__, ha->func_num));
602 return 1;
603 }
604
605 return 0;
606}
607
608/**
609 * qla4_83xx_need_reset_handler - Code to start reset sequence
610 * @ha: pointer to adapter structure
611 *
612 * Note: IDC lock must be held upon entry
613 **/
614void qla4_83xx_need_reset_handler(struct scsi_qla_host *ha)
615{
616 uint32_t dev_state, drv_state, drv_active;
617 unsigned long reset_timeout, dev_init_timeout;
618
619 ql4_printk(KERN_INFO, ha, "%s: Performing ISP error recovery\n",
620 __func__);
621
622 if (!test_bit(AF_8XXX_RST_OWNER, &ha->flags)) {
623 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: reset acknowledged\n",
624 __func__));
625 qla4_8xxx_set_rst_ready(ha);
626
627 /* Non-reset owners ACK Reset and wait for device INIT state
628 * as part of Reset Recovery by Reset Owner */
629 dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);
630
631 do {
632 if (time_after_eq(jiffies, dev_init_timeout)) {
633 ql4_printk(KERN_INFO, ha, "%s: Non Reset owner dev init timeout\n",
634 __func__);
635 break;
636 }
637
638 ha->isp_ops->idc_unlock(ha);
639 msleep(1000);
640 ha->isp_ops->idc_lock(ha);
641
642 dev_state = qla4_8xxx_rd_direct(ha,
643 QLA8XXX_CRB_DEV_STATE);
644 } while (dev_state == QLA8XXX_DEV_NEED_RESET);
645 } else {
646 qla4_8xxx_set_rst_ready(ha);
647 reset_timeout = jiffies + (ha->nx_reset_timeout * HZ);
648 drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
649 drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
650
651 ql4_printk(KERN_INFO, ha, "%s: drv_state = 0x%x, drv_active = 0x%x\n",
652 __func__, drv_state, drv_active);
653
654 while (drv_state != drv_active) {
655 if (time_after_eq(jiffies, reset_timeout)) {
656 ql4_printk(KERN_INFO, ha, "%s: %s: RESET TIMEOUT! drv_state: 0x%08x, drv_active: 0x%08x\n",
657 __func__, DRIVER_NAME, drv_state,
658 drv_active);
659 break;
660 }
661
662 ha->isp_ops->idc_unlock(ha);
663 msleep(1000);
664 ha->isp_ops->idc_lock(ha);
665
666 drv_state = qla4_8xxx_rd_direct(ha,
667 QLA8XXX_CRB_DRV_STATE);
668 drv_active = qla4_8xxx_rd_direct(ha,
669 QLA8XXX_CRB_DRV_ACTIVE);
670 }
671
672 if (drv_state != drv_active) {
673 ql4_printk(KERN_INFO, ha, "%s: Reset_owner turning off drv_active of non-acking function 0x%x\n",
674 __func__, (drv_active ^ drv_state));
675 drv_active = drv_active & drv_state;
676 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE,
677 drv_active);
678 }
679
680 clear_bit(AF_8XXX_RST_OWNER, &ha->flags);
681 /* Start Reset Recovery */
682 qla4_8xxx_device_bootstrap(ha);
683 }
684}
685
686void qla4_83xx_get_idc_param(struct scsi_qla_host *ha)
687{
688 uint32_t idc_params, ret_val;
689
690 ret_val = qla4_83xx_flash_read_u32(ha, QLA83XX_IDC_PARAM_ADDR,
691 (uint8_t *)&idc_params, 1);
692 if (ret_val == QLA_SUCCESS) {
693 ha->nx_dev_init_timeout = idc_params & 0xFFFF;
694 ha->nx_reset_timeout = (idc_params >> 16) & 0xFFFF;
695 } else {
696 ha->nx_dev_init_timeout = ROM_DEV_INIT_TIMEOUT;
697 ha->nx_reset_timeout = ROM_DRV_RESET_ACK_TIMEOUT;
698 }
699
700 DEBUG2(ql4_printk(KERN_DEBUG, ha,
701 "%s: ha->nx_dev_init_timeout = %d, ha->nx_reset_timeout = %d\n",
702 __func__, ha->nx_dev_init_timeout,
703 ha->nx_reset_timeout));
704}
705
706/*-------------------------Reset Sequence Functions-----------------------*/
707
708static void qla4_83xx_dump_reset_seq_hdr(struct scsi_qla_host *ha)
709{
710 uint8_t *phdr;
711
712 if (!ha->reset_tmplt.buff) {
713 ql4_printk(KERN_ERR, ha, "%s: Error: Invalid reset_seq_template\n",
714 __func__);
715 return;
716 }
717
718 phdr = ha->reset_tmplt.buff;
719
720 DEBUG2(ql4_printk(KERN_INFO, ha,
721 "Reset Template: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n",
722 *phdr, *(phdr+1), *(phdr+2), *(phdr+3), *(phdr+4),
723 *(phdr+5), *(phdr+6), *(phdr+7), *(phdr + 8),
724 *(phdr+9), *(phdr+10), *(phdr+11), *(phdr+12),
725 *(phdr+13), *(phdr+14), *(phdr+15)));
726}
727
728static int qla4_83xx_copy_bootloader(struct scsi_qla_host *ha)
729{
730 uint8_t *p_cache;
731 uint32_t src, count, size;
732 uint64_t dest;
733 int ret_val = QLA_SUCCESS;
734
735 src = QLA83XX_BOOTLOADER_FLASH_ADDR;
736 dest = qla4_83xx_rd_reg(ha, QLA83XX_BOOTLOADER_ADDR);
737 size = qla4_83xx_rd_reg(ha, QLA83XX_BOOTLOADER_SIZE);
738
739 /* 128 bit alignment check */
740 if (size & 0xF)
741 size = (size + 16) & ~0xF;
742
743 /* 16 byte count */
744 count = size/16;
745
746 p_cache = vmalloc(size);
747 if (p_cache == NULL) {
748 ql4_printk(KERN_ERR, ha, "%s: Failed to allocate memory for boot loader cache\n",
749 __func__);
750 ret_val = QLA_ERROR;
751 goto exit_copy_bootloader;
752 }
753
754 ret_val = qla4_83xx_lockless_flash_read_u32(ha, src, p_cache,
755 size / sizeof(uint32_t));
756 if (ret_val == QLA_ERROR) {
757 ql4_printk(KERN_ERR, ha, "%s: Error reading firmware from flash\n",
758 __func__);
759 goto exit_copy_error;
760 }
761 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Read firmware from flash\n",
762 __func__));
763
764 /* 128 bit/16 byte write to MS memory */
Tej Parkash3c3cab12014-02-24 22:07:00 -0500765 ret_val = qla4_8xxx_ms_mem_write_128b(ha, dest, (uint32_t *)p_cache,
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -0400766 count);
767 if (ret_val == QLA_ERROR) {
768 ql4_printk(KERN_ERR, ha, "%s: Error writing firmware to MS\n",
769 __func__);
770 goto exit_copy_error;
771 }
772
773 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Wrote firmware size %d to MS\n",
774 __func__, size));
775
776exit_copy_error:
777 vfree(p_cache);
778
779exit_copy_bootloader:
780 return ret_val;
781}
782
783static int qla4_83xx_check_cmd_peg_status(struct scsi_qla_host *ha)
784{
785 uint32_t val, ret_val = QLA_ERROR;
786 int retries = CRB_CMDPEG_CHECK_RETRY_COUNT;
787
788 do {
789 val = qla4_83xx_rd_reg(ha, QLA83XX_CMDPEG_STATE);
790 if (val == PHAN_INITIALIZE_COMPLETE) {
791 DEBUG2(ql4_printk(KERN_INFO, ha,
792 "%s: Command Peg initialization complete. State=0x%x\n",
793 __func__, val));
794 ret_val = QLA_SUCCESS;
795 break;
796 }
797 msleep(CRB_CMDPEG_CHECK_DELAY);
798 } while (--retries);
799
800 return ret_val;
801}
802
803/**
804 * qla4_83xx_poll_reg - Poll the given CRB addr for duration msecs till
805 * value read ANDed with test_mask is equal to test_result.
806 *
807 * @ha : Pointer to adapter structure
808 * @addr : CRB register address
809 * @duration : Poll for total of "duration" msecs
810 * @test_mask : Mask value read with "test_mask"
811 * @test_result : Compare (value&test_mask) with test_result.
812 **/
813static int qla4_83xx_poll_reg(struct scsi_qla_host *ha, uint32_t addr,
814 int duration, uint32_t test_mask,
815 uint32_t test_result)
816{
817 uint32_t value;
818 uint8_t retries;
819 int ret_val = QLA_SUCCESS;
820
821 ret_val = qla4_83xx_rd_reg_indirect(ha, addr, &value);
822 if (ret_val == QLA_ERROR)
823 goto exit_poll_reg;
824
825 retries = duration / 10;
826 do {
827 if ((value & test_mask) != test_result) {
828 msleep(duration / 10);
829 ret_val = qla4_83xx_rd_reg_indirect(ha, addr, &value);
830 if (ret_val == QLA_ERROR)
831 goto exit_poll_reg;
832
833 ret_val = QLA_ERROR;
834 } else {
835 ret_val = QLA_SUCCESS;
836 break;
837 }
838 } while (retries--);
839
840exit_poll_reg:
841 if (ret_val == QLA_ERROR) {
842 ha->reset_tmplt.seq_error++;
843 ql4_printk(KERN_ERR, ha, "%s: Poll Failed: 0x%08x 0x%08x 0x%08x\n",
844 __func__, value, test_mask, test_result);
845 }
846
847 return ret_val;
848}
849
850static int qla4_83xx_reset_seq_checksum_test(struct scsi_qla_host *ha)
851{
852 uint32_t sum = 0;
853 uint16_t *buff = (uint16_t *)ha->reset_tmplt.buff;
854 int u16_count = ha->reset_tmplt.hdr->size / sizeof(uint16_t);
855 int ret_val;
856
857 while (u16_count-- > 0)
858 sum += *buff++;
859
860 while (sum >> 16)
861 sum = (sum & 0xFFFF) + (sum >> 16);
862
863 /* checksum of 0 indicates a valid template */
864 if (~sum) {
865 ret_val = QLA_SUCCESS;
866 } else {
867 ql4_printk(KERN_ERR, ha, "%s: Reset seq checksum failed\n",
868 __func__);
869 ret_val = QLA_ERROR;
870 }
871
872 return ret_val;
873}
874
875/**
876 * qla4_83xx_read_reset_template - Read Reset Template from Flash
877 * @ha: Pointer to adapter structure
878 **/
879void qla4_83xx_read_reset_template(struct scsi_qla_host *ha)
880{
881 uint8_t *p_buff;
882 uint32_t addr, tmplt_hdr_def_size, tmplt_hdr_size;
883 uint32_t ret_val;
884
885 ha->reset_tmplt.seq_error = 0;
886 ha->reset_tmplt.buff = vmalloc(QLA83XX_RESTART_TEMPLATE_SIZE);
887 if (ha->reset_tmplt.buff == NULL) {
888 ql4_printk(KERN_ERR, ha, "%s: Failed to allocate reset template resources\n",
889 __func__);
890 goto exit_read_reset_template;
891 }
892
893 p_buff = ha->reset_tmplt.buff;
894 addr = QLA83XX_RESET_TEMPLATE_ADDR;
895
896 tmplt_hdr_def_size = sizeof(struct qla4_83xx_reset_template_hdr) /
897 sizeof(uint32_t);
898
899 DEBUG2(ql4_printk(KERN_INFO, ha,
900 "%s: Read template hdr size %d from Flash\n",
901 __func__, tmplt_hdr_def_size));
902
903 /* Copy template header from flash */
904 ret_val = qla4_83xx_flash_read_u32(ha, addr, p_buff,
905 tmplt_hdr_def_size);
906 if (ret_val != QLA_SUCCESS) {
907 ql4_printk(KERN_ERR, ha, "%s: Failed to read reset template\n",
908 __func__);
909 goto exit_read_template_error;
910 }
911
912 ha->reset_tmplt.hdr =
913 (struct qla4_83xx_reset_template_hdr *)ha->reset_tmplt.buff;
914
915 /* Validate the template header size and signature */
916 tmplt_hdr_size = ha->reset_tmplt.hdr->hdr_size/sizeof(uint32_t);
917 if ((tmplt_hdr_size != tmplt_hdr_def_size) ||
918 (ha->reset_tmplt.hdr->signature != RESET_TMPLT_HDR_SIGNATURE)) {
919 ql4_printk(KERN_ERR, ha, "%s: Template Header size %d is invalid, tmplt_hdr_def_size %d\n",
920 __func__, tmplt_hdr_size, tmplt_hdr_def_size);
921 goto exit_read_template_error;
922 }
923
924 addr = QLA83XX_RESET_TEMPLATE_ADDR + ha->reset_tmplt.hdr->hdr_size;
925 p_buff = ha->reset_tmplt.buff + ha->reset_tmplt.hdr->hdr_size;
926 tmplt_hdr_def_size = (ha->reset_tmplt.hdr->size -
927 ha->reset_tmplt.hdr->hdr_size) / sizeof(uint32_t);
928
929 DEBUG2(ql4_printk(KERN_INFO, ha,
930 "%s: Read rest of the template size %d\n",
931 __func__, ha->reset_tmplt.hdr->size));
932
933 /* Copy rest of the template */
934 ret_val = qla4_83xx_flash_read_u32(ha, addr, p_buff,
935 tmplt_hdr_def_size);
936 if (ret_val != QLA_SUCCESS) {
937 ql4_printk(KERN_ERR, ha, "%s: Failed to read reset tempelate\n",
938 __func__);
939 goto exit_read_template_error;
940 }
941
942 /* Integrity check */
943 if (qla4_83xx_reset_seq_checksum_test(ha)) {
944 ql4_printk(KERN_ERR, ha, "%s: Reset Seq checksum failed!\n",
945 __func__);
946 goto exit_read_template_error;
947 }
948 DEBUG2(ql4_printk(KERN_INFO, ha,
949 "%s: Reset Seq checksum passed, Get stop, start and init seq offsets\n",
950 __func__));
951
952 /* Get STOP, START, INIT sequence offsets */
953 ha->reset_tmplt.init_offset = ha->reset_tmplt.buff +
954 ha->reset_tmplt.hdr->init_seq_offset;
955 ha->reset_tmplt.start_offset = ha->reset_tmplt.buff +
956 ha->reset_tmplt.hdr->start_seq_offset;
957 ha->reset_tmplt.stop_offset = ha->reset_tmplt.buff +
958 ha->reset_tmplt.hdr->hdr_size;
959 qla4_83xx_dump_reset_seq_hdr(ha);
960
961 goto exit_read_reset_template;
962
963exit_read_template_error:
964 vfree(ha->reset_tmplt.buff);
965
966exit_read_reset_template:
967 return;
968}
969
970/**
971 * qla4_83xx_read_write_crb_reg - Read from raddr and write value to waddr.
972 *
973 * @ha : Pointer to adapter structure
974 * @raddr : CRB address to read from
975 * @waddr : CRB address to write to
976 **/
977static void qla4_83xx_read_write_crb_reg(struct scsi_qla_host *ha,
978 uint32_t raddr, uint32_t waddr)
979{
980 uint32_t value;
981
982 qla4_83xx_rd_reg_indirect(ha, raddr, &value);
983 qla4_83xx_wr_reg_indirect(ha, waddr, value);
984}
985
986/**
987 * qla4_83xx_rmw_crb_reg - Read Modify Write crb register
988 *
989 * This function read value from raddr, AND with test_mask,
990 * Shift Left,Right/OR/XOR with values RMW header and write value to waddr.
991 *
992 * @ha : Pointer to adapter structure
993 * @raddr : CRB address to read from
994 * @waddr : CRB address to write to
995 * @p_rmw_hdr : header with shift/or/xor values.
996 **/
997static void qla4_83xx_rmw_crb_reg(struct scsi_qla_host *ha, uint32_t raddr,
998 uint32_t waddr,
999 struct qla4_83xx_rmw *p_rmw_hdr)
1000{
1001 uint32_t value;
1002
1003 if (p_rmw_hdr->index_a)
1004 value = ha->reset_tmplt.array[p_rmw_hdr->index_a];
1005 else
1006 qla4_83xx_rd_reg_indirect(ha, raddr, &value);
1007
1008 value &= p_rmw_hdr->test_mask;
1009 value <<= p_rmw_hdr->shl;
1010 value >>= p_rmw_hdr->shr;
1011 value |= p_rmw_hdr->or_value;
1012 value ^= p_rmw_hdr->xor_value;
1013
1014 qla4_83xx_wr_reg_indirect(ha, waddr, value);
1015
1016 return;
1017}
1018
1019static void qla4_83xx_write_list(struct scsi_qla_host *ha,
1020 struct qla4_83xx_reset_entry_hdr *p_hdr)
1021{
1022 struct qla4_83xx_entry *p_entry;
1023 uint32_t i;
1024
1025 p_entry = (struct qla4_83xx_entry *)
1026 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1027
1028 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1029 qla4_83xx_wr_reg_indirect(ha, p_entry->arg1, p_entry->arg2);
1030 if (p_hdr->delay)
1031 udelay((uint32_t)(p_hdr->delay));
1032 }
1033}
1034
1035static void qla4_83xx_read_write_list(struct scsi_qla_host *ha,
1036 struct qla4_83xx_reset_entry_hdr *p_hdr)
1037{
1038 struct qla4_83xx_entry *p_entry;
1039 uint32_t i;
1040
1041 p_entry = (struct qla4_83xx_entry *)
1042 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1043
1044 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1045 qla4_83xx_read_write_crb_reg(ha, p_entry->arg1, p_entry->arg2);
1046 if (p_hdr->delay)
1047 udelay((uint32_t)(p_hdr->delay));
1048 }
1049}
1050
1051static void qla4_83xx_poll_list(struct scsi_qla_host *ha,
1052 struct qla4_83xx_reset_entry_hdr *p_hdr)
1053{
1054 long delay;
1055 struct qla4_83xx_entry *p_entry;
1056 struct qla4_83xx_poll *p_poll;
1057 uint32_t i;
1058 uint32_t value;
1059
1060 p_poll = (struct qla4_83xx_poll *)
1061 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1062
1063 /* Entries start after 8 byte qla4_83xx_poll, poll header contains
1064 * the test_mask, test_value. */
1065 p_entry = (struct qla4_83xx_entry *)((char *)p_poll +
1066 sizeof(struct qla4_83xx_poll));
1067
1068 delay = (long)p_hdr->delay;
1069 if (!delay) {
1070 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1071 qla4_83xx_poll_reg(ha, p_entry->arg1, delay,
1072 p_poll->test_mask,
1073 p_poll->test_value);
1074 }
1075 } else {
1076 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1077 if (qla4_83xx_poll_reg(ha, p_entry->arg1, delay,
1078 p_poll->test_mask,
1079 p_poll->test_value)) {
1080 qla4_83xx_rd_reg_indirect(ha, p_entry->arg1,
1081 &value);
1082 qla4_83xx_rd_reg_indirect(ha, p_entry->arg2,
1083 &value);
1084 }
1085 }
1086 }
1087}
1088
1089static void qla4_83xx_poll_write_list(struct scsi_qla_host *ha,
1090 struct qla4_83xx_reset_entry_hdr *p_hdr)
1091{
1092 long delay;
1093 struct qla4_83xx_quad_entry *p_entry;
1094 struct qla4_83xx_poll *p_poll;
1095 uint32_t i;
1096
1097 p_poll = (struct qla4_83xx_poll *)
1098 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1099 p_entry = (struct qla4_83xx_quad_entry *)
1100 ((char *)p_poll + sizeof(struct qla4_83xx_poll));
1101 delay = (long)p_hdr->delay;
1102
1103 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1104 qla4_83xx_wr_reg_indirect(ha, p_entry->dr_addr,
1105 p_entry->dr_value);
1106 qla4_83xx_wr_reg_indirect(ha, p_entry->ar_addr,
1107 p_entry->ar_value);
1108 if (delay) {
1109 if (qla4_83xx_poll_reg(ha, p_entry->ar_addr, delay,
1110 p_poll->test_mask,
1111 p_poll->test_value)) {
1112 DEBUG2(ql4_printk(KERN_INFO, ha,
1113 "%s: Timeout Error: poll list, item_num %d, entry_num %d\n",
1114 __func__, i,
1115 ha->reset_tmplt.seq_index));
1116 }
1117 }
1118 }
1119}
1120
1121static void qla4_83xx_read_modify_write(struct scsi_qla_host *ha,
1122 struct qla4_83xx_reset_entry_hdr *p_hdr)
1123{
1124 struct qla4_83xx_entry *p_entry;
1125 struct qla4_83xx_rmw *p_rmw_hdr;
1126 uint32_t i;
1127
1128 p_rmw_hdr = (struct qla4_83xx_rmw *)
1129 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1130 p_entry = (struct qla4_83xx_entry *)
1131 ((char *)p_rmw_hdr + sizeof(struct qla4_83xx_rmw));
1132
1133 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1134 qla4_83xx_rmw_crb_reg(ha, p_entry->arg1, p_entry->arg2,
1135 p_rmw_hdr);
1136 if (p_hdr->delay)
1137 udelay((uint32_t)(p_hdr->delay));
1138 }
1139}
1140
1141static void qla4_83xx_pause(struct scsi_qla_host *ha,
1142 struct qla4_83xx_reset_entry_hdr *p_hdr)
1143{
1144 if (p_hdr->delay)
1145 mdelay((uint32_t)((long)p_hdr->delay));
1146}
1147
1148static void qla4_83xx_poll_read_list(struct scsi_qla_host *ha,
1149 struct qla4_83xx_reset_entry_hdr *p_hdr)
1150{
1151 long delay;
1152 int index;
1153 struct qla4_83xx_quad_entry *p_entry;
1154 struct qla4_83xx_poll *p_poll;
1155 uint32_t i;
1156 uint32_t value;
1157
1158 p_poll = (struct qla4_83xx_poll *)
1159 ((char *)p_hdr + sizeof(struct qla4_83xx_reset_entry_hdr));
1160 p_entry = (struct qla4_83xx_quad_entry *)
1161 ((char *)p_poll + sizeof(struct qla4_83xx_poll));
1162 delay = (long)p_hdr->delay;
1163
1164 for (i = 0; i < p_hdr->count; i++, p_entry++) {
1165 qla4_83xx_wr_reg_indirect(ha, p_entry->ar_addr,
1166 p_entry->ar_value);
1167 if (delay) {
1168 if (qla4_83xx_poll_reg(ha, p_entry->ar_addr, delay,
1169 p_poll->test_mask,
1170 p_poll->test_value)) {
1171 DEBUG2(ql4_printk(KERN_INFO, ha,
1172 "%s: Timeout Error: poll list, Item_num %d, entry_num %d\n",
1173 __func__, i,
1174 ha->reset_tmplt.seq_index));
1175 } else {
1176 index = ha->reset_tmplt.array_index;
1177 qla4_83xx_rd_reg_indirect(ha, p_entry->dr_addr,
1178 &value);
1179 ha->reset_tmplt.array[index++] = value;
1180
1181 if (index == QLA83XX_MAX_RESET_SEQ_ENTRIES)
1182 ha->reset_tmplt.array_index = 1;
1183 }
1184 }
1185 }
1186}
1187
1188static void qla4_83xx_seq_end(struct scsi_qla_host *ha,
1189 struct qla4_83xx_reset_entry_hdr *p_hdr)
1190{
1191 ha->reset_tmplt.seq_end = 1;
1192}
1193
1194static void qla4_83xx_template_end(struct scsi_qla_host *ha,
1195 struct qla4_83xx_reset_entry_hdr *p_hdr)
1196{
1197 ha->reset_tmplt.template_end = 1;
1198
1199 if (ha->reset_tmplt.seq_error == 0) {
1200 DEBUG2(ql4_printk(KERN_INFO, ha,
1201 "%s: Reset sequence completed SUCCESSFULLY.\n",
1202 __func__));
1203 } else {
1204 ql4_printk(KERN_ERR, ha, "%s: Reset sequence completed with some timeout errors.\n",
1205 __func__);
1206 }
1207}
1208
1209/**
1210 * qla4_83xx_process_reset_template - Process reset template.
1211 *
1212 * Process all entries in reset template till entry with SEQ_END opcode,
1213 * which indicates end of the reset template processing. Each entry has a
1214 * Reset Entry header, entry opcode/command, with size of the entry, number
1215 * of entries in sub-sequence and delay in microsecs or timeout in millisecs.
1216 *
1217 * @ha : Pointer to adapter structure
1218 * @p_buff : Common reset entry header.
1219 **/
1220static void qla4_83xx_process_reset_template(struct scsi_qla_host *ha,
1221 char *p_buff)
1222{
1223 int index, entries;
1224 struct qla4_83xx_reset_entry_hdr *p_hdr;
1225 char *p_entry = p_buff;
1226
1227 ha->reset_tmplt.seq_end = 0;
1228 ha->reset_tmplt.template_end = 0;
1229 entries = ha->reset_tmplt.hdr->entries;
1230 index = ha->reset_tmplt.seq_index;
1231
1232 for (; (!ha->reset_tmplt.seq_end) && (index < entries); index++) {
1233
1234 p_hdr = (struct qla4_83xx_reset_entry_hdr *)p_entry;
1235 switch (p_hdr->cmd) {
1236 case OPCODE_NOP:
1237 break;
1238 case OPCODE_WRITE_LIST:
1239 qla4_83xx_write_list(ha, p_hdr);
1240 break;
1241 case OPCODE_READ_WRITE_LIST:
1242 qla4_83xx_read_write_list(ha, p_hdr);
1243 break;
1244 case OPCODE_POLL_LIST:
1245 qla4_83xx_poll_list(ha, p_hdr);
1246 break;
1247 case OPCODE_POLL_WRITE_LIST:
1248 qla4_83xx_poll_write_list(ha, p_hdr);
1249 break;
1250 case OPCODE_READ_MODIFY_WRITE:
1251 qla4_83xx_read_modify_write(ha, p_hdr);
1252 break;
1253 case OPCODE_SEQ_PAUSE:
1254 qla4_83xx_pause(ha, p_hdr);
1255 break;
1256 case OPCODE_SEQ_END:
1257 qla4_83xx_seq_end(ha, p_hdr);
1258 break;
1259 case OPCODE_TMPL_END:
1260 qla4_83xx_template_end(ha, p_hdr);
1261 break;
1262 case OPCODE_POLL_READ_LIST:
1263 qla4_83xx_poll_read_list(ha, p_hdr);
1264 break;
1265 default:
1266 ql4_printk(KERN_ERR, ha, "%s: Unknown command ==> 0x%04x on entry = %d\n",
1267 __func__, p_hdr->cmd, index);
1268 break;
1269 }
1270
1271 /* Set pointer to next entry in the sequence. */
1272 p_entry += p_hdr->size;
1273 }
1274
1275 ha->reset_tmplt.seq_index = index;
1276}
1277
1278static void qla4_83xx_process_stop_seq(struct scsi_qla_host *ha)
1279{
1280 ha->reset_tmplt.seq_index = 0;
1281 qla4_83xx_process_reset_template(ha, ha->reset_tmplt.stop_offset);
1282
1283 if (ha->reset_tmplt.seq_end != 1)
1284 ql4_printk(KERN_ERR, ha, "%s: Abrupt STOP Sub-Sequence end.\n",
1285 __func__);
1286}
1287
1288static void qla4_83xx_process_start_seq(struct scsi_qla_host *ha)
1289{
1290 qla4_83xx_process_reset_template(ha, ha->reset_tmplt.start_offset);
1291
1292 if (ha->reset_tmplt.template_end != 1)
1293 ql4_printk(KERN_ERR, ha, "%s: Abrupt START Sub-Sequence end.\n",
1294 __func__);
1295}
1296
1297static void qla4_83xx_process_init_seq(struct scsi_qla_host *ha)
1298{
1299 qla4_83xx_process_reset_template(ha, ha->reset_tmplt.init_offset);
1300
1301 if (ha->reset_tmplt.seq_end != 1)
1302 ql4_printk(KERN_ERR, ha, "%s: Abrupt INIT Sub-Sequence end.\n",
1303 __func__);
1304}
1305
1306static int qla4_83xx_restart(struct scsi_qla_host *ha)
1307{
1308 int ret_val = QLA_SUCCESS;
Vikas Chaudhary80645dc2013-12-16 06:49:34 -05001309 uint32_t idc_ctrl;
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04001310
1311 qla4_83xx_process_stop_seq(ha);
1312
Vikas Chaudhary80645dc2013-12-16 06:49:34 -05001313 /*
1314 * Collect minidump.
1315 * If IDC_CTRL BIT1 is set, clear it on going to INIT state and
1316 * don't collect minidump
1317 */
1318 idc_ctrl = qla4_83xx_rd_reg(ha, QLA83XX_IDC_DRV_CTRL);
1319 if (idc_ctrl & GRACEFUL_RESET_BIT1) {
1320 qla4_83xx_wr_reg(ha, QLA83XX_IDC_DRV_CTRL,
1321 (idc_ctrl & ~GRACEFUL_RESET_BIT1));
1322 ql4_printk(KERN_INFO, ha, "%s: Graceful RESET: Not collecting minidump\n",
1323 __func__);
1324 } else {
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04001325 qla4_8xxx_get_minidump(ha);
Vikas Chaudhary80645dc2013-12-16 06:49:34 -05001326 }
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04001327
1328 qla4_83xx_process_init_seq(ha);
1329
1330 if (qla4_83xx_copy_bootloader(ha)) {
1331 ql4_printk(KERN_ERR, ha, "%s: Copy bootloader, firmware restart failed!\n",
1332 __func__);
1333 ret_val = QLA_ERROR;
1334 goto exit_restart;
1335 }
1336
1337 qla4_83xx_wr_reg(ha, QLA83XX_FW_IMAGE_VALID, QLA83XX_BOOT_FROM_FLASH);
1338 qla4_83xx_process_start_seq(ha);
1339
1340exit_restart:
1341 return ret_val;
1342}
1343
1344int qla4_83xx_start_firmware(struct scsi_qla_host *ha)
1345{
1346 int ret_val = QLA_SUCCESS;
1347
1348 ret_val = qla4_83xx_restart(ha);
1349 if (ret_val == QLA_ERROR) {
1350 ql4_printk(KERN_ERR, ha, "%s: Restart error\n", __func__);
1351 goto exit_start_fw;
1352 } else {
1353 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Restart done\n",
1354 __func__));
1355 }
1356
1357 ret_val = qla4_83xx_check_cmd_peg_status(ha);
1358 if (ret_val == QLA_ERROR)
1359 ql4_printk(KERN_ERR, ha, "%s: Peg not initialized\n",
1360 __func__);
1361
1362exit_start_fw:
1363 return ret_val;
1364}
1365
1366/*----------------------Interrupt Related functions ---------------------*/
1367
Vikas Chaudhary5c19b922012-11-23 06:58:38 -05001368static void qla4_83xx_disable_iocb_intrs(struct scsi_qla_host *ha)
1369{
1370 if (test_and_clear_bit(AF_83XX_IOCB_INTR_ON, &ha->flags))
1371 qla4_8xxx_intr_disable(ha);
1372}
1373
1374static void qla4_83xx_disable_mbox_intrs(struct scsi_qla_host *ha)
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04001375{
1376 uint32_t mb_int, ret;
1377
Vikas Chaudhary5c19b922012-11-23 06:58:38 -05001378 if (test_and_clear_bit(AF_83XX_MBOX_INTR_ON, &ha->flags)) {
1379 ret = readl(&ha->qla4_83xx_reg->mbox_int);
1380 mb_int = ret & ~INT_ENABLE_FW_MB;
1381 writel(mb_int, &ha->qla4_83xx_reg->mbox_int);
1382 writel(1, &ha->qla4_83xx_reg->leg_int_mask);
1383 }
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04001384}
1385
Vikas Chaudhary5c19b922012-11-23 06:58:38 -05001386void qla4_83xx_disable_intrs(struct scsi_qla_host *ha)
1387{
1388 qla4_83xx_disable_mbox_intrs(ha);
1389 qla4_83xx_disable_iocb_intrs(ha);
1390}
1391
1392static void qla4_83xx_enable_iocb_intrs(struct scsi_qla_host *ha)
1393{
1394 if (!test_bit(AF_83XX_IOCB_INTR_ON, &ha->flags)) {
1395 qla4_8xxx_intr_enable(ha);
1396 set_bit(AF_83XX_IOCB_INTR_ON, &ha->flags);
1397 }
1398}
1399
1400void qla4_83xx_enable_mbox_intrs(struct scsi_qla_host *ha)
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04001401{
1402 uint32_t mb_int;
1403
Vikas Chaudhary5c19b922012-11-23 06:58:38 -05001404 if (!test_bit(AF_83XX_MBOX_INTR_ON, &ha->flags)) {
1405 mb_int = INT_ENABLE_FW_MB;
1406 writel(mb_int, &ha->qla4_83xx_reg->mbox_int);
1407 writel(0, &ha->qla4_83xx_reg->leg_int_mask);
1408 set_bit(AF_83XX_MBOX_INTR_ON, &ha->flags);
1409 }
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04001410}
1411
Vikas Chaudhary5c19b922012-11-23 06:58:38 -05001412
1413void qla4_83xx_enable_intrs(struct scsi_qla_host *ha)
1414{
1415 qla4_83xx_enable_mbox_intrs(ha);
1416 qla4_83xx_enable_iocb_intrs(ha);
1417}
1418
1419
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04001420void qla4_83xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
1421 int incount)
1422{
1423 int i;
1424
1425 /* Load all mailbox registers, except mailbox 0. */
1426 for (i = 1; i < incount; i++)
1427 writel(mbx_cmd[i], &ha->qla4_83xx_reg->mailbox_in[i]);
1428
1429 writel(mbx_cmd[0], &ha->qla4_83xx_reg->mailbox_in[0]);
1430
1431 /* Set Host Interrupt register to 1, to tell the firmware that
1432 * a mailbox command is pending. Firmware after reading the
1433 * mailbox command, clears the host interrupt register */
1434 writel(HINT_MBX_INT_PENDING, &ha->qla4_83xx_reg->host_intr);
1435}
1436
1437void qla4_83xx_process_mbox_intr(struct scsi_qla_host *ha, int outcount)
1438{
1439 int intr_status;
1440
1441 intr_status = readl(&ha->qla4_83xx_reg->risc_intr);
1442 if (intr_status) {
1443 ha->mbox_status_count = outcount;
1444 ha->isp_ops->interrupt_service_routine(ha, intr_status);
1445 }
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04001446}
1447
1448/**
1449 * qla4_83xx_isp_reset - Resets ISP and aborts all outstanding commands.
1450 * @ha: pointer to host adapter structure.
1451 **/
1452int qla4_83xx_isp_reset(struct scsi_qla_host *ha)
1453{
1454 int rval;
1455 uint32_t dev_state;
1456
1457 ha->isp_ops->idc_lock(ha);
1458 dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
1459
1460 if (ql4xdontresethba)
1461 qla4_83xx_set_idc_dontreset(ha);
1462
1463 if (dev_state == QLA8XXX_DEV_READY) {
1464 /* If IDC_CTRL DONTRESETHBA_BIT0 is set dont do reset
1465 * recovery */
1466 if (qla4_83xx_idc_dontreset(ha) == DONTRESET_BIT0) {
1467 ql4_printk(KERN_ERR, ha, "%s: Reset recovery disabled\n",
1468 __func__);
1469 rval = QLA_ERROR;
1470 goto exit_isp_reset;
1471 }
1472
1473 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: HW State: NEED RESET\n",
1474 __func__));
1475 qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
1476 QLA8XXX_DEV_NEED_RESET);
1477
1478 } else {
1479 /* If device_state is NEED_RESET, go ahead with
1480 * Reset,irrespective of ql4xdontresethba. This is to allow a
1481 * non-reset-owner to force a reset. Non-reset-owner sets
1482 * the IDC_CTRL BIT0 to prevent Reset-owner from doing a Reset
1483 * and then forces a Reset by setting device_state to
1484 * NEED_RESET. */
1485 DEBUG2(ql4_printk(KERN_INFO, ha,
1486 "%s: HW state already set to NEED_RESET\n",
1487 __func__));
1488 }
1489
Vikas Chaudharyb37ca412013-08-16 07:03:02 -04001490 /* For ISP8324 and ISP8042, Reset owner is NIC, iSCSI or FCOE based on
1491 * priority and which drivers are present. Unlike ISP8022, the function
1492 * setting NEED_RESET, may not be the Reset owner. */
Vikas Chaudhary6e7b4292012-08-22 07:55:08 -04001493 if (qla4_83xx_can_perform_reset(ha))
1494 set_bit(AF_8XXX_RST_OWNER, &ha->flags);
1495
1496 ha->isp_ops->idc_unlock(ha);
1497 rval = qla4_8xxx_device_state_handler(ha);
1498
1499 ha->isp_ops->idc_lock(ha);
1500 qla4_8xxx_clear_rst_ready(ha);
1501exit_isp_reset:
1502 ha->isp_ops->idc_unlock(ha);
1503
1504 if (rval == QLA_SUCCESS)
1505 clear_bit(AF_FW_RECOVERY, &ha->flags);
1506
1507 return rval;
1508}
Tej Parkash546fef22012-09-20 07:35:12 -04001509
1510static void qla4_83xx_dump_pause_control_regs(struct scsi_qla_host *ha)
1511{
1512 u32 val = 0, val1 = 0;
1513 int i, status = QLA_SUCCESS;
1514
1515 status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_SRE_SHIM_CONTROL, &val);
1516 DEBUG2(ql4_printk(KERN_INFO, ha, "SRE-Shim Ctrl:0x%x\n", val));
1517
1518 /* Port 0 Rx Buffer Pause Threshold Registers. */
1519 DEBUG2(ql4_printk(KERN_INFO, ha,
1520 "Port 0 Rx Buffer Pause Threshold Registers[TC7..TC0]:"));
1521 for (i = 0; i < 8; i++) {
1522 status = qla4_83xx_rd_reg_indirect(ha,
1523 QLA83XX_PORT0_RXB_PAUSE_THRS + (i * 0x4), &val);
1524 DEBUG2(pr_info("0x%x ", val));
1525 }
1526
1527 DEBUG2(pr_info("\n"));
1528
1529 /* Port 1 Rx Buffer Pause Threshold Registers. */
1530 DEBUG2(ql4_printk(KERN_INFO, ha,
1531 "Port 1 Rx Buffer Pause Threshold Registers[TC7..TC0]:"));
1532 for (i = 0; i < 8; i++) {
1533 status = qla4_83xx_rd_reg_indirect(ha,
1534 QLA83XX_PORT1_RXB_PAUSE_THRS + (i * 0x4), &val);
1535 DEBUG2(pr_info("0x%x ", val));
1536 }
1537
1538 DEBUG2(pr_info("\n"));
1539
1540 /* Port 0 RxB Traffic Class Max Cell Registers. */
1541 DEBUG2(ql4_printk(KERN_INFO, ha,
1542 "Port 0 RxB Traffic Class Max Cell Registers[3..0]:"));
1543 for (i = 0; i < 4; i++) {
1544 status = qla4_83xx_rd_reg_indirect(ha,
1545 QLA83XX_PORT0_RXB_TC_MAX_CELL + (i * 0x4), &val);
1546 DEBUG2(pr_info("0x%x ", val));
1547 }
1548
1549 DEBUG2(pr_info("\n"));
1550
1551 /* Port 1 RxB Traffic Class Max Cell Registers. */
1552 DEBUG2(ql4_printk(KERN_INFO, ha,
1553 "Port 1 RxB Traffic Class Max Cell Registers[3..0]:"));
1554 for (i = 0; i < 4; i++) {
1555 status = qla4_83xx_rd_reg_indirect(ha,
1556 QLA83XX_PORT1_RXB_TC_MAX_CELL + (i * 0x4), &val);
1557 DEBUG2(pr_info("0x%x ", val));
1558 }
1559
1560 DEBUG2(pr_info("\n"));
1561
1562 /* Port 0 RxB Rx Traffic Class Stats. */
1563 DEBUG2(ql4_printk(KERN_INFO, ha,
1564 "Port 0 RxB Rx Traffic Class Stats [TC7..TC0]"));
1565 for (i = 7; i >= 0; i--) {
1566 status = qla4_83xx_rd_reg_indirect(ha,
1567 QLA83XX_PORT0_RXB_TC_STATS,
1568 &val);
1569 val &= ~(0x7 << 29); /* Reset bits 29 to 31 */
1570 qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT0_RXB_TC_STATS,
1571 (val | (i << 29)));
1572 status = qla4_83xx_rd_reg_indirect(ha,
1573 QLA83XX_PORT0_RXB_TC_STATS,
1574 &val);
1575 DEBUG2(pr_info("0x%x ", val));
1576 }
1577
1578 DEBUG2(pr_info("\n"));
1579
1580 /* Port 1 RxB Rx Traffic Class Stats. */
1581 DEBUG2(ql4_printk(KERN_INFO, ha,
1582 "Port 1 RxB Rx Traffic Class Stats [TC7..TC0]"));
1583 for (i = 7; i >= 0; i--) {
1584 status = qla4_83xx_rd_reg_indirect(ha,
1585 QLA83XX_PORT1_RXB_TC_STATS,
1586 &val);
1587 val &= ~(0x7 << 29); /* Reset bits 29 to 31 */
1588 qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT1_RXB_TC_STATS,
1589 (val | (i << 29)));
1590 status = qla4_83xx_rd_reg_indirect(ha,
1591 QLA83XX_PORT1_RXB_TC_STATS,
1592 &val);
1593 DEBUG2(pr_info("0x%x ", val));
1594 }
1595
1596 DEBUG2(pr_info("\n"));
1597
1598 status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_PORT2_IFB_PAUSE_THRS,
1599 &val);
1600 status = qla4_83xx_rd_reg_indirect(ha, QLA83XX_PORT3_IFB_PAUSE_THRS,
1601 &val1);
1602
1603 DEBUG2(ql4_printk(KERN_INFO, ha,
1604 "IFB-Pause Thresholds: Port 2:0x%x, Port 3:0x%x\n",
1605 val, val1));
1606}
1607
1608static void __qla4_83xx_disable_pause(struct scsi_qla_host *ha)
1609{
1610 int i;
1611
1612 /* set SRE-Shim Control Register */
1613 qla4_83xx_wr_reg_indirect(ha, QLA83XX_SRE_SHIM_CONTROL,
1614 QLA83XX_SET_PAUSE_VAL);
1615
1616 for (i = 0; i < 8; i++) {
1617 /* Port 0 Rx Buffer Pause Threshold Registers. */
1618 qla4_83xx_wr_reg_indirect(ha,
1619 QLA83XX_PORT0_RXB_PAUSE_THRS + (i * 0x4),
1620 QLA83XX_SET_PAUSE_VAL);
1621 /* Port 1 Rx Buffer Pause Threshold Registers. */
1622 qla4_83xx_wr_reg_indirect(ha,
1623 QLA83XX_PORT1_RXB_PAUSE_THRS + (i * 0x4),
1624 QLA83XX_SET_PAUSE_VAL);
1625 }
1626
1627 for (i = 0; i < 4; i++) {
1628 /* Port 0 RxB Traffic Class Max Cell Registers. */
1629 qla4_83xx_wr_reg_indirect(ha,
1630 QLA83XX_PORT0_RXB_TC_MAX_CELL + (i * 0x4),
1631 QLA83XX_SET_TC_MAX_CELL_VAL);
1632 /* Port 1 RxB Traffic Class Max Cell Registers. */
1633 qla4_83xx_wr_reg_indirect(ha,
1634 QLA83XX_PORT1_RXB_TC_MAX_CELL + (i * 0x4),
1635 QLA83XX_SET_TC_MAX_CELL_VAL);
1636 }
1637
1638 qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT2_IFB_PAUSE_THRS,
1639 QLA83XX_SET_PAUSE_VAL);
1640 qla4_83xx_wr_reg_indirect(ha, QLA83XX_PORT3_IFB_PAUSE_THRS,
1641 QLA83XX_SET_PAUSE_VAL);
1642
1643 ql4_printk(KERN_INFO, ha, "Disabled pause frames successfully.\n");
1644}
1645
Manish Dusanec18b78e2013-03-07 05:43:07 -05001646/**
1647 * qla4_83xx_eport_init - Initialize EPort.
1648 * @ha: Pointer to host adapter structure.
1649 *
1650 * If EPort hardware is in reset state before disabling pause, there would be
1651 * serious hardware wedging issues. To prevent this perform eport init everytime
1652 * before disabling pause frames.
1653 **/
1654static void qla4_83xx_eport_init(struct scsi_qla_host *ha)
1655{
1656 /* Clear the 8 registers */
1657 qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_REG, 0x0);
1658 qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT0, 0x0);
1659 qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT1, 0x0);
1660 qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT2, 0x0);
1661 qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_PORT3, 0x0);
1662 qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_SRE_SHIM, 0x0);
1663 qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_EPG_SHIM, 0x0);
1664 qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_ETHER_PCS, 0x0);
1665
1666 /* Write any value to Reset Control register */
1667 qla4_83xx_wr_reg_indirect(ha, QLA83XX_RESET_CONTROL, 0xFF);
1668
1669 ql4_printk(KERN_INFO, ha, "EPORT is out of reset.\n");
1670}
1671
Tej Parkash546fef22012-09-20 07:35:12 -04001672void qla4_83xx_disable_pause(struct scsi_qla_host *ha)
1673{
1674 ha->isp_ops->idc_lock(ha);
Manish Dusanec18b78e2013-03-07 05:43:07 -05001675 /* Before disabling pause frames, ensure that eport is not in reset */
1676 qla4_83xx_eport_init(ha);
Tej Parkash546fef22012-09-20 07:35:12 -04001677 qla4_83xx_dump_pause_control_regs(ha);
1678 __qla4_83xx_disable_pause(ha);
1679 ha->isp_ops->idc_unlock(ha);
1680}
Vikas Chaudharya083e8b2013-12-16 06:49:32 -05001681
1682/**
1683 * qla4_83xx_is_detached - Check if we are marked invisible.
1684 * @ha: Pointer to host adapter structure.
1685 **/
1686int qla4_83xx_is_detached(struct scsi_qla_host *ha)
1687{
1688 uint32_t drv_active;
1689
1690 drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
1691
1692 if (test_bit(AF_INIT_DONE, &ha->flags) &&
1693 !(drv_active & (1 << ha->func_num))) {
1694 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: drv_active = 0x%X\n",
1695 __func__, drv_active));
1696 return QLA_SUCCESS;
1697 }
1698
1699 return QLA_ERROR;
1700}