linux/drivers/scsi/qla2xxx/qla_nx2.c
<<
>>
Prefs
   1/*
   2 * QLogic Fibre Channel HBA Driver
   3 * Copyright (c)  2003-2013 QLogic Corporation
   4 *
   5 * See LICENSE.qla2xxx for copyright and licensing details.
   6 */
   7
   8#include <linux/vmalloc.h>
   9
  10#include "qla_def.h"
  11#include "qla_gbl.h"
  12
  13#include <linux/delay.h>
  14
  15/* 8044 Flash Read/Write functions */
  16uint32_t
  17qla8044_rd_reg(struct qla_hw_data *ha, ulong addr)
  18{
  19        return readl((void __iomem *) (ha->nx_pcibase + addr));
  20}
  21
  22void
  23qla8044_wr_reg(struct qla_hw_data *ha, ulong addr, uint32_t val)
  24{
  25        writel(val, (void __iomem *)((ha)->nx_pcibase + addr));
  26}
  27
  28int
  29qla8044_rd_direct(struct scsi_qla_host *vha,
  30        const uint32_t crb_reg)
  31{
  32        struct qla_hw_data *ha = vha->hw;
  33
  34        if (crb_reg < CRB_REG_INDEX_MAX)
  35                return qla8044_rd_reg(ha, qla8044_reg_tbl[crb_reg]);
  36        else
  37                return QLA_FUNCTION_FAILED;
  38}
  39
  40void
  41qla8044_wr_direct(struct scsi_qla_host *vha,
  42        const uint32_t crb_reg,
  43        const uint32_t value)
  44{
  45        struct qla_hw_data *ha = vha->hw;
  46
  47        if (crb_reg < CRB_REG_INDEX_MAX)
  48                qla8044_wr_reg(ha, qla8044_reg_tbl[crb_reg], value);
  49}
  50
  51static int
  52qla8044_set_win_base(scsi_qla_host_t *vha, uint32_t addr)
  53{
  54        uint32_t val;
  55        int ret_val = QLA_SUCCESS;
  56        struct qla_hw_data *ha = vha->hw;
  57
  58        qla8044_wr_reg(ha, QLA8044_CRB_WIN_FUNC(ha->portnum), addr);
  59        val = qla8044_rd_reg(ha, QLA8044_CRB_WIN_FUNC(ha->portnum));
  60
  61        if (val != addr) {
  62                ql_log(ql_log_warn, vha, 0xb087,
  63                    "%s: Failed to set register window : "
  64                    "addr written 0x%x, read 0x%x!\n",
  65                    __func__, addr, val);
  66                ret_val = QLA_FUNCTION_FAILED;
  67        }
  68        return ret_val;
  69}
  70
  71static int
  72qla8044_rd_reg_indirect(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data)
  73{
  74        int ret_val = QLA_SUCCESS;
  75        struct qla_hw_data *ha = vha->hw;
  76
  77        ret_val = qla8044_set_win_base(vha, addr);
  78        if (!ret_val)
  79                *data = qla8044_rd_reg(ha, QLA8044_WILDCARD);
  80        else
  81                ql_log(ql_log_warn, vha, 0xb088,
  82                    "%s: failed read of addr 0x%x!\n", __func__, addr);
  83        return ret_val;
  84}
  85
  86static int
  87qla8044_wr_reg_indirect(scsi_qla_host_t *vha, uint32_t addr, uint32_t data)
  88{
  89        int ret_val = QLA_SUCCESS;
  90        struct qla_hw_data *ha = vha->hw;
  91
  92        ret_val = qla8044_set_win_base(vha, addr);
  93        if (!ret_val)
  94                qla8044_wr_reg(ha, QLA8044_WILDCARD, data);
  95        else
  96                ql_log(ql_log_warn, vha, 0xb089,
  97                    "%s: failed wrt to addr 0x%x, data 0x%x\n",
  98                    __func__, addr, data);
  99        return ret_val;
 100}
 101
 102/*
 103 * qla8044_read_write_crb_reg - Read from raddr and write value to waddr.
 104 *
 105 * @ha : Pointer to adapter structure
 106 * @raddr : CRB address to read from
 107 * @waddr : CRB address to write to
 108 *
 109 */
 110static void
 111qla8044_read_write_crb_reg(struct scsi_qla_host *vha,
 112        uint32_t raddr, uint32_t waddr)
 113{
 114        uint32_t value;
 115
 116        qla8044_rd_reg_indirect(vha, raddr, &value);
 117        qla8044_wr_reg_indirect(vha, waddr, value);
 118}
 119
 120/*
 121 * qla8044_rmw_crb_reg - Read value from raddr, AND with test_mask,
 122 * Shift Left,Right/OR/XOR with values RMW header and write value to waddr.
 123 *
 124 * @vha : Pointer to adapter structure
 125 * @raddr : CRB address to read from
 126 * @waddr : CRB address to write to
 127 * @p_rmw_hdr : header with shift/or/xor values.
 128 *
 129 */
 130static void
 131qla8044_rmw_crb_reg(struct scsi_qla_host *vha,
 132        uint32_t raddr, uint32_t waddr, struct qla8044_rmw *p_rmw_hdr)
 133{
 134        uint32_t value;
 135
 136        if (p_rmw_hdr->index_a)
 137                value = vha->reset_tmplt.array[p_rmw_hdr->index_a];
 138        else
 139                qla8044_rd_reg_indirect(vha, raddr, &value);
 140        value &= p_rmw_hdr->test_mask;
 141        value <<= p_rmw_hdr->shl;
 142        value >>= p_rmw_hdr->shr;
 143        value |= p_rmw_hdr->or_value;
 144        value ^= p_rmw_hdr->xor_value;
 145        qla8044_wr_reg_indirect(vha, waddr, value);
 146        return;
 147}
 148
 149inline void
 150qla8044_set_qsnt_ready(struct scsi_qla_host *vha)
 151{
 152        uint32_t qsnt_state;
 153        struct qla_hw_data *ha = vha->hw;
 154
 155        qsnt_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
 156        qsnt_state |= (1 << ha->portnum);
 157        qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, qsnt_state);
 158        ql_log(ql_log_info, vha, 0xb08e, "%s(%ld): qsnt_state: 0x%08x\n",
 159             __func__, vha->host_no, qsnt_state);
 160}
 161
 162void
 163qla8044_clear_qsnt_ready(struct scsi_qla_host *vha)
 164{
 165        uint32_t qsnt_state;
 166        struct qla_hw_data *ha = vha->hw;
 167
 168        qsnt_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
 169        qsnt_state &= ~(1 << ha->portnum);
 170        qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, qsnt_state);
 171        ql_log(ql_log_info, vha, 0xb08f, "%s(%ld): qsnt_state: 0x%08x\n",
 172            __func__, vha->host_no, qsnt_state);
 173}
 174
 175/**
 176 *
 177 * qla8044_lock_recovery - Recovers the idc_lock.
 178 * @ha : Pointer to adapter structure
 179 *
 180 * Lock Recovery Register
 181 * 5-2  Lock recovery owner: Function ID of driver doing lock recovery,
 182 *      valid if bits 1..0 are set by driver doing lock recovery.
 183 * 1-0  1 - Driver intends to force unlock the IDC lock.
 184 *      2 - Driver is moving forward to unlock the IDC lock. Driver clears
 185 *          this field after force unlocking the IDC lock.
 186 *
 187 * Lock Recovery process
 188 * a. Read the IDC_LOCK_RECOVERY register. If the value in bits 1..0 is
 189 *    greater than 0, then wait for the other driver to unlock otherwise
 190 *    move to the next step.
 191 * b. Indicate intent to force-unlock by writing 1h to the IDC_LOCK_RECOVERY
 192 *    register bits 1..0 and also set the function# in bits 5..2.
 193 * c. Read the IDC_LOCK_RECOVERY register again after a delay of 200ms.
 194 *    Wait for the other driver to perform lock recovery if the function
 195 *    number in bits 5..2 has changed, otherwise move to the next step.
 196 * d. Write a value of 2h to the IDC_LOCK_RECOVERY register bits 1..0
 197 *    leaving your function# in bits 5..2.
 198 * e. Force unlock using the DRIVER_UNLOCK register and immediately clear
 199 *    the IDC_LOCK_RECOVERY bits 5..0 by writing 0.
 200 **/
 201static int
 202qla8044_lock_recovery(struct scsi_qla_host *vha)
 203{
 204        uint32_t lock = 0, lockid;
 205        struct qla_hw_data *ha = vha->hw;
 206
 207        lockid = qla8044_rd_reg(ha, QLA8044_DRV_LOCKRECOVERY);
 208
 209        /* Check for other Recovery in progress, go wait */
 210        if ((lockid & IDC_LOCK_RECOVERY_STATE_MASK) != 0)
 211                return QLA_FUNCTION_FAILED;
 212
 213        /* Intent to Recover */
 214        qla8044_wr_reg(ha, QLA8044_DRV_LOCKRECOVERY,
 215            (ha->portnum <<
 216             IDC_LOCK_RECOVERY_STATE_SHIFT_BITS) | INTENT_TO_RECOVER);
 217        msleep(200);
 218
 219        /* Check Intent to Recover is advertised */
 220        lockid = qla8044_rd_reg(ha, QLA8044_DRV_LOCKRECOVERY);
 221        if ((lockid & IDC_LOCK_RECOVERY_OWNER_MASK) != (ha->portnum <<
 222            IDC_LOCK_RECOVERY_STATE_SHIFT_BITS))
 223                return QLA_FUNCTION_FAILED;
 224
 225        ql_dbg(ql_dbg_p3p, vha, 0xb08B, "%s:%d: IDC Lock recovery initiated\n"
 226            , __func__, ha->portnum);
 227
 228        /* Proceed to Recover */
 229        qla8044_wr_reg(ha, QLA8044_DRV_LOCKRECOVERY,
 230            (ha->portnum << IDC_LOCK_RECOVERY_STATE_SHIFT_BITS) |
 231            PROCEED_TO_RECOVER);
 232
 233        /* Force Unlock() */
 234        qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, 0xFF);
 235        qla8044_rd_reg(ha, QLA8044_DRV_UNLOCK);
 236
 237        /* Clear bits 0-5 in IDC_RECOVERY register*/
 238        qla8044_wr_reg(ha, QLA8044_DRV_LOCKRECOVERY, 0);
 239
 240        /* Get lock() */
 241        lock = qla8044_rd_reg(ha, QLA8044_DRV_LOCK);
 242        if (lock) {
 243                lockid = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
 244                lockid = ((lockid + (1 << 8)) & ~0xFF) | ha->portnum;
 245                qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, lockid);
 246                return QLA_SUCCESS;
 247        } else
 248                return QLA_FUNCTION_FAILED;
 249}
 250
 251int
 252qla8044_idc_lock(struct qla_hw_data *ha)
 253{
 254        uint32_t ret_val = QLA_SUCCESS, timeout = 0, status = 0;
 255        uint32_t lock_id, lock_cnt, func_num, tmo_owner = 0, first_owner = 0;
 256        scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
 257
 258        while (status == 0) {
 259                /* acquire semaphore5 from PCI HW block */
 260                status = qla8044_rd_reg(ha, QLA8044_DRV_LOCK);
 261
 262                if (status) {
 263                        /* Increment Counter (8-31) and update func_num (0-7) on
 264                         * getting a successful lock  */
 265                        lock_id = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
 266                        lock_id = ((lock_id + (1 << 8)) & ~0xFF) | ha->portnum;
 267                        qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, lock_id);
 268                        break;
 269                }
 270
 271                if (timeout == 0)
 272                        first_owner = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
 273
 274                if (++timeout >=
 275                    (QLA8044_DRV_LOCK_TIMEOUT / QLA8044_DRV_LOCK_MSLEEP)) {
 276                        tmo_owner = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
 277                        func_num = tmo_owner & 0xFF;
 278                        lock_cnt = tmo_owner >> 8;
 279                        ql_log(ql_log_warn, vha, 0xb114,
 280                            "%s: Lock by func %d failed after 2s, lock held "
 281                            "by func %d, lock count %d, first_owner %d\n",
 282                            __func__, ha->portnum, func_num, lock_cnt,
 283                            (first_owner & 0xFF));
 284                        if (first_owner != tmo_owner) {
 285                                /* Some other driver got lock,
 286                                 * OR same driver got lock again (counter
 287                                 * value changed), when we were waiting for
 288                                 * lock. Retry for another 2 sec */
 289                                ql_dbg(ql_dbg_p3p, vha, 0xb115,
 290                                    "%s: %d: IDC lock failed\n",
 291                                    __func__, ha->portnum);
 292                                timeout = 0;
 293                        } else {
 294                                /* Same driver holding lock > 2sec.
 295                                 * Force Recovery */
 296                                if (qla8044_lock_recovery(vha) == QLA_SUCCESS) {
 297                                        /* Recovered and got lock */
 298                                        ret_val = QLA_SUCCESS;
 299                                        ql_dbg(ql_dbg_p3p, vha, 0xb116,
 300                                            "%s:IDC lock Recovery by %d"
 301                                            "successful...\n", __func__,
 302                                             ha->portnum);
 303                                }
 304                                /* Recovery Failed, some other function
 305                                 * has the lock, wait for 2secs
 306                                 * and retry
 307                                 */
 308                                 ql_dbg(ql_dbg_p3p, vha, 0xb08a,
 309                                     "%s: IDC lock Recovery by %d "
 310                                     "failed, Retrying timout\n", __func__,
 311                                     ha->portnum);
 312                                 timeout = 0;
 313                        }
 314                }
 315                msleep(QLA8044_DRV_LOCK_MSLEEP);
 316        }
 317        return ret_val;
 318}
 319
 320void
 321qla8044_idc_unlock(struct qla_hw_data *ha)
 322{
 323        int id;
 324        scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
 325
 326        id = qla8044_rd_reg(ha, QLA8044_DRV_LOCK_ID);
 327
 328        if ((id & 0xFF) != ha->portnum) {
 329                ql_log(ql_log_warn, vha, 0xb118,
 330                    "%s: IDC Unlock by %d failed, lock owner is %d!\n",
 331                    __func__, ha->portnum, (id & 0xFF));
 332                return;
 333        }
 334
 335        /* Keep lock counter value, update the ha->func_num to 0xFF */
 336        qla8044_wr_reg(ha, QLA8044_DRV_LOCK_ID, (id | 0xFF));
 337        qla8044_rd_reg(ha, QLA8044_DRV_UNLOCK);
 338}
 339
 340/* 8044 Flash Lock/Unlock functions */
 341static int
 342qla8044_flash_lock(scsi_qla_host_t *vha)
 343{
 344        int lock_owner;
 345        int timeout = 0;
 346        uint32_t lock_status = 0;
 347        int ret_val = QLA_SUCCESS;
 348        struct qla_hw_data *ha = vha->hw;
 349
 350        while (lock_status == 0) {
 351                lock_status = qla8044_rd_reg(ha, QLA8044_FLASH_LOCK);
 352                if (lock_status)
 353                        break;
 354
 355                if (++timeout >= QLA8044_FLASH_LOCK_TIMEOUT / 20) {
 356                        lock_owner = qla8044_rd_reg(ha,
 357                            QLA8044_FLASH_LOCK_ID);
 358                        ql_log(ql_log_warn, vha, 0xb113,
 359                            "%s: flash lock by %d failed, held by %d\n",
 360                                __func__, ha->portnum, lock_owner);
 361                        ret_val = QLA_FUNCTION_FAILED;
 362                        break;
 363                }
 364                msleep(20);
 365        }
 366        qla8044_wr_reg(ha, QLA8044_FLASH_LOCK_ID, ha->portnum);
 367        return ret_val;
 368}
 369
 370static void
 371qla8044_flash_unlock(scsi_qla_host_t *vha)
 372{
 373        int ret_val;
 374        struct qla_hw_data *ha = vha->hw;
 375
 376        /* Reading FLASH_UNLOCK register unlocks the Flash */
 377        qla8044_wr_reg(ha, QLA8044_FLASH_LOCK_ID, 0xFF);
 378        ret_val = qla8044_rd_reg(ha, QLA8044_FLASH_UNLOCK);
 379}
 380
 381
 382static
 383void qla8044_flash_lock_recovery(struct scsi_qla_host *vha)
 384{
 385
 386        if (qla8044_flash_lock(vha)) {
 387                /* Someone else is holding the lock. */
 388                ql_log(ql_log_warn, vha, 0xb120, "Resetting flash_lock\n");
 389        }
 390
 391        /*
 392         * Either we got the lock, or someone
 393         * else died while holding it.
 394         * In either case, unlock.
 395         */
 396        qla8044_flash_unlock(vha);
 397}
 398
 399/*
 400 * Address and length are byte address
 401 */
 402static int
 403qla8044_read_flash_data(scsi_qla_host_t *vha,  uint8_t *p_data,
 404        uint32_t flash_addr, int u32_word_count)
 405{
 406        int i, ret_val = QLA_SUCCESS;
 407        uint32_t u32_word;
 408
 409        if (qla8044_flash_lock(vha) != QLA_SUCCESS) {
 410                ret_val = QLA_FUNCTION_FAILED;
 411                goto exit_lock_error;
 412        }
 413
 414        if (flash_addr & 0x03) {
 415                ql_log(ql_log_warn, vha, 0xb117,
 416                    "%s: Illegal addr = 0x%x\n", __func__, flash_addr);
 417                ret_val = QLA_FUNCTION_FAILED;
 418                goto exit_flash_read;
 419        }
 420
 421        for (i = 0; i < u32_word_count; i++) {
 422                if (qla8044_wr_reg_indirect(vha, QLA8044_FLASH_DIRECT_WINDOW,
 423                    (flash_addr & 0xFFFF0000))) {
 424                        ql_log(ql_log_warn, vha, 0xb119,
 425                            "%s: failed to write addr 0x%x to "
 426                            "FLASH_DIRECT_WINDOW\n! ",
 427                            __func__, flash_addr);
 428                        ret_val = QLA_FUNCTION_FAILED;
 429                        goto exit_flash_read;
 430                }
 431
 432                ret_val = qla8044_rd_reg_indirect(vha,
 433                    QLA8044_FLASH_DIRECT_DATA(flash_addr),
 434                    &u32_word);
 435                if (ret_val != QLA_SUCCESS) {
 436                        ql_log(ql_log_warn, vha, 0xb08c,
 437                            "%s: failed to read addr 0x%x!\n",
 438                            __func__, flash_addr);
 439                        goto exit_flash_read;
 440                }
 441
 442                *(uint32_t *)p_data = u32_word;
 443                p_data = p_data + 4;
 444                flash_addr = flash_addr + 4;
 445        }
 446
 447exit_flash_read:
 448        qla8044_flash_unlock(vha);
 449
 450exit_lock_error:
 451        return ret_val;
 452}
 453
 454/*
 455 * Address and length are byte address
 456 */
 457uint8_t *
 458qla8044_read_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
 459        uint32_t offset, uint32_t length)
 460{
 461        scsi_block_requests(vha->host);
 462        if (qla8044_read_flash_data(vha, (uint8_t *)buf, offset, length / 4)
 463            != QLA_SUCCESS) {
 464                ql_log(ql_log_warn, vha,  0xb08d,
 465                    "%s: Failed to read from flash\n",
 466                    __func__);
 467        }
 468        scsi_unblock_requests(vha->host);
 469        return buf;
 470}
 471
 472inline int
 473qla8044_need_reset(struct scsi_qla_host *vha)
 474{
 475        uint32_t drv_state, drv_active;
 476        int rval;
 477        struct qla_hw_data *ha = vha->hw;
 478
 479        drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
 480        drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
 481
 482        rval = drv_state & (1 << ha->portnum);
 483
 484        if (ha->flags.eeh_busy && drv_active)
 485                rval = 1;
 486        return rval;
 487}
 488
 489/*
 490 * qla8044_write_list - Write the value (p_entry->arg2) to address specified
 491 * by p_entry->arg1 for all entries in header with delay of p_hdr->delay between
 492 * entries.
 493 *
 494 * @vha : Pointer to adapter structure
 495 * @p_hdr : reset_entry header for WRITE_LIST opcode.
 496 *
 497 */
 498static void
 499qla8044_write_list(struct scsi_qla_host *vha,
 500        struct qla8044_reset_entry_hdr *p_hdr)
 501{
 502        struct qla8044_entry *p_entry;
 503        uint32_t i;
 504
 505        p_entry = (struct qla8044_entry *)((char *)p_hdr +
 506            sizeof(struct qla8044_reset_entry_hdr));
 507
 508        for (i = 0; i < p_hdr->count; i++, p_entry++) {
 509                qla8044_wr_reg_indirect(vha, p_entry->arg1, p_entry->arg2);
 510                if (p_hdr->delay)
 511                        udelay((uint32_t)(p_hdr->delay));
 512        }
 513}
 514
 515/*
 516 * qla8044_read_write_list - Read from address specified by p_entry->arg1,
 517 * write value read to address specified by p_entry->arg2, for all entries in
 518 * header with delay of p_hdr->delay between entries.
 519 *
 520 * @vha : Pointer to adapter structure
 521 * @p_hdr : reset_entry header for READ_WRITE_LIST opcode.
 522 *
 523 */
 524static void
 525qla8044_read_write_list(struct scsi_qla_host *vha,
 526        struct qla8044_reset_entry_hdr *p_hdr)
 527{
 528        struct qla8044_entry *p_entry;
 529        uint32_t i;
 530
 531        p_entry = (struct qla8044_entry *)((char *)p_hdr +
 532            sizeof(struct qla8044_reset_entry_hdr));
 533
 534        for (i = 0; i < p_hdr->count; i++, p_entry++) {
 535                qla8044_read_write_crb_reg(vha, p_entry->arg1,
 536                    p_entry->arg2);
 537                if (p_hdr->delay)
 538                        udelay((uint32_t)(p_hdr->delay));
 539        }
 540}
 541
 542/*
 543 * qla8044_poll_reg - Poll the given CRB addr for duration msecs till
 544 * value read ANDed with test_mask is equal to test_result.
 545 *
 546 * @ha : Pointer to adapter structure
 547 * @addr : CRB register address
 548 * @duration : Poll for total of "duration" msecs
 549 * @test_mask : Mask value read with "test_mask"
 550 * @test_result : Compare (value&test_mask) with test_result.
 551 *
 552 * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
 553 */
 554static int
 555qla8044_poll_reg(struct scsi_qla_host *vha, uint32_t addr,
 556        int duration, uint32_t test_mask, uint32_t test_result)
 557{
 558        uint32_t value;
 559        int timeout_error;
 560        uint8_t retries;
 561        int ret_val = QLA_SUCCESS;
 562
 563        ret_val = qla8044_rd_reg_indirect(vha, addr, &value);
 564        if (ret_val == QLA_FUNCTION_FAILED) {
 565                timeout_error = 1;
 566                goto exit_poll_reg;
 567        }
 568
 569        /* poll every 1/10 of the total duration */
 570        retries = duration/10;
 571
 572        do {
 573                if ((value & test_mask) != test_result) {
 574                        timeout_error = 1;
 575                        msleep(duration/10);
 576                        ret_val = qla8044_rd_reg_indirect(vha, addr, &value);
 577                        if (ret_val == QLA_FUNCTION_FAILED) {
 578                                timeout_error = 1;
 579                                goto exit_poll_reg;
 580                        }
 581                } else {
 582                        timeout_error = 0;
 583                        break;
 584                }
 585        } while (retries--);
 586
 587exit_poll_reg:
 588        if (timeout_error) {
 589                vha->reset_tmplt.seq_error++;
 590                ql_log(ql_log_fatal, vha, 0xb090,
 591                    "%s: Poll Failed: 0x%08x 0x%08x 0x%08x\n",
 592                    __func__, value, test_mask, test_result);
 593        }
 594
 595        return timeout_error;
 596}
 597
 598/*
 599 * qla8044_poll_list - For all entries in the POLL_LIST header, poll read CRB
 600 * register specified by p_entry->arg1 and compare (value AND test_mask) with
 601 * test_result to validate it. Wait for p_hdr->delay between processing entries.
 602 *
 603 * @ha : Pointer to adapter structure
 604 * @p_hdr : reset_entry header for POLL_LIST opcode.
 605 *
 606 */
 607static void
 608qla8044_poll_list(struct scsi_qla_host *vha,
 609        struct qla8044_reset_entry_hdr *p_hdr)
 610{
 611        long delay;
 612        struct qla8044_entry *p_entry;
 613        struct qla8044_poll *p_poll;
 614        uint32_t i;
 615        uint32_t value;
 616
 617        p_poll = (struct qla8044_poll *)
 618                ((char *)p_hdr + sizeof(struct qla8044_reset_entry_hdr));
 619
 620        /* Entries start after 8 byte qla8044_poll, poll header contains
 621         * the test_mask, test_value.
 622         */
 623        p_entry = (struct qla8044_entry *)((char *)p_poll +
 624            sizeof(struct qla8044_poll));
 625
 626        delay = (long)p_hdr->delay;
 627
 628        if (!delay) {
 629                for (i = 0; i < p_hdr->count; i++, p_entry++)
 630                        qla8044_poll_reg(vha, p_entry->arg1,
 631                            delay, p_poll->test_mask, p_poll->test_value);
 632        } else {
 633                for (i = 0; i < p_hdr->count; i++, p_entry++) {
 634                        if (delay) {
 635                                if (qla8044_poll_reg(vha,
 636                                    p_entry->arg1, delay,
 637                                    p_poll->test_mask,
 638                                    p_poll->test_value)) {
 639                                        /*If
 640                                        * (data_read&test_mask != test_value)
 641                                        * read TIMEOUT_ADDR (arg1) and
 642                                        * ADDR (arg2) registers
 643                                        */
 644                                        qla8044_rd_reg_indirect(vha,
 645                                            p_entry->arg1, &value);
 646                                        qla8044_rd_reg_indirect(vha,
 647                                            p_entry->arg2, &value);
 648                                }
 649                        }
 650                }
 651        }
 652}
 653
 654/*
 655 * qla8044_poll_write_list - Write dr_value, ar_value to dr_addr/ar_addr,
 656 * read ar_addr, if (value& test_mask != test_mask) re-read till timeout
 657 * expires.
 658 *
 659 * @vha : Pointer to adapter structure
 660 * @p_hdr : reset entry header for POLL_WRITE_LIST opcode.
 661 *
 662 */
 663static void
 664qla8044_poll_write_list(struct scsi_qla_host *vha,
 665        struct qla8044_reset_entry_hdr *p_hdr)
 666{
 667        long delay;
 668        struct qla8044_quad_entry *p_entry;
 669        struct qla8044_poll *p_poll;
 670        uint32_t i;
 671
 672        p_poll = (struct qla8044_poll *)((char *)p_hdr +
 673            sizeof(struct qla8044_reset_entry_hdr));
 674
 675        p_entry = (struct qla8044_quad_entry *)((char *)p_poll +
 676            sizeof(struct qla8044_poll));
 677
 678        delay = (long)p_hdr->delay;
 679
 680        for (i = 0; i < p_hdr->count; i++, p_entry++) {
 681                qla8044_wr_reg_indirect(vha,
 682                    p_entry->dr_addr, p_entry->dr_value);
 683                qla8044_wr_reg_indirect(vha,
 684                    p_entry->ar_addr, p_entry->ar_value);
 685                if (delay) {
 686                        if (qla8044_poll_reg(vha,
 687                            p_entry->ar_addr, delay,
 688                            p_poll->test_mask,
 689                            p_poll->test_value)) {
 690                                ql_dbg(ql_dbg_p3p, vha, 0xb091,
 691                                    "%s: Timeout Error: poll list, ",
 692                                    __func__);
 693                                ql_dbg(ql_dbg_p3p, vha, 0xb092,
 694                                    "item_num %d, entry_num %d\n", i,
 695                                    vha->reset_tmplt.seq_index);
 696                        }
 697                }
 698        }
 699}
 700
 701/*
 702 * qla8044_read_modify_write - Read value from p_entry->arg1, modify the
 703 * value, write value to p_entry->arg2. Process entries with p_hdr->delay
 704 * between entries.
 705 *
 706 * @vha : Pointer to adapter structure
 707 * @p_hdr : header with shift/or/xor values.
 708 *
 709 */
 710static void
 711qla8044_read_modify_write(struct scsi_qla_host *vha,
 712        struct qla8044_reset_entry_hdr *p_hdr)
 713{
 714        struct qla8044_entry *p_entry;
 715        struct qla8044_rmw *p_rmw_hdr;
 716        uint32_t i;
 717
 718        p_rmw_hdr = (struct qla8044_rmw *)((char *)p_hdr +
 719            sizeof(struct qla8044_reset_entry_hdr));
 720
 721        p_entry = (struct qla8044_entry *)((char *)p_rmw_hdr +
 722            sizeof(struct qla8044_rmw));
 723
 724        for (i = 0; i < p_hdr->count; i++, p_entry++) {
 725                qla8044_rmw_crb_reg(vha, p_entry->arg1,
 726                    p_entry->arg2, p_rmw_hdr);
 727                if (p_hdr->delay)
 728                        udelay((uint32_t)(p_hdr->delay));
 729        }
 730}
 731
 732/*
 733 * qla8044_pause - Wait for p_hdr->delay msecs, called between processing
 734 * two entries of a sequence.
 735 *
 736 * @vha : Pointer to adapter structure
 737 * @p_hdr : Common reset entry header.
 738 *
 739 */
 740static
 741void qla8044_pause(struct scsi_qla_host *vha,
 742        struct qla8044_reset_entry_hdr *p_hdr)
 743{
 744        if (p_hdr->delay)
 745                mdelay((uint32_t)((long)p_hdr->delay));
 746}
 747
 748/*
 749 * qla8044_template_end - Indicates end of reset sequence processing.
 750 *
 751 * @vha : Pointer to adapter structure
 752 * @p_hdr : Common reset entry header.
 753 *
 754 */
 755static void
 756qla8044_template_end(struct scsi_qla_host *vha,
 757        struct qla8044_reset_entry_hdr *p_hdr)
 758{
 759        vha->reset_tmplt.template_end = 1;
 760
 761        if (vha->reset_tmplt.seq_error == 0) {
 762                ql_dbg(ql_dbg_p3p, vha, 0xb093,
 763                    "%s: Reset sequence completed SUCCESSFULLY.\n", __func__);
 764        } else {
 765                ql_log(ql_log_fatal, vha, 0xb094,
 766                    "%s: Reset sequence completed with some timeout "
 767                    "errors.\n", __func__);
 768        }
 769}
 770
 771/*
 772 * qla8044_poll_read_list - Write ar_value to ar_addr register, read ar_addr,
 773 * if (value & test_mask != test_value) re-read till timeout value expires,
 774 * read dr_addr register and assign to reset_tmplt.array.
 775 *
 776 * @vha : Pointer to adapter structure
 777 * @p_hdr : Common reset entry header.
 778 *
 779 */
 780static void
 781qla8044_poll_read_list(struct scsi_qla_host *vha,
 782        struct qla8044_reset_entry_hdr *p_hdr)
 783{
 784        long delay;
 785        int index;
 786        struct qla8044_quad_entry *p_entry;
 787        struct qla8044_poll *p_poll;
 788        uint32_t i;
 789        uint32_t value;
 790
 791        p_poll = (struct qla8044_poll *)
 792                ((char *)p_hdr + sizeof(struct qla8044_reset_entry_hdr));
 793
 794        p_entry = (struct qla8044_quad_entry *)
 795                ((char *)p_poll + sizeof(struct qla8044_poll));
 796
 797        delay = (long)p_hdr->delay;
 798
 799        for (i = 0; i < p_hdr->count; i++, p_entry++) {
 800                qla8044_wr_reg_indirect(vha, p_entry->ar_addr,
 801                    p_entry->ar_value);
 802                if (delay) {
 803                        if (qla8044_poll_reg(vha, p_entry->ar_addr, delay,
 804                            p_poll->test_mask, p_poll->test_value)) {
 805                                ql_dbg(ql_dbg_p3p, vha, 0xb095,
 806                                    "%s: Timeout Error: poll "
 807                                    "list, ", __func__);
 808                                ql_dbg(ql_dbg_p3p, vha, 0xb096,
 809                                    "Item_num %d, "
 810                                    "entry_num %d\n", i,
 811                                    vha->reset_tmplt.seq_index);
 812                        } else {
 813                                index = vha->reset_tmplt.array_index;
 814                                qla8044_rd_reg_indirect(vha,
 815                                    p_entry->dr_addr, &value);
 816                                vha->reset_tmplt.array[index++] = value;
 817                                if (index == QLA8044_MAX_RESET_SEQ_ENTRIES)
 818                                        vha->reset_tmplt.array_index = 1;
 819                        }
 820                }
 821        }
 822}
 823
 824/*
 825 * qla8031_process_reset_template - Process all entries in reset template
 826 * till entry with SEQ_END opcode, which indicates end of the reset template
 827 * processing. Each entry has a Reset Entry header, entry opcode/command, with
 828 * size of the entry, number of entries in sub-sequence and delay in microsecs
 829 * or timeout in millisecs.
 830 *
 831 * @ha : Pointer to adapter structure
 832 * @p_buff : Common reset entry header.
 833 *
 834 */
 835static void
 836qla8044_process_reset_template(struct scsi_qla_host *vha,
 837        char *p_buff)
 838{
 839        int index, entries;
 840        struct qla8044_reset_entry_hdr *p_hdr;
 841        char *p_entry = p_buff;
 842
 843        vha->reset_tmplt.seq_end = 0;
 844        vha->reset_tmplt.template_end = 0;
 845        entries = vha->reset_tmplt.hdr->entries;
 846        index = vha->reset_tmplt.seq_index;
 847
 848        for (; (!vha->reset_tmplt.seq_end) && (index  < entries); index++) {
 849                p_hdr = (struct qla8044_reset_entry_hdr *)p_entry;
 850                switch (p_hdr->cmd) {
 851                case OPCODE_NOP:
 852                        break;
 853                case OPCODE_WRITE_LIST:
 854                        qla8044_write_list(vha, p_hdr);
 855                        break;
 856                case OPCODE_READ_WRITE_LIST:
 857                        qla8044_read_write_list(vha, p_hdr);
 858                        break;
 859                case OPCODE_POLL_LIST:
 860                        qla8044_poll_list(vha, p_hdr);
 861                        break;
 862                case OPCODE_POLL_WRITE_LIST:
 863                        qla8044_poll_write_list(vha, p_hdr);
 864                        break;
 865                case OPCODE_READ_MODIFY_WRITE:
 866                        qla8044_read_modify_write(vha, p_hdr);
 867                        break;
 868                case OPCODE_SEQ_PAUSE:
 869                        qla8044_pause(vha, p_hdr);
 870                        break;
 871                case OPCODE_SEQ_END:
 872                        vha->reset_tmplt.seq_end = 1;
 873                        break;
 874                case OPCODE_TMPL_END:
 875                        qla8044_template_end(vha, p_hdr);
 876                        break;
 877                case OPCODE_POLL_READ_LIST:
 878                        qla8044_poll_read_list(vha, p_hdr);
 879                        break;
 880                default:
 881                        ql_log(ql_log_fatal, vha, 0xb097,
 882                            "%s: Unknown command ==> 0x%04x on "
 883                            "entry = %d\n", __func__, p_hdr->cmd, index);
 884                        break;
 885                }
 886                /*
 887                 *Set pointer to next entry in the sequence.
 888                */
 889                p_entry += p_hdr->size;
 890        }
 891        vha->reset_tmplt.seq_index = index;
 892}
 893
 894static void
 895qla8044_process_init_seq(struct scsi_qla_host *vha)
 896{
 897        qla8044_process_reset_template(vha,
 898            vha->reset_tmplt.init_offset);
 899        if (vha->reset_tmplt.seq_end != 1)
 900                ql_log(ql_log_fatal, vha, 0xb098,
 901                    "%s: Abrupt INIT Sub-Sequence end.\n",
 902                    __func__);
 903}
 904
 905static void
 906qla8044_process_stop_seq(struct scsi_qla_host *vha)
 907{
 908        vha->reset_tmplt.seq_index = 0;
 909        qla8044_process_reset_template(vha, vha->reset_tmplt.stop_offset);
 910        if (vha->reset_tmplt.seq_end != 1)
 911                ql_log(ql_log_fatal, vha, 0xb099,
 912                    "%s: Abrupt STOP Sub-Sequence end.\n", __func__);
 913}
 914
 915static void
 916qla8044_process_start_seq(struct scsi_qla_host *vha)
 917{
 918        qla8044_process_reset_template(vha, vha->reset_tmplt.start_offset);
 919        if (vha->reset_tmplt.template_end != 1)
 920                ql_log(ql_log_fatal, vha, 0xb09a,
 921                    "%s: Abrupt START Sub-Sequence end.\n",
 922                    __func__);
 923}
 924
 925static int
 926qla8044_lockless_flash_read_u32(struct scsi_qla_host *vha,
 927        uint32_t flash_addr, uint8_t *p_data, int u32_word_count)
 928{
 929        uint32_t i;
 930        uint32_t u32_word;
 931        uint32_t flash_offset;
 932        uint32_t addr = flash_addr;
 933        int ret_val = QLA_SUCCESS;
 934
 935        flash_offset = addr & (QLA8044_FLASH_SECTOR_SIZE - 1);
 936
 937        if (addr & 0x3) {
 938                ql_log(ql_log_fatal, vha, 0xb09b, "%s: Illegal addr = 0x%x\n",
 939                    __func__, addr);
 940                ret_val = QLA_FUNCTION_FAILED;
 941                goto exit_lockless_read;
 942        }
 943
 944        ret_val = qla8044_wr_reg_indirect(vha,
 945            QLA8044_FLASH_DIRECT_WINDOW, (addr));
 946
 947        if (ret_val != QLA_SUCCESS) {
 948                ql_log(ql_log_fatal, vha, 0xb09c,
 949                    "%s: failed to write addr 0x%x to FLASH_DIRECT_WINDOW!\n",
 950                    __func__, addr);
 951                goto exit_lockless_read;
 952        }
 953
 954        /* Check if data is spread across multiple sectors  */
 955        if ((flash_offset + (u32_word_count * sizeof(uint32_t))) >
 956            (QLA8044_FLASH_SECTOR_SIZE - 1)) {
 957                /* Multi sector read */
 958                for (i = 0; i < u32_word_count; i++) {
 959                        ret_val = qla8044_rd_reg_indirect(vha,
 960                            QLA8044_FLASH_DIRECT_DATA(addr), &u32_word);
 961                        if (ret_val != QLA_SUCCESS) {
 962                                ql_log(ql_log_fatal, vha, 0xb09d,
 963                                    "%s: failed to read addr 0x%x!\n",
 964                                    __func__, addr);
 965                                goto exit_lockless_read;
 966                        }
 967                        *(uint32_t *)p_data  = u32_word;
 968                        p_data = p_data + 4;
 969                        addr = addr + 4;
 970                        flash_offset = flash_offset + 4;
 971                        if (flash_offset > (QLA8044_FLASH_SECTOR_SIZE - 1)) {
 972                                /* This write is needed once for each sector */
 973                                ret_val = qla8044_wr_reg_indirect(vha,
 974                                    QLA8044_FLASH_DIRECT_WINDOW, (addr));
 975                                if (ret_val != QLA_SUCCESS) {
 976                                        ql_log(ql_log_fatal, vha, 0xb09f,
 977                                            "%s: failed to write addr "
 978                                            "0x%x to FLASH_DIRECT_WINDOW!\n",
 979                                            __func__, addr);
 980                                        goto exit_lockless_read;
 981                                }
 982                                flash_offset = 0;
 983                        }
 984                }
 985        } else {
 986                /* Single sector read */
 987                for (i = 0; i < u32_word_count; i++) {
 988                        ret_val = qla8044_rd_reg_indirect(vha,
 989                            QLA8044_FLASH_DIRECT_DATA(addr), &u32_word);
 990                        if (ret_val != QLA_SUCCESS) {
 991                                ql_log(ql_log_fatal, vha, 0xb0a0,
 992                                    "%s: failed to read addr 0x%x!\n",
 993                                    __func__, addr);
 994                                goto exit_lockless_read;
 995                        }
 996                        *(uint32_t *)p_data = u32_word;
 997                        p_data = p_data + 4;
 998                        addr = addr + 4;
 999                }
1000        }
1001
1002exit_lockless_read:
1003        return ret_val;
1004}
1005
1006/*
1007 * qla8044_ms_mem_write_128b - Writes data to MS/off-chip memory
1008 *
1009 * @vha : Pointer to adapter structure
1010 * addr : Flash address to write to
1011 * data : Data to be written
1012 * count : word_count to be written
1013 *
1014 * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
1015 */
1016static int
1017qla8044_ms_mem_write_128b(struct scsi_qla_host *vha,
1018        uint64_t addr, uint32_t *data, uint32_t count)
1019{
1020        int i, j, ret_val = QLA_SUCCESS;
1021        uint32_t agt_ctrl;
1022        unsigned long flags;
1023        struct qla_hw_data *ha = vha->hw;
1024
1025        /* Only 128-bit aligned access */
1026        if (addr & 0xF) {
1027                ret_val = QLA_FUNCTION_FAILED;
1028                goto exit_ms_mem_write;
1029        }
1030        write_lock_irqsave(&ha->hw_lock, flags);
1031
1032        /* Write address */
1033        ret_val = qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_ADDR_HI, 0);
1034        if (ret_val == QLA_FUNCTION_FAILED) {
1035                ql_log(ql_log_fatal, vha, 0xb0a1,
1036                    "%s: write to AGT_ADDR_HI failed!\n", __func__);
1037                goto exit_ms_mem_write_unlock;
1038        }
1039
1040        for (i = 0; i < count; i++, addr += 16) {
1041                if (!((QLA8044_ADDR_IN_RANGE(addr, QLA8044_ADDR_QDR_NET,
1042                    QLA8044_ADDR_QDR_NET_MAX)) ||
1043                    (QLA8044_ADDR_IN_RANGE(addr, QLA8044_ADDR_DDR_NET,
1044                        QLA8044_ADDR_DDR_NET_MAX)))) {
1045                        ret_val = QLA_FUNCTION_FAILED;
1046                        goto exit_ms_mem_write_unlock;
1047                }
1048
1049                ret_val = qla8044_wr_reg_indirect(vha,
1050                    MD_MIU_TEST_AGT_ADDR_LO, addr);
1051
1052                /* Write data */
1053                ret_val += qla8044_wr_reg_indirect(vha,
1054                    MD_MIU_TEST_AGT_WRDATA_LO, *data++);
1055                ret_val += qla8044_wr_reg_indirect(vha,
1056                    MD_MIU_TEST_AGT_WRDATA_HI, *data++);
1057                ret_val += qla8044_wr_reg_indirect(vha,
1058                    MD_MIU_TEST_AGT_WRDATA_ULO, *data++);
1059                ret_val += qla8044_wr_reg_indirect(vha,
1060                    MD_MIU_TEST_AGT_WRDATA_UHI, *data++);
1061                if (ret_val == QLA_FUNCTION_FAILED) {
1062                        ql_log(ql_log_fatal, vha, 0xb0a2,
1063                            "%s: write to AGT_WRDATA failed!\n",
1064                            __func__);
1065                        goto exit_ms_mem_write_unlock;
1066                }
1067
1068                /* Check write status */
1069                ret_val = qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL,
1070                    MIU_TA_CTL_WRITE_ENABLE);
1071                ret_val += qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL,
1072                    MIU_TA_CTL_WRITE_START);
1073                if (ret_val == QLA_FUNCTION_FAILED) {
1074                        ql_log(ql_log_fatal, vha, 0xb0a3,
1075                            "%s: write to AGT_CTRL failed!\n", __func__);
1076                        goto exit_ms_mem_write_unlock;
1077                }
1078
1079                for (j = 0; j < MAX_CTL_CHECK; j++) {
1080                        ret_val = qla8044_rd_reg_indirect(vha,
1081                            MD_MIU_TEST_AGT_CTRL, &agt_ctrl);
1082                        if (ret_val == QLA_FUNCTION_FAILED) {
1083                                ql_log(ql_log_fatal, vha, 0xb0a4,
1084                                    "%s: failed to read "
1085                                    "MD_MIU_TEST_AGT_CTRL!\n", __func__);
1086                                goto exit_ms_mem_write_unlock;
1087                        }
1088                        if ((agt_ctrl & MIU_TA_CTL_BUSY) == 0)
1089                                break;
1090                }
1091
1092                /* Status check failed */
1093                if (j >= MAX_CTL_CHECK) {
1094                        ql_log(ql_log_fatal, vha, 0xb0a5,
1095                            "%s: MS memory write failed!\n",
1096                           __func__);
1097                        ret_val = QLA_FUNCTION_FAILED;
1098                        goto exit_ms_mem_write_unlock;
1099                }
1100        }
1101
1102exit_ms_mem_write_unlock:
1103        write_unlock_irqrestore(&ha->hw_lock, flags);
1104
1105exit_ms_mem_write:
1106        return ret_val;
1107}
1108
1109static int
1110qla8044_copy_bootloader(struct scsi_qla_host *vha)
1111{
1112        uint8_t *p_cache;
1113        uint32_t src, count, size;
1114        uint64_t dest;
1115        int ret_val = QLA_SUCCESS;
1116        struct qla_hw_data *ha = vha->hw;
1117
1118        src = QLA8044_BOOTLOADER_FLASH_ADDR;
1119        dest = qla8044_rd_reg(ha, QLA8044_BOOTLOADER_ADDR);
1120        size = qla8044_rd_reg(ha, QLA8044_BOOTLOADER_SIZE);
1121
1122        /* 128 bit alignment check */
1123        if (size & 0xF)
1124                size = (size + 16) & ~0xF;
1125
1126        /* 16 byte count */
1127        count = size/16;
1128
1129        p_cache = vmalloc(size);
1130        if (p_cache == NULL) {
1131                ql_log(ql_log_fatal, vha, 0xb0a6,
1132                    "%s: Failed to allocate memory for "
1133                    "boot loader cache\n", __func__);
1134                ret_val = QLA_FUNCTION_FAILED;
1135                goto exit_copy_bootloader;
1136        }
1137
1138        ret_val = qla8044_lockless_flash_read_u32(vha, src,
1139            p_cache, size/sizeof(uint32_t));
1140        if (ret_val == QLA_FUNCTION_FAILED) {
1141                ql_log(ql_log_fatal, vha, 0xb0a7,
1142                    "%s: Error reading F/W from flash!!!\n", __func__);
1143                goto exit_copy_error;
1144        }
1145        ql_dbg(ql_dbg_p3p, vha, 0xb0a8, "%s: Read F/W from flash!\n",
1146            __func__);
1147
1148        /* 128 bit/16 byte write to MS memory */
1149        ret_val = qla8044_ms_mem_write_128b(vha, dest,
1150            (uint32_t *)p_cache, count);
1151        if (ret_val == QLA_FUNCTION_FAILED) {
1152                ql_log(ql_log_fatal, vha, 0xb0a9,
1153                    "%s: Error writing F/W to MS !!!\n", __func__);
1154                goto exit_copy_error;
1155        }
1156        ql_dbg(ql_dbg_p3p, vha, 0xb0aa,
1157            "%s: Wrote F/W (size %d) to MS !!!\n",
1158            __func__, size);
1159
1160exit_copy_error:
1161        vfree(p_cache);
1162
1163exit_copy_bootloader:
1164        return ret_val;
1165}
1166
1167static int
1168qla8044_restart(struct scsi_qla_host *vha)
1169{
1170        int ret_val = QLA_SUCCESS;
1171        struct qla_hw_data *ha = vha->hw;
1172
1173        qla8044_process_stop_seq(vha);
1174
1175        /* Collect minidump */
1176        if (ql2xmdenable)
1177                qla8044_get_minidump(vha);
1178        else
1179                ql_log(ql_log_fatal, vha, 0xb14c,
1180                    "Minidump disabled.\n");
1181
1182        qla8044_process_init_seq(vha);
1183
1184        if (qla8044_copy_bootloader(vha)) {
1185                ql_log(ql_log_fatal, vha, 0xb0ab,
1186                    "%s: Copy bootloader, firmware restart failed!\n",
1187                    __func__);
1188                ret_val = QLA_FUNCTION_FAILED;
1189                goto exit_restart;
1190        }
1191
1192        /*
1193         *  Loads F/W from flash
1194         */
1195        qla8044_wr_reg(ha, QLA8044_FW_IMAGE_VALID, QLA8044_BOOT_FROM_FLASH);
1196
1197        qla8044_process_start_seq(vha);
1198
1199exit_restart:
1200        return ret_val;
1201}
1202
1203/*
1204 * qla8044_check_cmd_peg_status - Check peg status to see if Peg is
1205 * initialized.
1206 *
1207 * @ha : Pointer to adapter structure
1208 *
1209 * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
1210 */
1211static int
1212qla8044_check_cmd_peg_status(struct scsi_qla_host *vha)
1213{
1214        uint32_t val, ret_val = QLA_FUNCTION_FAILED;
1215        int retries = CRB_CMDPEG_CHECK_RETRY_COUNT;
1216        struct qla_hw_data *ha = vha->hw;
1217
1218        do {
1219                val = qla8044_rd_reg(ha, QLA8044_CMDPEG_STATE);
1220                if (val == PHAN_INITIALIZE_COMPLETE) {
1221                        ql_dbg(ql_dbg_p3p, vha, 0xb0ac,
1222                            "%s: Command Peg initialization "
1223                            "complete! state=0x%x\n", __func__, val);
1224                        ret_val = QLA_SUCCESS;
1225                        break;
1226                }
1227                msleep(CRB_CMDPEG_CHECK_DELAY);
1228        } while (--retries);
1229
1230        return ret_val;
1231}
1232
1233static int
1234qla8044_start_firmware(struct scsi_qla_host *vha)
1235{
1236        int ret_val = QLA_SUCCESS;
1237
1238        if (qla8044_restart(vha)) {
1239                ql_log(ql_log_fatal, vha, 0xb0ad,
1240                    "%s: Restart Error!!!, Need Reset!!!\n",
1241                    __func__);
1242                ret_val = QLA_FUNCTION_FAILED;
1243                goto exit_start_fw;
1244        } else
1245                ql_dbg(ql_dbg_p3p, vha, 0xb0af,
1246                    "%s: Restart done!\n", __func__);
1247
1248        ret_val = qla8044_check_cmd_peg_status(vha);
1249        if (ret_val) {
1250                ql_log(ql_log_fatal, vha, 0xb0b0,
1251                    "%s: Peg not initialized!\n", __func__);
1252                ret_val = QLA_FUNCTION_FAILED;
1253        }
1254
1255exit_start_fw:
1256        return ret_val;
1257}
1258
1259void
1260qla8044_clear_drv_active(struct scsi_qla_host *vha)
1261{
1262        uint32_t drv_active;
1263        struct qla_hw_data *ha = vha->hw;
1264
1265        drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
1266        drv_active &= ~(1 << (ha->portnum));
1267
1268        ql_log(ql_log_info, vha, 0xb0b1,
1269            "%s(%ld): drv_active: 0x%08x\n",
1270            __func__, vha->host_no, drv_active);
1271
1272        qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, drv_active);
1273}
1274
1275/*
1276 * qla8044_device_bootstrap - Initialize device, set DEV_READY, start fw
1277 * @ha: pointer to adapter structure
1278 *
1279 * Note: IDC lock must be held upon entry
1280 **/
1281static int
1282qla8044_device_bootstrap(struct scsi_qla_host *vha)
1283{
1284        int rval = QLA_FUNCTION_FAILED;
1285        int i;
1286        uint32_t old_count = 0, count = 0;
1287        int need_reset = 0;
1288        uint32_t idc_ctrl;
1289        struct qla_hw_data *ha = vha->hw;
1290
1291        need_reset = qla8044_need_reset(vha);
1292
1293        if (!need_reset) {
1294                old_count = qla8044_rd_direct(vha,
1295                    QLA8044_PEG_ALIVE_COUNTER_INDEX);
1296
1297                for (i = 0; i < 10; i++) {
1298                        msleep(200);
1299
1300                        count = qla8044_rd_direct(vha,
1301                            QLA8044_PEG_ALIVE_COUNTER_INDEX);
1302                        if (count != old_count) {
1303                                rval = QLA_SUCCESS;
1304                                goto dev_ready;
1305                        }
1306                }
1307                qla8044_flash_lock_recovery(vha);
1308        } else {
1309                /* We are trying to perform a recovery here. */
1310                if (ha->flags.isp82xx_fw_hung)
1311                        qla8044_flash_lock_recovery(vha);
1312        }
1313
1314        /* set to DEV_INITIALIZING */
1315        ql_log(ql_log_info, vha, 0xb0b2,
1316            "%s: HW State: INITIALIZING\n", __func__);
1317        qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
1318            QLA8XXX_DEV_INITIALIZING);
1319
1320        qla8044_idc_unlock(ha);
1321        rval = qla8044_start_firmware(vha);
1322        qla8044_idc_lock(ha);
1323
1324        if (rval != QLA_SUCCESS) {
1325                ql_log(ql_log_info, vha, 0xb0b3,
1326                     "%s: HW State: FAILED\n", __func__);
1327                qla8044_clear_drv_active(vha);
1328                qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
1329                    QLA8XXX_DEV_FAILED);
1330                return rval;
1331        }
1332
1333        /* For ISP8044, If IDC_CTRL GRACEFUL_RESET_BIT1 is set , reset it after
1334         * device goes to INIT state. */
1335        idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
1336        if (idc_ctrl & GRACEFUL_RESET_BIT1) {
1337                qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL,
1338                    (idc_ctrl & ~GRACEFUL_RESET_BIT1));
1339                ha->fw_dumped = 0;
1340        }
1341
1342dev_ready:
1343        ql_log(ql_log_info, vha, 0xb0b4,
1344            "%s: HW State: READY\n", __func__);
1345        qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX, QLA8XXX_DEV_READY);
1346
1347        return rval;
1348}
1349
1350/*-------------------------Reset Sequence Functions-----------------------*/
1351static void
1352qla8044_dump_reset_seq_hdr(struct scsi_qla_host *vha)
1353{
1354        u8 *phdr;
1355
1356        if (!vha->reset_tmplt.buff) {
1357                ql_log(ql_log_fatal, vha, 0xb0b5,
1358                    "%s: Error Invalid reset_seq_template\n", __func__);
1359                return;
1360        }
1361
1362        phdr = vha->reset_tmplt.buff;
1363        ql_dbg(ql_dbg_p3p, vha, 0xb0b6,
1364            "Reset Template :\n\t0x%X 0x%X 0x%X 0x%X"
1365            "0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n"
1366            "\t0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n\n",
1367            *phdr, *(phdr+1), *(phdr+2), *(phdr+3), *(phdr+4),
1368            *(phdr+5), *(phdr+6), *(phdr+7), *(phdr + 8),
1369            *(phdr+9), *(phdr+10), *(phdr+11), *(phdr+12),
1370            *(phdr+13), *(phdr+14), *(phdr+15));
1371}
1372
1373/*
1374 * qla8044_reset_seq_checksum_test - Validate Reset Sequence template.
1375 *
1376 * @ha : Pointer to adapter structure
1377 *
1378 * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
1379 */
1380static int
1381qla8044_reset_seq_checksum_test(struct scsi_qla_host *vha)
1382{
1383        uint32_t sum =  0;
1384        uint16_t *buff = (uint16_t *)vha->reset_tmplt.buff;
1385        int u16_count =  vha->reset_tmplt.hdr->size / sizeof(uint16_t);
1386
1387        while (u16_count-- > 0)
1388                sum += *buff++;
1389
1390        while (sum >> 16)
1391                sum = (sum & 0xFFFF) +  (sum >> 16);
1392
1393        /* checksum of 0 indicates a valid template */
1394        if (~sum) {
1395                return QLA_SUCCESS;
1396        } else {
1397                ql_log(ql_log_fatal, vha, 0xb0b7,
1398                    "%s: Reset seq checksum failed\n", __func__);
1399                return QLA_FUNCTION_FAILED;
1400        }
1401}
1402
1403/*
1404 * qla8044_read_reset_template - Read Reset Template from Flash, validate
1405 * the template and store offsets of stop/start/init offsets in ha->reset_tmplt.
1406 *
1407 * @ha : Pointer to adapter structure
1408 */
1409void
1410qla8044_read_reset_template(struct scsi_qla_host *vha)
1411{
1412        uint8_t *p_buff;
1413        uint32_t addr, tmplt_hdr_def_size, tmplt_hdr_size;
1414
1415        vha->reset_tmplt.seq_error = 0;
1416        vha->reset_tmplt.buff = vmalloc(QLA8044_RESTART_TEMPLATE_SIZE);
1417        if (vha->reset_tmplt.buff == NULL) {
1418                ql_log(ql_log_fatal, vha, 0xb0b8,
1419                    "%s: Failed to allocate reset template resources\n",
1420                    __func__);
1421                goto exit_read_reset_template;
1422        }
1423
1424        p_buff = vha->reset_tmplt.buff;
1425        addr = QLA8044_RESET_TEMPLATE_ADDR;
1426
1427        tmplt_hdr_def_size =
1428            sizeof(struct qla8044_reset_template_hdr) / sizeof(uint32_t);
1429
1430        ql_dbg(ql_dbg_p3p, vha, 0xb0b9,
1431            "%s: Read template hdr size %d from Flash\n",
1432            __func__, tmplt_hdr_def_size);
1433
1434        /* Copy template header from flash */
1435        if (qla8044_read_flash_data(vha, p_buff, addr, tmplt_hdr_def_size)) {
1436                ql_log(ql_log_fatal, vha, 0xb0ba,
1437                    "%s: Failed to read reset template\n", __func__);
1438                goto exit_read_template_error;
1439        }
1440
1441        vha->reset_tmplt.hdr =
1442         (struct qla8044_reset_template_hdr *) vha->reset_tmplt.buff;
1443
1444        /* Validate the template header size and signature */
1445        tmplt_hdr_size = vha->reset_tmplt.hdr->hdr_size/sizeof(uint32_t);
1446        if ((tmplt_hdr_size != tmplt_hdr_def_size) ||
1447            (vha->reset_tmplt.hdr->signature != RESET_TMPLT_HDR_SIGNATURE)) {
1448                ql_log(ql_log_fatal, vha, 0xb0bb,
1449                    "%s: Template Header size invalid %d "
1450                    "tmplt_hdr_def_size %d!!!\n", __func__,
1451                    tmplt_hdr_size, tmplt_hdr_def_size);
1452                goto exit_read_template_error;
1453        }
1454
1455        addr = QLA8044_RESET_TEMPLATE_ADDR + vha->reset_tmplt.hdr->hdr_size;
1456        p_buff = vha->reset_tmplt.buff + vha->reset_tmplt.hdr->hdr_size;
1457        tmplt_hdr_def_size = (vha->reset_tmplt.hdr->size -
1458            vha->reset_tmplt.hdr->hdr_size)/sizeof(uint32_t);
1459
1460        ql_dbg(ql_dbg_p3p, vha, 0xb0bc,
1461            "%s: Read rest of the template size %d\n",
1462            __func__, vha->reset_tmplt.hdr->size);
1463
1464        /* Copy rest of the template */
1465        if (qla8044_read_flash_data(vha, p_buff, addr, tmplt_hdr_def_size)) {
1466                ql_log(ql_log_fatal, vha, 0xb0bd,
1467                    "%s: Failed to read reset tempelate\n", __func__);
1468                goto exit_read_template_error;
1469        }
1470
1471        /* Integrity check */
1472        if (qla8044_reset_seq_checksum_test(vha)) {
1473                ql_log(ql_log_fatal, vha, 0xb0be,
1474                    "%s: Reset Seq checksum failed!\n", __func__);
1475                goto exit_read_template_error;
1476        }
1477
1478        ql_dbg(ql_dbg_p3p, vha, 0xb0bf,
1479            "%s: Reset Seq checksum passed! Get stop, "
1480            "start and init seq offsets\n", __func__);
1481
1482        /* Get STOP, START, INIT sequence offsets */
1483        vha->reset_tmplt.init_offset = vha->reset_tmplt.buff +
1484            vha->reset_tmplt.hdr->init_seq_offset;
1485
1486        vha->reset_tmplt.start_offset = vha->reset_tmplt.buff +
1487            vha->reset_tmplt.hdr->start_seq_offset;
1488
1489        vha->reset_tmplt.stop_offset = vha->reset_tmplt.buff +
1490            vha->reset_tmplt.hdr->hdr_size;
1491
1492        qla8044_dump_reset_seq_hdr(vha);
1493
1494        goto exit_read_reset_template;
1495
1496exit_read_template_error:
1497        vfree(vha->reset_tmplt.buff);
1498
1499exit_read_reset_template:
1500        return;
1501}
1502
1503void
1504qla8044_set_idc_dontreset(struct scsi_qla_host *vha)
1505{
1506        uint32_t idc_ctrl;
1507        struct qla_hw_data *ha = vha->hw;
1508
1509        idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
1510        idc_ctrl |= DONTRESET_BIT0;
1511        ql_dbg(ql_dbg_p3p, vha, 0xb0c0,
1512            "%s: idc_ctrl = %d\n", __func__, idc_ctrl);
1513        qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL, idc_ctrl);
1514}
1515
1516inline void
1517qla8044_set_rst_ready(struct scsi_qla_host *vha)
1518{
1519        uint32_t drv_state;
1520        struct qla_hw_data *ha = vha->hw;
1521
1522        drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
1523
1524        /* For ISP8044, drv_active register has 1 bit per function,
1525         * shift 1 by func_num to set a bit for the function.*/
1526        drv_state |= (1 << ha->portnum);
1527
1528        ql_log(ql_log_info, vha, 0xb0c1,
1529            "%s(%ld): drv_state: 0x%08x\n",
1530            __func__, vha->host_no, drv_state);
1531        qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, drv_state);
1532}
1533
1534/**
1535 * qla8044_need_reset_handler - Code to start reset sequence
1536 * @ha: pointer to adapter structure
1537 *
1538 * Note: IDC lock must be held upon entry
1539 **/
1540static void
1541qla8044_need_reset_handler(struct scsi_qla_host *vha)
1542{
1543        uint32_t dev_state = 0, drv_state, drv_active;
1544        unsigned long reset_timeout, dev_init_timeout;
1545        struct qla_hw_data *ha = vha->hw;
1546
1547        ql_log(ql_log_fatal, vha, 0xb0c2,
1548            "%s: Performing ISP error recovery\n", __func__);
1549
1550        if (vha->flags.online) {
1551                qla8044_idc_unlock(ha);
1552                qla2x00_abort_isp_cleanup(vha);
1553                ha->isp_ops->get_flash_version(vha, vha->req->ring);
1554                ha->isp_ops->nvram_config(vha);
1555                qla8044_idc_lock(ha);
1556        }
1557
1558        if (!ha->flags.nic_core_reset_owner) {
1559                ql_dbg(ql_dbg_p3p, vha, 0xb0c3,
1560                    "%s(%ld): reset acknowledged\n",
1561                    __func__, vha->host_no);
1562                qla8044_set_rst_ready(vha);
1563
1564                /* Non-reset owners ACK Reset and wait for device INIT state
1565                 * as part of Reset Recovery by Reset Owner
1566                 */
1567                dev_init_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
1568
1569                do {
1570                        if (time_after_eq(jiffies, dev_init_timeout)) {
1571                                ql_log(ql_log_info, vha, 0xb0c4,
1572                                    "%s: Non Reset owner DEV INIT "
1573                                    "TIMEOUT!\n", __func__);
1574                                break;
1575                        }
1576
1577                        qla8044_idc_unlock(ha);
1578                        msleep(1000);
1579                        qla8044_idc_lock(ha);
1580
1581                        dev_state = qla8044_rd_direct(vha,
1582                                        QLA8044_CRB_DEV_STATE_INDEX);
1583                } while (dev_state == QLA8XXX_DEV_NEED_RESET);
1584        } else {
1585                qla8044_set_rst_ready(vha);
1586
1587                /* wait for 10 seconds for reset ack from all functions */
1588                reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
1589
1590                drv_state = qla8044_rd_direct(vha,
1591                    QLA8044_CRB_DRV_STATE_INDEX);
1592                drv_active = qla8044_rd_direct(vha,
1593                    QLA8044_CRB_DRV_ACTIVE_INDEX);
1594
1595                ql_log(ql_log_info, vha, 0xb0c5,
1596                    "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
1597                    __func__, vha->host_no, drv_state, drv_active);
1598
1599                while (drv_state != drv_active) {
1600                        if (time_after_eq(jiffies, reset_timeout)) {
1601                                ql_log(ql_log_info, vha, 0xb0c6,
1602                                    "%s: RESET TIMEOUT!"
1603                                    "drv_state: 0x%08x, drv_active: 0x%08x\n",
1604                                    QLA2XXX_DRIVER_NAME, drv_state, drv_active);
1605                                break;
1606                        }
1607
1608                        qla8044_idc_unlock(ha);
1609                        msleep(1000);
1610                        qla8044_idc_lock(ha);
1611
1612                        drv_state = qla8044_rd_direct(vha,
1613                            QLA8044_CRB_DRV_STATE_INDEX);
1614                        drv_active = qla8044_rd_direct(vha,
1615                            QLA8044_CRB_DRV_ACTIVE_INDEX);
1616                }
1617
1618                if (drv_state != drv_active) {
1619                        ql_log(ql_log_info, vha, 0xb0c7,
1620                            "%s(%ld): Reset_owner turning off drv_active "
1621                            "of non-acking function 0x%x\n", __func__,
1622                            vha->host_no, (drv_active ^ drv_state));
1623                        drv_active = drv_active & drv_state;
1624                        qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX,
1625                            drv_active);
1626                }
1627
1628                /*
1629                * Clear RESET OWNER, will be set at next reset
1630                * by next RST_OWNER
1631                */
1632                ha->flags.nic_core_reset_owner = 0;
1633
1634                /* Start Reset Recovery */
1635                qla8044_device_bootstrap(vha);
1636        }
1637}
1638
1639static void
1640qla8044_set_drv_active(struct scsi_qla_host *vha)
1641{
1642        uint32_t drv_active;
1643        struct qla_hw_data *ha = vha->hw;
1644
1645        drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
1646
1647        /* For ISP8044, drv_active register has 1 bit per function,
1648         * shift 1 by func_num to set a bit for the function.*/
1649        drv_active |= (1 << ha->portnum);
1650
1651        ql_log(ql_log_info, vha, 0xb0c8,
1652            "%s(%ld): drv_active: 0x%08x\n",
1653            __func__, vha->host_no, drv_active);
1654        qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, drv_active);
1655}
1656
1657static void
1658qla8044_clear_idc_dontreset(struct scsi_qla_host *vha)
1659{
1660        uint32_t idc_ctrl;
1661        struct qla_hw_data *ha = vha->hw;
1662
1663        idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
1664        idc_ctrl &= ~DONTRESET_BIT0;
1665        ql_log(ql_log_info, vha, 0xb0c9,
1666            "%s: idc_ctrl = %d\n", __func__,
1667            idc_ctrl);
1668        qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL, idc_ctrl);
1669}
1670
1671static int
1672qla8044_set_idc_ver(struct scsi_qla_host *vha)
1673{
1674        int idc_ver;
1675        uint32_t drv_active;
1676        int rval = QLA_SUCCESS;
1677        struct qla_hw_data *ha = vha->hw;
1678
1679        drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
1680        if (drv_active == (1 << ha->portnum)) {
1681                idc_ver = qla8044_rd_direct(vha,
1682                    QLA8044_CRB_DRV_IDC_VERSION_INDEX);
1683                idc_ver &= (~0xFF);
1684                idc_ver |= QLA8044_IDC_VER_MAJ_VALUE;
1685                qla8044_wr_direct(vha, QLA8044_CRB_DRV_IDC_VERSION_INDEX,
1686                    idc_ver);
1687                ql_log(ql_log_info, vha, 0xb0ca,
1688                    "%s: IDC version updated to %d\n",
1689                    __func__, idc_ver);
1690        } else {
1691                idc_ver = qla8044_rd_direct(vha,
1692                    QLA8044_CRB_DRV_IDC_VERSION_INDEX);
1693                idc_ver &= 0xFF;
1694                if (QLA8044_IDC_VER_MAJ_VALUE != idc_ver) {
1695                        ql_log(ql_log_info, vha, 0xb0cb,
1696                            "%s: qla4xxx driver IDC version %d "
1697                            "is not compatible with IDC version %d "
1698                            "of other drivers!\n",
1699                            __func__, QLA8044_IDC_VER_MAJ_VALUE,
1700                            idc_ver);
1701                        rval = QLA_FUNCTION_FAILED;
1702                        goto exit_set_idc_ver;
1703                }
1704        }
1705
1706        /* Update IDC_MINOR_VERSION */
1707        idc_ver = qla8044_rd_reg(ha, QLA8044_CRB_IDC_VER_MINOR);
1708        idc_ver &= ~(0x03 << (ha->portnum * 2));
1709        idc_ver |= (QLA8044_IDC_VER_MIN_VALUE << (ha->portnum * 2));
1710        qla8044_wr_reg(ha, QLA8044_CRB_IDC_VER_MINOR, idc_ver);
1711
1712exit_set_idc_ver:
1713        return rval;
1714}
1715
1716static int
1717qla8044_update_idc_reg(struct scsi_qla_host *vha)
1718{
1719        uint32_t drv_active;
1720        int rval = QLA_SUCCESS;
1721        struct qla_hw_data *ha = vha->hw;
1722
1723        if (vha->flags.init_done)
1724                goto exit_update_idc_reg;
1725
1726        qla8044_idc_lock(ha);
1727        qla8044_set_drv_active(vha);
1728
1729        drv_active = qla8044_rd_direct(vha,
1730            QLA8044_CRB_DRV_ACTIVE_INDEX);
1731
1732        /* If we are the first driver to load and
1733         * ql2xdontresethba is not set, clear IDC_CTRL BIT0. */
1734        if ((drv_active == (1 << ha->portnum)) && !ql2xdontresethba)
1735                qla8044_clear_idc_dontreset(vha);
1736
1737        rval = qla8044_set_idc_ver(vha);
1738        if (rval == QLA_FUNCTION_FAILED)
1739                qla8044_clear_drv_active(vha);
1740        qla8044_idc_unlock(ha);
1741
1742exit_update_idc_reg:
1743        return rval;
1744}
1745
1746/**
1747 * qla8044_need_qsnt_handler - Code to start qsnt
1748 * @ha: pointer to adapter structure
1749 **/
1750static void
1751qla8044_need_qsnt_handler(struct scsi_qla_host *vha)
1752{
1753        unsigned long qsnt_timeout;
1754        uint32_t drv_state, drv_active, dev_state;
1755        struct qla_hw_data *ha = vha->hw;
1756
1757        if (vha->flags.online)
1758                qla2x00_quiesce_io(vha);
1759        else
1760                return;
1761
1762        qla8044_set_qsnt_ready(vha);
1763
1764        /* Wait for 30 secs for all functions to ack qsnt mode */
1765        qsnt_timeout = jiffies + (QSNT_ACK_TOV * HZ);
1766        drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
1767        drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX);
1768
1769        /* Shift drv_active by 1 to match drv_state. As quiescent ready bit
1770           position is at bit 1 and drv active is at bit 0 */
1771        drv_active = drv_active << 1;
1772
1773        while (drv_state != drv_active) {
1774                if (time_after_eq(jiffies, qsnt_timeout)) {
1775                        /* Other functions did not ack, changing state to
1776                         * DEV_READY
1777                         */
1778                        clear_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
1779                        qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
1780                                            QLA8XXX_DEV_READY);
1781                        qla8044_clear_qsnt_ready(vha);
1782                        ql_log(ql_log_info, vha, 0xb0cc,
1783                            "Timeout waiting for quiescent ack!!!\n");
1784                        return;
1785                }
1786                qla8044_idc_unlock(ha);
1787                msleep(1000);
1788                qla8044_idc_lock(ha);
1789
1790                drv_state = qla8044_rd_direct(vha,
1791                    QLA8044_CRB_DRV_STATE_INDEX);
1792                drv_active = qla8044_rd_direct(vha,
1793                    QLA8044_CRB_DRV_ACTIVE_INDEX);
1794                drv_active = drv_active << 1;
1795        }
1796
1797        /* All functions have Acked. Set quiescent state */
1798        dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
1799
1800        if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT) {
1801                qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
1802                    QLA8XXX_DEV_QUIESCENT);
1803                ql_log(ql_log_info, vha, 0xb0cd,
1804                    "%s: HW State: QUIESCENT\n", __func__);
1805        }
1806}
1807
1808/*
1809 * qla8044_device_state_handler - Adapter state machine
1810 * @ha: pointer to host adapter structure.
1811 *
1812 * Note: IDC lock must be UNLOCKED upon entry
1813 **/
1814int
1815qla8044_device_state_handler(struct scsi_qla_host *vha)
1816{
1817        uint32_t dev_state;
1818        int rval = QLA_SUCCESS;
1819        unsigned long dev_init_timeout;
1820        struct qla_hw_data *ha = vha->hw;
1821
1822        rval = qla8044_update_idc_reg(vha);
1823        if (rval == QLA_FUNCTION_FAILED)
1824                goto exit_error;
1825
1826        dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
1827        ql_dbg(ql_dbg_p3p, vha, 0xb0ce,
1828            "Device state is 0x%x = %s\n",
1829            dev_state, dev_state < MAX_STATES ?
1830            qdev_state(dev_state) : "Unknown");
1831
1832        /* wait for 30 seconds for device to go ready */
1833        dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout * HZ);
1834
1835        qla8044_idc_lock(ha);
1836
1837        while (1) {
1838                if (time_after_eq(jiffies, dev_init_timeout)) {
1839                        ql_log(ql_log_warn, vha, 0xb0cf,
1840                            "%s: Device Init Failed 0x%x = %s\n",
1841                            QLA2XXX_DRIVER_NAME, dev_state,
1842                            dev_state < MAX_STATES ?
1843                            qdev_state(dev_state) : "Unknown");
1844
1845                        qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
1846                            QLA8XXX_DEV_FAILED);
1847                }
1848
1849                dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
1850                ql_log(ql_log_info, vha, 0xb0d0,
1851                    "Device state is 0x%x = %s\n",
1852                    dev_state, dev_state < MAX_STATES ?
1853                    qdev_state(dev_state) : "Unknown");
1854
1855                /* NOTE: Make sure idc unlocked upon exit of switch statement */
1856                switch (dev_state) {
1857                case QLA8XXX_DEV_READY:
1858                        ha->flags.nic_core_reset_owner = 0;
1859                        goto exit;
1860                case QLA8XXX_DEV_COLD:
1861                        rval = qla8044_device_bootstrap(vha);
1862                        goto exit;
1863                case QLA8XXX_DEV_INITIALIZING:
1864                        qla8044_idc_unlock(ha);
1865                        msleep(1000);
1866                        qla8044_idc_lock(ha);
1867                        break;
1868                case QLA8XXX_DEV_NEED_RESET:
1869                        /* For ISP8044, if NEED_RESET is set by any driver,
1870                         * it should be honored, irrespective of IDC_CTRL
1871                         * DONTRESET_BIT0 */
1872                        qla8044_need_reset_handler(vha);
1873                        break;
1874                case QLA8XXX_DEV_NEED_QUIESCENT:
1875                        /* idc locked/unlocked in handler */
1876                        qla8044_need_qsnt_handler(vha);
1877
1878                        /* Reset the init timeout after qsnt handler */
1879                        dev_init_timeout = jiffies +
1880                            (ha->fcoe_reset_timeout * HZ);
1881                        break;
1882                case QLA8XXX_DEV_QUIESCENT:
1883                        ql_log(ql_log_info, vha, 0xb0d1,
1884                            "HW State: QUIESCENT\n");
1885
1886                        qla8044_idc_unlock(ha);
1887                        msleep(1000);
1888                        qla8044_idc_lock(ha);
1889
1890                        /* Reset the init timeout after qsnt handler */
1891                        dev_init_timeout = jiffies +
1892                            (ha->fcoe_reset_timeout * HZ);
1893                        break;
1894                case QLA8XXX_DEV_FAILED:
1895                        ha->flags.nic_core_reset_owner = 0;
1896                        qla8044_idc_unlock(ha);
1897                        qla8xxx_dev_failed_handler(vha);
1898                        rval = QLA_FUNCTION_FAILED;
1899                        qla8044_idc_lock(ha);
1900                        goto exit;
1901                default:
1902                        qla8044_idc_unlock(ha);
1903                        qla8xxx_dev_failed_handler(vha);
1904                        rval = QLA_FUNCTION_FAILED;
1905                        qla8044_idc_lock(ha);
1906                        goto exit;
1907                }
1908        }
1909exit:
1910        qla8044_idc_unlock(ha);
1911
1912exit_error:
1913        return rval;
1914}
1915
1916/**
1917 * qla4_8xxx_check_temp - Check the ISP82XX temperature.
1918 * @ha: adapter block pointer.
1919 *
1920 * Note: The caller should not hold the idc lock.
1921 **/
1922static int
1923qla8044_check_temp(struct scsi_qla_host *vha)
1924{
1925        uint32_t temp, temp_state, temp_val;
1926        int status = QLA_SUCCESS;
1927
1928        temp = qla8044_rd_direct(vha, QLA8044_CRB_TEMP_STATE_INDEX);
1929        temp_state = qla82xx_get_temp_state(temp);
1930        temp_val = qla82xx_get_temp_val(temp);
1931
1932        if (temp_state == QLA82XX_TEMP_PANIC) {
1933                ql_log(ql_log_warn, vha, 0xb0d2,
1934                    "Device temperature %d degrees C"
1935                    " exceeds maximum allowed. Hardware has been shut"
1936                    " down\n", temp_val);
1937                status = QLA_FUNCTION_FAILED;
1938                return status;
1939        } else if (temp_state == QLA82XX_TEMP_WARN) {
1940                ql_log(ql_log_warn, vha, 0xb0d3,
1941                    "Device temperature %d"
1942                    " degrees C exceeds operating range."
1943                    " Immediate action needed.\n", temp_val);
1944        }
1945        return 0;
1946}
1947
1948int qla8044_read_temperature(scsi_qla_host_t *vha)
1949{
1950        uint32_t temp;
1951
1952        temp = qla8044_rd_direct(vha, QLA8044_CRB_TEMP_STATE_INDEX);
1953        return qla82xx_get_temp_val(temp);
1954}
1955
1956/**
1957 * qla8044_check_fw_alive  - Check firmware health
1958 * @ha: Pointer to host adapter structure.
1959 *
1960 * Context: Interrupt
1961 **/
1962int
1963qla8044_check_fw_alive(struct scsi_qla_host *vha)
1964{
1965        uint32_t fw_heartbeat_counter;
1966        uint32_t halt_status1, halt_status2;
1967        int status = QLA_SUCCESS;
1968
1969        fw_heartbeat_counter = qla8044_rd_direct(vha,
1970            QLA8044_PEG_ALIVE_COUNTER_INDEX);
1971
1972        /* If PEG_ALIVE_COUNTER is 0xffffffff, AER/EEH is in progress, ignore */
1973        if (fw_heartbeat_counter == 0xffffffff) {
1974                ql_dbg(ql_dbg_p3p, vha, 0xb0d4,
1975                    "scsi%ld: %s: Device in frozen "
1976                    "state, QLA82XX_PEG_ALIVE_COUNTER is 0xffffffff\n",
1977                    vha->host_no, __func__);
1978                return status;
1979        }
1980
1981        if (vha->fw_heartbeat_counter == fw_heartbeat_counter) {
1982                vha->seconds_since_last_heartbeat++;
1983                /* FW not alive after 2 seconds */
1984                if (vha->seconds_since_last_heartbeat == 2) {
1985                        vha->seconds_since_last_heartbeat = 0;
1986                        halt_status1 = qla8044_rd_direct(vha,
1987                            QLA8044_PEG_HALT_STATUS1_INDEX);
1988                        halt_status2 = qla8044_rd_direct(vha,
1989                            QLA8044_PEG_HALT_STATUS2_INDEX);
1990
1991                        ql_log(ql_log_info, vha, 0xb0d5,
1992                            "scsi(%ld): %s, ISP8044 "
1993                            "Dumping hw/fw registers:\n"
1994                            " PEG_HALT_STATUS1: 0x%x, "
1995                            "PEG_HALT_STATUS2: 0x%x,\n",
1996                            vha->host_no, __func__, halt_status1,
1997                            halt_status2);
1998                        status = QLA_FUNCTION_FAILED;
1999                }
2000        } else
2001                vha->seconds_since_last_heartbeat = 0;
2002
2003        vha->fw_heartbeat_counter = fw_heartbeat_counter;
2004        return status;
2005}
2006
2007void
2008qla8044_watchdog(struct scsi_qla_host *vha)
2009{
2010        uint32_t dev_state, halt_status;
2011        int halt_status_unrecoverable = 0;
2012        struct qla_hw_data *ha = vha->hw;
2013
2014        /* don't poll if reset is going on or FW hang in quiescent state */
2015        if (!(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
2016            test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
2017            test_bit(ISP_ABORT_RETRY, &vha->dpc_flags) ||
2018            test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags))) {
2019                dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
2020
2021                if (qla8044_check_temp(vha)) {
2022                        set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags);
2023                        ha->flags.isp82xx_fw_hung = 1;
2024                        qla2xxx_wake_dpc(vha);
2025                } else if (dev_state == QLA8XXX_DEV_NEED_RESET &&
2026                           !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) {
2027                        ql_log(ql_log_info, vha, 0xb0d6,
2028                            "%s: HW State: NEED RESET!\n",
2029                            __func__);
2030                        set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
2031                        qla2xxx_wake_dpc(vha);
2032                } else if (dev_state == QLA8XXX_DEV_NEED_QUIESCENT &&
2033                    !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) {
2034                        ql_log(ql_log_info, vha, 0xb0d7,
2035                            "%s: HW State: NEED QUIES detected!\n",
2036                            __func__);
2037                        set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
2038                        qla2xxx_wake_dpc(vha);
2039                } else  {
2040                        /* Check firmware health */
2041                        if (qla8044_check_fw_alive(vha)) {
2042                                halt_status = qla8044_rd_direct(vha,
2043                                        QLA8044_PEG_HALT_STATUS1_INDEX);
2044                                if (halt_status &
2045                                    QLA8044_HALT_STATUS_FW_RESET) {
2046                                        ql_log(ql_log_fatal, vha,
2047                                            0xb0d8, "%s: Firmware "
2048                                            "error detected device "
2049                                            "is being reset\n",
2050                                            __func__);
2051                                } else if (halt_status &
2052                                            QLA8044_HALT_STATUS_UNRECOVERABLE) {
2053                                                halt_status_unrecoverable = 1;
2054                                }
2055
2056                                /* Since we cannot change dev_state in interrupt
2057                                 * context, set appropriate DPC flag then wakeup
2058                                 *  DPC */
2059                                if (halt_status_unrecoverable) {
2060                                        set_bit(ISP_UNRECOVERABLE,
2061                                            &vha->dpc_flags);
2062                                } else {
2063                                        if (dev_state ==
2064                                            QLA8XXX_DEV_QUIESCENT) {
2065                                                set_bit(FCOE_CTX_RESET_NEEDED,
2066                                                    &vha->dpc_flags);
2067                                                ql_log(ql_log_info, vha, 0xb0d9,
2068                                                    "%s: FW CONTEXT Reset "
2069                                                    "needed!\n", __func__);
2070                                        } else {
2071                                                ql_log(ql_log_info, vha,
2072                                                    0xb0da, "%s: "
2073                                                    "detect abort needed\n",
2074                                                    __func__);
2075                                                set_bit(ISP_ABORT_NEEDED,
2076                                                    &vha->dpc_flags);
2077                                                qla82xx_clear_pending_mbx(vha);
2078                                        }
2079                                }
2080                                ha->flags.isp82xx_fw_hung = 1;
2081                                ql_log(ql_log_warn, vha, 0xb10a,
2082                                    "Firmware hung.\n");
2083                                qla2xxx_wake_dpc(vha);
2084                        }
2085                }
2086
2087        }
2088}
2089
2090static int
2091qla8044_minidump_process_control(struct scsi_qla_host *vha,
2092                                 struct qla8044_minidump_entry_hdr *entry_hdr)
2093{
2094        struct qla8044_minidump_entry_crb *crb_entry;
2095        uint32_t read_value, opcode, poll_time, addr, index;
2096        uint32_t crb_addr, rval = QLA_SUCCESS;
2097        unsigned long wtime;
2098        struct qla8044_minidump_template_hdr *tmplt_hdr;
2099        int i;
2100        struct qla_hw_data *ha = vha->hw;
2101
2102        ql_dbg(ql_dbg_p3p, vha, 0xb0dd, "Entering fn: %s\n", __func__);
2103        tmplt_hdr = (struct qla8044_minidump_template_hdr *)
2104                ha->md_tmplt_hdr;
2105        crb_entry = (struct qla8044_minidump_entry_crb *)entry_hdr;
2106
2107        crb_addr = crb_entry->addr;
2108        for (i = 0; i < crb_entry->op_count; i++) {
2109                opcode = crb_entry->crb_ctrl.opcode;
2110
2111                if (opcode & QLA82XX_DBG_OPCODE_WR) {
2112                        qla8044_wr_reg_indirect(vha, crb_addr,
2113                            crb_entry->value_1);
2114                        opcode &= ~QLA82XX_DBG_OPCODE_WR;
2115                }
2116
2117                if (opcode & QLA82XX_DBG_OPCODE_RW) {
2118                        qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
2119                        qla8044_wr_reg_indirect(vha, crb_addr, read_value);
2120                        opcode &= ~QLA82XX_DBG_OPCODE_RW;
2121                }
2122
2123                if (opcode & QLA82XX_DBG_OPCODE_AND) {
2124                        qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
2125                        read_value &= crb_entry->value_2;
2126                        opcode &= ~QLA82XX_DBG_OPCODE_AND;
2127                        if (opcode & QLA82XX_DBG_OPCODE_OR) {
2128                                read_value |= crb_entry->value_3;
2129                                opcode &= ~QLA82XX_DBG_OPCODE_OR;
2130                        }
2131                        qla8044_wr_reg_indirect(vha, crb_addr, read_value);
2132                }
2133                if (opcode & QLA82XX_DBG_OPCODE_OR) {
2134                        qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
2135                        read_value |= crb_entry->value_3;
2136                        qla8044_wr_reg_indirect(vha, crb_addr, read_value);
2137                        opcode &= ~QLA82XX_DBG_OPCODE_OR;
2138                }
2139                if (opcode & QLA82XX_DBG_OPCODE_POLL) {
2140                        poll_time = crb_entry->crb_strd.poll_timeout;
2141                        wtime = jiffies + poll_time;
2142                        qla8044_rd_reg_indirect(vha, crb_addr, &read_value);
2143
2144                        do {
2145                                if ((read_value & crb_entry->value_2) ==
2146                                    crb_entry->value_1) {
2147                                        break;
2148                                } else if (time_after_eq(jiffies, wtime)) {
2149                                        /* capturing dump failed */
2150                                        rval = QLA_FUNCTION_FAILED;
2151                                        break;
2152                                } else {
2153                                        qla8044_rd_reg_indirect(vha,
2154                                            crb_addr, &read_value);
2155                                }
2156                        } while (1);
2157                        opcode &= ~QLA82XX_DBG_OPCODE_POLL;
2158                }
2159
2160                if (opcode & QLA82XX_DBG_OPCODE_RDSTATE) {
2161                        if (crb_entry->crb_strd.state_index_a) {
2162                                index = crb_entry->crb_strd.state_index_a;
2163                                addr = tmplt_hdr->saved_state_array[index];
2164                        } else {
2165                                addr = crb_addr;
2166                        }
2167
2168                        qla8044_rd_reg_indirect(vha, addr, &read_value);
2169                        index = crb_entry->crb_ctrl.state_index_v;
2170                        tmplt_hdr->saved_state_array[index] = read_value;
2171                        opcode &= ~QLA82XX_DBG_OPCODE_RDSTATE;
2172                }
2173
2174                if (opcode & QLA82XX_DBG_OPCODE_WRSTATE) {
2175                        if (crb_entry->crb_strd.state_index_a) {
2176                                index = crb_entry->crb_strd.state_index_a;
2177                                addr = tmplt_hdr->saved_state_array[index];
2178                        } else {
2179                                addr = crb_addr;
2180                        }
2181
2182                        if (crb_entry->crb_ctrl.state_index_v) {
2183                                index = crb_entry->crb_ctrl.state_index_v;
2184                                read_value =
2185                                    tmplt_hdr->saved_state_array[index];
2186                        } else {
2187                                read_value = crb_entry->value_1;
2188                        }
2189
2190                        qla8044_wr_reg_indirect(vha, addr, read_value);
2191                        opcode &= ~QLA82XX_DBG_OPCODE_WRSTATE;
2192                }
2193
2194                if (opcode & QLA82XX_DBG_OPCODE_MDSTATE) {
2195                        index = crb_entry->crb_ctrl.state_index_v;
2196                        read_value = tmplt_hdr->saved_state_array[index];
2197                        read_value <<= crb_entry->crb_ctrl.shl;
2198                        read_value >>= crb_entry->crb_ctrl.shr;
2199                        if (crb_entry->value_2)
2200                                read_value &= crb_entry->value_2;
2201                        read_value |= crb_entry->value_3;
2202                        read_value += crb_entry->value_1;
2203                        tmplt_hdr->saved_state_array[index] = read_value;
2204                        opcode &= ~QLA82XX_DBG_OPCODE_MDSTATE;
2205                }
2206                crb_addr += crb_entry->crb_strd.addr_stride;
2207        }
2208        return rval;
2209}
2210
2211static void
2212qla8044_minidump_process_rdcrb(struct scsi_qla_host *vha,
2213        struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2214{
2215        uint32_t r_addr, r_stride, loop_cnt, i, r_value;
2216        struct qla8044_minidump_entry_crb *crb_hdr;
2217        uint32_t *data_ptr = *d_ptr;
2218
2219        ql_dbg(ql_dbg_p3p, vha, 0xb0de, "Entering fn: %s\n", __func__);
2220        crb_hdr = (struct qla8044_minidump_entry_crb *)entry_hdr;
2221        r_addr = crb_hdr->addr;
2222        r_stride = crb_hdr->crb_strd.addr_stride;
2223        loop_cnt = crb_hdr->op_count;
2224
2225        for (i = 0; i < loop_cnt; i++) {
2226                qla8044_rd_reg_indirect(vha, r_addr, &r_value);
2227                *data_ptr++ = r_addr;
2228                *data_ptr++ = r_value;
2229                r_addr += r_stride;
2230        }
2231        *d_ptr = data_ptr;
2232}
2233
2234static int
2235qla8044_minidump_process_rdmem(struct scsi_qla_host *vha,
2236        struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2237{
2238        uint32_t r_addr, r_value, r_data;
2239        uint32_t i, j, loop_cnt;
2240        struct qla8044_minidump_entry_rdmem *m_hdr;
2241        unsigned long flags;
2242        uint32_t *data_ptr = *d_ptr;
2243        struct qla_hw_data *ha = vha->hw;
2244
2245        ql_dbg(ql_dbg_p3p, vha, 0xb0df, "Entering fn: %s\n", __func__);
2246        m_hdr = (struct qla8044_minidump_entry_rdmem *)entry_hdr;
2247        r_addr = m_hdr->read_addr;
2248        loop_cnt = m_hdr->read_data_size/16;
2249
2250        ql_dbg(ql_dbg_p3p, vha, 0xb0f0,
2251            "[%s]: Read addr: 0x%x, read_data_size: 0x%x\n",
2252            __func__, r_addr, m_hdr->read_data_size);
2253
2254        if (r_addr & 0xf) {
2255                ql_dbg(ql_dbg_p3p, vha, 0xb0f1,
2256                    "[%s]: Read addr 0x%x not 16 bytes alligned\n",
2257                    __func__, r_addr);
2258                return QLA_FUNCTION_FAILED;
2259        }
2260
2261        if (m_hdr->read_data_size % 16) {
2262                ql_dbg(ql_dbg_p3p, vha, 0xb0f2,
2263                    "[%s]: Read data[0x%x] not multiple of 16 bytes\n",
2264                    __func__, m_hdr->read_data_size);
2265                return QLA_FUNCTION_FAILED;
2266        }
2267
2268        ql_dbg(ql_dbg_p3p, vha, 0xb0f3,
2269            "[%s]: rdmem_addr: 0x%x, read_data_size: 0x%x, loop_cnt: 0x%x\n",
2270            __func__, r_addr, m_hdr->read_data_size, loop_cnt);
2271
2272        write_lock_irqsave(&ha->hw_lock, flags);
2273        for (i = 0; i < loop_cnt; i++) {
2274                qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_ADDR_LO, r_addr);
2275                r_value = 0;
2276                qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_ADDR_HI, r_value);
2277                r_value = MIU_TA_CTL_ENABLE;
2278                qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL, r_value);
2279                r_value = MIU_TA_CTL_START_ENABLE;
2280                qla8044_wr_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL, r_value);
2281
2282                for (j = 0; j < MAX_CTL_CHECK; j++) {
2283                        qla8044_rd_reg_indirect(vha, MD_MIU_TEST_AGT_CTRL,
2284                            &r_value);
2285                        if ((r_value & MIU_TA_CTL_BUSY) == 0)
2286                                break;
2287                }
2288
2289                if (j >= MAX_CTL_CHECK) {
2290                        printk_ratelimited(KERN_ERR
2291                            "%s: failed to read through agent\n", __func__);
2292                        write_unlock_irqrestore(&ha->hw_lock, flags);
2293                        return QLA_SUCCESS;
2294                }
2295
2296                for (j = 0; j < 4; j++) {
2297                        qla8044_rd_reg_indirect(vha, MD_MIU_TEST_AGT_RDDATA[j],
2298                            &r_data);
2299                        *data_ptr++ = r_data;
2300                }
2301
2302                r_addr += 16;
2303        }
2304        write_unlock_irqrestore(&ha->hw_lock, flags);
2305
2306        ql_dbg(ql_dbg_p3p, vha, 0xb0f4,
2307            "Leaving fn: %s datacount: 0x%x\n",
2308             __func__, (loop_cnt * 16));
2309
2310        *d_ptr = data_ptr;
2311        return QLA_SUCCESS;
2312}
2313
2314/* ISP83xx flash read for _RDROM _BOARD */
2315static uint32_t
2316qla8044_minidump_process_rdrom(struct scsi_qla_host *vha,
2317        struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2318{
2319        uint32_t fl_addr, u32_count, rval;
2320        struct qla8044_minidump_entry_rdrom *rom_hdr;
2321        uint32_t *data_ptr = *d_ptr;
2322
2323        rom_hdr = (struct qla8044_minidump_entry_rdrom *)entry_hdr;
2324        fl_addr = rom_hdr->read_addr;
2325        u32_count = (rom_hdr->read_data_size)/sizeof(uint32_t);
2326
2327        ql_dbg(ql_dbg_p3p, vha, 0xb0f5, "[%s]: fl_addr: 0x%x, count: 0x%x\n",
2328            __func__, fl_addr, u32_count);
2329
2330        rval = qla8044_lockless_flash_read_u32(vha, fl_addr,
2331            (u8 *)(data_ptr), u32_count);
2332
2333        if (rval != QLA_SUCCESS) {
2334                ql_log(ql_log_fatal, vha, 0xb0f6,
2335                    "%s: Flash Read Error,Count=%d\n", __func__, u32_count);
2336                return QLA_FUNCTION_FAILED;
2337        } else {
2338                data_ptr += u32_count;
2339                *d_ptr = data_ptr;
2340                return QLA_SUCCESS;
2341        }
2342}
2343
2344static void
2345qla8044_mark_entry_skipped(struct scsi_qla_host *vha,
2346        struct qla8044_minidump_entry_hdr *entry_hdr, int index)
2347{
2348        entry_hdr->d_ctrl.driver_flags |= QLA82XX_DBG_SKIPPED_FLAG;
2349
2350        ql_log(ql_log_info, vha, 0xb0f7,
2351            "scsi(%ld): Skipping entry[%d]: ETYPE[0x%x]-ELEVEL[0x%x]\n",
2352            vha->host_no, index, entry_hdr->entry_type,
2353            entry_hdr->d_ctrl.entry_capture_mask);
2354}
2355
2356static int
2357qla8044_minidump_process_l2tag(struct scsi_qla_host *vha,
2358        struct qla8044_minidump_entry_hdr *entry_hdr,
2359                                 uint32_t **d_ptr)
2360{
2361        uint32_t addr, r_addr, c_addr, t_r_addr;
2362        uint32_t i, k, loop_count, t_value, r_cnt, r_value;
2363        unsigned long p_wait, w_time, p_mask;
2364        uint32_t c_value_w, c_value_r;
2365        struct qla8044_minidump_entry_cache *cache_hdr;
2366        int rval = QLA_FUNCTION_FAILED;
2367        uint32_t *data_ptr = *d_ptr;
2368
2369        ql_dbg(ql_dbg_p3p, vha, 0xb0f8, "Entering fn: %s\n", __func__);
2370        cache_hdr = (struct qla8044_minidump_entry_cache *)entry_hdr;
2371
2372        loop_count = cache_hdr->op_count;
2373        r_addr = cache_hdr->read_addr;
2374        c_addr = cache_hdr->control_addr;
2375        c_value_w = cache_hdr->cache_ctrl.write_value;
2376
2377        t_r_addr = cache_hdr->tag_reg_addr;
2378        t_value = cache_hdr->addr_ctrl.init_tag_value;
2379        r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
2380        p_wait = cache_hdr->cache_ctrl.poll_wait;
2381        p_mask = cache_hdr->cache_ctrl.poll_mask;
2382
2383        for (i = 0; i < loop_count; i++) {
2384                qla8044_wr_reg_indirect(vha, t_r_addr, t_value);
2385                if (c_value_w)
2386                        qla8044_wr_reg_indirect(vha, c_addr, c_value_w);
2387
2388                if (p_mask) {
2389                        w_time = jiffies + p_wait;
2390                        do {
2391                                qla8044_rd_reg_indirect(vha, c_addr,
2392                                    &c_value_r);
2393                                if ((c_value_r & p_mask) == 0) {
2394                                        break;
2395                                } else if (time_after_eq(jiffies, w_time)) {
2396                                        /* capturing dump failed */
2397                                        return rval;
2398                                }
2399                        } while (1);
2400                }
2401
2402                addr = r_addr;
2403                for (k = 0; k < r_cnt; k++) {
2404                        qla8044_rd_reg_indirect(vha, addr, &r_value);
2405                        *data_ptr++ = r_value;
2406                        addr += cache_hdr->read_ctrl.read_addr_stride;
2407                }
2408                t_value += cache_hdr->addr_ctrl.tag_value_stride;
2409        }
2410        *d_ptr = data_ptr;
2411        return QLA_SUCCESS;
2412}
2413
2414static void
2415qla8044_minidump_process_l1cache(struct scsi_qla_host *vha,
2416        struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2417{
2418        uint32_t addr, r_addr, c_addr, t_r_addr;
2419        uint32_t i, k, loop_count, t_value, r_cnt, r_value;
2420        uint32_t c_value_w;
2421        struct qla8044_minidump_entry_cache *cache_hdr;
2422        uint32_t *data_ptr = *d_ptr;
2423
2424        cache_hdr = (struct qla8044_minidump_entry_cache *)entry_hdr;
2425        loop_count = cache_hdr->op_count;
2426        r_addr = cache_hdr->read_addr;
2427        c_addr = cache_hdr->control_addr;
2428        c_value_w = cache_hdr->cache_ctrl.write_value;
2429
2430        t_r_addr = cache_hdr->tag_reg_addr;
2431        t_value = cache_hdr->addr_ctrl.init_tag_value;
2432        r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
2433
2434        for (i = 0; i < loop_count; i++) {
2435                qla8044_wr_reg_indirect(vha, t_r_addr, t_value);
2436                qla8044_wr_reg_indirect(vha, c_addr, c_value_w);
2437                addr = r_addr;
2438                for (k = 0; k < r_cnt; k++) {
2439                        qla8044_rd_reg_indirect(vha, addr, &r_value);
2440                        *data_ptr++ = r_value;
2441                        addr += cache_hdr->read_ctrl.read_addr_stride;
2442                }
2443                t_value += cache_hdr->addr_ctrl.tag_value_stride;
2444        }
2445        *d_ptr = data_ptr;
2446}
2447
2448static void
2449qla8044_minidump_process_rdocm(struct scsi_qla_host *vha,
2450        struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2451{
2452        uint32_t r_addr, r_stride, loop_cnt, i, r_value;
2453        struct qla8044_minidump_entry_rdocm *ocm_hdr;
2454        uint32_t *data_ptr = *d_ptr;
2455        struct qla_hw_data *ha = vha->hw;
2456
2457        ql_dbg(ql_dbg_p3p, vha, 0xb0f9, "Entering fn: %s\n", __func__);
2458
2459        ocm_hdr = (struct qla8044_minidump_entry_rdocm *)entry_hdr;
2460        r_addr = ocm_hdr->read_addr;
2461        r_stride = ocm_hdr->read_addr_stride;
2462        loop_cnt = ocm_hdr->op_count;
2463
2464        ql_dbg(ql_dbg_p3p, vha, 0xb0fa,
2465            "[%s]: r_addr: 0x%x, r_stride: 0x%x, loop_cnt: 0x%x\n",
2466            __func__, r_addr, r_stride, loop_cnt);
2467
2468        for (i = 0; i < loop_cnt; i++) {
2469                r_value = readl((void __iomem *)(r_addr + ha->nx_pcibase));
2470                *data_ptr++ = r_value;
2471                r_addr += r_stride;
2472        }
2473        ql_dbg(ql_dbg_p3p, vha, 0xb0fb, "Leaving fn: %s datacount: 0x%lx\n",
2474            __func__, (long unsigned int) (loop_cnt * sizeof(uint32_t)));
2475
2476        *d_ptr = data_ptr;
2477}
2478
2479static void
2480qla8044_minidump_process_rdmux(struct scsi_qla_host *vha,
2481        struct qla8044_minidump_entry_hdr *entry_hdr,
2482        uint32_t **d_ptr)
2483{
2484        uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value;
2485        struct qla8044_minidump_entry_mux *mux_hdr;
2486        uint32_t *data_ptr = *d_ptr;
2487
2488        ql_dbg(ql_dbg_p3p, vha, 0xb0fc, "Entering fn: %s\n", __func__);
2489
2490        mux_hdr = (struct qla8044_minidump_entry_mux *)entry_hdr;
2491        r_addr = mux_hdr->read_addr;
2492        s_addr = mux_hdr->select_addr;
2493        s_stride = mux_hdr->select_value_stride;
2494        s_value = mux_hdr->select_value;
2495        loop_cnt = mux_hdr->op_count;
2496
2497        for (i = 0; i < loop_cnt; i++) {
2498                qla8044_wr_reg_indirect(vha, s_addr, s_value);
2499                qla8044_rd_reg_indirect(vha, r_addr, &r_value);
2500                *data_ptr++ = s_value;
2501                *data_ptr++ = r_value;
2502                s_value += s_stride;
2503        }
2504        *d_ptr = data_ptr;
2505}
2506
2507static void
2508qla8044_minidump_process_queue(struct scsi_qla_host *vha,
2509        struct qla8044_minidump_entry_hdr *entry_hdr,
2510        uint32_t **d_ptr)
2511{
2512        uint32_t s_addr, r_addr;
2513        uint32_t r_stride, r_value, r_cnt, qid = 0;
2514        uint32_t i, k, loop_cnt;
2515        struct qla8044_minidump_entry_queue *q_hdr;
2516        uint32_t *data_ptr = *d_ptr;
2517
2518        ql_dbg(ql_dbg_p3p, vha, 0xb0fd, "Entering fn: %s\n", __func__);
2519        q_hdr = (struct qla8044_minidump_entry_queue *)entry_hdr;
2520        s_addr = q_hdr->select_addr;
2521        r_cnt = q_hdr->rd_strd.read_addr_cnt;
2522        r_stride = q_hdr->rd_strd.read_addr_stride;
2523        loop_cnt = q_hdr->op_count;
2524
2525        for (i = 0; i < loop_cnt; i++) {
2526                qla8044_wr_reg_indirect(vha, s_addr, qid);
2527                r_addr = q_hdr->read_addr;
2528                for (k = 0; k < r_cnt; k++) {
2529                        qla8044_rd_reg_indirect(vha, r_addr, &r_value);
2530                        *data_ptr++ = r_value;
2531                        r_addr += r_stride;
2532                }
2533                qid += q_hdr->q_strd.queue_id_stride;
2534        }
2535        *d_ptr = data_ptr;
2536}
2537
2538/* ISP83xx functions to process new minidump entries... */
2539static uint32_t
2540qla8044_minidump_process_pollrd(struct scsi_qla_host *vha,
2541        struct qla8044_minidump_entry_hdr *entry_hdr,
2542        uint32_t **d_ptr)
2543{
2544        uint32_t r_addr, s_addr, s_value, r_value, poll_wait, poll_mask;
2545        uint16_t s_stride, i;
2546        struct qla8044_minidump_entry_pollrd *pollrd_hdr;
2547        uint32_t *data_ptr = *d_ptr;
2548
2549        pollrd_hdr = (struct qla8044_minidump_entry_pollrd *) entry_hdr;
2550        s_addr = pollrd_hdr->select_addr;
2551        r_addr = pollrd_hdr->read_addr;
2552        s_value = pollrd_hdr->select_value;
2553        s_stride = pollrd_hdr->select_value_stride;
2554
2555        poll_wait = pollrd_hdr->poll_wait;
2556        poll_mask = pollrd_hdr->poll_mask;
2557
2558        for (i = 0; i < pollrd_hdr->op_count; i++) {
2559                qla8044_wr_reg_indirect(vha, s_addr, s_value);
2560                poll_wait = pollrd_hdr->poll_wait;
2561                while (1) {
2562                        qla8044_rd_reg_indirect(vha, s_addr, &r_value);
2563                        if ((r_value & poll_mask) != 0) {
2564                                break;
2565                        } else {
2566                                usleep_range(1000, 1100);
2567                                if (--poll_wait == 0) {
2568                                        ql_log(ql_log_fatal, vha, 0xb0fe,
2569                                            "%s: TIMEOUT\n", __func__);
2570                                        goto error;
2571                                }
2572                        }
2573                }
2574                qla8044_rd_reg_indirect(vha, r_addr, &r_value);
2575                *data_ptr++ = s_value;
2576                *data_ptr++ = r_value;
2577
2578                s_value += s_stride;
2579        }
2580        *d_ptr = data_ptr;
2581        return QLA_SUCCESS;
2582
2583error:
2584        return QLA_FUNCTION_FAILED;
2585}
2586
2587static void
2588qla8044_minidump_process_rdmux2(struct scsi_qla_host *vha,
2589        struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2590{
2591        uint32_t sel_val1, sel_val2, t_sel_val, data, i;
2592        uint32_t sel_addr1, sel_addr2, sel_val_mask, read_addr;
2593        struct qla8044_minidump_entry_rdmux2 *rdmux2_hdr;
2594        uint32_t *data_ptr = *d_ptr;
2595
2596        rdmux2_hdr = (struct qla8044_minidump_entry_rdmux2 *) entry_hdr;
2597        sel_val1 = rdmux2_hdr->select_value_1;
2598        sel_val2 = rdmux2_hdr->select_value_2;
2599        sel_addr1 = rdmux2_hdr->select_addr_1;
2600        sel_addr2 = rdmux2_hdr->select_addr_2;
2601        sel_val_mask = rdmux2_hdr->select_value_mask;
2602        read_addr = rdmux2_hdr->read_addr;
2603
2604        for (i = 0; i < rdmux2_hdr->op_count; i++) {
2605                qla8044_wr_reg_indirect(vha, sel_addr1, sel_val1);
2606                t_sel_val = sel_val1 & sel_val_mask;
2607                *data_ptr++ = t_sel_val;
2608
2609                qla8044_wr_reg_indirect(vha, sel_addr2, t_sel_val);
2610                qla8044_rd_reg_indirect(vha, read_addr, &data);
2611
2612                *data_ptr++ = data;
2613
2614                qla8044_wr_reg_indirect(vha, sel_addr1, sel_val2);
2615                t_sel_val = sel_val2 & sel_val_mask;
2616                *data_ptr++ = t_sel_val;
2617
2618                qla8044_wr_reg_indirect(vha, sel_addr2, t_sel_val);
2619                qla8044_rd_reg_indirect(vha, read_addr, &data);
2620
2621                *data_ptr++ = data;
2622
2623                sel_val1 += rdmux2_hdr->select_value_stride;
2624                sel_val2 += rdmux2_hdr->select_value_stride;
2625        }
2626
2627        *d_ptr = data_ptr;
2628}
2629
2630static uint32_t
2631qla8044_minidump_process_pollrdmwr(struct scsi_qla_host *vha,
2632        struct qla8044_minidump_entry_hdr *entry_hdr,
2633        uint32_t **d_ptr)
2634{
2635        uint32_t poll_wait, poll_mask, r_value, data;
2636        uint32_t addr_1, addr_2, value_1, value_2;
2637        struct qla8044_minidump_entry_pollrdmwr *poll_hdr;
2638        uint32_t *data_ptr = *d_ptr;
2639
2640        poll_hdr = (struct qla8044_minidump_entry_pollrdmwr *) entry_hdr;
2641        addr_1 = poll_hdr->addr_1;
2642        addr_2 = poll_hdr->addr_2;
2643        value_1 = poll_hdr->value_1;
2644        value_2 = poll_hdr->value_2;
2645        poll_mask = poll_hdr->poll_mask;
2646
2647        qla8044_wr_reg_indirect(vha, addr_1, value_1);
2648
2649        poll_wait = poll_hdr->poll_wait;
2650        while (1) {
2651                qla8044_rd_reg_indirect(vha, addr_1, &r_value);
2652
2653                if ((r_value & poll_mask) != 0) {
2654                        break;
2655                } else {
2656                        usleep_range(1000, 1100);
2657                        if (--poll_wait == 0) {
2658                                ql_log(ql_log_fatal, vha, 0xb0ff,
2659                                    "%s: TIMEOUT\n", __func__);
2660                                goto error;
2661                        }
2662                }
2663        }
2664
2665        qla8044_rd_reg_indirect(vha, addr_2, &data);
2666        data &= poll_hdr->modify_mask;
2667        qla8044_wr_reg_indirect(vha, addr_2, data);
2668        qla8044_wr_reg_indirect(vha, addr_1, value_2);
2669
2670        poll_wait = poll_hdr->poll_wait;
2671        while (1) {
2672                qla8044_rd_reg_indirect(vha, addr_1, &r_value);
2673
2674                if ((r_value & poll_mask) != 0) {
2675                        break;
2676                } else {
2677                        usleep_range(1000, 1100);
2678                        if (--poll_wait == 0) {
2679                                ql_log(ql_log_fatal, vha, 0xb100,
2680                                    "%s: TIMEOUT2\n", __func__);
2681                                goto error;
2682                        }
2683                }
2684        }
2685
2686        *data_ptr++ = addr_2;
2687        *data_ptr++ = data;
2688
2689        *d_ptr = data_ptr;
2690
2691        return QLA_SUCCESS;
2692
2693error:
2694        return QLA_FUNCTION_FAILED;
2695}
2696
2697#define ISP8044_PEX_DMA_ENGINE_INDEX            8
2698#define ISP8044_PEX_DMA_BASE_ADDRESS            0x77320000
2699#define ISP8044_PEX_DMA_NUM_OFFSET              0x10000
2700#define ISP8044_PEX_DMA_CMD_ADDR_LOW            0x0
2701#define ISP8044_PEX_DMA_CMD_ADDR_HIGH           0x04
2702#define ISP8044_PEX_DMA_CMD_STS_AND_CNTRL       0x08
2703
2704#define ISP8044_PEX_DMA_READ_SIZE       (16 * 1024)
2705#define ISP8044_PEX_DMA_MAX_WAIT        (100 * 100) /* Max wait of 100 msecs */
2706
2707static int
2708qla8044_check_dma_engine_state(struct scsi_qla_host *vha)
2709{
2710        struct qla_hw_data *ha = vha->hw;
2711        int rval = QLA_SUCCESS;
2712        uint32_t dma_eng_num = 0, cmd_sts_and_cntrl = 0;
2713        uint64_t dma_base_addr = 0;
2714        struct qla8044_minidump_template_hdr *tmplt_hdr = NULL;
2715
2716        tmplt_hdr = ha->md_tmplt_hdr;
2717        dma_eng_num =
2718            tmplt_hdr->saved_state_array[ISP8044_PEX_DMA_ENGINE_INDEX];
2719        dma_base_addr = ISP8044_PEX_DMA_BASE_ADDRESS +
2720                (dma_eng_num * ISP8044_PEX_DMA_NUM_OFFSET);
2721
2722        /* Read the pex-dma's command-status-and-control register. */
2723        rval = qla8044_rd_reg_indirect(vha,
2724            (dma_base_addr + ISP8044_PEX_DMA_CMD_STS_AND_CNTRL),
2725            &cmd_sts_and_cntrl);
2726        if (rval)
2727                return QLA_FUNCTION_FAILED;
2728
2729        /* Check if requested pex-dma engine is available. */
2730        if (cmd_sts_and_cntrl & BIT_31)
2731                return QLA_SUCCESS;
2732
2733        return QLA_FUNCTION_FAILED;
2734}
2735
2736static int
2737qla8044_start_pex_dma(struct scsi_qla_host *vha,
2738        struct qla8044_minidump_entry_rdmem_pex_dma *m_hdr)
2739{
2740        struct qla_hw_data *ha = vha->hw;
2741        int rval = QLA_SUCCESS, wait = 0;
2742        uint32_t dma_eng_num = 0, cmd_sts_and_cntrl = 0;
2743        uint64_t dma_base_addr = 0;
2744        struct qla8044_minidump_template_hdr *tmplt_hdr = NULL;
2745
2746        tmplt_hdr = ha->md_tmplt_hdr;
2747        dma_eng_num =
2748            tmplt_hdr->saved_state_array[ISP8044_PEX_DMA_ENGINE_INDEX];
2749        dma_base_addr = ISP8044_PEX_DMA_BASE_ADDRESS +
2750                (dma_eng_num * ISP8044_PEX_DMA_NUM_OFFSET);
2751
2752        rval = qla8044_wr_reg_indirect(vha,
2753            dma_base_addr + ISP8044_PEX_DMA_CMD_ADDR_LOW,
2754            m_hdr->desc_card_addr);
2755        if (rval)
2756                goto error_exit;
2757
2758        rval = qla8044_wr_reg_indirect(vha,
2759            dma_base_addr + ISP8044_PEX_DMA_CMD_ADDR_HIGH, 0);
2760        if (rval)
2761                goto error_exit;
2762
2763        rval = qla8044_wr_reg_indirect(vha,
2764            dma_base_addr + ISP8044_PEX_DMA_CMD_STS_AND_CNTRL,
2765            m_hdr->start_dma_cmd);
2766        if (rval)
2767                goto error_exit;
2768
2769        /* Wait for dma operation to complete. */
2770        for (wait = 0; wait < ISP8044_PEX_DMA_MAX_WAIT; wait++) {
2771                rval = qla8044_rd_reg_indirect(vha,
2772                    (dma_base_addr + ISP8044_PEX_DMA_CMD_STS_AND_CNTRL),
2773                    &cmd_sts_and_cntrl);
2774                if (rval)
2775                        goto error_exit;
2776
2777                if ((cmd_sts_and_cntrl & BIT_1) == 0)
2778                        break;
2779
2780                udelay(10);
2781        }
2782
2783        /* Wait a max of 100 ms, otherwise fallback to rdmem entry read */
2784        if (wait >= ISP8044_PEX_DMA_MAX_WAIT) {
2785                rval = QLA_FUNCTION_FAILED;
2786                goto error_exit;
2787        }
2788
2789error_exit:
2790        return rval;
2791}
2792
2793static int
2794qla8044_minidump_pex_dma_read(struct scsi_qla_host *vha,
2795        struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr)
2796{
2797        struct qla_hw_data *ha = vha->hw;
2798        int rval = QLA_SUCCESS;
2799        struct qla8044_minidump_entry_rdmem_pex_dma *m_hdr = NULL;
2800        uint32_t chunk_size, read_size;
2801        uint8_t *data_ptr = (uint8_t *)*d_ptr;
2802        void *rdmem_buffer = NULL;
2803        dma_addr_t rdmem_dma;
2804        struct qla8044_pex_dma_descriptor dma_desc;
2805
2806        rval = qla8044_check_dma_engine_state(vha);
2807        if (rval != QLA_SUCCESS) {
2808                ql_dbg(ql_dbg_p3p, vha, 0xb147,
2809                    "DMA engine not available. Fallback to rdmem-read.\n");
2810                return QLA_FUNCTION_FAILED;
2811        }
2812
2813        m_hdr = (void *)entry_hdr;
2814
2815        rdmem_buffer = dma_alloc_coherent(&ha->pdev->dev,
2816            ISP8044_PEX_DMA_READ_SIZE, &rdmem_dma, GFP_KERNEL);
2817        if (!rdmem_buffer) {
2818                ql_dbg(ql_dbg_p3p, vha, 0xb148,
2819                    "Unable to allocate rdmem dma buffer\n");
2820                return QLA_FUNCTION_FAILED;
2821        }
2822
2823        /* Prepare pex-dma descriptor to be written to MS memory. */
2824        /* dma-desc-cmd layout:
2825         *              0-3: dma-desc-cmd 0-3
2826         *              4-7: pcid function number
2827         *              8-15: dma-desc-cmd 8-15
2828         * dma_bus_addr: dma buffer address
2829         * cmd.read_data_size: amount of data-chunk to be read.
2830         */
2831        dma_desc.cmd.dma_desc_cmd = (m_hdr->dma_desc_cmd & 0xff0f);
2832        dma_desc.cmd.dma_desc_cmd |=
2833            ((PCI_FUNC(ha->pdev->devfn) & 0xf) << 0x4);
2834
2835        dma_desc.dma_bus_addr = rdmem_dma;
2836        dma_desc.cmd.read_data_size = chunk_size = ISP8044_PEX_DMA_READ_SIZE;
2837        read_size = 0;
2838
2839        /*
2840         * Perform rdmem operation using pex-dma.
2841         * Prepare dma in chunks of ISP8044_PEX_DMA_READ_SIZE.
2842         */
2843        while (read_size < m_hdr->read_data_size) {
2844                if (m_hdr->read_data_size - read_size <
2845                    ISP8044_PEX_DMA_READ_SIZE) {
2846                        chunk_size = (m_hdr->read_data_size - read_size);
2847                        dma_desc.cmd.read_data_size = chunk_size;
2848                }
2849
2850                dma_desc.src_addr = m_hdr->read_addr + read_size;
2851
2852                /* Prepare: Write pex-dma descriptor to MS memory. */
2853                rval = qla8044_ms_mem_write_128b(vha,
2854                    m_hdr->desc_card_addr, (void *)&dma_desc,
2855                    (sizeof(struct qla8044_pex_dma_descriptor)/16));
2856                if (rval) {
2857                        ql_log(ql_log_warn, vha, 0xb14a,
2858                            "%s: Error writing rdmem-dma-init to MS !!!\n",
2859                            __func__);
2860                        goto error_exit;
2861                }
2862                ql_dbg(ql_dbg_p3p, vha, 0xb14b,
2863                    "%s: Dma-descriptor: Instruct for rdmem dma "
2864                    "(chunk_size 0x%x).\n", __func__, chunk_size);
2865
2866                /* Execute: Start pex-dma operation. */
2867                rval = qla8044_start_pex_dma(vha, m_hdr);
2868                if (rval)
2869                        goto error_exit;
2870
2871                memcpy(data_ptr, rdmem_buffer, chunk_size);
2872                data_ptr += chunk_size;
2873                read_size += chunk_size;
2874        }
2875
2876        *d_ptr = (void *)data_ptr;
2877
2878error_exit:
2879        if (rdmem_buffer)
2880                dma_free_coherent(&ha->pdev->dev, ISP8044_PEX_DMA_READ_SIZE,
2881                    rdmem_buffer, rdmem_dma);
2882
2883        return rval;
2884}
2885
2886/*
2887 *
2888 * qla8044_collect_md_data - Retrieve firmware minidump data.
2889 * @ha: pointer to adapter structure
2890 **/
2891int
2892qla8044_collect_md_data(struct scsi_qla_host *vha)
2893{
2894        int num_entry_hdr = 0;
2895        struct qla8044_minidump_entry_hdr *entry_hdr;
2896        struct qla8044_minidump_template_hdr *tmplt_hdr;
2897        uint32_t *data_ptr;
2898        uint32_t data_collected = 0, f_capture_mask;
2899        int i, rval = QLA_FUNCTION_FAILED;
2900        uint64_t now;
2901        uint32_t timestamp, idc_control;
2902        struct qla_hw_data *ha = vha->hw;
2903
2904        if (!ha->md_dump) {
2905                ql_log(ql_log_info, vha, 0xb101,
2906                    "%s(%ld) No buffer to dump\n",
2907                    __func__, vha->host_no);
2908                return rval;
2909        }
2910
2911        if (ha->fw_dumped) {
2912                ql_log(ql_log_warn, vha, 0xb10d,
2913                    "Firmware has been previously dumped (%p) "
2914                    "-- ignoring request.\n", ha->fw_dump);
2915                goto md_failed;
2916        }
2917
2918        ha->fw_dumped = 0;
2919
2920        if (!ha->md_tmplt_hdr || !ha->md_dump) {
2921                ql_log(ql_log_warn, vha, 0xb10e,
2922                    "Memory not allocated for minidump capture\n");
2923                goto md_failed;
2924        }
2925
2926        qla8044_idc_lock(ha);
2927        idc_control = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
2928        if (idc_control & GRACEFUL_RESET_BIT1) {
2929                ql_log(ql_log_warn, vha, 0xb112,
2930                    "Forced reset from application, "
2931                    "ignore minidump capture\n");
2932                qla8044_wr_reg(ha, QLA8044_IDC_DRV_CTRL,
2933                    (idc_control & ~GRACEFUL_RESET_BIT1));
2934                qla8044_idc_unlock(ha);
2935
2936                goto md_failed;
2937        }
2938        qla8044_idc_unlock(ha);
2939
2940        if (qla82xx_validate_template_chksum(vha)) {
2941                ql_log(ql_log_info, vha, 0xb109,
2942                    "Template checksum validation error\n");
2943                goto md_failed;
2944        }
2945
2946        tmplt_hdr = (struct qla8044_minidump_template_hdr *)
2947                ha->md_tmplt_hdr;
2948        data_ptr = (uint32_t *)((uint8_t *)ha->md_dump);
2949        num_entry_hdr = tmplt_hdr->num_of_entries;
2950
2951        ql_dbg(ql_dbg_p3p, vha, 0xb11a,
2952            "Capture Mask obtained: 0x%x\n", tmplt_hdr->capture_debug_level);
2953
2954        f_capture_mask = tmplt_hdr->capture_debug_level & 0xFF;
2955
2956        /* Validate whether required debug level is set */
2957        if ((f_capture_mask & 0x3) != 0x3) {
2958                ql_log(ql_log_warn, vha, 0xb10f,
2959                    "Minimum required capture mask[0x%x] level not set\n",
2960                    f_capture_mask);
2961
2962        }
2963        tmplt_hdr->driver_capture_mask = ql2xmdcapmask;
2964        ql_log(ql_log_info, vha, 0xb102,
2965            "[%s]: starting data ptr: %p\n",
2966           __func__, data_ptr);
2967        ql_log(ql_log_info, vha, 0xb10b,
2968           "[%s]: no of entry headers in Template: 0x%x\n",
2969           __func__, num_entry_hdr);
2970        ql_log(ql_log_info, vha, 0xb10c,
2971            "[%s]: Total_data_size 0x%x, %d obtained\n",
2972           __func__, ha->md_dump_size, ha->md_dump_size);
2973
2974        /* Update current timestamp before taking dump */
2975        now = get_jiffies_64();
2976        timestamp = (u32)(jiffies_to_msecs(now) / 1000);
2977        tmplt_hdr->driver_timestamp = timestamp;
2978
2979        entry_hdr = (struct qla8044_minidump_entry_hdr *)
2980                (((uint8_t *)ha->md_tmplt_hdr) + tmplt_hdr->first_entry_offset);
2981        tmplt_hdr->saved_state_array[QLA8044_SS_OCM_WNDREG_INDEX] =
2982            tmplt_hdr->ocm_window_reg[ha->portnum];
2983
2984        /* Walk through the entry headers - validate/perform required action */
2985        for (i = 0; i < num_entry_hdr; i++) {
2986                if (data_collected > ha->md_dump_size) {
2987                        ql_log(ql_log_info, vha, 0xb103,
2988                            "Data collected: [0x%x], "
2989                            "Total Dump size: [0x%x]\n",
2990                            data_collected, ha->md_dump_size);
2991                        return rval;
2992                }
2993
2994                if (!(entry_hdr->d_ctrl.entry_capture_mask &
2995                      ql2xmdcapmask)) {
2996                        entry_hdr->d_ctrl.driver_flags |=
2997                            QLA82XX_DBG_SKIPPED_FLAG;
2998                        goto skip_nxt_entry;
2999                }
3000
3001                ql_dbg(ql_dbg_p3p, vha, 0xb104,
3002                    "Data collected: [0x%x], Dump size left:[0x%x]\n",
3003                    data_collected,
3004                    (ha->md_dump_size - data_collected));
3005
3006                /* Decode the entry type and take required action to capture
3007                 * debug data
3008                 */
3009                switch (entry_hdr->entry_type) {
3010                case QLA82XX_RDEND:
3011                        qla8044_mark_entry_skipped(vha, entry_hdr, i);
3012                        break;
3013                case QLA82XX_CNTRL:
3014                        rval = qla8044_minidump_process_control(vha,
3015                            entry_hdr);
3016                        if (rval != QLA_SUCCESS) {
3017                                qla8044_mark_entry_skipped(vha, entry_hdr, i);
3018                                goto md_failed;
3019                        }
3020                        break;
3021                case QLA82XX_RDCRB:
3022                        qla8044_minidump_process_rdcrb(vha,
3023                            entry_hdr, &data_ptr);
3024                        break;
3025                case QLA82XX_RDMEM:
3026                        rval = qla8044_minidump_pex_dma_read(vha,
3027                            entry_hdr, &data_ptr);
3028                        if (rval != QLA_SUCCESS) {
3029                                rval = qla8044_minidump_process_rdmem(vha,
3030                                    entry_hdr, &data_ptr);
3031                                if (rval != QLA_SUCCESS) {
3032                                        qla8044_mark_entry_skipped(vha,
3033                                            entry_hdr, i);
3034                                        goto md_failed;
3035                                }
3036                        }
3037                        break;
3038                case QLA82XX_BOARD:
3039                case QLA82XX_RDROM:
3040                        rval = qla8044_minidump_process_rdrom(vha,
3041                            entry_hdr, &data_ptr);
3042                        if (rval != QLA_SUCCESS) {
3043                                qla8044_mark_entry_skipped(vha,
3044                                    entry_hdr, i);
3045                        }
3046                        break;
3047                case QLA82XX_L2DTG:
3048                case QLA82XX_L2ITG:
3049                case QLA82XX_L2DAT:
3050                case QLA82XX_L2INS:
3051                        rval = qla8044_minidump_process_l2tag(vha,
3052                            entry_hdr, &data_ptr);
3053                        if (rval != QLA_SUCCESS) {
3054                                qla8044_mark_entry_skipped(vha, entry_hdr, i);
3055                                goto md_failed;
3056                        }
3057                        break;
3058                case QLA8044_L1DTG:
3059                case QLA8044_L1ITG:
3060                case QLA82XX_L1DAT:
3061                case QLA82XX_L1INS:
3062                        qla8044_minidump_process_l1cache(vha,
3063                            entry_hdr, &data_ptr);
3064                        break;
3065                case QLA82XX_RDOCM:
3066                        qla8044_minidump_process_rdocm(vha,
3067                            entry_hdr, &data_ptr);
3068                        break;
3069                case QLA82XX_RDMUX:
3070                        qla8044_minidump_process_rdmux(vha,
3071                            entry_hdr, &data_ptr);
3072                        break;
3073                case QLA82XX_QUEUE:
3074                        qla8044_minidump_process_queue(vha,
3075                            entry_hdr, &data_ptr);
3076                        break;
3077                case QLA8044_POLLRD:
3078                        rval = qla8044_minidump_process_pollrd(vha,
3079                            entry_hdr, &data_ptr);
3080                        if (rval != QLA_SUCCESS)
3081                                qla8044_mark_entry_skipped(vha, entry_hdr, i);
3082                        break;
3083                case QLA8044_RDMUX2:
3084                        qla8044_minidump_process_rdmux2(vha,
3085                            entry_hdr, &data_ptr);
3086                        break;
3087                case QLA8044_POLLRDMWR:
3088                        rval = qla8044_minidump_process_pollrdmwr(vha,
3089                            entry_hdr, &data_ptr);
3090                        if (rval != QLA_SUCCESS)
3091                                qla8044_mark_entry_skipped(vha, entry_hdr, i);
3092                        break;
3093                case QLA82XX_RDNOP:
3094                default:
3095                        qla8044_mark_entry_skipped(vha, entry_hdr, i);
3096                        break;
3097                }
3098
3099                data_collected = (uint8_t *)data_ptr -
3100                    (uint8_t *)((uint8_t *)ha->md_dump);
3101skip_nxt_entry:
3102                /*
3103                 * next entry in the template
3104                 */
3105                entry_hdr = (struct qla8044_minidump_entry_hdr *)
3106                    (((uint8_t *)entry_hdr) + entry_hdr->entry_size);
3107        }
3108
3109        if (data_collected != ha->md_dump_size) {
3110                ql_log(ql_log_info, vha, 0xb105,
3111                    "Dump data mismatch: Data collected: "
3112                    "[0x%x], total_data_size:[0x%x]\n",
3113                    data_collected, ha->md_dump_size);
3114                goto md_failed;
3115        }
3116
3117        ql_log(ql_log_info, vha, 0xb110,
3118            "Firmware dump saved to temp buffer (%ld/%p %ld/%p).\n",
3119            vha->host_no, ha->md_tmplt_hdr, vha->host_no, ha->md_dump);
3120        ha->fw_dumped = 1;
3121        qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
3122
3123
3124        ql_log(ql_log_info, vha, 0xb106,
3125            "Leaving fn: %s Last entry: 0x%x\n",
3126            __func__, i);
3127md_failed:
3128        return rval;
3129}
3130
3131void
3132qla8044_get_minidump(struct scsi_qla_host *vha)
3133{
3134        struct qla_hw_data *ha = vha->hw;
3135
3136        if (!qla8044_collect_md_data(vha)) {
3137                ha->fw_dumped = 1;
3138        } else {
3139                ql_log(ql_log_fatal, vha, 0xb0db,
3140                    "%s: Unable to collect minidump\n",
3141                    __func__);
3142        }
3143}
3144
3145static int
3146qla8044_poll_flash_status_reg(struct scsi_qla_host *vha)
3147{
3148        uint32_t flash_status;
3149        int retries = QLA8044_FLASH_READ_RETRY_COUNT;
3150        int ret_val = QLA_SUCCESS;
3151
3152        while (retries--) {
3153                ret_val = qla8044_rd_reg_indirect(vha, QLA8044_FLASH_STATUS,
3154                    &flash_status);
3155                if (ret_val) {
3156                        ql_log(ql_log_warn, vha, 0xb13c,
3157                            "%s: Failed to read FLASH_STATUS reg.\n",
3158                            __func__);
3159                        break;
3160                }
3161                if ((flash_status & QLA8044_FLASH_STATUS_READY) ==
3162                    QLA8044_FLASH_STATUS_READY)
3163                        break;
3164                msleep(QLA8044_FLASH_STATUS_REG_POLL_DELAY);
3165        }
3166
3167        if (!retries)
3168                ret_val = QLA_FUNCTION_FAILED;
3169
3170        return ret_val;
3171}
3172
3173static int
3174qla8044_write_flash_status_reg(struct scsi_qla_host *vha,
3175                               uint32_t data)
3176{
3177        int ret_val = QLA_SUCCESS;
3178        uint32_t cmd;
3179
3180        cmd = vha->hw->fdt_wrt_sts_reg_cmd;
3181
3182        ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3183            QLA8044_FLASH_STATUS_WRITE_DEF_SIG | cmd);
3184        if (ret_val) {
3185                ql_log(ql_log_warn, vha, 0xb125,
3186                    "%s: Failed to write to FLASH_ADDR.\n", __func__);
3187                goto exit_func;
3188        }
3189
3190        ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, data);
3191        if (ret_val) {
3192                ql_log(ql_log_warn, vha, 0xb126,
3193                    "%s: Failed to write to FLASH_WRDATA.\n", __func__);
3194                goto exit_func;
3195        }
3196
3197        ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
3198            QLA8044_FLASH_SECOND_ERASE_MS_VAL);
3199        if (ret_val) {
3200                ql_log(ql_log_warn, vha, 0xb127,
3201                    "%s: Failed to write to FLASH_CONTROL.\n", __func__);
3202                goto exit_func;
3203        }
3204
3205        ret_val = qla8044_poll_flash_status_reg(vha);
3206        if (ret_val)
3207                ql_log(ql_log_warn, vha, 0xb128,
3208                    "%s: Error polling flash status reg.\n", __func__);
3209
3210exit_func:
3211        return ret_val;
3212}
3213
3214/*
3215 * This function assumes that the flash lock is held.
3216 */
3217static int
3218qla8044_unprotect_flash(scsi_qla_host_t *vha)
3219{
3220        int ret_val;
3221        struct qla_hw_data *ha = vha->hw;
3222
3223        ret_val = qla8044_write_flash_status_reg(vha, ha->fdt_wrt_enable);
3224        if (ret_val)
3225                ql_log(ql_log_warn, vha, 0xb139,
3226                    "%s: Write flash status failed.\n", __func__);
3227
3228        return ret_val;
3229}
3230
3231/*
3232 * This function assumes that the flash lock is held.
3233 */
3234static int
3235qla8044_protect_flash(scsi_qla_host_t *vha)
3236{
3237        int ret_val;
3238        struct qla_hw_data *ha = vha->hw;
3239
3240        ret_val = qla8044_write_flash_status_reg(vha, ha->fdt_wrt_disable);
3241        if (ret_val)
3242                ql_log(ql_log_warn, vha, 0xb13b,
3243                    "%s: Write flash status failed.\n", __func__);
3244
3245        return ret_val;
3246}
3247
3248
3249static int
3250qla8044_erase_flash_sector(struct scsi_qla_host *vha,
3251                           uint32_t sector_start_addr)
3252{
3253        uint32_t reversed_addr;
3254        int ret_val = QLA_SUCCESS;
3255
3256        ret_val = qla8044_poll_flash_status_reg(vha);
3257        if (ret_val) {
3258                ql_log(ql_log_warn, vha, 0xb12e,
3259                    "%s: Poll flash status after erase failed..\n", __func__);
3260        }
3261
3262        reversed_addr = (((sector_start_addr & 0xFF) << 16) |
3263            (sector_start_addr & 0xFF00) |
3264            ((sector_start_addr & 0xFF0000) >> 16));
3265
3266        ret_val = qla8044_wr_reg_indirect(vha,
3267            QLA8044_FLASH_WRDATA, reversed_addr);
3268        if (ret_val) {
3269                ql_log(ql_log_warn, vha, 0xb12f,
3270                    "%s: Failed to write to FLASH_WRDATA.\n", __func__);
3271        }
3272        ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3273           QLA8044_FLASH_ERASE_SIG | vha->hw->fdt_erase_cmd);
3274        if (ret_val) {
3275                ql_log(ql_log_warn, vha, 0xb130,
3276                    "%s: Failed to write to FLASH_ADDR.\n", __func__);
3277        }
3278        ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
3279            QLA8044_FLASH_LAST_ERASE_MS_VAL);
3280        if (ret_val) {
3281                ql_log(ql_log_warn, vha, 0xb131,
3282                    "%s: Failed write to FLASH_CONTROL.\n", __func__);
3283        }
3284        ret_val = qla8044_poll_flash_status_reg(vha);
3285        if (ret_val) {
3286                ql_log(ql_log_warn, vha, 0xb132,
3287                    "%s: Poll flash status failed.\n", __func__);
3288        }
3289
3290
3291        return ret_val;
3292}
3293
3294/*
3295 * qla8044_flash_write_u32 - Write data to flash
3296 *
3297 * @ha : Pointer to adapter structure
3298 * addr : Flash address to write to
3299 * p_data : Data to be written
3300 *
3301 * Return Value - QLA_SUCCESS/QLA_FUNCTION_FAILED
3302 *
3303 * NOTE: Lock should be held on entry
3304 */
3305static int
3306qla8044_flash_write_u32(struct scsi_qla_host *vha, uint32_t addr,
3307                        uint32_t *p_data)
3308{
3309        int ret_val = QLA_SUCCESS;
3310
3311        ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3312            0x00800000 | (addr >> 2));
3313        if (ret_val) {
3314                ql_log(ql_log_warn, vha, 0xb134,
3315                    "%s: Failed write to FLASH_ADDR.\n", __func__);
3316                goto exit_func;
3317        }
3318        ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, *p_data);
3319        if (ret_val) {
3320                ql_log(ql_log_warn, vha, 0xb135,
3321                    "%s: Failed write to FLASH_WRDATA.\n", __func__);
3322                goto exit_func;
3323        }
3324        ret_val = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL, 0x3D);
3325        if (ret_val) {
3326                ql_log(ql_log_warn, vha, 0xb136,
3327                    "%s: Failed write to FLASH_CONTROL.\n", __func__);
3328                goto exit_func;
3329        }
3330        ret_val = qla8044_poll_flash_status_reg(vha);
3331        if (ret_val) {
3332                ql_log(ql_log_warn, vha, 0xb137,
3333                    "%s: Poll flash status failed.\n", __func__);
3334        }
3335
3336exit_func:
3337        return ret_val;
3338}
3339
3340static int
3341qla8044_write_flash_buffer_mode(scsi_qla_host_t *vha, uint32_t *dwptr,
3342                                uint32_t faddr, uint32_t dwords)
3343{
3344        int ret = QLA_FUNCTION_FAILED;
3345        uint32_t spi_val;
3346
3347        if (dwords < QLA8044_MIN_OPTROM_BURST_DWORDS ||
3348            dwords > QLA8044_MAX_OPTROM_BURST_DWORDS) {
3349                ql_dbg(ql_dbg_user, vha, 0xb123,
3350                    "Got unsupported dwords = 0x%x.\n",
3351                    dwords);
3352                return QLA_FUNCTION_FAILED;
3353        }
3354
3355        qla8044_rd_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL, &spi_val);
3356        qla8044_wr_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL,
3357            spi_val | QLA8044_FLASH_SPI_CTL);
3358        qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3359            QLA8044_FLASH_FIRST_TEMP_VAL);
3360
3361        /* First DWORD write to FLASH_WRDATA */
3362        ret = qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA,
3363            *dwptr++);
3364        qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
3365            QLA8044_FLASH_FIRST_MS_PATTERN);
3366
3367        ret = qla8044_poll_flash_status_reg(vha);
3368        if (ret) {
3369                ql_log(ql_log_warn, vha, 0xb124,
3370                    "%s: Failed.\n", __func__);
3371                goto exit_func;
3372        }
3373
3374        dwords--;
3375
3376        qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3377            QLA8044_FLASH_SECOND_TEMP_VAL);
3378
3379
3380        /* Second to N-1 DWORDS writes */
3381        while (dwords != 1) {
3382                qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, *dwptr++);
3383                qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
3384                    QLA8044_FLASH_SECOND_MS_PATTERN);
3385                ret = qla8044_poll_flash_status_reg(vha);
3386                if (ret) {
3387                        ql_log(ql_log_warn, vha, 0xb129,
3388                            "%s: Failed.\n", __func__);
3389                        goto exit_func;
3390                }
3391                dwords--;
3392        }
3393
3394        qla8044_wr_reg_indirect(vha, QLA8044_FLASH_ADDR,
3395            QLA8044_FLASH_FIRST_TEMP_VAL | (faddr >> 2));
3396
3397        /* Last DWORD write */
3398        qla8044_wr_reg_indirect(vha, QLA8044_FLASH_WRDATA, *dwptr++);
3399        qla8044_wr_reg_indirect(vha, QLA8044_FLASH_CONTROL,
3400            QLA8044_FLASH_LAST_MS_PATTERN);
3401        ret = qla8044_poll_flash_status_reg(vha);
3402        if (ret) {
3403                ql_log(ql_log_warn, vha, 0xb12a,
3404                    "%s: Failed.\n", __func__);
3405                goto exit_func;
3406        }
3407        qla8044_rd_reg_indirect(vha, QLA8044_FLASH_SPI_STATUS, &spi_val);
3408
3409        if ((spi_val & QLA8044_FLASH_SPI_CTL) == QLA8044_FLASH_SPI_CTL) {
3410                ql_log(ql_log_warn, vha, 0xb12b,
3411                    "%s: Failed.\n", __func__);
3412                spi_val = 0;
3413                /* Operation failed, clear error bit. */
3414                qla8044_rd_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL,
3415                    &spi_val);
3416                qla8044_wr_reg_indirect(vha, QLA8044_FLASH_SPI_CONTROL,
3417                    spi_val | QLA8044_FLASH_SPI_CTL);
3418        }
3419exit_func:
3420        return ret;
3421}
3422
3423static int
3424qla8044_write_flash_dword_mode(scsi_qla_host_t *vha, uint32_t *dwptr,
3425                               uint32_t faddr, uint32_t dwords)
3426{
3427        int ret = QLA_FUNCTION_FAILED;
3428        uint32_t liter;
3429
3430        for (liter = 0; liter < dwords; liter++, faddr += 4, dwptr++) {
3431                ret = qla8044_flash_write_u32(vha, faddr, dwptr);
3432                if (ret) {
3433                        ql_dbg(ql_dbg_p3p, vha, 0xb141,
3434                            "%s: flash address=%x data=%x.\n", __func__,
3435                             faddr, *dwptr);
3436                        break;
3437                }
3438        }
3439
3440        return ret;
3441}
3442
3443int
3444qla8044_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
3445                          uint32_t offset, uint32_t length)
3446{
3447        int rval = QLA_FUNCTION_FAILED, i, burst_iter_count;
3448        int dword_count, erase_sec_count;
3449        uint32_t erase_offset;
3450        uint8_t *p_cache, *p_src;
3451
3452        erase_offset = offset;
3453
3454        p_cache = kcalloc(length, sizeof(uint8_t), GFP_KERNEL);
3455        if (!p_cache)
3456                return QLA_FUNCTION_FAILED;
3457
3458        memcpy(p_cache, buf, length);
3459        p_src = p_cache;
3460        dword_count = length / sizeof(uint32_t);
3461        /* Since the offset and legth are sector aligned, it will be always
3462         * multiple of burst_iter_count (64)
3463         */
3464        burst_iter_count = dword_count / QLA8044_MAX_OPTROM_BURST_DWORDS;
3465        erase_sec_count = length / QLA8044_SECTOR_SIZE;
3466
3467        /* Suspend HBA. */
3468        scsi_block_requests(vha->host);
3469        /* Lock and enable write for whole operation. */
3470        qla8044_flash_lock(vha);
3471        qla8044_unprotect_flash(vha);
3472
3473        /* Erasing the sectors */
3474        for (i = 0; i < erase_sec_count; i++) {
3475                rval = qla8044_erase_flash_sector(vha, erase_offset);
3476                ql_dbg(ql_dbg_user, vha, 0xb138,
3477                    "Done erase of sector=0x%x.\n",
3478                    erase_offset);
3479                if (rval) {
3480                        ql_log(ql_log_warn, vha, 0xb121,
3481                            "Failed to erase the sector having address: "
3482                            "0x%x.\n", erase_offset);
3483                        goto out;
3484                }
3485                erase_offset += QLA8044_SECTOR_SIZE;
3486        }
3487        ql_dbg(ql_dbg_user, vha, 0xb13f,
3488            "Got write for addr = 0x%x length=0x%x.\n",
3489            offset, length);
3490
3491        for (i = 0; i < burst_iter_count; i++) {
3492
3493                /* Go with write. */
3494                rval = qla8044_write_flash_buffer_mode(vha, (uint32_t *)p_src,
3495                    offset, QLA8044_MAX_OPTROM_BURST_DWORDS);
3496                if (rval) {
3497                        /* Buffer Mode failed skip to dword mode */
3498                        ql_log(ql_log_warn, vha, 0xb122,
3499                            "Failed to write flash in buffer mode, "
3500                            "Reverting to slow-write.\n");
3501                        rval = qla8044_write_flash_dword_mode(vha,
3502                            (uint32_t *)p_src, offset,
3503                            QLA8044_MAX_OPTROM_BURST_DWORDS);
3504                }
3505                p_src +=  sizeof(uint32_t) * QLA8044_MAX_OPTROM_BURST_DWORDS;
3506                offset += sizeof(uint32_t) * QLA8044_MAX_OPTROM_BURST_DWORDS;
3507        }
3508        ql_dbg(ql_dbg_user, vha, 0xb133,
3509            "Done writing.\n");
3510
3511out:
3512        qla8044_protect_flash(vha);
3513        qla8044_flash_unlock(vha);
3514        scsi_unblock_requests(vha->host);
3515        kfree(p_cache);
3516
3517        return rval;
3518}
3519
3520#define LEG_INT_PTR_B31         (1 << 31)
3521#define LEG_INT_PTR_B30         (1 << 30)
3522#define PF_BITS_MASK            (0xF << 16)
3523/**
3524 * qla8044_intr_handler() - Process interrupts for the ISP8044
3525 * @irq:
3526 * @dev_id: SCSI driver HA context
3527 *
3528 * Called by system whenever the host adapter generates an interrupt.
3529 *
3530 * Returns handled flag.
3531 */
3532irqreturn_t
3533qla8044_intr_handler(int irq, void *dev_id)
3534{
3535        scsi_qla_host_t *vha;
3536        struct qla_hw_data *ha;
3537        struct rsp_que *rsp;
3538        struct device_reg_82xx __iomem *reg;
3539        int             status = 0;
3540        unsigned long   flags;
3541        unsigned long   iter;
3542        uint32_t        stat;
3543        uint16_t        mb[4];
3544        uint32_t leg_int_ptr = 0, pf_bit;
3545
3546        rsp = (struct rsp_que *) dev_id;
3547        if (!rsp) {
3548                ql_log(ql_log_info, NULL, 0xb143,
3549                    "%s(): NULL response queue pointer\n", __func__);
3550                return IRQ_NONE;
3551        }
3552        ha = rsp->hw;
3553        vha = pci_get_drvdata(ha->pdev);
3554
3555        if (unlikely(pci_channel_offline(ha->pdev)))
3556                return IRQ_HANDLED;
3557
3558        leg_int_ptr = qla8044_rd_reg(ha, LEG_INTR_PTR_OFFSET);
3559
3560        /* Legacy interrupt is valid if bit31 of leg_int_ptr is set */
3561        if (!(leg_int_ptr & (LEG_INT_PTR_B31))) {
3562                ql_dbg(ql_dbg_p3p, vha, 0xb144,
3563                    "%s: Legacy Interrupt Bit 31 not set, "
3564                    "spurious interrupt!\n", __func__);
3565                return IRQ_NONE;
3566        }
3567
3568        pf_bit = ha->portnum << 16;
3569        /* Validate the PCIE function ID set in leg_int_ptr bits [19..16] */
3570        if ((leg_int_ptr & (PF_BITS_MASK)) != pf_bit) {
3571                ql_dbg(ql_dbg_p3p, vha, 0xb145,
3572                    "%s: Incorrect function ID 0x%x in "
3573                    "legacy interrupt register, "
3574                    "ha->pf_bit = 0x%x\n", __func__,
3575                    (leg_int_ptr & (PF_BITS_MASK)), pf_bit);
3576                return IRQ_NONE;
3577        }
3578
3579        /* To de-assert legacy interrupt, write 0 to Legacy Interrupt Trigger
3580         * Control register and poll till Legacy Interrupt Pointer register
3581         * bit32 is 0.
3582         */
3583        qla8044_wr_reg(ha, LEG_INTR_TRIG_OFFSET, 0);
3584        do {
3585                leg_int_ptr = qla8044_rd_reg(ha, LEG_INTR_PTR_OFFSET);
3586                if ((leg_int_ptr & (PF_BITS_MASK)) != pf_bit)
3587                        break;
3588        } while (leg_int_ptr & (LEG_INT_PTR_B30));
3589
3590        reg = &ha->iobase->isp82;
3591        spin_lock_irqsave(&ha->hardware_lock, flags);
3592        for (iter = 1; iter--; ) {
3593
3594                if (RD_REG_DWORD(&reg->host_int)) {
3595                        stat = RD_REG_DWORD(&reg->host_status);
3596                        if ((stat & HSRX_RISC_INT) == 0)
3597                                break;
3598
3599                        switch (stat & 0xff) {
3600                        case 0x1:
3601                        case 0x2:
3602                        case 0x10:
3603                        case 0x11:
3604                                qla82xx_mbx_completion(vha, MSW(stat));
3605                                status |= MBX_INTERRUPT;
3606                                break;
3607                        case 0x12:
3608                                mb[0] = MSW(stat);
3609                                mb[1] = RD_REG_WORD(&reg->mailbox_out[1]);
3610                                mb[2] = RD_REG_WORD(&reg->mailbox_out[2]);
3611                                mb[3] = RD_REG_WORD(&reg->mailbox_out[3]);
3612                                qla2x00_async_event(vha, rsp, mb);
3613                                break;
3614                        case 0x13:
3615                                qla24xx_process_response_queue(vha, rsp);
3616                                break;
3617                        default:
3618                                ql_dbg(ql_dbg_p3p, vha, 0xb146,
3619                                    "Unrecognized interrupt type "
3620                                    "(%d).\n", stat & 0xff);
3621                                break;
3622                        }
3623                }
3624                WRT_REG_DWORD(&reg->host_int, 0);
3625        }
3626
3627        qla2x00_handle_mbx_completion(ha, status);
3628        spin_unlock_irqrestore(&ha->hardware_lock, flags);
3629
3630        return IRQ_HANDLED;
3631}
3632
3633static int
3634qla8044_idc_dontreset(struct qla_hw_data *ha)
3635{
3636        uint32_t idc_ctrl;
3637
3638        idc_ctrl = qla8044_rd_reg(ha, QLA8044_IDC_DRV_CTRL);
3639        return idc_ctrl & DONTRESET_BIT0;
3640}
3641
3642static void
3643qla8044_clear_rst_ready(scsi_qla_host_t *vha)
3644{
3645        uint32_t drv_state;
3646
3647        drv_state = qla8044_rd_direct(vha, QLA8044_CRB_DRV_STATE_INDEX);
3648
3649        /*
3650         * For ISP8044, drv_active register has 1 bit per function,
3651         * shift 1 by func_num to set a bit for the function.
3652         * For ISP82xx, drv_active has 4 bits per function
3653         */
3654        drv_state &= ~(1 << vha->hw->portnum);
3655
3656        ql_dbg(ql_dbg_p3p, vha, 0xb13d,
3657            "drv_state: 0x%08x\n", drv_state);
3658        qla8044_wr_direct(vha, QLA8044_CRB_DRV_STATE_INDEX, drv_state);
3659}
3660
3661int
3662qla8044_abort_isp(scsi_qla_host_t *vha)
3663{
3664        int rval;
3665        uint32_t dev_state;
3666        struct qla_hw_data *ha = vha->hw;
3667
3668        qla8044_idc_lock(ha);
3669        dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX);
3670
3671        if (ql2xdontresethba)
3672                qla8044_set_idc_dontreset(vha);
3673
3674        /* If device_state is NEED_RESET, go ahead with
3675         * Reset,irrespective of ql2xdontresethba. This is to allow a
3676         * non-reset-owner to force a reset. Non-reset-owner sets
3677         * the IDC_CTRL BIT0 to prevent Reset-owner from doing a Reset
3678         * and then forces a Reset by setting device_state to
3679         * NEED_RESET. */
3680        if (dev_state == QLA8XXX_DEV_READY) {
3681                /* If IDC_CTRL DONTRESETHBA_BIT0 is set don't do reset
3682                 * recovery */
3683                if (qla8044_idc_dontreset(ha) == DONTRESET_BIT0) {
3684                        ql_dbg(ql_dbg_p3p, vha, 0xb13e,
3685                            "Reset recovery disabled\n");
3686                        rval = QLA_FUNCTION_FAILED;
3687                        goto exit_isp_reset;
3688                }
3689
3690                ql_dbg(ql_dbg_p3p, vha, 0xb140,
3691                    "HW State: NEED RESET\n");
3692                qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX,
3693                    QLA8XXX_DEV_NEED_RESET);
3694        }
3695
3696        /* For ISP8044, Reset owner is NIC, iSCSI or FCOE based on priority
3697         * and which drivers are present. Unlike ISP82XX, the function setting
3698         * NEED_RESET, may not be the Reset owner. */
3699        qla83xx_reset_ownership(vha);
3700
3701        qla8044_idc_unlock(ha);
3702        rval = qla8044_device_state_handler(vha);
3703        qla8044_idc_lock(ha);
3704        qla8044_clear_rst_ready(vha);
3705
3706exit_isp_reset:
3707        qla8044_idc_unlock(ha);
3708        if (rval == QLA_SUCCESS) {
3709                ha->flags.isp82xx_fw_hung = 0;
3710                ha->flags.nic_core_reset_hdlr_active = 0;
3711                rval = qla82xx_restart_isp(vha);
3712        }
3713
3714        return rval;
3715}
3716
3717