linux/drivers/staging/qlge/qlge_dbg.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   3
   4#include <linux/slab.h>
   5
   6#include "qlge.h"
   7
   8/* Read a NIC register from the alternate function. */
   9static u32 qlge_read_other_func_reg(struct qlge_adapter *qdev,
  10                                    u32 reg)
  11{
  12        u32 register_to_read;
  13        u32 reg_val;
  14        unsigned int status = 0;
  15
  16        register_to_read = MPI_NIC_REG_BLOCK
  17                                | MPI_NIC_READ
  18                                | (qdev->alt_func << MPI_NIC_FUNCTION_SHIFT)
  19                                | reg;
  20        status = qlge_read_mpi_reg(qdev, register_to_read, &reg_val);
  21        if (status != 0)
  22                return 0xffffffff;
  23
  24        return reg_val;
  25}
  26
  27/* Write a NIC register from the alternate function. */
  28static int qlge_write_other_func_reg(struct qlge_adapter *qdev,
  29                                     u32 reg, u32 reg_val)
  30{
  31        u32 register_to_read;
  32
  33        register_to_read = MPI_NIC_REG_BLOCK
  34                                | MPI_NIC_READ
  35                                | (qdev->alt_func << MPI_NIC_FUNCTION_SHIFT)
  36                                | reg;
  37
  38        return qlge_write_mpi_reg(qdev, register_to_read, reg_val);
  39}
  40
  41static int qlge_wait_other_func_reg_rdy(struct qlge_adapter *qdev, u32 reg,
  42                                        u32 bit, u32 err_bit)
  43{
  44        u32 temp;
  45        int count;
  46
  47        for (count = 10; count; count--) {
  48                temp = qlge_read_other_func_reg(qdev, reg);
  49
  50                /* check for errors */
  51                if (temp & err_bit)
  52                        return -1;
  53                else if (temp & bit)
  54                        return 0;
  55                mdelay(10);
  56        }
  57        return -1;
  58}
  59
  60static int qlge_read_other_func_serdes_reg(struct qlge_adapter *qdev, u32 reg,
  61                                           u32 *data)
  62{
  63        int status;
  64
  65        /* wait for reg to come ready */
  66        status = qlge_wait_other_func_reg_rdy(qdev, XG_SERDES_ADDR / 4,
  67                                              XG_SERDES_ADDR_RDY, 0);
  68        if (status)
  69                goto exit;
  70
  71        /* set up for reg read */
  72        qlge_write_other_func_reg(qdev, XG_SERDES_ADDR / 4, reg | PROC_ADDR_R);
  73
  74        /* wait for reg to come ready */
  75        status = qlge_wait_other_func_reg_rdy(qdev, XG_SERDES_ADDR / 4,
  76                                              XG_SERDES_ADDR_RDY, 0);
  77        if (status)
  78                goto exit;
  79
  80        /* get the data */
  81        *data = qlge_read_other_func_reg(qdev, (XG_SERDES_DATA / 4));
  82exit:
  83        return status;
  84}
  85
  86/* Read out the SERDES registers */
  87static int qlge_read_serdes_reg(struct qlge_adapter *qdev, u32 reg, u32 *data)
  88{
  89        int status;
  90
  91        /* wait for reg to come ready */
  92        status = qlge_wait_reg_rdy(qdev, XG_SERDES_ADDR, XG_SERDES_ADDR_RDY, 0);
  93        if (status)
  94                goto exit;
  95
  96        /* set up for reg read */
  97        qlge_write32(qdev, XG_SERDES_ADDR, reg | PROC_ADDR_R);
  98
  99        /* wait for reg to come ready */
 100        status = qlge_wait_reg_rdy(qdev, XG_SERDES_ADDR, XG_SERDES_ADDR_RDY, 0);
 101        if (status)
 102                goto exit;
 103
 104        /* get the data */
 105        *data = qlge_read32(qdev, XG_SERDES_DATA);
 106exit:
 107        return status;
 108}
 109
 110static void qlge_get_both_serdes(struct qlge_adapter *qdev, u32 addr,
 111                                 u32 *direct_ptr, u32 *indirect_ptr,
 112                                 bool direct_valid, bool indirect_valid)
 113{
 114        unsigned int status;
 115
 116        status = 1;
 117        if (direct_valid)
 118                status = qlge_read_serdes_reg(qdev, addr, direct_ptr);
 119        /* Dead fill any failures or invalids. */
 120        if (status)
 121                *direct_ptr = 0xDEADBEEF;
 122
 123        status = 1;
 124        if (indirect_valid)
 125                status = qlge_read_other_func_serdes_reg(qdev, addr,
 126                                                         indirect_ptr);
 127        /* Dead fill any failures or invalids. */
 128        if (status)
 129                *indirect_ptr = 0xDEADBEEF;
 130}
 131
 132static int qlge_get_serdes_regs(struct qlge_adapter *qdev,
 133                                struct qlge_mpi_coredump *mpi_coredump)
 134{
 135        int status;
 136        bool xfi_direct_valid = false, xfi_indirect_valid = false;
 137        bool xaui_direct_valid = true, xaui_indirect_valid = true;
 138        unsigned int i;
 139        u32 *direct_ptr, temp;
 140        u32 *indirect_ptr;
 141
 142        /* The XAUI needs to be read out per port */
 143        status = qlge_read_other_func_serdes_reg(qdev,
 144                                                 XG_SERDES_XAUI_HSS_PCS_START,
 145                                                 &temp);
 146        if (status)
 147                temp = XG_SERDES_ADDR_XAUI_PWR_DOWN;
 148
 149        if ((temp & XG_SERDES_ADDR_XAUI_PWR_DOWN) ==
 150                                XG_SERDES_ADDR_XAUI_PWR_DOWN)
 151                xaui_indirect_valid = false;
 152
 153        status = qlge_read_serdes_reg(qdev, XG_SERDES_XAUI_HSS_PCS_START, &temp);
 154
 155        if (status)
 156                temp = XG_SERDES_ADDR_XAUI_PWR_DOWN;
 157
 158        if ((temp & XG_SERDES_ADDR_XAUI_PWR_DOWN) ==
 159                                XG_SERDES_ADDR_XAUI_PWR_DOWN)
 160                xaui_direct_valid = false;
 161
 162        /*
 163         * XFI register is shared so only need to read one
 164         * functions and then check the bits.
 165         */
 166        status = qlge_read_serdes_reg(qdev, XG_SERDES_ADDR_STS, &temp);
 167        if (status)
 168                temp = 0;
 169
 170        if ((temp & XG_SERDES_ADDR_XFI1_PWR_UP) ==
 171                                        XG_SERDES_ADDR_XFI1_PWR_UP) {
 172                /* now see if i'm NIC 1 or NIC 2 */
 173                if (qdev->func & 1)
 174                        /* I'm NIC 2, so the indirect (NIC1) xfi is up. */
 175                        xfi_indirect_valid = true;
 176                else
 177                        xfi_direct_valid = true;
 178        }
 179        if ((temp & XG_SERDES_ADDR_XFI2_PWR_UP) ==
 180                                        XG_SERDES_ADDR_XFI2_PWR_UP) {
 181                /* now see if i'm NIC 1 or NIC 2 */
 182                if (qdev->func & 1)
 183                        /* I'm NIC 2, so the indirect (NIC1) xfi is up. */
 184                        xfi_direct_valid = true;
 185                else
 186                        xfi_indirect_valid = true;
 187        }
 188
 189        /* Get XAUI_AN register block. */
 190        if (qdev->func & 1) {
 191                /* Function 2 is direct */
 192                direct_ptr = mpi_coredump->serdes2_xaui_an;
 193                indirect_ptr = mpi_coredump->serdes_xaui_an;
 194        } else {
 195                /* Function 1 is direct */
 196                direct_ptr = mpi_coredump->serdes_xaui_an;
 197                indirect_ptr = mpi_coredump->serdes2_xaui_an;
 198        }
 199
 200        for (i = 0; i <= 0x000000034; i += 4, direct_ptr++, indirect_ptr++)
 201                qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
 202                                     xaui_direct_valid, xaui_indirect_valid);
 203
 204        /* Get XAUI_HSS_PCS register block. */
 205        if (qdev->func & 1) {
 206                direct_ptr =
 207                        mpi_coredump->serdes2_xaui_hss_pcs;
 208                indirect_ptr =
 209                        mpi_coredump->serdes_xaui_hss_pcs;
 210        } else {
 211                direct_ptr =
 212                        mpi_coredump->serdes_xaui_hss_pcs;
 213                indirect_ptr =
 214                        mpi_coredump->serdes2_xaui_hss_pcs;
 215        }
 216
 217        for (i = 0x800; i <= 0x880; i += 4, direct_ptr++, indirect_ptr++)
 218                qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
 219                                     xaui_direct_valid, xaui_indirect_valid);
 220
 221        /* Get XAUI_XFI_AN register block. */
 222        if (qdev->func & 1) {
 223                direct_ptr = mpi_coredump->serdes2_xfi_an;
 224                indirect_ptr = mpi_coredump->serdes_xfi_an;
 225        } else {
 226                direct_ptr = mpi_coredump->serdes_xfi_an;
 227                indirect_ptr = mpi_coredump->serdes2_xfi_an;
 228        }
 229
 230        for (i = 0x1000; i <= 0x1034; i += 4, direct_ptr++, indirect_ptr++)
 231                qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
 232                                     xfi_direct_valid, xfi_indirect_valid);
 233
 234        /* Get XAUI_XFI_TRAIN register block. */
 235        if (qdev->func & 1) {
 236                direct_ptr = mpi_coredump->serdes2_xfi_train;
 237                indirect_ptr =
 238                        mpi_coredump->serdes_xfi_train;
 239        } else {
 240                direct_ptr = mpi_coredump->serdes_xfi_train;
 241                indirect_ptr =
 242                        mpi_coredump->serdes2_xfi_train;
 243        }
 244
 245        for (i = 0x1050; i <= 0x107c; i += 4, direct_ptr++, indirect_ptr++)
 246                qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
 247                                     xfi_direct_valid, xfi_indirect_valid);
 248
 249        /* Get XAUI_XFI_HSS_PCS register block. */
 250        if (qdev->func & 1) {
 251                direct_ptr =
 252                        mpi_coredump->serdes2_xfi_hss_pcs;
 253                indirect_ptr =
 254                        mpi_coredump->serdes_xfi_hss_pcs;
 255        } else {
 256                direct_ptr =
 257                        mpi_coredump->serdes_xfi_hss_pcs;
 258                indirect_ptr =
 259                        mpi_coredump->serdes2_xfi_hss_pcs;
 260        }
 261
 262        for (i = 0x1800; i <= 0x1838; i += 4, direct_ptr++, indirect_ptr++)
 263                qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
 264                                     xfi_direct_valid, xfi_indirect_valid);
 265
 266        /* Get XAUI_XFI_HSS_TX register block. */
 267        if (qdev->func & 1) {
 268                direct_ptr =
 269                        mpi_coredump->serdes2_xfi_hss_tx;
 270                indirect_ptr =
 271                        mpi_coredump->serdes_xfi_hss_tx;
 272        } else {
 273                direct_ptr = mpi_coredump->serdes_xfi_hss_tx;
 274                indirect_ptr =
 275                        mpi_coredump->serdes2_xfi_hss_tx;
 276        }
 277        for (i = 0x1c00; i <= 0x1c1f; i++, direct_ptr++, indirect_ptr++)
 278                qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
 279                                     xfi_direct_valid, xfi_indirect_valid);
 280
 281        /* Get XAUI_XFI_HSS_RX register block. */
 282        if (qdev->func & 1) {
 283                direct_ptr =
 284                        mpi_coredump->serdes2_xfi_hss_rx;
 285                indirect_ptr =
 286                        mpi_coredump->serdes_xfi_hss_rx;
 287        } else {
 288                direct_ptr = mpi_coredump->serdes_xfi_hss_rx;
 289                indirect_ptr =
 290                        mpi_coredump->serdes2_xfi_hss_rx;
 291        }
 292
 293        for (i = 0x1c40; i <= 0x1c5f; i++, direct_ptr++, indirect_ptr++)
 294                qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
 295                                     xfi_direct_valid, xfi_indirect_valid);
 296
 297        /* Get XAUI_XFI_HSS_PLL register block. */
 298        if (qdev->func & 1) {
 299                direct_ptr =
 300                        mpi_coredump->serdes2_xfi_hss_pll;
 301                indirect_ptr =
 302                        mpi_coredump->serdes_xfi_hss_pll;
 303        } else {
 304                direct_ptr =
 305                        mpi_coredump->serdes_xfi_hss_pll;
 306                indirect_ptr =
 307                        mpi_coredump->serdes2_xfi_hss_pll;
 308        }
 309        for (i = 0x1e00; i <= 0x1e1f; i++, direct_ptr++, indirect_ptr++)
 310                qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
 311                                     xfi_direct_valid, xfi_indirect_valid);
 312        return 0;
 313}
 314
 315static int qlge_read_other_func_xgmac_reg(struct qlge_adapter *qdev, u32 reg,
 316                                          u32 *data)
 317{
 318        int status = 0;
 319
 320        /* wait for reg to come ready */
 321        status = qlge_wait_other_func_reg_rdy(qdev, XGMAC_ADDR / 4,
 322                                              XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
 323        if (status)
 324                goto exit;
 325
 326        /* set up for reg read */
 327        qlge_write_other_func_reg(qdev, XGMAC_ADDR / 4, reg | XGMAC_ADDR_R);
 328
 329        /* wait for reg to come ready */
 330        status = qlge_wait_other_func_reg_rdy(qdev, XGMAC_ADDR / 4,
 331                                              XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
 332        if (status)
 333                goto exit;
 334
 335        /* get the data */
 336        *data = qlge_read_other_func_reg(qdev, XGMAC_DATA / 4);
 337exit:
 338        return status;
 339}
 340
 341/* Read the 400 xgmac control/statistics registers
 342 * skipping unused locations.
 343 */
 344static int qlge_get_xgmac_regs(struct qlge_adapter *qdev, u32 *buf,
 345                               unsigned int other_function)
 346{
 347        int status = 0;
 348        int i;
 349
 350        for (i = PAUSE_SRC_LO; i < XGMAC_REGISTER_END; i += 4, buf++) {
 351                /* We're reading 400 xgmac registers, but we filter out
 352                 * several locations that are non-responsive to reads.
 353                 */
 354                if ((i == 0x00000114) ||
 355                    (i == 0x00000118) ||
 356                        (i == 0x0000013c) ||
 357                        (i == 0x00000140) ||
 358                        (i > 0x00000150 && i < 0x000001fc) ||
 359                        (i > 0x00000278 && i < 0x000002a0) ||
 360                        (i > 0x000002c0 && i < 0x000002cf) ||
 361                        (i > 0x000002dc && i < 0x000002f0) ||
 362                        (i > 0x000003c8 && i < 0x00000400) ||
 363                        (i > 0x00000400 && i < 0x00000410) ||
 364                        (i > 0x00000410 && i < 0x00000420) ||
 365                        (i > 0x00000420 && i < 0x00000430) ||
 366                        (i > 0x00000430 && i < 0x00000440) ||
 367                        (i > 0x00000440 && i < 0x00000450) ||
 368                        (i > 0x00000450 && i < 0x00000500) ||
 369                        (i > 0x0000054c && i < 0x00000568) ||
 370                        (i > 0x000005c8 && i < 0x00000600)) {
 371                        if (other_function)
 372                                status =
 373                                qlge_read_other_func_xgmac_reg(qdev, i, buf);
 374                        else
 375                                status = qlge_read_xgmac_reg(qdev, i, buf);
 376
 377                        if (status)
 378                                *buf = 0xdeadbeef;
 379                        break;
 380                }
 381        }
 382        return status;
 383}
 384
 385static int qlge_get_ets_regs(struct qlge_adapter *qdev, u32 *buf)
 386{
 387        int i;
 388
 389        for (i = 0; i < 8; i++, buf++) {
 390                qlge_write32(qdev, NIC_ETS, i << 29 | 0x08000000);
 391                *buf = qlge_read32(qdev, NIC_ETS);
 392        }
 393
 394        for (i = 0; i < 2; i++, buf++) {
 395                qlge_write32(qdev, CNA_ETS, i << 29 | 0x08000000);
 396                *buf = qlge_read32(qdev, CNA_ETS);
 397        }
 398
 399        return 0;
 400}
 401
 402static void qlge_get_intr_states(struct qlge_adapter *qdev, u32 *buf)
 403{
 404        int i;
 405
 406        for (i = 0; i < qdev->rx_ring_count; i++, buf++) {
 407                qlge_write32(qdev, INTR_EN,
 408                             qdev->intr_context[i].intr_read_mask);
 409                *buf = qlge_read32(qdev, INTR_EN);
 410        }
 411}
 412
 413static int qlge_get_cam_entries(struct qlge_adapter *qdev, u32 *buf)
 414{
 415        int i, status;
 416        u32 value[3];
 417
 418        status = qlge_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
 419        if (status)
 420                return status;
 421
 422        for (i = 0; i < 16; i++) {
 423                status = qlge_get_mac_addr_reg(qdev,
 424                                               MAC_ADDR_TYPE_CAM_MAC, i, value);
 425                if (status) {
 426                        netif_err(qdev, drv, qdev->ndev,
 427                                  "Failed read of mac index register\n");
 428                        goto err;
 429                }
 430                *buf++ = value[0];      /* lower MAC address */
 431                *buf++ = value[1];      /* upper MAC address */
 432                *buf++ = value[2];      /* output */
 433        }
 434        for (i = 0; i < 32; i++) {
 435                status = qlge_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_MULTI_MAC,
 436                                               i, value);
 437                if (status) {
 438                        netif_err(qdev, drv, qdev->ndev,
 439                                  "Failed read of mac index register\n");
 440                        goto err;
 441                }
 442                *buf++ = value[0];      /* lower Mcast address */
 443                *buf++ = value[1];      /* upper Mcast address */
 444        }
 445err:
 446        qlge_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
 447        return status;
 448}
 449
 450static int qlge_get_routing_entries(struct qlge_adapter *qdev, u32 *buf)
 451{
 452        int status;
 453        u32 value, i;
 454
 455        status = qlge_sem_spinlock(qdev, SEM_RT_IDX_MASK);
 456        if (status)
 457                return status;
 458
 459        for (i = 0; i < 16; i++) {
 460                status = qlge_get_routing_reg(qdev, i, &value);
 461                if (status) {
 462                        netif_err(qdev, drv, qdev->ndev,
 463                                  "Failed read of routing index register\n");
 464                        goto err;
 465                } else {
 466                        *buf++ = value;
 467                }
 468        }
 469err:
 470        qlge_sem_unlock(qdev, SEM_RT_IDX_MASK);
 471        return status;
 472}
 473
 474/* Read the MPI Processor shadow registers */
 475static int qlge_get_mpi_shadow_regs(struct qlge_adapter *qdev, u32 *buf)
 476{
 477        u32 i;
 478        int status;
 479
 480        for (i = 0; i < MPI_CORE_SH_REGS_CNT; i++, buf++) {
 481                status = qlge_write_mpi_reg(qdev,
 482                                            RISC_124,
 483                                            (SHADOW_OFFSET | i << SHADOW_REG_SHIFT));
 484                if (status)
 485                        goto end;
 486                status = qlge_read_mpi_reg(qdev, RISC_127, buf);
 487                if (status)
 488                        goto end;
 489        }
 490end:
 491        return status;
 492}
 493
 494/* Read the MPI Processor core registers */
 495static int qlge_get_mpi_regs(struct qlge_adapter *qdev, u32 *buf,
 496                             u32 offset, u32 count)
 497{
 498        int i, status = 0;
 499
 500        for (i = 0; i < count; i++, buf++) {
 501                status = qlge_read_mpi_reg(qdev, offset + i, buf);
 502                if (status)
 503                        return status;
 504        }
 505        return status;
 506}
 507
 508/* Read the ASIC probe dump */
 509static unsigned int *qlge_get_probe(struct qlge_adapter *qdev, u32 clock,
 510                                    u32 valid, u32 *buf)
 511{
 512        u32 module, mux_sel, probe, lo_val, hi_val;
 513
 514        for (module = 0; module < PRB_MX_ADDR_MAX_MODS; module++) {
 515                if (!((valid >> module) & 1))
 516                        continue;
 517                for (mux_sel = 0; mux_sel < PRB_MX_ADDR_MAX_MUX; mux_sel++) {
 518                        probe = clock
 519                                | PRB_MX_ADDR_ARE
 520                                | mux_sel
 521                                | (module << PRB_MX_ADDR_MOD_SEL_SHIFT);
 522                        qlge_write32(qdev, PRB_MX_ADDR, probe);
 523                        lo_val = qlge_read32(qdev, PRB_MX_DATA);
 524                        if (mux_sel == 0) {
 525                                *buf = probe;
 526                                buf++;
 527                        }
 528                        probe |= PRB_MX_ADDR_UP;
 529                        qlge_write32(qdev, PRB_MX_ADDR, probe);
 530                        hi_val = qlge_read32(qdev, PRB_MX_DATA);
 531                        *buf = lo_val;
 532                        buf++;
 533                        *buf = hi_val;
 534                        buf++;
 535                }
 536        }
 537        return buf;
 538}
 539
 540static int qlge_get_probe_dump(struct qlge_adapter *qdev, unsigned int *buf)
 541{
 542        /* First we have to enable the probe mux */
 543        qlge_write_mpi_reg(qdev, MPI_TEST_FUNC_PRB_CTL, MPI_TEST_FUNC_PRB_EN);
 544        buf = qlge_get_probe(qdev, PRB_MX_ADDR_SYS_CLOCK,
 545                             PRB_MX_ADDR_VALID_SYS_MOD, buf);
 546        buf = qlge_get_probe(qdev, PRB_MX_ADDR_PCI_CLOCK,
 547                             PRB_MX_ADDR_VALID_PCI_MOD, buf);
 548        buf = qlge_get_probe(qdev, PRB_MX_ADDR_XGM_CLOCK,
 549                             PRB_MX_ADDR_VALID_XGM_MOD, buf);
 550        buf = qlge_get_probe(qdev, PRB_MX_ADDR_FC_CLOCK,
 551                             PRB_MX_ADDR_VALID_FC_MOD, buf);
 552        return 0;
 553}
 554
 555/* Read out the routing index registers */
 556static int qlge_get_routing_index_registers(struct qlge_adapter *qdev, u32 *buf)
 557{
 558        int status;
 559        u32 type, index, index_max;
 560        u32 result_index;
 561        u32 result_data;
 562        u32 val;
 563
 564        status = qlge_sem_spinlock(qdev, SEM_RT_IDX_MASK);
 565        if (status)
 566                return status;
 567
 568        for (type = 0; type < 4; type++) {
 569                if (type < 2)
 570                        index_max = 8;
 571                else
 572                        index_max = 16;
 573                for (index = 0; index < index_max; index++) {
 574                        val = RT_IDX_RS
 575                                | (type << RT_IDX_TYPE_SHIFT)
 576                                | (index << RT_IDX_IDX_SHIFT);
 577                        qlge_write32(qdev, RT_IDX, val);
 578                        result_index = 0;
 579                        while ((result_index & RT_IDX_MR) == 0)
 580                                result_index = qlge_read32(qdev, RT_IDX);
 581                        result_data = qlge_read32(qdev, RT_DATA);
 582                        *buf = type;
 583                        buf++;
 584                        *buf = index;
 585                        buf++;
 586                        *buf = result_index;
 587                        buf++;
 588                        *buf = result_data;
 589                        buf++;
 590                }
 591        }
 592        qlge_sem_unlock(qdev, SEM_RT_IDX_MASK);
 593        return status;
 594}
 595
 596/* Read out the MAC protocol registers */
 597static void qlge_get_mac_protocol_registers(struct qlge_adapter *qdev, u32 *buf)
 598{
 599        u32 result_index, result_data;
 600        u32 type;
 601        u32 index;
 602        u32 offset;
 603        u32 val;
 604        u32 initial_val = MAC_ADDR_RS;
 605        u32 max_index;
 606        u32 max_offset;
 607
 608        for (type = 0; type < MAC_ADDR_TYPE_COUNT; type++) {
 609                switch (type) {
 610                case 0: /* CAM */
 611                        initial_val |= MAC_ADDR_ADR;
 612                        max_index = MAC_ADDR_MAX_CAM_ENTRIES;
 613                        max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
 614                        break;
 615                case 1: /* Multicast MAC Address */
 616                        max_index = MAC_ADDR_MAX_CAM_WCOUNT;
 617                        max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
 618                        break;
 619                case 2: /* VLAN filter mask */
 620                case 3: /* MC filter mask */
 621                        max_index = MAC_ADDR_MAX_CAM_WCOUNT;
 622                        max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
 623                        break;
 624                case 4: /* FC MAC addresses */
 625                        max_index = MAC_ADDR_MAX_FC_MAC_ENTRIES;
 626                        max_offset = MAC_ADDR_MAX_FC_MAC_WCOUNT;
 627                        break;
 628                case 5: /* Mgmt MAC addresses */
 629                        max_index = MAC_ADDR_MAX_MGMT_MAC_ENTRIES;
 630                        max_offset = MAC_ADDR_MAX_MGMT_MAC_WCOUNT;
 631                        break;
 632                case 6: /* Mgmt VLAN addresses */
 633                        max_index = MAC_ADDR_MAX_MGMT_VLAN_ENTRIES;
 634                        max_offset = MAC_ADDR_MAX_MGMT_VLAN_WCOUNT;
 635                        break;
 636                case 7: /* Mgmt IPv4 address */
 637                        max_index = MAC_ADDR_MAX_MGMT_V4_ENTRIES;
 638                        max_offset = MAC_ADDR_MAX_MGMT_V4_WCOUNT;
 639                        break;
 640                case 8: /* Mgmt IPv6 address */
 641                        max_index = MAC_ADDR_MAX_MGMT_V6_ENTRIES;
 642                        max_offset = MAC_ADDR_MAX_MGMT_V6_WCOUNT;
 643                        break;
 644                case 9: /* Mgmt TCP/UDP Dest port */
 645                        max_index = MAC_ADDR_MAX_MGMT_TU_DP_ENTRIES;
 646                        max_offset = MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT;
 647                        break;
 648                default:
 649                        netdev_err(qdev->ndev, "Bad type!!! 0x%08x\n", type);
 650                        max_index = 0;
 651                        max_offset = 0;
 652                        break;
 653                }
 654                for (index = 0; index < max_index; index++) {
 655                        for (offset = 0; offset < max_offset; offset++) {
 656                                val = initial_val
 657                                        | (type << MAC_ADDR_TYPE_SHIFT)
 658                                        | (index << MAC_ADDR_IDX_SHIFT)
 659                                        | (offset);
 660                                qlge_write32(qdev, MAC_ADDR_IDX, val);
 661                                result_index = 0;
 662                                while ((result_index & MAC_ADDR_MR) == 0) {
 663                                        result_index = qlge_read32(qdev,
 664                                                                   MAC_ADDR_IDX);
 665                                }
 666                                result_data = qlge_read32(qdev, MAC_ADDR_DATA);
 667                                *buf = result_index;
 668                                buf++;
 669                                *buf = result_data;
 670                                buf++;
 671                        }
 672                }
 673        }
 674}
 675
 676static void qlge_get_sem_registers(struct qlge_adapter *qdev, u32 *buf)
 677{
 678        u32 func_num, reg, reg_val;
 679        int status;
 680
 681        for (func_num = 0; func_num < MAX_SEMAPHORE_FUNCTIONS ; func_num++) {
 682                reg = MPI_NIC_REG_BLOCK
 683                        | (func_num << MPI_NIC_FUNCTION_SHIFT)
 684                        | (SEM / 4);
 685                status = qlge_read_mpi_reg(qdev, reg, &reg_val);
 686                *buf = reg_val;
 687                /* if the read failed then dead fill the element. */
 688                if (!status)
 689                        *buf = 0xdeadbeef;
 690                buf++;
 691        }
 692}
 693
 694/* Create a coredump segment header */
 695static void qlge_build_coredump_seg_header(struct mpi_coredump_segment_header *seg_hdr,
 696                                           u32 seg_number, u32 seg_size, u8 *desc)
 697{
 698        memset(seg_hdr, 0, sizeof(struct mpi_coredump_segment_header));
 699        seg_hdr->cookie = MPI_COREDUMP_COOKIE;
 700        seg_hdr->seg_num = seg_number;
 701        seg_hdr->seg_size = seg_size;
 702        strncpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
 703}
 704
 705/*
 706 * This function should be called when a coredump / probedump
 707 * is to be extracted from the HBA. It is assumed there is a
 708 * qdev structure that contains the base address of the register
 709 * space for this function as well as a coredump structure that
 710 * will contain the dump.
 711 */
 712int qlge_core_dump(struct qlge_adapter *qdev, struct qlge_mpi_coredump *mpi_coredump)
 713{
 714        int status;
 715        int i;
 716
 717        if (!mpi_coredump) {
 718                netif_err(qdev, drv, qdev->ndev, "No memory allocated\n");
 719                return -EINVAL;
 720        }
 721
 722        /* Try to get the spinlock, but dont worry if
 723         * it isn't available.  If the firmware died it
 724         * might be holding the sem.
 725         */
 726        qlge_sem_spinlock(qdev, SEM_PROC_REG_MASK);
 727
 728        status = qlge_pause_mpi_risc(qdev);
 729        if (status) {
 730                netif_err(qdev, drv, qdev->ndev,
 731                          "Failed RISC pause. Status = 0x%.08x\n", status);
 732                goto err;
 733        }
 734
 735        /* Insert the global header */
 736        memset(&mpi_coredump->mpi_global_header, 0,
 737               sizeof(struct mpi_coredump_global_header));
 738        mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
 739        mpi_coredump->mpi_global_header.header_size =
 740                sizeof(struct mpi_coredump_global_header);
 741        mpi_coredump->mpi_global_header.image_size =
 742                sizeof(struct qlge_mpi_coredump);
 743        strncpy(mpi_coredump->mpi_global_header.id_string, "MPI Coredump",
 744                sizeof(mpi_coredump->mpi_global_header.id_string));
 745
 746        /* Get generic NIC reg dump */
 747        qlge_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr,
 748                                       NIC1_CONTROL_SEG_NUM,
 749                                       sizeof(struct mpi_coredump_segment_header) +
 750                                       sizeof(mpi_coredump->nic_regs), "NIC1 Registers");
 751
 752        qlge_build_coredump_seg_header(&mpi_coredump->nic2_regs_seg_hdr,
 753                                       NIC2_CONTROL_SEG_NUM,
 754                                       sizeof(struct mpi_coredump_segment_header) +
 755                                       sizeof(mpi_coredump->nic2_regs), "NIC2 Registers");
 756
 757        /* Get XGMac registers. (Segment 18, Rev C. step 21) */
 758        qlge_build_coredump_seg_header(&mpi_coredump->xgmac1_seg_hdr,
 759                                       NIC1_XGMAC_SEG_NUM,
 760                                       sizeof(struct mpi_coredump_segment_header) +
 761                                       sizeof(mpi_coredump->xgmac1), "NIC1 XGMac Registers");
 762
 763        qlge_build_coredump_seg_header(&mpi_coredump->xgmac2_seg_hdr,
 764                                       NIC2_XGMAC_SEG_NUM,
 765                                       sizeof(struct mpi_coredump_segment_header) +
 766                                       sizeof(mpi_coredump->xgmac2), "NIC2 XGMac Registers");
 767
 768        if (qdev->func & 1) {
 769                /* Odd means our function is NIC 2 */
 770                for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
 771                        mpi_coredump->nic2_regs[i] =
 772                                qlge_read32(qdev, i * sizeof(u32));
 773
 774                for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
 775                        mpi_coredump->nic_regs[i] =
 776                                qlge_read_other_func_reg(qdev, (i * sizeof(u32)) / 4);
 777
 778                qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac2[0], 0);
 779                qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac1[0], 1);
 780        } else {
 781                /* Even means our function is NIC 1 */
 782                for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
 783                        mpi_coredump->nic_regs[i] =
 784                                qlge_read32(qdev, i * sizeof(u32));
 785                for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
 786                        mpi_coredump->nic2_regs[i] =
 787                                qlge_read_other_func_reg(qdev, (i * sizeof(u32)) / 4);
 788
 789                qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac1[0], 0);
 790                qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac2[0], 1);
 791        }
 792
 793        /* Rev C. Step 20a */
 794        qlge_build_coredump_seg_header(&mpi_coredump->xaui_an_hdr,
 795                                       XAUI_AN_SEG_NUM,
 796                                       sizeof(struct mpi_coredump_segment_header) +
 797                                       sizeof(mpi_coredump->serdes_xaui_an),
 798                                       "XAUI AN Registers");
 799
 800        /* Rev C. Step 20b */
 801        qlge_build_coredump_seg_header(&mpi_coredump->xaui_hss_pcs_hdr,
 802                                       XAUI_HSS_PCS_SEG_NUM,
 803                                       sizeof(struct mpi_coredump_segment_header) +
 804                                       sizeof(mpi_coredump->serdes_xaui_hss_pcs),
 805                                       "XAUI HSS PCS Registers");
 806
 807        qlge_build_coredump_seg_header(&mpi_coredump->xfi_an_hdr, XFI_AN_SEG_NUM,
 808                                       sizeof(struct mpi_coredump_segment_header) +
 809                                       sizeof(mpi_coredump->serdes_xfi_an),
 810                                       "XFI AN Registers");
 811
 812        qlge_build_coredump_seg_header(&mpi_coredump->xfi_train_hdr,
 813                                       XFI_TRAIN_SEG_NUM,
 814                                       sizeof(struct mpi_coredump_segment_header) +
 815                                       sizeof(mpi_coredump->serdes_xfi_train),
 816                                       "XFI TRAIN Registers");
 817
 818        qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_pcs_hdr,
 819                                       XFI_HSS_PCS_SEG_NUM,
 820                                       sizeof(struct mpi_coredump_segment_header) +
 821                                       sizeof(mpi_coredump->serdes_xfi_hss_pcs),
 822                                       "XFI HSS PCS Registers");
 823
 824        qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_tx_hdr,
 825                                       XFI_HSS_TX_SEG_NUM,
 826                                       sizeof(struct mpi_coredump_segment_header) +
 827                                       sizeof(mpi_coredump->serdes_xfi_hss_tx),
 828                                       "XFI HSS TX Registers");
 829
 830        qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_rx_hdr,
 831                                       XFI_HSS_RX_SEG_NUM,
 832                                       sizeof(struct mpi_coredump_segment_header) +
 833                                       sizeof(mpi_coredump->serdes_xfi_hss_rx),
 834                                       "XFI HSS RX Registers");
 835
 836        qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_pll_hdr,
 837                                       XFI_HSS_PLL_SEG_NUM,
 838                                       sizeof(struct mpi_coredump_segment_header) +
 839                                       sizeof(mpi_coredump->serdes_xfi_hss_pll),
 840                                       "XFI HSS PLL Registers");
 841
 842        qlge_build_coredump_seg_header(&mpi_coredump->xaui2_an_hdr,
 843                                       XAUI2_AN_SEG_NUM,
 844                                       sizeof(struct mpi_coredump_segment_header) +
 845                                       sizeof(mpi_coredump->serdes2_xaui_an),
 846                                       "XAUI2 AN Registers");
 847
 848        qlge_build_coredump_seg_header(&mpi_coredump->xaui2_hss_pcs_hdr,
 849                                       XAUI2_HSS_PCS_SEG_NUM,
 850                                       sizeof(struct mpi_coredump_segment_header) +
 851                                       sizeof(mpi_coredump->serdes2_xaui_hss_pcs),
 852                                       "XAUI2 HSS PCS Registers");
 853
 854        qlge_build_coredump_seg_header(&mpi_coredump->xfi2_an_hdr,
 855                                       XFI2_AN_SEG_NUM,
 856                                       sizeof(struct mpi_coredump_segment_header) +
 857                                       sizeof(mpi_coredump->serdes2_xfi_an),
 858                                       "XFI2 AN Registers");
 859
 860        qlge_build_coredump_seg_header(&mpi_coredump->xfi2_train_hdr,
 861                                       XFI2_TRAIN_SEG_NUM,
 862                                       sizeof(struct mpi_coredump_segment_header) +
 863                                       sizeof(mpi_coredump->serdes2_xfi_train),
 864                                       "XFI2 TRAIN Registers");
 865
 866        qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_pcs_hdr,
 867                                       XFI2_HSS_PCS_SEG_NUM,
 868                                       sizeof(struct mpi_coredump_segment_header) +
 869                                       sizeof(mpi_coredump->serdes2_xfi_hss_pcs),
 870                                       "XFI2 HSS PCS Registers");
 871
 872        qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_tx_hdr,
 873                                       XFI2_HSS_TX_SEG_NUM,
 874                                       sizeof(struct mpi_coredump_segment_header) +
 875                                       sizeof(mpi_coredump->serdes2_xfi_hss_tx),
 876                                       "XFI2 HSS TX Registers");
 877
 878        qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_rx_hdr,
 879                                       XFI2_HSS_RX_SEG_NUM,
 880                                       sizeof(struct mpi_coredump_segment_header) +
 881                                       sizeof(mpi_coredump->serdes2_xfi_hss_rx),
 882                                       "XFI2 HSS RX Registers");
 883
 884        qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_pll_hdr,
 885                                       XFI2_HSS_PLL_SEG_NUM,
 886                                       sizeof(struct mpi_coredump_segment_header) +
 887                                       sizeof(mpi_coredump->serdes2_xfi_hss_pll),
 888                                       "XFI2 HSS PLL Registers");
 889
 890        status = qlge_get_serdes_regs(qdev, mpi_coredump);
 891        if (status) {
 892                netif_err(qdev, drv, qdev->ndev,
 893                          "Failed Dump of Serdes Registers. Status = 0x%.08x\n",
 894                          status);
 895                goto err;
 896        }
 897
 898        qlge_build_coredump_seg_header(&mpi_coredump->core_regs_seg_hdr,
 899                                       CORE_SEG_NUM,
 900                                       sizeof(mpi_coredump->core_regs_seg_hdr) +
 901                                       sizeof(mpi_coredump->mpi_core_regs) +
 902                                       sizeof(mpi_coredump->mpi_core_sh_regs),
 903                                       "Core Registers");
 904
 905        /* Get the MPI Core Registers */
 906        status = qlge_get_mpi_regs(qdev, &mpi_coredump->mpi_core_regs[0],
 907                                   MPI_CORE_REGS_ADDR, MPI_CORE_REGS_CNT);
 908        if (status)
 909                goto err;
 910        /* Get the 16 MPI shadow registers */
 911        status = qlge_get_mpi_shadow_regs(qdev,
 912                                          &mpi_coredump->mpi_core_sh_regs[0]);
 913        if (status)
 914                goto err;
 915
 916        /* Get the Test Logic Registers */
 917        qlge_build_coredump_seg_header(&mpi_coredump->test_logic_regs_seg_hdr,
 918                                       TEST_LOGIC_SEG_NUM,
 919                                       sizeof(struct mpi_coredump_segment_header)
 920                                       + sizeof(mpi_coredump->test_logic_regs),
 921                                       "Test Logic Regs");
 922        status = qlge_get_mpi_regs(qdev, &mpi_coredump->test_logic_regs[0],
 923                                   TEST_REGS_ADDR, TEST_REGS_CNT);
 924        if (status)
 925                goto err;
 926
 927        /* Get the RMII Registers */
 928        qlge_build_coredump_seg_header(&mpi_coredump->rmii_regs_seg_hdr,
 929                                       RMII_SEG_NUM,
 930                                       sizeof(struct mpi_coredump_segment_header)
 931                                       + sizeof(mpi_coredump->rmii_regs),
 932                                       "RMII Registers");
 933        status = qlge_get_mpi_regs(qdev, &mpi_coredump->rmii_regs[0],
 934                                   RMII_REGS_ADDR, RMII_REGS_CNT);
 935        if (status)
 936                goto err;
 937
 938        /* Get the FCMAC1 Registers */
 939        qlge_build_coredump_seg_header(&mpi_coredump->fcmac1_regs_seg_hdr,
 940                                       FCMAC1_SEG_NUM,
 941                                       sizeof(struct mpi_coredump_segment_header)
 942                                       + sizeof(mpi_coredump->fcmac1_regs),
 943                                       "FCMAC1 Registers");
 944        status = qlge_get_mpi_regs(qdev, &mpi_coredump->fcmac1_regs[0],
 945                                   FCMAC1_REGS_ADDR, FCMAC_REGS_CNT);
 946        if (status)
 947                goto err;
 948
 949        /* Get the FCMAC2 Registers */
 950
 951        qlge_build_coredump_seg_header(&mpi_coredump->fcmac2_regs_seg_hdr,
 952                                       FCMAC2_SEG_NUM,
 953                                       sizeof(struct mpi_coredump_segment_header)
 954                                       + sizeof(mpi_coredump->fcmac2_regs),
 955                                       "FCMAC2 Registers");
 956
 957        status = qlge_get_mpi_regs(qdev, &mpi_coredump->fcmac2_regs[0],
 958                                   FCMAC2_REGS_ADDR, FCMAC_REGS_CNT);
 959        if (status)
 960                goto err;
 961
 962        /* Get the FC1 MBX Registers */
 963        qlge_build_coredump_seg_header(&mpi_coredump->fc1_mbx_regs_seg_hdr,
 964                                       FC1_MBOX_SEG_NUM,
 965                                       sizeof(struct mpi_coredump_segment_header)
 966                                       + sizeof(mpi_coredump->fc1_mbx_regs),
 967                                       "FC1 MBox Regs");
 968        status = qlge_get_mpi_regs(qdev, &mpi_coredump->fc1_mbx_regs[0],
 969                                   FC1_MBX_REGS_ADDR, FC_MBX_REGS_CNT);
 970        if (status)
 971                goto err;
 972
 973        /* Get the IDE Registers */
 974        qlge_build_coredump_seg_header(&mpi_coredump->ide_regs_seg_hdr,
 975                                       IDE_SEG_NUM,
 976                                       sizeof(struct mpi_coredump_segment_header)
 977                                       + sizeof(mpi_coredump->ide_regs),
 978                                       "IDE Registers");
 979        status = qlge_get_mpi_regs(qdev, &mpi_coredump->ide_regs[0],
 980                                   IDE_REGS_ADDR, IDE_REGS_CNT);
 981        if (status)
 982                goto err;
 983
 984        /* Get the NIC1 MBX Registers */
 985        qlge_build_coredump_seg_header(&mpi_coredump->nic1_mbx_regs_seg_hdr,
 986                                       NIC1_MBOX_SEG_NUM,
 987                                       sizeof(struct mpi_coredump_segment_header)
 988                                       + sizeof(mpi_coredump->nic1_mbx_regs),
 989                                       "NIC1 MBox Regs");
 990        status = qlge_get_mpi_regs(qdev, &mpi_coredump->nic1_mbx_regs[0],
 991                                   NIC1_MBX_REGS_ADDR, NIC_MBX_REGS_CNT);
 992        if (status)
 993                goto err;
 994
 995        /* Get the SMBus Registers */
 996        qlge_build_coredump_seg_header(&mpi_coredump->smbus_regs_seg_hdr,
 997                                       SMBUS_SEG_NUM,
 998                                       sizeof(struct mpi_coredump_segment_header)
 999                                       + sizeof(mpi_coredump->smbus_regs),
1000                                       "SMBus Registers");
1001        status = qlge_get_mpi_regs(qdev, &mpi_coredump->smbus_regs[0],
1002                                   SMBUS_REGS_ADDR, SMBUS_REGS_CNT);
1003        if (status)
1004                goto err;
1005
1006        /* Get the FC2 MBX Registers */
1007        qlge_build_coredump_seg_header(&mpi_coredump->fc2_mbx_regs_seg_hdr,
1008                                       FC2_MBOX_SEG_NUM,
1009                                       sizeof(struct mpi_coredump_segment_header)
1010                                       + sizeof(mpi_coredump->fc2_mbx_regs),
1011                                       "FC2 MBox Regs");
1012        status = qlge_get_mpi_regs(qdev, &mpi_coredump->fc2_mbx_regs[0],
1013                                   FC2_MBX_REGS_ADDR, FC_MBX_REGS_CNT);
1014        if (status)
1015                goto err;
1016
1017        /* Get the NIC2 MBX Registers */
1018        qlge_build_coredump_seg_header(&mpi_coredump->nic2_mbx_regs_seg_hdr,
1019                                       NIC2_MBOX_SEG_NUM,
1020                                       sizeof(struct mpi_coredump_segment_header)
1021                                       + sizeof(mpi_coredump->nic2_mbx_regs),
1022                                       "NIC2 MBox Regs");
1023        status = qlge_get_mpi_regs(qdev, &mpi_coredump->nic2_mbx_regs[0],
1024                                   NIC2_MBX_REGS_ADDR, NIC_MBX_REGS_CNT);
1025        if (status)
1026                goto err;
1027
1028        /* Get the I2C Registers */
1029        qlge_build_coredump_seg_header(&mpi_coredump->i2c_regs_seg_hdr,
1030                                       I2C_SEG_NUM,
1031                                       sizeof(struct mpi_coredump_segment_header)
1032                                       + sizeof(mpi_coredump->i2c_regs),
1033                                       "I2C Registers");
1034        status = qlge_get_mpi_regs(qdev, &mpi_coredump->i2c_regs[0],
1035                                   I2C_REGS_ADDR, I2C_REGS_CNT);
1036        if (status)
1037                goto err;
1038
1039        /* Get the MEMC Registers */
1040        qlge_build_coredump_seg_header(&mpi_coredump->memc_regs_seg_hdr,
1041                                       MEMC_SEG_NUM,
1042                                       sizeof(struct mpi_coredump_segment_header)
1043                                       + sizeof(mpi_coredump->memc_regs),
1044                                       "MEMC Registers");
1045        status = qlge_get_mpi_regs(qdev, &mpi_coredump->memc_regs[0],
1046                                   MEMC_REGS_ADDR, MEMC_REGS_CNT);
1047        if (status)
1048                goto err;
1049
1050        /* Get the PBus Registers */
1051        qlge_build_coredump_seg_header(&mpi_coredump->pbus_regs_seg_hdr,
1052                                       PBUS_SEG_NUM,
1053                                       sizeof(struct mpi_coredump_segment_header)
1054                                       + sizeof(mpi_coredump->pbus_regs),
1055                                       "PBUS Registers");
1056        status = qlge_get_mpi_regs(qdev, &mpi_coredump->pbus_regs[0],
1057                                   PBUS_REGS_ADDR, PBUS_REGS_CNT);
1058        if (status)
1059                goto err;
1060
1061        /* Get the MDE Registers */
1062        qlge_build_coredump_seg_header(&mpi_coredump->mde_regs_seg_hdr,
1063                                       MDE_SEG_NUM,
1064                                       sizeof(struct mpi_coredump_segment_header)
1065                                       + sizeof(mpi_coredump->mde_regs),
1066                                       "MDE Registers");
1067        status = qlge_get_mpi_regs(qdev, &mpi_coredump->mde_regs[0],
1068                                   MDE_REGS_ADDR, MDE_REGS_CNT);
1069        if (status)
1070                goto err;
1071
1072        qlge_build_coredump_seg_header(&mpi_coredump->misc_nic_seg_hdr,
1073                                       MISC_NIC_INFO_SEG_NUM,
1074                                       sizeof(struct mpi_coredump_segment_header)
1075                                       + sizeof(mpi_coredump->misc_nic_info),
1076                                       "MISC NIC INFO");
1077        mpi_coredump->misc_nic_info.rx_ring_count = qdev->rx_ring_count;
1078        mpi_coredump->misc_nic_info.tx_ring_count = qdev->tx_ring_count;
1079        mpi_coredump->misc_nic_info.intr_count = qdev->intr_count;
1080        mpi_coredump->misc_nic_info.function = qdev->func;
1081
1082        /* Segment 31 */
1083        /* Get indexed register values. */
1084        qlge_build_coredump_seg_header(&mpi_coredump->intr_states_seg_hdr,
1085                                       INTR_STATES_SEG_NUM,
1086                                       sizeof(struct mpi_coredump_segment_header)
1087                                       + sizeof(mpi_coredump->intr_states),
1088                                       "INTR States");
1089        qlge_get_intr_states(qdev, &mpi_coredump->intr_states[0]);
1090
1091        qlge_build_coredump_seg_header(&mpi_coredump->cam_entries_seg_hdr,
1092                                       CAM_ENTRIES_SEG_NUM,
1093                                       sizeof(struct mpi_coredump_segment_header)
1094                                       + sizeof(mpi_coredump->cam_entries),
1095                                       "CAM Entries");
1096        status = qlge_get_cam_entries(qdev, &mpi_coredump->cam_entries[0]);
1097        if (status)
1098                goto err;
1099
1100        qlge_build_coredump_seg_header(&mpi_coredump->nic_routing_words_seg_hdr,
1101                                       ROUTING_WORDS_SEG_NUM,
1102                                       sizeof(struct mpi_coredump_segment_header)
1103                                       + sizeof(mpi_coredump->nic_routing_words),
1104                                       "Routing Words");
1105        status = qlge_get_routing_entries(qdev,
1106                                          &mpi_coredump->nic_routing_words[0]);
1107        if (status)
1108                goto err;
1109
1110        /* Segment 34 (Rev C. step 23) */
1111        qlge_build_coredump_seg_header(&mpi_coredump->ets_seg_hdr,
1112                                       ETS_SEG_NUM,
1113                                       sizeof(struct mpi_coredump_segment_header)
1114                                       + sizeof(mpi_coredump->ets),
1115                                       "ETS Registers");
1116        status = qlge_get_ets_regs(qdev, &mpi_coredump->ets[0]);
1117        if (status)
1118                goto err;
1119
1120        qlge_build_coredump_seg_header(&mpi_coredump->probe_dump_seg_hdr,
1121                                       PROBE_DUMP_SEG_NUM,
1122                                       sizeof(struct mpi_coredump_segment_header)
1123                                       + sizeof(mpi_coredump->probe_dump),
1124                                       "Probe Dump");
1125        qlge_get_probe_dump(qdev, &mpi_coredump->probe_dump[0]);
1126
1127        qlge_build_coredump_seg_header(&mpi_coredump->routing_reg_seg_hdr,
1128                                       ROUTING_INDEX_SEG_NUM,
1129                                       sizeof(struct mpi_coredump_segment_header)
1130                                       + sizeof(mpi_coredump->routing_regs),
1131                                       "Routing Regs");
1132        status = qlge_get_routing_index_registers(qdev,
1133                                                  &mpi_coredump->routing_regs[0]);
1134        if (status)
1135                goto err;
1136
1137        qlge_build_coredump_seg_header(&mpi_coredump->mac_prot_reg_seg_hdr,
1138                                       MAC_PROTOCOL_SEG_NUM,
1139                                       sizeof(struct mpi_coredump_segment_header)
1140                                       + sizeof(mpi_coredump->mac_prot_regs),
1141                                       "MAC Prot Regs");
1142        qlge_get_mac_protocol_registers(qdev, &mpi_coredump->mac_prot_regs[0]);
1143
1144        /* Get the semaphore registers for all 5 functions */
1145        qlge_build_coredump_seg_header(&mpi_coredump->sem_regs_seg_hdr,
1146                                       SEM_REGS_SEG_NUM,
1147                                       sizeof(struct mpi_coredump_segment_header) +
1148                                       sizeof(mpi_coredump->sem_regs),  "Sem Registers");
1149
1150        qlge_get_sem_registers(qdev, &mpi_coredump->sem_regs[0]);
1151
1152        /* Prevent the mpi restarting while we dump the memory.*/
1153        qlge_write_mpi_reg(qdev, MPI_TEST_FUNC_RST_STS, MPI_TEST_FUNC_RST_FRC);
1154
1155        /* clear the pause */
1156        status = qlge_unpause_mpi_risc(qdev);
1157        if (status) {
1158                netif_err(qdev, drv, qdev->ndev,
1159                          "Failed RISC unpause. Status = 0x%.08x\n", status);
1160                goto err;
1161        }
1162
1163        /* Reset the RISC so we can dump RAM */
1164        status = qlge_hard_reset_mpi_risc(qdev);
1165        if (status) {
1166                netif_err(qdev, drv, qdev->ndev,
1167                          "Failed RISC reset. Status = 0x%.08x\n", status);
1168                goto err;
1169        }
1170
1171        qlge_build_coredump_seg_header(&mpi_coredump->code_ram_seg_hdr,
1172                                       WCS_RAM_SEG_NUM,
1173                                       sizeof(struct mpi_coredump_segment_header)
1174                                       + sizeof(mpi_coredump->code_ram),
1175                                       "WCS RAM");
1176        status = qlge_dump_risc_ram_area(qdev, &mpi_coredump->code_ram[0],
1177                                         CODE_RAM_ADDR, CODE_RAM_CNT);
1178        if (status) {
1179                netif_err(qdev, drv, qdev->ndev,
1180                          "Failed Dump of CODE RAM. Status = 0x%.08x\n",
1181                          status);
1182                goto err;
1183        }
1184
1185        /* Insert the segment header */
1186        qlge_build_coredump_seg_header(&mpi_coredump->memc_ram_seg_hdr,
1187                                       MEMC_RAM_SEG_NUM,
1188                                       sizeof(struct mpi_coredump_segment_header)
1189                                       + sizeof(mpi_coredump->memc_ram),
1190                                       "MEMC RAM");
1191        status = qlge_dump_risc_ram_area(qdev, &mpi_coredump->memc_ram[0],
1192                                         MEMC_RAM_ADDR, MEMC_RAM_CNT);
1193        if (status) {
1194                netif_err(qdev, drv, qdev->ndev,
1195                          "Failed Dump of MEMC RAM. Status = 0x%.08x\n",
1196                          status);
1197                goto err;
1198        }
1199err:
1200        qlge_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */
1201        return status;
1202}
1203
1204static void qlge_get_core_dump(struct qlge_adapter *qdev)
1205{
1206        if (!qlge_own_firmware(qdev)) {
1207                netif_err(qdev, drv, qdev->ndev, "Don't own firmware!\n");
1208                return;
1209        }
1210
1211        if (!netif_running(qdev->ndev)) {
1212                netif_err(qdev, ifup, qdev->ndev,
1213                          "Force Coredump can only be done from interface that is up\n");
1214                return;
1215        }
1216        qlge_queue_fw_error(qdev);
1217}
1218
1219static void qlge_gen_reg_dump(struct qlge_adapter *qdev,
1220                              struct qlge_reg_dump *mpi_coredump)
1221{
1222        int i, status;
1223
1224        memset(&mpi_coredump->mpi_global_header, 0,
1225               sizeof(struct mpi_coredump_global_header));
1226        mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
1227        mpi_coredump->mpi_global_header.header_size =
1228                sizeof(struct mpi_coredump_global_header);
1229        mpi_coredump->mpi_global_header.image_size =
1230                sizeof(struct qlge_reg_dump);
1231        strncpy(mpi_coredump->mpi_global_header.id_string, "MPI Coredump",
1232                sizeof(mpi_coredump->mpi_global_header.id_string));
1233
1234        /* segment 16 */
1235        qlge_build_coredump_seg_header(&mpi_coredump->misc_nic_seg_hdr,
1236                                       MISC_NIC_INFO_SEG_NUM,
1237                                       sizeof(struct mpi_coredump_segment_header)
1238                                       + sizeof(mpi_coredump->misc_nic_info),
1239                                       "MISC NIC INFO");
1240        mpi_coredump->misc_nic_info.rx_ring_count = qdev->rx_ring_count;
1241        mpi_coredump->misc_nic_info.tx_ring_count = qdev->tx_ring_count;
1242        mpi_coredump->misc_nic_info.intr_count = qdev->intr_count;
1243        mpi_coredump->misc_nic_info.function = qdev->func;
1244
1245        /* Segment 16, Rev C. Step 18 */
1246        qlge_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr,
1247                                       NIC1_CONTROL_SEG_NUM,
1248                                       sizeof(struct mpi_coredump_segment_header)
1249                                       + sizeof(mpi_coredump->nic_regs),
1250                                       "NIC Registers");
1251        /* Get generic reg dump */
1252        for (i = 0; i < 64; i++)
1253                mpi_coredump->nic_regs[i] = qlge_read32(qdev, i * sizeof(u32));
1254
1255        /* Segment 31 */
1256        /* Get indexed register values. */
1257        qlge_build_coredump_seg_header(&mpi_coredump->intr_states_seg_hdr,
1258                                       INTR_STATES_SEG_NUM,
1259                                       sizeof(struct mpi_coredump_segment_header)
1260                                       + sizeof(mpi_coredump->intr_states),
1261                                       "INTR States");
1262        qlge_get_intr_states(qdev, &mpi_coredump->intr_states[0]);
1263
1264        qlge_build_coredump_seg_header(&mpi_coredump->cam_entries_seg_hdr,
1265                                       CAM_ENTRIES_SEG_NUM,
1266                                       sizeof(struct mpi_coredump_segment_header)
1267                                       + sizeof(mpi_coredump->cam_entries),
1268                                       "CAM Entries");
1269        status = qlge_get_cam_entries(qdev, &mpi_coredump->cam_entries[0]);
1270        if (status)
1271                return;
1272
1273        qlge_build_coredump_seg_header(&mpi_coredump->nic_routing_words_seg_hdr,
1274                                       ROUTING_WORDS_SEG_NUM,
1275                                       sizeof(struct mpi_coredump_segment_header)
1276                                       + sizeof(mpi_coredump->nic_routing_words),
1277                                       "Routing Words");
1278        status = qlge_get_routing_entries(qdev,
1279                                          &mpi_coredump->nic_routing_words[0]);
1280        if (status)
1281                return;
1282
1283        /* Segment 34 (Rev C. step 23) */
1284        qlge_build_coredump_seg_header(&mpi_coredump->ets_seg_hdr,
1285                                       ETS_SEG_NUM,
1286                                       sizeof(struct mpi_coredump_segment_header)
1287                                       + sizeof(mpi_coredump->ets),
1288                                       "ETS Registers");
1289        status = qlge_get_ets_regs(qdev, &mpi_coredump->ets[0]);
1290        if (status)
1291                return;
1292}
1293
1294void qlge_get_dump(struct qlge_adapter *qdev, void *buff)
1295{
1296        /*
1297         * If the dump has already been taken and is stored
1298         * in our internal buffer and if force dump is set then
1299         * just start the spool to dump it to the log file
1300         * and also, take a snapshot of the general regs
1301         * to the user's buffer or else take complete dump
1302         * to the user's buffer if force is not set.
1303         */
1304
1305        if (!test_bit(QL_FRC_COREDUMP, &qdev->flags)) {
1306                if (!qlge_core_dump(qdev, buff))
1307                        qlge_soft_reset_mpi_risc(qdev);
1308                else
1309                        netif_err(qdev, drv, qdev->ndev, "coredump failed!\n");
1310        } else {
1311                qlge_gen_reg_dump(qdev, buff);
1312                qlge_get_core_dump(qdev);
1313        }
1314}
1315