/*-
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright (c) 2013-2014 Qlogic Corporation
 * All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * File: qls_dump.c
 */
#include <sys/cdefs.h>
#include "qls_os.h"
#include "qls_hw.h"
#include "qls_def.h"
#include "qls_glbl.h"
#include "qls_dump.h"

qls_mpi_coredump_t ql_mpi_coredump;

#define Q81_CORE_SEG_NUM              1
#define Q81_TEST_LOGIC_SEG_NUM        2
#define Q81_RMII_SEG_NUM              3
#define Q81_FCMAC1_SEG_NUM            4
#define Q81_FCMAC2_SEG_NUM            5
#define Q81_FC1_MBOX_SEG_NUM          6
#define Q81_IDE_SEG_NUM               7
#define Q81_NIC1_MBOX_SEG_NUM         8
#define Q81_SMBUS_SEG_NUM             9
#define Q81_FC2_MBOX_SEG_NUM          10
#define Q81_NIC2_MBOX_SEG_NUM         11
#define Q81_I2C_SEG_NUM               12
#define Q81_MEMC_SEG_NUM              13
#define Q81_PBUS_SEG_NUM              14
#define Q81_MDE_SEG_NUM               15
#define Q81_NIC1_CONTROL_SEG_NUM      16
#define Q81_NIC2_CONTROL_SEG_NUM      17
#define Q81_NIC1_XGMAC_SEG_NUM        18
#define Q81_NIC2_XGMAC_SEG_NUM        19
#define Q81_WCS_RAM_SEG_NUM           20
#define Q81_MEMC_RAM_SEG_NUM          21
#define Q81_XAUI1_AN_SEG_NUM          22
#define Q81_XAUI1_HSS_PCS_SEG_NUM     23
#define Q81_XFI1_AN_SEG_NUM           24
#define Q81_XFI1_TRAIN_SEG_NUM        25
#define Q81_XFI1_HSS_PCS_SEG_NUM      26
#define Q81_XFI1_HSS_TX_SEG_NUM       27
#define Q81_XFI1_HSS_RX_SEG_NUM       28
#define Q81_XFI1_HSS_PLL_SEG_NUM      29
#define Q81_INTR_STATES_SEG_NUM       31
#define Q81_ETS_SEG_NUM               34
#define Q81_PROBE_DUMP_SEG_NUM        35
#define Q81_ROUTING_INDEX_SEG_NUM     36
#define Q81_MAC_PROTOCOL_SEG_NUM      37
#define Q81_XAUI2_AN_SEG_NUM          38
#define Q81_XAUI2_HSS_PCS_SEG_NUM     39
#define Q81_XFI2_AN_SEG_NUM           40
#define Q81_XFI2_TRAIN_SEG_NUM        41
#define Q81_XFI2_HSS_PCS_SEG_NUM      42
#define Q81_XFI2_HSS_TX_SEG_NUM       43
#define Q81_XFI2_HSS_RX_SEG_NUM       44
#define Q81_XFI2_HSS_PLL_SEG_NUM      45
#define Q81_WQC1_SEG_NUM              46
#define Q81_CQC1_SEG_NUM              47
#define Q81_WQC2_SEG_NUM              48
#define Q81_CQC2_SEG_NUM              49
#define Q81_SEM_REGS_SEG_NUM          50

enum
{
	Q81_PAUSE_SRC_LO               = 0x00000100,
	Q81_PAUSE_SRC_HI               = 0x00000104,
	Q81_GLOBAL_CFG                 = 0x00000108,
	Q81_GLOBAL_CFG_RESET           = (1 << 0),    /*Control*/
	Q81_GLOBAL_CFG_JUMBO           = (1 << 6),    /*Control*/
	Q81_GLOBAL_CFG_TX_STAT_EN      = (1 << 10),   /*Control*/
	Q81_GLOBAL_CFG_RX_STAT_EN      = (1 << 11),   /*Control*/
	Q81_TX_CFG                     = 0x0000010c,
	Q81_TX_CFG_RESET               = (1 << 0),    /*Control*/
	Q81_TX_CFG_EN                  = (1 << 1),    /*Control*/
	Q81_TX_CFG_PREAM               = (1 << 2),    /*Control*/
	Q81_RX_CFG                     = 0x00000110,
	Q81_RX_CFG_RESET               = (1 << 0),    /*Control*/
	Q81_RX_CFG_EN                  = (1 << 1),    /*Control*/
	Q81_RX_CFG_PREAM               = (1 << 2),    /*Control*/
	Q81_FLOW_CTL                   = 0x0000011c,
	Q81_PAUSE_OPCODE               = 0x00000120,
	Q81_PAUSE_TIMER                = 0x00000124,
	Q81_PAUSE_FRM_DEST_LO          = 0x00000128,
	Q81_PAUSE_FRM_DEST_HI          = 0x0000012c,
	Q81_MAC_TX_PARAMS              = 0x00000134,
	Q81_MAC_TX_PARAMS_JUMBO        = (1U << 31),   /*Control*/
	Q81_MAC_TX_PARAMS_SIZE_SHIFT   = 16,          /*Control*/
	Q81_MAC_RX_PARAMS              = 0x00000138,
	Q81_MAC_SYS_INT                = 0x00000144,
	Q81_MAC_SYS_INT_MASK           = 0x00000148,
	Q81_MAC_MGMT_INT               = 0x0000014c,
	Q81_MAC_MGMT_IN_MASK           = 0x00000150,
	Q81_EXT_ARB_MODE               = 0x000001fc,
	Q81_TX_PKTS                    = 0x00000200,
	Q81_TX_PKTS_LO                 = 0x00000204,
	Q81_TX_BYTES                   = 0x00000208,
	Q81_TX_BYTES_LO                = 0x0000020C,
	Q81_TX_MCAST_PKTS              = 0x00000210,
	Q81_TX_MCAST_PKTS_LO           = 0x00000214,
	Q81_TX_BCAST_PKTS              = 0x00000218,
	Q81_TX_BCAST_PKTS_LO           = 0x0000021C,
	Q81_TX_UCAST_PKTS              = 0x00000220,
	Q81_TX_UCAST_PKTS_LO           = 0x00000224,
	Q81_TX_CTL_PKTS                = 0x00000228,
	Q81_TX_CTL_PKTS_LO             = 0x0000022c,
	Q81_TX_PAUSE_PKTS              = 0x00000230,
	Q81_TX_PAUSE_PKTS_LO           = 0x00000234,
	Q81_TX_64_PKT                  = 0x00000238,
	Q81_TX_64_PKT_LO               = 0x0000023c,
	Q81_TX_65_TO_127_PKT           = 0x00000240,
	Q81_TX_65_TO_127_PKT_LO        = 0x00000244,
	Q81_TX_128_TO_255_PKT          = 0x00000248,
	Q81_TX_128_TO_255_PKT_LO       = 0x0000024c,
	Q81_TX_256_511_PKT             = 0x00000250,
	Q81_TX_256_511_PKT_LO          = 0x00000254,
	Q81_TX_512_TO_1023_PKT         = 0x00000258,
	Q81_TX_512_TO_1023_PKT_LO      = 0x0000025c,
	Q81_TX_1024_TO_1518_PKT        = 0x00000260,
	Q81_TX_1024_TO_1518_PKT_LO     = 0x00000264,
	Q81_TX_1519_TO_MAX_PKT         = 0x00000268,
	Q81_TX_1519_TO_MAX_PKT_LO      = 0x0000026c,
	Q81_TX_UNDERSIZE_PKT           = 0x00000270,
	Q81_TX_UNDERSIZE_PKT_LO        = 0x00000274,
	Q81_TX_OVERSIZE_PKT            = 0x00000278,
	Q81_TX_OVERSIZE_PKT_LO         = 0x0000027c,
	Q81_RX_HALF_FULL_DET           = 0x000002a0,
	Q81_TX_HALF_FULL_DET_LO        = 0x000002a4,
	Q81_RX_OVERFLOW_DET            = 0x000002a8,
	Q81_TX_OVERFLOW_DET_LO         = 0x000002ac,
	Q81_RX_HALF_FULL_MASK          = 0x000002b0,
	Q81_TX_HALF_FULL_MASK_LO       = 0x000002b4,
	Q81_RX_OVERFLOW_MASK           = 0x000002b8,
	Q81_TX_OVERFLOW_MASK_LO        = 0x000002bc,
	Q81_STAT_CNT_CTL               = 0x000002c0,
	Q81_STAT_CNT_CTL_CLEAR_TX      = (1 << 0),   /*Control*/
	Q81_STAT_CNT_CTL_CLEAR_RX      = (1 << 1),   /*Control*/
	Q81_AUX_RX_HALF_FULL_DET       = 0x000002d0,
	Q81_AUX_TX_HALF_FULL_DET       = 0x000002d4,
	Q81_AUX_RX_OVERFLOW_DET        = 0x000002d8,
	Q81_AUX_TX_OVERFLOW_DET        = 0x000002dc,
	Q81_AUX_RX_HALF_FULL_MASK      = 0x000002f0,
	Q81_AUX_TX_HALF_FULL_MASK      = 0x000002f4,
	Q81_AUX_RX_OVERFLOW_MASK       = 0x000002f8,
	Q81_AUX_TX_OVERFLOW_MASK       = 0x000002fc,
	Q81_RX_BYTES                   = 0x00000300,
	Q81_RX_BYTES_LO                = 0x00000304,
	Q81_RX_BYTES_OK                = 0x00000308,
	Q81_RX_BYTES_OK_LO             = 0x0000030c,
	Q81_RX_PKTS                    = 0x00000310,
	Q81_RX_PKTS_LO                 = 0x00000314,
	Q81_RX_PKTS_OK                 = 0x00000318,
	Q81_RX_PKTS_OK_LO              = 0x0000031c,
	Q81_RX_BCAST_PKTS              = 0x00000320,
	Q81_RX_BCAST_PKTS_LO           = 0x00000324,
	Q81_RX_MCAST_PKTS              = 0x00000328,
	Q81_RX_MCAST_PKTS_LO           = 0x0000032c,
	Q81_RX_UCAST_PKTS              = 0x00000330,
	Q81_RX_UCAST_PKTS_LO           = 0x00000334,
	Q81_RX_UNDERSIZE_PKTS          = 0x00000338,
	Q81_RX_UNDERSIZE_PKTS_LO       = 0x0000033c,
	Q81_RX_OVERSIZE_PKTS           = 0x00000340,
	Q81_RX_OVERSIZE_PKTS_LO        = 0x00000344,
	Q81_RX_JABBER_PKTS             = 0x00000348,
	Q81_RX_JABBER_PKTS_LO          = 0x0000034c,
	Q81_RX_UNDERSIZE_FCERR_PKTS    = 0x00000350,
	Q81_RX_UNDERSIZE_FCERR_PKTS_LO = 0x00000354,
	Q81_RX_DROP_EVENTS             = 0x00000358,
	Q81_RX_DROP_EVENTS_LO          = 0x0000035c,
	Q81_RX_FCERR_PKTS              = 0x00000360,
	Q81_RX_FCERR_PKTS_LO           = 0x00000364,
	Q81_RX_ALIGN_ERR               = 0x00000368,
	Q81_RX_ALIGN_ERR_LO            = 0x0000036c,
	Q81_RX_SYMBOL_ERR              = 0x00000370,
	Q81_RX_SYMBOL_ERR_LO           = 0x00000374,
	Q81_RX_MAC_ERR                 = 0x00000378,
	Q81_RX_MAC_ERR_LO              = 0x0000037c,
	Q81_RX_CTL_PKTS                = 0x00000380,
	Q81_RX_CTL_PKTS_LO             = 0x00000384,
	Q81_RX_PAUSE_PKTS              = 0x00000388,
	Q81_RX_PAUSE_PKTS_LO           = 0x0000038c,
	Q81_RX_64_PKTS                 = 0x00000390,
	Q81_RX_64_PKTS_LO              = 0x00000394,
	Q81_RX_65_TO_127_PKTS          = 0x00000398,
	Q81_RX_65_TO_127_PKTS_LO       = 0x0000039c,
	Q81_RX_128_255_PKTS            = 0x000003a0,
	Q81_RX_128_255_PKTS_LO         = 0x000003a4,
	Q81_RX_256_511_PKTS            = 0x000003a8,
	Q81_RX_256_511_PKTS_LO         = 0x000003ac,
	Q81_RX_512_TO_1023_PKTS        = 0x000003b0,
	Q81_RX_512_TO_1023_PKTS_LO     = 0x000003b4,
	Q81_RX_1024_TO_1518_PKTS       = 0x000003b8,
	Q81_RX_1024_TO_1518_PKTS_LO    = 0x000003bc,
	Q81_RX_1519_TO_MAX_PKTS        = 0x000003c0,
	Q81_RX_1519_TO_MAX_PKTS_LO     = 0x000003c4,
	Q81_RX_LEN_ERR_PKTS            = 0x000003c8,
	Q81_RX_LEN_ERR_PKTS_LO         = 0x000003cc,
	Q81_MDIO_TX_DATA               = 0x00000400,
	Q81_MDIO_RX_DATA               = 0x00000410,
	Q81_MDIO_CMD                   = 0x00000420,
	Q81_MDIO_PHY_ADDR              = 0x00000430,
	Q81_MDIO_PORT                  = 0x00000440,
	Q81_MDIO_STATUS                = 0x00000450,
	Q81_TX_CBFC_PAUSE_FRAMES0      = 0x00000500,
	Q81_TX_CBFC_PAUSE_FRAMES0_LO   = 0x00000504,
	Q81_TX_CBFC_PAUSE_FRAMES1      = 0x00000508,
	Q81_TX_CBFC_PAUSE_FRAMES1_LO   = 0x0000050C,
	Q81_TX_CBFC_PAUSE_FRAMES2      = 0x00000510,
	Q81_TX_CBFC_PAUSE_FRAMES2_LO   = 0x00000514,
	Q81_TX_CBFC_PAUSE_FRAMES3      = 0x00000518,
	Q81_TX_CBFC_PAUSE_FRAMES3_LO   = 0x0000051C,
	Q81_TX_CBFC_PAUSE_FRAMES4      = 0x00000520,
	Q81_TX_CBFC_PAUSE_FRAMES4_LO   = 0x00000524,
	Q81_TX_CBFC_PAUSE_FRAMES5      = 0x00000528,
	Q81_TX_CBFC_PAUSE_FRAMES5_LO   = 0x0000052C,
	Q81_TX_CBFC_PAUSE_FRAMES6      = 0x00000530,
	Q81_TX_CBFC_PAUSE_FRAMES6_LO   = 0x00000534,
	Q81_TX_CBFC_PAUSE_FRAMES7      = 0x00000538,
	Q81_TX_CBFC_PAUSE_FRAMES7_LO   = 0x0000053C,
	Q81_TX_FCOE_PKTS               = 0x00000540,
	Q81_TX_FCOE_PKTS_LO            = 0x00000544,
	Q81_TX_MGMT_PKTS               = 0x00000548,
	Q81_TX_MGMT_PKTS_LO            = 0x0000054C,
	Q81_RX_CBFC_PAUSE_FRAMES0      = 0x00000568,
	Q81_RX_CBFC_PAUSE_FRAMES0_LO   = 0x0000056C,
	Q81_RX_CBFC_PAUSE_FRAMES1      = 0x00000570,
	Q81_RX_CBFC_PAUSE_FRAMES1_LO   = 0x00000574,
	Q81_RX_CBFC_PAUSE_FRAMES2      = 0x00000578,
	Q81_RX_CBFC_PAUSE_FRAMES2_LO   = 0x0000057C,
	Q81_RX_CBFC_PAUSE_FRAMES3      = 0x00000580,
	Q81_RX_CBFC_PAUSE_FRAMES3_LO   = 0x00000584,
	Q81_RX_CBFC_PAUSE_FRAMES4      = 0x00000588,
	Q81_RX_CBFC_PAUSE_FRAMES4_LO   = 0x0000058C,
	Q81_RX_CBFC_PAUSE_FRAMES5      = 0x00000590,
	Q81_RX_CBFC_PAUSE_FRAMES5_LO   = 0x00000594,
	Q81_RX_CBFC_PAUSE_FRAMES6      = 0x00000598,
	Q81_RX_CBFC_PAUSE_FRAMES6_LO   = 0x0000059C,
	Q81_RX_CBFC_PAUSE_FRAMES7      = 0x000005A0,
	Q81_RX_CBFC_PAUSE_FRAMES7_LO   = 0x000005A4,
	Q81_RX_FCOE_PKTS               = 0x000005A8,
	Q81_RX_FCOE_PKTS_LO            = 0x000005AC,
	Q81_RX_MGMT_PKTS               = 0x000005B0,
	Q81_RX_MGMT_PKTS_LO            = 0x000005B4,
	Q81_RX_NIC_FIFO_DROP           = 0x000005B8,
	Q81_RX_NIC_FIFO_DROP_LO        = 0x000005BC,
	Q81_RX_FCOE_FIFO_DROP          = 0x000005C0,
	Q81_RX_FCOE_FIFO_DROP_LO       = 0x000005C4,
	Q81_RX_MGMT_FIFO_DROP          = 0x000005C8,
	Q81_RX_MGMT_FIFO_DROP_LO       = 0x000005CC,
	Q81_RX_PKTS_PRIORITY0          = 0x00000600,
	Q81_RX_PKTS_PRIORITY0_LO       = 0x00000604,
	Q81_RX_PKTS_PRIORITY1          = 0x00000608,
	Q81_RX_PKTS_PRIORITY1_LO       = 0x0000060C,
	Q81_RX_PKTS_PRIORITY2          = 0x00000610,
	Q81_RX_PKTS_PRIORITY2_LO       = 0x00000614,
	Q81_RX_PKTS_PRIORITY3          = 0x00000618,
	Q81_RX_PKTS_PRIORITY3_LO       = 0x0000061C,
	Q81_RX_PKTS_PRIORITY4          = 0x00000620,
	Q81_RX_PKTS_PRIORITY4_LO       = 0x00000624,
	Q81_RX_PKTS_PRIORITY5          = 0x00000628,
	Q81_RX_PKTS_PRIORITY5_LO       = 0x0000062C,
	Q81_RX_PKTS_PRIORITY6          = 0x00000630,
	Q81_RX_PKTS_PRIORITY6_LO       = 0x00000634,
	Q81_RX_PKTS_PRIORITY7          = 0x00000638,
	Q81_RX_PKTS_PRIORITY7_LO       = 0x0000063C,
	Q81_RX_OCTETS_PRIORITY0        = 0x00000640,
	Q81_RX_OCTETS_PRIORITY0_LO     = 0x00000644,
	Q81_RX_OCTETS_PRIORITY1        = 0x00000648,
	Q81_RX_OCTETS_PRIORITY1_LO     = 0x0000064C,
	Q81_RX_OCTETS_PRIORITY2        = 0x00000650,
	Q81_RX_OCTETS_PRIORITY2_LO     = 0x00000654,
	Q81_RX_OCTETS_PRIORITY3        = 0x00000658,
	Q81_RX_OCTETS_PRIORITY3_LO     = 0x0000065C,
	Q81_RX_OCTETS_PRIORITY4        = 0x00000660,
	Q81_RX_OCTETS_PRIORITY4_LO     = 0x00000664,
	Q81_RX_OCTETS_PRIORITY5        = 0x00000668,
	Q81_RX_OCTETS_PRIORITY5_LO     = 0x0000066C,
	Q81_RX_OCTETS_PRIORITY6        = 0x00000670,
	Q81_RX_OCTETS_PRIORITY6_LO     = 0x00000674,
	Q81_RX_OCTETS_PRIORITY7        = 0x00000678,
	Q81_RX_OCTETS_PRIORITY7_LO     = 0x0000067C,
	Q81_TX_PKTS_PRIORITY0          = 0x00000680,
	Q81_TX_PKTS_PRIORITY0_LO       = 0x00000684,
	Q81_TX_PKTS_PRIORITY1          = 0x00000688,
	Q81_TX_PKTS_PRIORITY1_LO       = 0x0000068C,
	Q81_TX_PKTS_PRIORITY2          = 0x00000690,
	Q81_TX_PKTS_PRIORITY2_LO       = 0x00000694,
	Q81_TX_PKTS_PRIORITY3          = 0x00000698,
	Q81_TX_PKTS_PRIORITY3_LO       = 0x0000069C,
	Q81_TX_PKTS_PRIORITY4          = 0x000006A0,
	Q81_TX_PKTS_PRIORITY4_LO       = 0x000006A4,
	Q81_TX_PKTS_PRIORITY5          = 0x000006A8,
	Q81_TX_PKTS_PRIORITY5_LO       = 0x000006AC,
	Q81_TX_PKTS_PRIORITY6          = 0x000006B0,
	Q81_TX_PKTS_PRIORITY6_LO       = 0x000006B4,
	Q81_TX_PKTS_PRIORITY7          = 0x000006B8,
	Q81_TX_PKTS_PRIORITY7_LO       = 0x000006BC,
	Q81_TX_OCTETS_PRIORITY0        = 0x000006C0,
	Q81_TX_OCTETS_PRIORITY0_LO     = 0x000006C4,
	Q81_TX_OCTETS_PRIORITY1        = 0x000006C8,
	Q81_TX_OCTETS_PRIORITY1_LO     = 0x000006CC,
	Q81_TX_OCTETS_PRIORITY2        = 0x000006D0,
	Q81_TX_OCTETS_PRIORITY2_LO     = 0x000006D4,
	Q81_TX_OCTETS_PRIORITY3        = 0x000006D8,
	Q81_TX_OCTETS_PRIORITY3_LO     = 0x000006DC,
	Q81_TX_OCTETS_PRIORITY4        = 0x000006E0,
	Q81_TX_OCTETS_PRIORITY4_LO     = 0x000006E4,
	Q81_TX_OCTETS_PRIORITY5        = 0x000006E8,
	Q81_TX_OCTETS_PRIORITY5_LO     = 0x000006EC,
	Q81_TX_OCTETS_PRIORITY6        = 0x000006F0,
	Q81_TX_OCTETS_PRIORITY6_LO     = 0x000006F4,
	Q81_TX_OCTETS_PRIORITY7        = 0x000006F8,
	Q81_TX_OCTETS_PRIORITY7_LO     = 0x000006FC,
	Q81_RX_DISCARD_PRIORITY0       = 0x00000700,
	Q81_RX_DISCARD_PRIORITY0_LO    = 0x00000704,
	Q81_RX_DISCARD_PRIORITY1       = 0x00000708,
	Q81_RX_DISCARD_PRIORITY1_LO    = 0x0000070C,
	Q81_RX_DISCARD_PRIORITY2       = 0x00000710,
	Q81_RX_DISCARD_PRIORITY2_LO    = 0x00000714,
	Q81_RX_DISCARD_PRIORITY3       = 0x00000718,
	Q81_RX_DISCARD_PRIORITY3_LO    = 0x0000071C,
	Q81_RX_DISCARD_PRIORITY4       = 0x00000720,
	Q81_RX_DISCARD_PRIORITY4_LO    = 0x00000724,
	Q81_RX_DISCARD_PRIORITY5       = 0x00000728,
	Q81_RX_DISCARD_PRIORITY5_LO    = 0x0000072C,
	Q81_RX_DISCARD_PRIORITY6       = 0x00000730,
	Q81_RX_DISCARD_PRIORITY6_LO    = 0x00000734,
	Q81_RX_DISCARD_PRIORITY7       = 0x00000738,
	Q81_RX_DISCARD_PRIORITY7_LO    = 0x0000073C
};

static void
qls_mpid_seg_hdr(qls_mpid_seg_hdr_t *seg_hdr, uint32_t seg_num,
	uint32_t seg_size, unsigned char *desc)
{
	memset(seg_hdr, 0, sizeof(qls_mpid_seg_hdr_t));

	seg_hdr->cookie = Q81_MPID_COOKIE;
	seg_hdr->seg_num = seg_num;
	seg_hdr->seg_size = seg_size;

	memcpy(seg_hdr->desc, desc, (sizeof(seg_hdr->desc))-1);

	return;
}

static int
qls_wait_reg_rdy(qla_host_t *ha , uint32_t reg, uint32_t bit, uint32_t err_bit)
{
	uint32_t data;
	int count = 10;

	while (count) {
		data = READ_REG32(ha, reg);

		if (data & err_bit)
			return (-1);
		else if (data & bit)
			return (0);

		qls_mdelay(__func__, 10);
		count--;
	}
	return (-1);
}

static int
qls_rd_mpi_reg(qla_host_t *ha, uint32_t reg, uint32_t *data)
{
        int ret;

        ret = qls_wait_reg_rdy(ha, Q81_CTL_PROC_ADDR, Q81_CTL_PROC_ADDR_RDY,
			Q81_CTL_PROC_ADDR_ERR);

        if (ret)
                goto exit_qls_rd_mpi_reg;

        WRITE_REG32(ha, Q81_CTL_PROC_ADDR, reg | Q81_CTL_PROC_ADDR_READ);

        ret = qls_wait_reg_rdy(ha, Q81_CTL_PROC_ADDR, Q81_CTL_PROC_ADDR_RDY,
			Q81_CTL_PROC_ADDR_ERR);

        if (ret)
                goto exit_qls_rd_mpi_reg;

        *data = READ_REG32(ha, Q81_CTL_PROC_DATA);

exit_qls_rd_mpi_reg:
        return (ret);
}

static int
qls_wr_mpi_reg(qla_host_t *ha, uint32_t reg, uint32_t data)
{
        int ret = 0;

        ret = qls_wait_reg_rdy(ha, Q81_CTL_PROC_ADDR, Q81_CTL_PROC_ADDR_RDY,
			Q81_CTL_PROC_ADDR_ERR);
        if (ret)
                goto exit_qls_wr_mpi_reg;

        WRITE_REG32(ha, Q81_CTL_PROC_DATA, data);

        WRITE_REG32(ha, Q81_CTL_PROC_ADDR, reg);

        ret = qls_wait_reg_rdy(ha, Q81_CTL_PROC_ADDR, Q81_CTL_PROC_ADDR_RDY,
			Q81_CTL_PROC_ADDR_ERR);
exit_qls_wr_mpi_reg:
        return (ret);
}

#define Q81_TEST_LOGIC_FUNC_PORT_CONFIG 0x1002
#define Q81_INVALID_NUM		0xFFFFFFFF

#define Q81_NIC1_FUNC_ENABLE	0x00000001
#define Q81_NIC1_FUNC_MASK	0x0000000e
#define Q81_NIC1_FUNC_SHIFT	1
#define Q81_NIC2_FUNC_ENABLE	0x00000010
#define Q81_NIC2_FUNC_MASK	0x000000e0
#define Q81_NIC2_FUNC_SHIFT	5
#define Q81_FUNCTION_SHIFT	6

static uint32_t
qls_get_other_fnum(qla_host_t *ha)
{
	int		ret;
	uint32_t	o_func;
	uint32_t	test_logic;
	uint32_t	nic1_fnum = Q81_INVALID_NUM;
	uint32_t	nic2_fnum = Q81_INVALID_NUM;

	ret = qls_rd_mpi_reg(ha, Q81_TEST_LOGIC_FUNC_PORT_CONFIG, &test_logic);
	if (ret)
		return(Q81_INVALID_NUM);

	if (test_logic & Q81_NIC1_FUNC_ENABLE)
		nic1_fnum = (test_logic & Q81_NIC1_FUNC_MASK) >>
					Q81_NIC1_FUNC_SHIFT;

	if (test_logic & Q81_NIC2_FUNC_ENABLE)
		nic2_fnum = (test_logic & Q81_NIC2_FUNC_MASK) >>
					Q81_NIC2_FUNC_SHIFT;

	if (ha->pci_func == 0)
		o_func = nic2_fnum;
	else
		o_func = nic1_fnum;

	return(o_func);
}

static uint32_t
qls_rd_ofunc_reg(qla_host_t *ha, uint32_t reg)
{
	uint32_t	ofunc;
	uint32_t	data;
	int		ret = 0;

	ofunc = qls_get_other_fnum(ha);

	if (ofunc == Q81_INVALID_NUM)
		return(Q81_INVALID_NUM);

	reg = Q81_CTL_PROC_ADDR_REG_BLOCK | (ofunc << Q81_FUNCTION_SHIFT) | reg;

	ret = qls_rd_mpi_reg(ha, reg, &data);

	if (ret != 0)
		return(Q81_INVALID_NUM);

	return(data);
}

static void
qls_wr_ofunc_reg(qla_host_t *ha, uint32_t reg, uint32_t value)
{
	uint32_t ofunc;

	ofunc = qls_get_other_fnum(ha);

	if (ofunc == Q81_INVALID_NUM)
		return;

	reg = Q81_CTL_PROC_ADDR_REG_BLOCK | (ofunc << Q81_FUNCTION_SHIFT) | reg;

	qls_wr_mpi_reg(ha, reg, value);

	return;
}

static int
qls_wait_ofunc_reg_rdy(qla_host_t *ha , uint32_t reg, uint32_t bit,
	uint32_t err_bit)
{
        uint32_t data;
        int count = 10;

        while (count) {
                data = qls_rd_ofunc_reg(ha, reg);

                if (data & err_bit)
                        return (-1);
                else if (data & bit)
                        return (0);

                qls_mdelay(__func__, 10);
                count--;
        }
        return (-1);
}

#define Q81_XG_SERDES_ADDR_RDY	BIT_31
#define Q81_XG_SERDES_ADDR_READ	BIT_30

static int
qls_rd_ofunc_serdes_reg(qla_host_t *ha, uint32_t reg, uint32_t *data)
{
	int ret;

	/* wait for reg to come ready */
	ret = qls_wait_ofunc_reg_rdy(ha, (Q81_CTL_XG_SERDES_ADDR >> 2),
			Q81_XG_SERDES_ADDR_RDY, 0);
	if (ret)
		goto exit_qls_rd_ofunc_serdes_reg;

	/* set up for reg read */
	qls_wr_ofunc_reg(ha, (Q81_CTL_XG_SERDES_ADDR >> 2),
		(reg | Q81_XG_SERDES_ADDR_READ));

	/* wait for reg to come ready */
	ret = qls_wait_ofunc_reg_rdy(ha, (Q81_CTL_XG_SERDES_ADDR >> 2),
			Q81_XG_SERDES_ADDR_RDY, 0);
	if (ret)
		goto exit_qls_rd_ofunc_serdes_reg;

	/* get the data */
	*data = qls_rd_ofunc_reg(ha, (Q81_CTL_XG_SERDES_DATA >> 2));

exit_qls_rd_ofunc_serdes_reg:
	return ret;
}

#define Q81_XGMAC_ADDR_RDY	BIT_31
#define Q81_XGMAC_ADDR_R	BIT_30
#define Q81_XGMAC_ADDR_XME	BIT_29

static int
qls_rd_ofunc_xgmac_reg(qla_host_t *ha, uint32_t reg, uint32_t *data)
{
	int ret = 0;

	ret = qls_wait_ofunc_reg_rdy(ha, (Q81_CTL_XGMAC_ADDR >> 2),
			Q81_XGMAC_ADDR_RDY, Q81_XGMAC_ADDR_XME);

	if (ret)
		goto exit_qls_rd_ofunc_xgmac_reg;

	qls_wr_ofunc_reg(ha, (Q81_XGMAC_ADDR_RDY >> 2),
		(reg | Q81_XGMAC_ADDR_R));

	ret = qls_wait_ofunc_reg_rdy(ha, (Q81_CTL_XGMAC_ADDR >> 2),
			Q81_XGMAC_ADDR_RDY, Q81_XGMAC_ADDR_XME);
	if (ret)
		goto exit_qls_rd_ofunc_xgmac_reg;

	*data = qls_rd_ofunc_reg(ha, Q81_CTL_XGMAC_DATA);

exit_qls_rd_ofunc_xgmac_reg:
	return ret;
}

static int
qls_rd_serdes_reg(qla_host_t *ha, uint32_t reg, uint32_t *data)
{
	int ret;

	ret = qls_wait_reg_rdy(ha, Q81_CTL_XG_SERDES_ADDR,
			Q81_XG_SERDES_ADDR_RDY, 0);

	if (ret)
		goto exit_qls_rd_serdes_reg;

	WRITE_REG32(ha, Q81_CTL_XG_SERDES_ADDR, \
		(reg | Q81_XG_SERDES_ADDR_READ));

	ret = qls_wait_reg_rdy(ha, Q81_CTL_XG_SERDES_ADDR,
			Q81_XG_SERDES_ADDR_RDY, 0);

	if (ret)
		goto exit_qls_rd_serdes_reg;

	*data = READ_REG32(ha, Q81_CTL_XG_SERDES_DATA);

exit_qls_rd_serdes_reg:

	return ret;
}

static void
qls_get_both_serdes(qla_host_t *ha, uint32_t addr, uint32_t *dptr,
	uint32_t *ind_ptr, uint32_t dvalid, uint32_t ind_valid)
{
	int ret = -1;

	if (dvalid)
		ret = qls_rd_serdes_reg(ha, addr, dptr);

	if (ret)
		*dptr = Q81_BAD_DATA;

	ret = -1;

	if(ind_valid)
		ret = qls_rd_ofunc_serdes_reg(ha, addr, ind_ptr);

	if (ret)
		*ind_ptr = Q81_BAD_DATA;
}

#define Q81_XFI1_POWERED_UP 0x00000005
#define Q81_XFI2_POWERED_UP 0x0000000A
#define Q81_XAUI_POWERED_UP 0x00000001

static int
qls_rd_serdes_regs(qla_host_t *ha, qls_mpi_coredump_t *mpi_dump)
{
	int ret;
	uint32_t xfi_d_valid, xfi_ind_valid, xaui_d_valid, xaui_ind_valid;
	uint32_t temp, xaui_reg, i;
	uint32_t *dptr, *indptr;

	xfi_d_valid = xfi_ind_valid = xaui_d_valid = xaui_ind_valid = 0;

	xaui_reg = 0x800;

	ret = qls_rd_ofunc_serdes_reg(ha, xaui_reg, &temp);
	if (ret)
		temp = 0;

	if ((temp & Q81_XAUI_POWERED_UP) == Q81_XAUI_POWERED_UP)
		xaui_ind_valid = 1;

	ret = qls_rd_serdes_reg(ha, xaui_reg, &temp);
	if (ret)
		temp = 0;

	if ((temp & Q81_XAUI_POWERED_UP) == Q81_XAUI_POWERED_UP)
		xaui_d_valid = 1;

	ret = qls_rd_serdes_reg(ha, 0x1E06, &temp);
	if (ret)
		temp = 0;

	if ((temp & Q81_XFI1_POWERED_UP) == Q81_XFI1_POWERED_UP) {
		if (ha->pci_func & 1)
         		xfi_ind_valid = 1; /* NIC 2, so the indirect
						 (NIC1) xfi is up*/
		else
			xfi_d_valid = 1;
	}

	if((temp & Q81_XFI2_POWERED_UP) == Q81_XFI2_POWERED_UP) {
		if(ha->pci_func & 1)
			xfi_d_valid = 1; /* NIC 2, so the indirect (NIC1)
						xfi is up */
		else
			xfi_ind_valid = 1;
	}

	if (ha->pci_func & 1) {
		dptr = (uint32_t *)(&mpi_dump->serdes2_xaui_an);
		indptr = (uint32_t *)(&mpi_dump->serdes1_xaui_an);
	} else {
		dptr = (uint32_t *)(&mpi_dump->serdes1_xaui_an);
		indptr = (uint32_t *)(&mpi_dump->serdes2_xaui_an);
	}

	for (i = 0; i <= 0x000000034; i += 4, dptr ++, indptr ++) {
		qls_get_both_serdes(ha, i, dptr, indptr,
			xaui_d_valid, xaui_ind_valid);
	}

	if (ha->pci_func & 1) {
		dptr = (uint32_t *)(&mpi_dump->serdes2_xaui_hss_pcs);
		indptr = (uint32_t *)(&mpi_dump->serdes1_xaui_hss_pcs);
	} else {
		dptr = (uint32_t *)(&mpi_dump->serdes1_xaui_hss_pcs);
		indptr = (uint32_t *)(&mpi_dump->serdes2_xaui_hss_pcs);
	}

	for (i = 0x800; i <= 0x880; i += 4, dptr ++, indptr ++) {
		qls_get_both_serdes(ha, i, dptr, indptr,
			xaui_d_valid, xaui_ind_valid);
	}

	if (ha->pci_func & 1) {
		dptr = (uint32_t *)(&mpi_dump->serdes2_xfi_an);
		indptr = (uint32_t *)(&mpi_dump->serdes1_xfi_an);
	} else {
		dptr = (uint32_t *)(&mpi_dump->serdes1_xfi_an);
		indptr = (uint32_t *)(&mpi_dump->serdes2_xfi_an);
	}

	for (i = 0x1000; i <= 0x1034; i += 4, dptr ++, indptr ++) {
		qls_get_both_serdes(ha, i, dptr, indptr,
			xfi_d_valid, xfi_ind_valid);
	}

	if (ha->pci_func & 1) {
		dptr = (uint32_t *)(&mpi_dump->serdes2_xfi_train);
		indptr = (uint32_t *)(&mpi_dump->serdes1_xfi_train);
	} else {
		dptr = (uint32_t *)(&mpi_dump->serdes1_xfi_train);
		indptr = (uint32_t *)(&mpi_dump->serdes2_xfi_train);
	}

	for (i = 0x1050; i <= 0x107c; i += 4, dptr ++, indptr ++) {
		qls_get_both_serdes(ha, i, dptr, indptr,
			xfi_d_valid, xfi_ind_valid);
	}

	if (ha->pci_func & 1) {
		dptr = (uint32_t *)(&mpi_dump->serdes2_xfi_hss_pcs);
		indptr = (uint32_t *)(&mpi_dump->serdes1_xfi_hss_pcs);
	} else {
		dptr = (uint32_t *)(&mpi_dump->serdes1_xfi_hss_pcs);
		indptr = (uint32_t *)(&mpi_dump->serdes2_xfi_hss_pcs);
	}

	for (i = 0x1800; i <= 0x1838; i += 4, dptr++, indptr ++) {
		qls_get_both_serdes(ha, i, dptr, indptr,
			xfi_d_valid, xfi_ind_valid);
	}

	if (ha->pci_func & 1) {
		dptr = (uint32_t *)(&mpi_dump->serdes2_xfi_hss_tx);
		indptr = (uint32_t *)(&mpi_dump->serdes1_xfi_hss_tx);
	} else {
		dptr = (uint32_t *)(&mpi_dump->serdes1_xfi_hss_tx);
		indptr = (uint32_t *)(&mpi_dump->serdes2_xfi_hss_tx);
	}

	for (i = 0x1c00; i <= 0x1c1f; i++, dptr ++, indptr ++) {
		qls_get_both_serdes(ha, i, dptr, indptr,
			xfi_d_valid, xfi_ind_valid);
	}

	if (ha->pci_func & 1) {
		dptr = (uint32_t *)(&mpi_dump->serdes2_xfi_hss_rx);
		indptr = (uint32_t *)(&mpi_dump->serdes1_xfi_hss_rx);
	} else {
		dptr = (uint32_t *)(&mpi_dump->serdes1_xfi_hss_rx);
		indptr = (uint32_t *)(&mpi_dump->serdes2_xfi_hss_rx);
	}

	for (i = 0x1c40; i <= 0x1c5f; i++, dptr ++, indptr ++) {
		qls_get_both_serdes(ha, i, dptr, indptr,
			xfi_d_valid, xfi_ind_valid);
	}

	if (ha->pci_func & 1) {
		dptr = (uint32_t *)(&mpi_dump->serdes2_xfi_hss_pll);
		indptr = (uint32_t *)(&mpi_dump->serdes1_xfi_hss_pll);
	} else {
		dptr = (uint32_t *)(&mpi_dump->serdes1_xfi_hss_pll);
		indptr = (uint32_t *)(&mpi_dump->serdes2_xfi_hss_pll);
	}

	for (i = 0x1e00; i <= 0x1e1f; i++, dptr ++, indptr ++) {
		qls_get_both_serdes(ha, i, dptr, indptr,
			xfi_d_valid, xfi_ind_valid);
	}

	return(0);
}

static int
qls_unpause_mpi_risc(qla_host_t *ha)
{
	uint32_t data;

	data = READ_REG32(ha, Q81_CTL_HOST_CMD_STATUS);

	if (!(data & Q81_CTL_HCS_RISC_PAUSED))
		return -1;

	WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS, \
		Q81_CTL_HCS_CMD_CLR_RISC_PAUSE);

	return 0;
}

static int
qls_pause_mpi_risc(qla_host_t *ha)
{
	uint32_t data;
	int count = 10;

	WRITE_REG32(ha, Q81_CTL_HOST_CMD_STATUS, \
		Q81_CTL_HCS_CMD_SET_RISC_PAUSE);

	do {
		data = READ_REG32(ha, Q81_CTL_HOST_CMD_STATUS);

		if (data & Q81_CTL_HCS_RISC_PAUSED)
			break;

		qls_mdelay(__func__, 10);

		count--;

	} while (count);

	return ((count == 0) ? -1 : 0);
}

static void
qls_get_intr_states(qla_host_t *ha, uint32_t *buf)
{
	int i;

	for (i = 0; i < MAX_RX_RINGS; i++, buf++) {
		WRITE_REG32(ha, Q81_CTL_INTR_ENABLE, (0x037f0300 + i));

		*buf = READ_REG32(ha, Q81_CTL_INTR_ENABLE);
	}
}

static int
qls_rd_xgmac_reg(qla_host_t *ha, uint32_t reg, uint32_t*data)
{
	int ret = 0;

	ret = qls_wait_reg_rdy(ha, Q81_CTL_XGMAC_ADDR, Q81_XGMAC_ADDR_RDY,
			Q81_XGMAC_ADDR_XME);
	if (ret)
		goto exit_qls_rd_xgmac_reg;

	WRITE_REG32(ha, Q81_CTL_XGMAC_ADDR, (reg | Q81_XGMAC_ADDR_R));

	ret = qls_wait_reg_rdy(ha, Q81_CTL_XGMAC_ADDR, Q81_XGMAC_ADDR_RDY,
			Q81_XGMAC_ADDR_XME);
	if (ret)
		goto exit_qls_rd_xgmac_reg;

	*data = READ_REG32(ha, Q81_CTL_XGMAC_DATA);

exit_qls_rd_xgmac_reg:
	return ret;
}

static int
qls_rd_xgmac_regs(qla_host_t *ha, uint32_t *buf, uint32_t o_func)
{
	int ret = 0;
	int i;

	for (i = 0; i < Q81_XGMAC_REGISTER_END; i += 4, buf ++) {
		switch (i) {
		case  Q81_PAUSE_SRC_LO               :
		case  Q81_PAUSE_SRC_HI               :
		case  Q81_GLOBAL_CFG                 :
		case  Q81_TX_CFG                     :
		case  Q81_RX_CFG                     :
		case  Q81_FLOW_CTL                   :
		case  Q81_PAUSE_OPCODE               :
		case  Q81_PAUSE_TIMER                :
		case  Q81_PAUSE_FRM_DEST_LO          :
		case  Q81_PAUSE_FRM_DEST_HI          :
		case  Q81_MAC_TX_PARAMS              :
		case  Q81_MAC_RX_PARAMS              :
		case  Q81_MAC_SYS_INT                :
		case  Q81_MAC_SYS_INT_MASK           :
		case  Q81_MAC_MGMT_INT               :
		case  Q81_MAC_MGMT_IN_MASK           :
		case  Q81_EXT_ARB_MODE               :
		case  Q81_TX_PKTS                    :
		case  Q81_TX_PKTS_LO                 :
		case  Q81_TX_BYTES                   :
		case  Q81_TX_BYTES_LO                :
		case  Q81_TX_MCAST_PKTS              :
		case  Q81_TX_MCAST_PKTS_LO           :
		case  Q81_TX_BCAST_PKTS              :
		case  Q81_TX_BCAST_PKTS_LO           :
		case  Q81_TX_UCAST_PKTS              :
		case  Q81_TX_UCAST_PKTS_LO           :
		case  Q81_TX_CTL_PKTS                :
		case  Q81_TX_CTL_PKTS_LO             :
		case  Q81_TX_PAUSE_PKTS              :
		case  Q81_TX_PAUSE_PKTS_LO           :
		case  Q81_TX_64_PKT                  :
		case  Q81_TX_64_PKT_LO               :
		case  Q81_TX_65_TO_127_PKT           :
		case  Q81_TX_65_TO_127_PKT_LO        :
		case  Q81_TX_128_TO_255_PKT          :
		case  Q81_TX_128_TO_255_PKT_LO       :
		case  Q81_TX_256_511_PKT             :
		case  Q81_TX_256_511_PKT_LO          :
		case  Q81_TX_512_TO_1023_PKT         :
		case  Q81_TX_512_TO_1023_PKT_LO      :
		case  Q81_TX_1024_TO_1518_PKT        :
		case  Q81_TX_1024_TO_1518_PKT_LO     :
		case  Q81_TX_1519_TO_MAX_PKT         :
		case  Q81_TX_1519_TO_MAX_PKT_LO      :
		case  Q81_TX_UNDERSIZE_PKT           :
		case  Q81_TX_UNDERSIZE_PKT_LO        :
		case  Q81_TX_OVERSIZE_PKT            :
		case  Q81_TX_OVERSIZE_PKT_LO         :
		case  Q81_RX_HALF_FULL_DET           :
		case  Q81_TX_HALF_FULL_DET_LO        :
		case  Q81_RX_OVERFLOW_DET            :
		case  Q81_TX_OVERFLOW_DET_LO         :
		case  Q81_RX_HALF_FULL_MASK          :
		case  Q81_TX_HALF_FULL_MASK_LO       :
		case  Q81_RX_OVERFLOW_MASK           :
		case  Q81_TX_OVERFLOW_MASK_LO        :
		case  Q81_STAT_CNT_CTL               :
		case  Q81_AUX_RX_HALF_FULL_DET       :
		case  Q81_AUX_TX_HALF_FULL_DET       :
		case  Q81_AUX_RX_OVERFLOW_DET        :
		case  Q81_AUX_TX_OVERFLOW_DET        :
		case  Q81_AUX_RX_HALF_FULL_MASK      :
		case  Q81_AUX_TX_HALF_FULL_MASK      :
		case  Q81_AUX_RX_OVERFLOW_MASK       :
		case  Q81_AUX_TX_OVERFLOW_MASK       :
		case  Q81_RX_BYTES                   :
		case  Q81_RX_BYTES_LO                :
		case  Q81_RX_BYTES_OK                :
		case  Q81_RX_BYTES_OK_LO             :
		case  Q81_RX_PKTS                    :
		case  Q81_RX_PKTS_LO                 :
		case  Q81_RX_PKTS_OK                 :
		case  Q81_RX_PKTS_OK_LO              :
		case  Q81_RX_BCAST_PKTS              :
		case  Q81_RX_BCAST_PKTS_LO           :
		case  Q81_RX_MCAST_PKTS              :
		case  Q81_RX_MCAST_PKTS_LO           :
		case  Q81_RX_UCAST_PKTS              :
		case  Q81_RX_UCAST_PKTS_LO           :
		case  Q81_RX_UNDERSIZE_PKTS          :
		case  Q81_RX_UNDERSIZE_PKTS_LO       :
		case  Q81_RX_OVERSIZE_PKTS           :
		case  Q81_RX_OVERSIZE_PKTS_LO        :
		case  Q81_RX_JABBER_PKTS             :
		case  Q81_RX_JABBER_PKTS_LO          :
		case  Q81_RX_UNDERSIZE_FCERR_PKTS    :
		case  Q81_RX_UNDERSIZE_FCERR_PKTS_LO :
		case  Q81_RX_DROP_EVENTS             :
		case  Q81_RX_DROP_EVENTS_LO          :
		case  Q81_RX_FCERR_PKTS              :
		case  Q81_RX_FCERR_PKTS_LO           :
		case  Q81_RX_ALIGN_ERR               :
		case  Q81_RX_ALIGN_ERR_LO            :
		case  Q81_RX_SYMBOL_ERR              :
		case  Q81_RX_SYMBOL_ERR_LO           :
		case  Q81_RX_MAC_ERR                 :
		case  Q81_RX_MAC_ERR_LO              :
		case  Q81_RX_CTL_PKTS                :
		case  Q81_RX_CTL_PKTS_LO             :
		case  Q81_RX_PAUSE_PKTS              :
		case  Q81_RX_PAUSE_PKTS_LO           :
		case  Q81_RX_64_PKTS                 :
		case  Q81_RX_64_PKTS_LO              :
		case  Q81_RX_65_TO_127_PKTS          :
		case  Q81_RX_65_TO_127_PKTS_LO       :
		case  Q81_RX_128_255_PKTS            :
		case  Q81_RX_128_255_PKTS_LO         :
		case  Q81_RX_256_511_PKTS            :
		case  Q81_RX_256_511_PKTS_LO         :
		case  Q81_RX_512_TO_1023_PKTS        :
		case  Q81_RX_512_TO_1023_PKTS_LO     :
		case  Q81_RX_1024_TO_1518_PKTS       :
		case  Q81_RX_1024_TO_1518_PKTS_LO    :
		case  Q81_RX_1519_TO_MAX_PKTS        :
		case  Q81_RX_1519_TO_MAX_PKTS_LO     :
		case  Q81_RX_LEN_ERR_PKTS            :
		case  Q81_RX_LEN_ERR_PKTS_LO         :
		case  Q81_MDIO_TX_DATA               :
		case  Q81_MDIO_RX_DATA               :
		case  Q81_MDIO_CMD                   :
		case  Q81_MDIO_PHY_ADDR              :
		case  Q81_MDIO_PORT                  :
		case  Q81_MDIO_STATUS                :
		case  Q81_TX_CBFC_PAUSE_FRAMES0      :
		case  Q81_TX_CBFC_PAUSE_FRAMES0_LO   :
		case  Q81_TX_CBFC_PAUSE_FRAMES1      :
		case  Q81_TX_CBFC_PAUSE_FRAMES1_LO   :
		case  Q81_TX_CBFC_PAUSE_FRAMES2      :
		case  Q81_TX_CBFC_PAUSE_FRAMES2_LO   :
		case  Q81_TX_CBFC_PAUSE_FRAMES3      :
		case  Q81_TX_CBFC_PAUSE_FRAMES3_LO   :
		case  Q81_TX_CBFC_PAUSE_FRAMES4      :
		case  Q81_TX_CBFC_PAUSE_FRAMES4_LO   :
		case  Q81_TX_CBFC_PAUSE_FRAMES5      :
		case  Q81_TX_CBFC_PAUSE_FRAMES5_LO   :
		case  Q81_TX_CBFC_PAUSE_FRAMES6      :
		case  Q81_TX_CBFC_PAUSE_FRAMES6_LO   :
		case  Q81_TX_CBFC_PAUSE_FRAMES7      :
		case  Q81_TX_CBFC_PAUSE_FRAMES7_LO   :
		case  Q81_TX_FCOE_PKTS               :
		case  Q81_TX_FCOE_PKTS_LO            :
		case  Q81_TX_MGMT_PKTS               :
		case  Q81_TX_MGMT_PKTS_LO            :
		case  Q81_RX_CBFC_PAUSE_FRAMES0      :
		case  Q81_RX_CBFC_PAUSE_FRAMES0_LO   :
		case  Q81_RX_CBFC_PAUSE_FRAMES1      :
		case  Q81_RX_CBFC_PAUSE_FRAMES1_LO   :
		case  Q81_RX_CBFC_PAUSE_FRAMES2      :
		case  Q81_RX_CBFC_PAUSE_FRAMES2_LO   :
		case  Q81_RX_CBFC_PAUSE_FRAMES3      :
		case  Q81_RX_CBFC_PAUSE_FRAMES3_LO   :
		case  Q81_RX_CBFC_PAUSE_FRAMES4      :
		case  Q81_RX_CBFC_PAUSE_FRAMES4_LO   :
		case  Q81_RX_CBFC_PAUSE_FRAMES5      :
		case  Q81_RX_CBFC_PAUSE_FRAMES5_LO   :
		case  Q81_RX_CBFC_PAUSE_FRAMES6      :
		case  Q81_RX_CBFC_PAUSE_FRAMES6_LO   :
		case  Q81_RX_CBFC_PAUSE_FRAMES7      :
		case  Q81_RX_CBFC_PAUSE_FRAMES7_LO   :
		case  Q81_RX_FCOE_PKTS               :
		case  Q81_RX_FCOE_PKTS_LO            :
		case  Q81_RX_MGMT_PKTS               :
		case  Q81_RX_MGMT_PKTS_LO            :
		case  Q81_RX_NIC_FIFO_DROP           :
		case  Q81_RX_NIC_FIFO_DROP_LO        :
		case  Q81_RX_FCOE_FIFO_DROP          :
		case  Q81_RX_FCOE_FIFO_DROP_LO       :
		case  Q81_RX_MGMT_FIFO_DROP          :
		case  Q81_RX_MGMT_FIFO_DROP_LO       :
		case  Q81_RX_PKTS_PRIORITY0          :
		case  Q81_RX_PKTS_PRIORITY0_LO       :
		case  Q81_RX_PKTS_PRIORITY1          :
		case  Q81_RX_PKTS_PRIORITY1_LO       :
		case  Q81_RX_PKTS_PRIORITY2          :
		case  Q81_RX_PKTS_PRIORITY2_LO       :
		case  Q81_RX_PKTS_PRIORITY3          :
		case  Q81_RX_PKTS_PRIORITY3_LO       :
		case  Q81_RX_PKTS_PRIORITY4          :
		case  Q81_RX_PKTS_PRIORITY4_LO       :
		case  Q81_RX_PKTS_PRIORITY5          :
		case  Q81_RX_PKTS_PRIORITY5_LO       :
		case  Q81_RX_PKTS_PRIORITY6          :
		case  Q81_RX_PKTS_PRIORITY6_LO       :
		case  Q81_RX_PKTS_PRIORITY7          :
		case  Q81_RX_PKTS_PRIORITY7_LO       :
		case  Q81_RX_OCTETS_PRIORITY0        :
		case  Q81_RX_OCTETS_PRIORITY0_LO     :
		case  Q81_RX_OCTETS_PRIORITY1        :
		case  Q81_RX_OCTETS_PRIORITY1_LO     :
		case  Q81_RX_OCTETS_PRIORITY2        :
		case  Q81_RX_OCTETS_PRIORITY2_LO     :
		case  Q81_RX_OCTETS_PRIORITY3        :
		case  Q81_RX_OCTETS_PRIORITY3_LO     :
		case  Q81_RX_OCTETS_PRIORITY4        :
		case  Q81_RX_OCTETS_PRIORITY4_LO     :
		case  Q81_RX_OCTETS_PRIORITY5        :
		case  Q81_RX_OCTETS_PRIORITY5_LO     :
		case  Q81_RX_OCTETS_PRIORITY6        :
		case  Q81_RX_OCTETS_PRIORITY6_LO     :
		case  Q81_RX_OCTETS_PRIORITY7        :
		case  Q81_RX_OCTETS_PRIORITY7_LO     :
		case  Q81_TX_PKTS_PRIORITY0          :
		case  Q81_TX_PKTS_PRIORITY0_LO       :
		case  Q81_TX_PKTS_PRIORITY1          :
		case  Q81_TX_PKTS_PRIORITY1_LO       :
		case  Q81_TX_PKTS_PRIORITY2          :
		case  Q81_TX_PKTS_PRIORITY2_LO       :
		case  Q81_TX_PKTS_PRIORITY3          :
		case  Q81_TX_PKTS_PRIORITY3_LO       :
		case  Q81_TX_PKTS_PRIORITY4          :
		case  Q81_TX_PKTS_PRIORITY4_LO       :
		case  Q81_TX_PKTS_PRIORITY5          :
		case  Q81_TX_PKTS_PRIORITY5_LO       :
		case  Q81_TX_PKTS_PRIORITY6          :
		case  Q81_TX_PKTS_PRIORITY6_LO       :
		case  Q81_TX_PKTS_PRIORITY7          :
		case  Q81_TX_PKTS_PRIORITY7_LO       :
		case  Q81_TX_OCTETS_PRIORITY0        :
		case  Q81_TX_OCTETS_PRIORITY0_LO     :
		case  Q81_TX_OCTETS_PRIORITY1        :
		case  Q81_TX_OCTETS_PRIORITY1_LO     :
		case  Q81_TX_OCTETS_PRIORITY2        :
		case  Q81_TX_OCTETS_PRIORITY2_LO     :
		case  Q81_TX_OCTETS_PRIORITY3        :
		case  Q81_TX_OCTETS_PRIORITY3_LO     :
		case  Q81_TX_OCTETS_PRIORITY4        :
		case  Q81_TX_OCTETS_PRIORITY4_LO     :
		case  Q81_TX_OCTETS_PRIORITY5        :
		case  Q81_TX_OCTETS_PRIORITY5_LO     :
		case  Q81_TX_OCTETS_PRIORITY6        :
		case  Q81_TX_OCTETS_PRIORITY6_LO     :
		case  Q81_TX_OCTETS_PRIORITY7        :
		case  Q81_TX_OCTETS_PRIORITY7_LO     :
		case  Q81_RX_DISCARD_PRIORITY0       :
		case  Q81_RX_DISCARD_PRIORITY0_LO    :
		case  Q81_RX_DISCARD_PRIORITY1       :
		case  Q81_RX_DISCARD_PRIORITY1_LO    :
		case  Q81_RX_DISCARD_PRIORITY2       :
		case  Q81_RX_DISCARD_PRIORITY2_LO    :
		case  Q81_RX_DISCARD_PRIORITY3       :
		case  Q81_RX_DISCARD_PRIORITY3_LO    :
		case  Q81_RX_DISCARD_PRIORITY4       :
		case  Q81_RX_DISCARD_PRIORITY4_LO    :
		case  Q81_RX_DISCARD_PRIORITY5       :
		case  Q81_RX_DISCARD_PRIORITY5_LO    :
		case  Q81_RX_DISCARD_PRIORITY6       :
		case  Q81_RX_DISCARD_PRIORITY6_LO    :
		case  Q81_RX_DISCARD_PRIORITY7       :
		case  Q81_RX_DISCARD_PRIORITY7_LO    :

			if (o_func)
				ret = qls_rd_ofunc_xgmac_reg(ha,
						i, buf);
			else
				ret = qls_rd_xgmac_reg(ha, i, buf);

			if (ret)
				*buf = Q81_BAD_DATA;

			break;

		default:
			break;
		}
	}
	return 0;
}

static int
qls_get_mpi_regs(qla_host_t *ha, uint32_t *buf, uint32_t offset, uint32_t count)
{
	int i, ret = 0;

	for (i = 0; i < count; i++, buf++) {
		ret = qls_rd_mpi_reg(ha, (offset + i), buf);

		if (ret)
			return ret;
	}

	return (ret);
}

static int
qls_get_mpi_shadow_regs(qla_host_t *ha, uint32_t *buf)
{
	uint32_t	i;
	int		ret;

#define Q81_RISC_124 0x0000007c
#define Q81_RISC_127 0x0000007f
#define Q81_SHADOW_OFFSET 0xb0000000

	for (i = 0; i < Q81_MPI_CORE_SH_REGS_CNT; i++, buf++) {
		ret = qls_wr_mpi_reg(ha,
				(Q81_CTL_PROC_ADDR_RISC_INT_REG | Q81_RISC_124),
                                (Q81_SHADOW_OFFSET | i << 20));
		if (ret)
			goto exit_qls_get_mpi_shadow_regs;

		ret = qls_mpi_risc_rd_reg(ha,
				(Q81_CTL_PROC_ADDR_RISC_INT_REG | Q81_RISC_127),
				 buf);
		if (ret)
			goto exit_qls_get_mpi_shadow_regs;
	}

exit_qls_get_mpi_shadow_regs:
	return ret;
}

#define SYS_CLOCK (0x00)
#define PCI_CLOCK (0x80)
#define FC_CLOCK  (0x140)
#define XGM_CLOCK (0x180)

#define Q81_ADDRESS_REGISTER_ENABLE 0x00010000
#define Q81_UP                      0x00008000
#define Q81_MAX_MUX                 0x40
#define Q81_MAX_MODULES             0x1F

static uint32_t *
qls_get_probe(qla_host_t *ha, uint32_t clock, uint8_t *valid, uint32_t *buf)
{
	uint32_t module, mux_sel, probe, lo_val, hi_val;

	for (module = 0; module < Q81_MAX_MODULES; module ++) {
		if (valid[module]) {
			for (mux_sel = 0; mux_sel < Q81_MAX_MUX; mux_sel++) {
				probe = clock | Q81_ADDRESS_REGISTER_ENABLE |
						mux_sel | (module << 9);
				WRITE_REG32(ha, Q81_CTL_XG_PROBE_MUX_ADDR,\
					probe);

				lo_val = READ_REG32(ha,\
						Q81_CTL_XG_PROBE_MUX_DATA);

				if (mux_sel == 0) {
					*buf = probe;
					buf ++;
				}

				probe |= Q81_UP;

				WRITE_REG32(ha, Q81_CTL_XG_PROBE_MUX_ADDR,\
					probe);
				hi_val = READ_REG32(ha,\
						Q81_CTL_XG_PROBE_MUX_DATA);

				*buf = lo_val;
				buf++;
				*buf = hi_val;
				buf++;
			}
		}
	}

	return(buf);
}

static int
qls_get_probe_dump(qla_host_t *ha, uint32_t *buf)
{

	uint8_t sys_clock_valid_modules[0x20] = {
		1,   // 0x00
		1,   // 0x01
		1,   // 0x02
		0,   // 0x03
		1,   // 0x04
		1,   // 0x05
		1,   // 0x06
		1,   // 0x07
		1,   // 0x08
		1,   // 0x09
		1,   // 0x0A
		1,   // 0x0B
		1,   // 0x0C
		1,   // 0x0D
		1,   // 0x0E
		0,   // 0x0F
		1,   // 0x10
		1,   // 0x11
		1,   // 0x12
		1,   // 0x13
		0,   // 0x14
		0,   // 0x15
		0,   // 0x16
		0,   // 0x17
		0,   // 0x18
		0,   // 0x19
		0,   // 0x1A
		0,   // 0x1B
		0,   // 0x1C
		0,   // 0x1D
		0,   // 0x1E
		0    // 0x1F
	};

	uint8_t pci_clock_valid_modules[0x20] = {
		1,   // 0x00
		0,   // 0x01
		0,   // 0x02
		0,   // 0x03
		0,   // 0x04
		0,   // 0x05
		1,   // 0x06
		1,   // 0x07
		0,   // 0x08
		0,   // 0x09
		0,   // 0x0A
		0,   // 0x0B
		0,   // 0x0C
		0,   // 0x0D
		1,   // 0x0E
		0,   // 0x0F
		0,   // 0x10
		0,   // 0x11
		0,   // 0x12
		0,   // 0x13
		0,   // 0x14
		0,   // 0x15
		0,   // 0x16
		0,   // 0x17
		0,   // 0x18
		0,   // 0x19
		0,   // 0x1A
		0,   // 0x1B
		0,   // 0x1C
		0,   // 0x1D
		0,   // 0x1E
		0    // 0x1F
	};

	uint8_t xgm_clock_valid_modules[0x20] = {
		1,   // 0x00
		0,   // 0x01
		0,   // 0x02
		1,   // 0x03
		0,   // 0x04
		0,   // 0x05
		0,   // 0x06
		0,   // 0x07
		1,   // 0x08
		1,   // 0x09
		0,   // 0x0A
		0,   // 0x0B
		1,   // 0x0C
		1,   // 0x0D
		1,   // 0x0E
		0,   // 0x0F
		1,   // 0x10
		1,   // 0x11
		0,   // 0x12
		0,   // 0x13
		0,   // 0x14
		0,   // 0x15
		0,   // 0x16
		0,   // 0x17
		0,   // 0x18
		0,   // 0x19
		0,   // 0x1A
		0,   // 0x1B
		0,   // 0x1C
		0,   // 0x1D
		0,   // 0x1E
		0    // 0x1F
	};

	uint8_t fc_clock_valid_modules[0x20] = {
		1,   // 0x00
		0,   // 0x01
		0,   // 0x02
		0,   // 0x03
		0,   // 0x04
		0,   // 0x05
		0,   // 0x06
		0,   // 0x07
		0,   // 0x08
		0,   // 0x09
		0,   // 0x0A
		0,   // 0x0B
		1,   // 0x0C
		1,   // 0x0D
		0,   // 0x0E
		0,   // 0x0F
		0,   // 0x10
		0,   // 0x11
		0,   // 0x12
		0,   // 0x13
		0,   // 0x14
		0,   // 0x15
		0,   // 0x16
		0,   // 0x17
		0,   // 0x18
		0,   // 0x19
		0,   // 0x1A
		0,   // 0x1B
		0,   // 0x1C
		0,   // 0x1D
		0,   // 0x1E
		0    // 0x1F
	};

	qls_wr_mpi_reg(ha, 0x100e, 0x18a20000);

	buf = qls_get_probe(ha, SYS_CLOCK, sys_clock_valid_modules, buf);

	buf = qls_get_probe(ha, PCI_CLOCK, pci_clock_valid_modules, buf);

	buf = qls_get_probe(ha, XGM_CLOCK, xgm_clock_valid_modules, buf);

	buf = qls_get_probe(ha, FC_CLOCK, fc_clock_valid_modules, buf);

	return(0);
}

static void
qls_get_ridx_registers(qla_host_t *ha, uint32_t *buf)
{
	uint32_t type, idx, idx_max;
	uint32_t r_idx;
	uint32_t r_data;
	uint32_t val;

	for (type = 0; type < 4; type ++) {
		if (type < 2)
			idx_max = 8;
		else
			idx_max = 16;

		for (idx = 0; idx < idx_max; idx ++) {
			val = 0x04000000 | (type << 16) | (idx << 8);
			WRITE_REG32(ha, Q81_CTL_ROUTING_INDEX, val);

			r_idx = 0;
			while ((r_idx & 0x40000000) == 0)
				r_idx = READ_REG32(ha, Q81_CTL_ROUTING_INDEX);

			r_data = READ_REG32(ha, Q81_CTL_ROUTING_DATA);

			*buf = type;
			buf ++;
			*buf = idx;
			buf ++;
			*buf = r_idx;
			buf ++;
			*buf = r_data;
			buf ++;
		}
	}
}

static void
qls_get_mac_proto_regs(qla_host_t *ha, uint32_t* buf)
{

#define Q81_RS_AND_ADR 0x06000000
#define Q81_RS_ONLY    0x04000000
#define Q81_NUM_TYPES  10

	uint32_t result_index, result_data;
	uint32_t type;
	uint32_t index;
	uint32_t offset;
	uint32_t val;
	uint32_t initial_val;
	uint32_t max_index;
	uint32_t max_offset;

	for (type = 0; type < Q81_NUM_TYPES; type ++) {
		switch (type) {
		case 0: // CAM
			initial_val = Q81_RS_AND_ADR;
			max_index = 512;
			max_offset = 3;
			break;

		case 1: // Multicast MAC Address
			initial_val = Q81_RS_ONLY;
			max_index = 32;
			max_offset = 2;
			break;

		case 2: // VLAN filter mask
		case 3: // MC filter mask
			initial_val = Q81_RS_ONLY;
			max_index = 4096;
			max_offset = 1;
			break;

		case 4: // FC MAC addresses
			initial_val = Q81_RS_ONLY;
			max_index = 4;
			max_offset = 2;
			break;

		case 5: // Mgmt MAC addresses
			initial_val = Q81_RS_ONLY;
			max_index = 8;
			max_offset = 2;
			break;

		case 6: // Mgmt VLAN addresses
			initial_val = Q81_RS_ONLY;
			max_index = 16;
			max_offset = 1;
			break;

		case 7: // Mgmt IPv4 address
			initial_val = Q81_RS_ONLY;
			max_index = 4;
			max_offset = 1;
			break;

		case 8: // Mgmt IPv6 address
			initial_val = Q81_RS_ONLY;
			max_index = 4;
			max_offset = 4;
			break;

		case 9: // Mgmt TCP/UDP Dest port
			initial_val = Q81_RS_ONLY;
			max_index = 4;
			max_offset = 1;
			break;

		default:
			printf("Bad type!!! 0x%08x\n", type);
			max_index = 0;
			max_offset = 0;
			break;
		}

		for (index = 0; index < max_index; index ++) {
			for (offset = 0; offset < max_offset; offset ++) {
				val = initial_val | (type << 16) |
					(index << 4) | (offset);

				WRITE_REG32(ha, Q81_CTL_MAC_PROTO_ADDR_INDEX,\
					val);

				result_index = 0;

				while ((result_index & 0x40000000) == 0)
					result_index =
						READ_REG32(ha, \
						Q81_CTL_MAC_PROTO_ADDR_INDEX);

				result_data = READ_REG32(ha,\
						Q81_CTL_MAC_PROTO_ADDR_DATA);

				*buf = result_index;
				buf ++;

				*buf = result_data;
				buf ++;
			}
		}
	}
}

static int
qls_get_ets_regs(qla_host_t *ha, uint32_t *buf)
{
	int ret = 0;
	int i;

	for(i = 0; i < 8; i ++, buf ++) {
		WRITE_REG32(ha, Q81_CTL_NIC_ENH_TX_SCHD, \
			((i << 29) | 0x08000000));
		*buf = READ_REG32(ha, Q81_CTL_NIC_ENH_TX_SCHD);
	}

	for(i = 0; i < 2; i ++, buf ++) {
		WRITE_REG32(ha, Q81_CTL_CNA_ENH_TX_SCHD, \
			((i << 29) | 0x08000000));
		*buf = READ_REG32(ha, Q81_CTL_CNA_ENH_TX_SCHD);
	}

	return ret;
}

int
qls_mpi_core_dump(qla_host_t *ha)
{
	int ret;
	int i;
	uint32_t reg, reg_val;

	qls_mpi_coredump_t *mpi_dump = &ql_mpi_coredump;

	ret = qls_pause_mpi_risc(ha);
	if (ret) {
		printf("Failed RISC pause. Status = 0x%.08x\n",ret);
		return(-1);
	}

	memset(&(mpi_dump->mpi_global_header), 0,
			sizeof(qls_mpid_glbl_hdr_t));

	mpi_dump->mpi_global_header.cookie = Q81_MPID_COOKIE;
	mpi_dump->mpi_global_header.hdr_size =
		sizeof(qls_mpid_glbl_hdr_t);
	mpi_dump->mpi_global_header.img_size =
		sizeof(qls_mpi_coredump_t);

	memcpy(mpi_dump->mpi_global_header.id, "MPI Coredump",
		sizeof(mpi_dump->mpi_global_header.id));

	qls_mpid_seg_hdr(&mpi_dump->nic1_regs_seg_hdr,
		Q81_NIC1_CONTROL_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->nic1_regs)),
		"NIC1 Registers");

	qls_mpid_seg_hdr(&mpi_dump->nic2_regs_seg_hdr,
		Q81_NIC2_CONTROL_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->nic2_regs)),
		"NIC2 Registers");

	qls_mpid_seg_hdr(&mpi_dump->xgmac1_seg_hdr,
		Q81_NIC1_XGMAC_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->xgmac1)),
		"NIC1 XGMac Registers");

	qls_mpid_seg_hdr(&mpi_dump->xgmac2_seg_hdr,
		Q81_NIC2_XGMAC_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->xgmac2)),
		"NIC2 XGMac Registers");

	if (ha->pci_func & 1) {
		for (i = 0; i < 64; i++)
			mpi_dump->nic2_regs[i] =
				READ_REG32(ha, i * sizeof(uint32_t));

		for (i = 0; i < 64; i++)
			mpi_dump->nic1_regs[i] =
				qls_rd_ofunc_reg(ha,
					(i * sizeof(uint32_t)) / 4);

		qls_rd_xgmac_regs(ha, &mpi_dump->xgmac2[0], 0);
		qls_rd_xgmac_regs(ha, &mpi_dump->xgmac1[0], 1);
	} else {
		for (i = 0; i < 64; i++)
			mpi_dump->nic1_regs[i] =
				READ_REG32(ha, i * sizeof(uint32_t));

		for (i = 0; i < 64; i++)
			mpi_dump->nic2_regs[i] =
				qls_rd_ofunc_reg(ha,
					(i * sizeof(uint32_t)) / 4);

		qls_rd_xgmac_regs(ha, &mpi_dump->xgmac1[0], 0);
		qls_rd_xgmac_regs(ha, &mpi_dump->xgmac2[0], 1);
	}

	qls_mpid_seg_hdr(&mpi_dump->xaui1_an_hdr,
		Q81_XAUI1_AN_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes1_xaui_an)),
		"XAUI1 AN Registers");

	qls_mpid_seg_hdr(&mpi_dump->xaui1_hss_pcs_hdr,
		Q81_XAUI1_HSS_PCS_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes1_xaui_hss_pcs)),
		"XAUI1 HSS PCS Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi1_an_hdr,
		Q81_XFI1_AN_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->serdes1_xfi_an)),
		"XFI1 AN Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi1_train_hdr,
		Q81_XFI1_TRAIN_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes1_xfi_train)),
		"XFI1 TRAIN Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi1_hss_pcs_hdr,
		Q81_XFI1_HSS_PCS_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes1_xfi_hss_pcs)),
		"XFI1 HSS PCS Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi1_hss_tx_hdr,
		Q81_XFI1_HSS_TX_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes1_xfi_hss_tx)),
		"XFI1 HSS TX Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi1_hss_rx_hdr,
		Q81_XFI1_HSS_RX_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes1_xfi_hss_rx)),
		"XFI1 HSS RX Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi1_hss_pll_hdr,
		Q81_XFI1_HSS_PLL_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes1_xfi_hss_pll)),
		"XFI1 HSS PLL Registers");

	qls_mpid_seg_hdr(&mpi_dump->xaui2_an_hdr,
		Q81_XAUI2_AN_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes2_xaui_an)),
		"XAUI2 AN Registers");

	qls_mpid_seg_hdr(&mpi_dump->xaui2_hss_pcs_hdr,
		Q81_XAUI2_HSS_PCS_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes2_xaui_hss_pcs)),
		"XAUI2 HSS PCS Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi2_an_hdr,
		Q81_XFI2_AN_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->serdes2_xfi_an)),
		"XFI2 AN Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi2_train_hdr,
		Q81_XFI2_TRAIN_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes2_xfi_train)),
		"XFI2 TRAIN Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi2_hss_pcs_hdr,
		Q81_XFI2_HSS_PCS_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes2_xfi_hss_pcs)),
		"XFI2 HSS PCS Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi2_hss_tx_hdr,
		Q81_XFI2_HSS_TX_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes2_xfi_hss_tx)),
		"XFI2 HSS TX Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi2_hss_rx_hdr,
		Q81_XFI2_HSS_RX_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes2_xfi_hss_rx)),
		"XFI2 HSS RX Registers");

	qls_mpid_seg_hdr(&mpi_dump->xfi2_hss_pll_hdr,
		Q81_XFI2_HSS_PLL_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->serdes2_xfi_hss_pll)),
		"XFI2 HSS PLL Registers");

	qls_rd_serdes_regs(ha, mpi_dump);

	qls_mpid_seg_hdr(&mpi_dump->core_regs_seg_hdr,
		Q81_CORE_SEG_NUM,
		(sizeof(mpi_dump->core_regs_seg_hdr) +
		 sizeof(mpi_dump->mpi_core_regs) +
		 sizeof(mpi_dump->mpi_core_sh_regs)),
		"Core Registers");

	ret = qls_get_mpi_regs(ha, &mpi_dump->mpi_core_regs[0],
			Q81_MPI_CORE_REGS_ADDR, Q81_MPI_CORE_REGS_CNT);

	ret = qls_get_mpi_shadow_regs(ha,
			&mpi_dump->mpi_core_sh_regs[0]);

	qls_mpid_seg_hdr(&mpi_dump->test_logic_regs_seg_hdr,
		Q81_TEST_LOGIC_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->test_logic_regs)),
		"Test Logic Regs");

	ret = qls_get_mpi_regs(ha, &mpi_dump->test_logic_regs[0],
                            Q81_TEST_REGS_ADDR, Q81_TEST_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->rmii_regs_seg_hdr,
		Q81_RMII_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->rmii_regs)),
		"RMII Registers");

	ret = qls_get_mpi_regs(ha, &mpi_dump->rmii_regs[0],
                            Q81_RMII_REGS_ADDR, Q81_RMII_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->fcmac1_regs_seg_hdr,
		Q81_FCMAC1_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->fcmac1_regs)),
		"FCMAC1 Registers");

	ret = qls_get_mpi_regs(ha, &mpi_dump->fcmac1_regs[0],
                            Q81_FCMAC1_REGS_ADDR, Q81_FCMAC_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->fcmac2_regs_seg_hdr,
		Q81_FCMAC2_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->fcmac2_regs)),
		"FCMAC2 Registers");

	ret = qls_get_mpi_regs(ha, &mpi_dump->fcmac2_regs[0],
                            Q81_FCMAC2_REGS_ADDR, Q81_FCMAC_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->fc1_mbx_regs_seg_hdr,
		Q81_FC1_MBOX_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->fc1_mbx_regs)),
		"FC1 MBox Regs");

	ret = qls_get_mpi_regs(ha, &mpi_dump->fc1_mbx_regs[0],
                            Q81_FC1_MBX_REGS_ADDR, Q81_FC_MBX_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->ide_regs_seg_hdr,
		Q81_IDE_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->ide_regs)),
		"IDE Registers");

	ret = qls_get_mpi_regs(ha, &mpi_dump->ide_regs[0],
                            Q81_IDE_REGS_ADDR, Q81_IDE_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->nic1_mbx_regs_seg_hdr,
		Q81_NIC1_MBOX_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->nic1_mbx_regs)),
		"NIC1 MBox Regs");

	ret = qls_get_mpi_regs(ha, &mpi_dump->nic1_mbx_regs[0],
                            Q81_NIC1_MBX_REGS_ADDR, Q81_NIC_MBX_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->smbus_regs_seg_hdr,
		Q81_SMBUS_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->smbus_regs)),
		"SMBus Registers");

	ret = qls_get_mpi_regs(ha, &mpi_dump->smbus_regs[0],
                            Q81_SMBUS_REGS_ADDR, Q81_SMBUS_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->fc2_mbx_regs_seg_hdr,
		Q81_FC2_MBOX_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->fc2_mbx_regs)),
		"FC2 MBox Regs");

	ret = qls_get_mpi_regs(ha, &mpi_dump->fc2_mbx_regs[0],
                            Q81_FC2_MBX_REGS_ADDR, Q81_FC_MBX_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->nic2_mbx_regs_seg_hdr,
		Q81_NIC2_MBOX_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->nic2_mbx_regs)),
		"NIC2 MBox Regs");

	ret = qls_get_mpi_regs(ha, &mpi_dump->nic2_mbx_regs[0],
                            Q81_NIC2_MBX_REGS_ADDR, Q81_NIC_MBX_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->i2c_regs_seg_hdr,
		Q81_I2C_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) +
			sizeof(mpi_dump->i2c_regs)),
		"I2C Registers");

	ret = qls_get_mpi_regs(ha, &mpi_dump->i2c_regs[0],
                            Q81_I2C_REGS_ADDR, Q81_I2C_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->memc_regs_seg_hdr,
		Q81_MEMC_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->memc_regs)),
		"MEMC Registers");

	ret = qls_get_mpi_regs(ha, &mpi_dump->memc_regs[0],
                            Q81_MEMC_REGS_ADDR, Q81_MEMC_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->pbus_regs_seg_hdr,
		Q81_PBUS_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->pbus_regs)),
		"PBUS Registers");

	ret = qls_get_mpi_regs(ha, &mpi_dump->pbus_regs[0],
                            Q81_PBUS_REGS_ADDR, Q81_PBUS_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->mde_regs_seg_hdr,
		Q81_MDE_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->mde_regs)),
		"MDE Registers");

	ret = qls_get_mpi_regs(ha, &mpi_dump->mde_regs[0],
                            Q81_MDE_REGS_ADDR, Q81_MDE_REGS_CNT);

	qls_mpid_seg_hdr(&mpi_dump->intr_states_seg_hdr,
		Q81_INTR_STATES_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->intr_states)),
		"INTR States");

	qls_get_intr_states(ha, &mpi_dump->intr_states[0]);

	qls_mpid_seg_hdr(&mpi_dump->probe_dump_seg_hdr,
		Q81_PROBE_DUMP_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->probe_dump)),
		"Probe Dump");

	qls_get_probe_dump(ha, &mpi_dump->probe_dump[0]);

	qls_mpid_seg_hdr(&mpi_dump->routing_reg_seg_hdr,
		Q81_ROUTING_INDEX_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->routing_regs)),
		"Routing Regs");

	qls_get_ridx_registers(ha, &mpi_dump->routing_regs[0]);

	qls_mpid_seg_hdr(&mpi_dump->mac_prot_reg_seg_hdr,
		Q81_MAC_PROTOCOL_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->mac_prot_regs)),
		"MAC Prot Regs");

	qls_get_mac_proto_regs(ha, &mpi_dump->mac_prot_regs[0]);

	qls_mpid_seg_hdr(&mpi_dump->ets_seg_hdr,
		Q81_ETS_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->ets)),
		"ETS Registers");

	ret = qls_get_ets_regs(ha, &mpi_dump->ets[0]);

	qls_mpid_seg_hdr(&mpi_dump->sem_regs_seg_hdr,
		Q81_SEM_REGS_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->sem_regs)),
		"Sem Registers");

	for(i = 0; i < Q81_MAX_SEMAPHORE_FUNCTIONS ; i ++) {
		reg = Q81_CTL_PROC_ADDR_REG_BLOCK | (i << Q81_FUNCTION_SHIFT) |
				(Q81_CTL_SEMAPHORE >> 2);

		ret = qls_mpi_risc_rd_reg(ha, reg, &reg_val);
		mpi_dump->sem_regs[i] = reg_val;

		if (ret != 0)
			mpi_dump->sem_regs[i] = Q81_BAD_DATA;
	}

	ret = qls_unpause_mpi_risc(ha);
	if (ret)
		printf("Failed RISC unpause. Status = 0x%.08x\n",ret);

	ret = qls_mpi_reset(ha);
	if (ret)
		printf("Failed RISC reset. Status = 0x%.08x\n",ret);

	WRITE_REG32(ha, Q81_CTL_FUNC_SPECIFIC, 0x80008000);

	qls_mpid_seg_hdr(&mpi_dump->memc_ram_seg_hdr,
		Q81_MEMC_RAM_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->memc_ram)),
		"MEMC RAM");

	ret = qls_mbx_dump_risc_ram(ha, &mpi_dump->memc_ram[0],
			Q81_MEMC_RAM_ADDR, Q81_MEMC_RAM_CNT);
	if (ret)
		printf("Failed Dump of MEMC RAM. Status = 0x%.08x\n",ret);

	qls_mpid_seg_hdr(&mpi_dump->code_ram_seg_hdr,
		Q81_WCS_RAM_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->code_ram)),
		"WCS RAM");

	ret = qls_mbx_dump_risc_ram(ha, &mpi_dump->memc_ram[0],
			Q81_CODE_RAM_ADDR, Q81_CODE_RAM_CNT);
	if (ret)
		printf("Failed Dump of CODE RAM. Status = 0x%.08x\n",ret);

	qls_mpid_seg_hdr(&mpi_dump->wqc1_seg_hdr,
		Q81_WQC1_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->wqc1)),
		"WQC 1");

	qls_mpid_seg_hdr(&mpi_dump->wqc2_seg_hdr,
		Q81_WQC2_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->wqc2)),
		"WQC 2");

	qls_mpid_seg_hdr(&mpi_dump->cqc1_seg_hdr,
		Q81_CQC1_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->cqc1)),
		"CQC 1");

	qls_mpid_seg_hdr(&mpi_dump->cqc2_seg_hdr,
		Q81_CQC2_SEG_NUM,
		(sizeof(qls_mpid_seg_hdr_t) + sizeof(mpi_dump->cqc2)),
		"CQC 2");

	return 0;
}