Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0003 
0004 #include <linux/slab.h>
0005 
0006 #include "qlge.h"
0007 
0008 /* Read a NIC register from the alternate function. */
0009 static u32 qlge_read_other_func_reg(struct qlge_adapter *qdev,
0010                     u32 reg)
0011 {
0012     u32 register_to_read;
0013     u32 reg_val;
0014     unsigned int status = 0;
0015 
0016     register_to_read = MPI_NIC_REG_BLOCK
0017                 | MPI_NIC_READ
0018                 | (qdev->alt_func << MPI_NIC_FUNCTION_SHIFT)
0019                 | reg;
0020     status = qlge_read_mpi_reg(qdev, register_to_read, &reg_val);
0021     if (status != 0)
0022         return 0xffffffff;
0023 
0024     return reg_val;
0025 }
0026 
0027 /* Write a NIC register from the alternate function. */
0028 static int qlge_write_other_func_reg(struct qlge_adapter *qdev,
0029                      u32 reg, u32 reg_val)
0030 {
0031     u32 register_to_read;
0032 
0033     register_to_read = MPI_NIC_REG_BLOCK
0034                 | MPI_NIC_READ
0035                 | (qdev->alt_func << MPI_NIC_FUNCTION_SHIFT)
0036                 | reg;
0037 
0038     return qlge_write_mpi_reg(qdev, register_to_read, reg_val);
0039 }
0040 
0041 static int qlge_wait_other_func_reg_rdy(struct qlge_adapter *qdev, u32 reg,
0042                     u32 bit, u32 err_bit)
0043 {
0044     u32 temp;
0045     int count;
0046 
0047     for (count = 10; count; count--) {
0048         temp = qlge_read_other_func_reg(qdev, reg);
0049 
0050         /* check for errors */
0051         if (temp & err_bit)
0052             return -1;
0053         else if (temp & bit)
0054             return 0;
0055         mdelay(10);
0056     }
0057     return -1;
0058 }
0059 
0060 static int qlge_read_other_func_serdes_reg(struct qlge_adapter *qdev, u32 reg,
0061                        u32 *data)
0062 {
0063     int status;
0064 
0065     /* wait for reg to come ready */
0066     status = qlge_wait_other_func_reg_rdy(qdev, XG_SERDES_ADDR / 4,
0067                           XG_SERDES_ADDR_RDY, 0);
0068     if (status)
0069         goto exit;
0070 
0071     /* set up for reg read */
0072     qlge_write_other_func_reg(qdev, XG_SERDES_ADDR / 4, reg | PROC_ADDR_R);
0073 
0074     /* wait for reg to come ready */
0075     status = qlge_wait_other_func_reg_rdy(qdev, XG_SERDES_ADDR / 4,
0076                           XG_SERDES_ADDR_RDY, 0);
0077     if (status)
0078         goto exit;
0079 
0080     /* get the data */
0081     *data = qlge_read_other_func_reg(qdev, (XG_SERDES_DATA / 4));
0082 exit:
0083     return status;
0084 }
0085 
0086 /* Read out the SERDES registers */
0087 static int qlge_read_serdes_reg(struct qlge_adapter *qdev, u32 reg, u32 *data)
0088 {
0089     int status;
0090 
0091     /* wait for reg to come ready */
0092     status = qlge_wait_reg_rdy(qdev, XG_SERDES_ADDR, XG_SERDES_ADDR_RDY, 0);
0093     if (status)
0094         goto exit;
0095 
0096     /* set up for reg read */
0097     qlge_write32(qdev, XG_SERDES_ADDR, reg | PROC_ADDR_R);
0098 
0099     /* wait for reg to come ready */
0100     status = qlge_wait_reg_rdy(qdev, XG_SERDES_ADDR, XG_SERDES_ADDR_RDY, 0);
0101     if (status)
0102         goto exit;
0103 
0104     /* get the data */
0105     *data = qlge_read32(qdev, XG_SERDES_DATA);
0106 exit:
0107     return status;
0108 }
0109 
0110 static void qlge_get_both_serdes(struct qlge_adapter *qdev, u32 addr,
0111                  u32 *direct_ptr, u32 *indirect_ptr,
0112                  bool direct_valid, bool indirect_valid)
0113 {
0114     unsigned int status;
0115 
0116     status = 1;
0117     if (direct_valid)
0118         status = qlge_read_serdes_reg(qdev, addr, direct_ptr);
0119     /* Dead fill any failures or invalids. */
0120     if (status)
0121         *direct_ptr = 0xDEADBEEF;
0122 
0123     status = 1;
0124     if (indirect_valid)
0125         status = qlge_read_other_func_serdes_reg(qdev, addr,
0126                              indirect_ptr);
0127     /* Dead fill any failures or invalids. */
0128     if (status)
0129         *indirect_ptr = 0xDEADBEEF;
0130 }
0131 
0132 static int qlge_get_serdes_regs(struct qlge_adapter *qdev,
0133                 struct qlge_mpi_coredump *mpi_coredump)
0134 {
0135     int status;
0136     bool xfi_direct_valid = false, xfi_indirect_valid = false;
0137     bool xaui_direct_valid = true, xaui_indirect_valid = true;
0138     unsigned int i;
0139     u32 *direct_ptr, temp;
0140     u32 *indirect_ptr;
0141 
0142     /* The XAUI needs to be read out per port */
0143     status = qlge_read_other_func_serdes_reg(qdev,
0144                          XG_SERDES_XAUI_HSS_PCS_START,
0145                          &temp);
0146     if (status)
0147         temp = XG_SERDES_ADDR_XAUI_PWR_DOWN;
0148 
0149     if ((temp & XG_SERDES_ADDR_XAUI_PWR_DOWN) ==
0150                 XG_SERDES_ADDR_XAUI_PWR_DOWN)
0151         xaui_indirect_valid = false;
0152 
0153     status = qlge_read_serdes_reg(qdev, XG_SERDES_XAUI_HSS_PCS_START, &temp);
0154 
0155     if (status)
0156         temp = XG_SERDES_ADDR_XAUI_PWR_DOWN;
0157 
0158     if ((temp & XG_SERDES_ADDR_XAUI_PWR_DOWN) ==
0159                 XG_SERDES_ADDR_XAUI_PWR_DOWN)
0160         xaui_direct_valid = false;
0161 
0162     /*
0163      * XFI register is shared so only need to read one
0164      * functions and then check the bits.
0165      */
0166     status = qlge_read_serdes_reg(qdev, XG_SERDES_ADDR_STS, &temp);
0167     if (status)
0168         temp = 0;
0169 
0170     if ((temp & XG_SERDES_ADDR_XFI1_PWR_UP) ==
0171                     XG_SERDES_ADDR_XFI1_PWR_UP) {
0172         /* now see if i'm NIC 1 or NIC 2 */
0173         if (qdev->func & 1)
0174             /* I'm NIC 2, so the indirect (NIC1) xfi is up. */
0175             xfi_indirect_valid = true;
0176         else
0177             xfi_direct_valid = true;
0178     }
0179     if ((temp & XG_SERDES_ADDR_XFI2_PWR_UP) ==
0180                     XG_SERDES_ADDR_XFI2_PWR_UP) {
0181         /* now see if i'm NIC 1 or NIC 2 */
0182         if (qdev->func & 1)
0183             /* I'm NIC 2, so the indirect (NIC1) xfi is up. */
0184             xfi_direct_valid = true;
0185         else
0186             xfi_indirect_valid = true;
0187     }
0188 
0189     /* Get XAUI_AN register block. */
0190     if (qdev->func & 1) {
0191         /* Function 2 is direct */
0192         direct_ptr = mpi_coredump->serdes2_xaui_an;
0193         indirect_ptr = mpi_coredump->serdes_xaui_an;
0194     } else {
0195         /* Function 1 is direct */
0196         direct_ptr = mpi_coredump->serdes_xaui_an;
0197         indirect_ptr = mpi_coredump->serdes2_xaui_an;
0198     }
0199 
0200     for (i = 0; i <= 0x000000034; i += 4, direct_ptr++, indirect_ptr++)
0201         qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
0202                      xaui_direct_valid, xaui_indirect_valid);
0203 
0204     /* Get XAUI_HSS_PCS register block. */
0205     if (qdev->func & 1) {
0206         direct_ptr =
0207             mpi_coredump->serdes2_xaui_hss_pcs;
0208         indirect_ptr =
0209             mpi_coredump->serdes_xaui_hss_pcs;
0210     } else {
0211         direct_ptr =
0212             mpi_coredump->serdes_xaui_hss_pcs;
0213         indirect_ptr =
0214             mpi_coredump->serdes2_xaui_hss_pcs;
0215     }
0216 
0217     for (i = 0x800; i <= 0x880; i += 4, direct_ptr++, indirect_ptr++)
0218         qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
0219                      xaui_direct_valid, xaui_indirect_valid);
0220 
0221     /* Get XAUI_XFI_AN register block. */
0222     if (qdev->func & 1) {
0223         direct_ptr = mpi_coredump->serdes2_xfi_an;
0224         indirect_ptr = mpi_coredump->serdes_xfi_an;
0225     } else {
0226         direct_ptr = mpi_coredump->serdes_xfi_an;
0227         indirect_ptr = mpi_coredump->serdes2_xfi_an;
0228     }
0229 
0230     for (i = 0x1000; i <= 0x1034; i += 4, direct_ptr++, indirect_ptr++)
0231         qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
0232                      xfi_direct_valid, xfi_indirect_valid);
0233 
0234     /* Get XAUI_XFI_TRAIN register block. */
0235     if (qdev->func & 1) {
0236         direct_ptr = mpi_coredump->serdes2_xfi_train;
0237         indirect_ptr =
0238             mpi_coredump->serdes_xfi_train;
0239     } else {
0240         direct_ptr = mpi_coredump->serdes_xfi_train;
0241         indirect_ptr =
0242             mpi_coredump->serdes2_xfi_train;
0243     }
0244 
0245     for (i = 0x1050; i <= 0x107c; i += 4, direct_ptr++, indirect_ptr++)
0246         qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
0247                      xfi_direct_valid, xfi_indirect_valid);
0248 
0249     /* Get XAUI_XFI_HSS_PCS register block. */
0250     if (qdev->func & 1) {
0251         direct_ptr =
0252             mpi_coredump->serdes2_xfi_hss_pcs;
0253         indirect_ptr =
0254             mpi_coredump->serdes_xfi_hss_pcs;
0255     } else {
0256         direct_ptr =
0257             mpi_coredump->serdes_xfi_hss_pcs;
0258         indirect_ptr =
0259             mpi_coredump->serdes2_xfi_hss_pcs;
0260     }
0261 
0262     for (i = 0x1800; i <= 0x1838; i += 4, direct_ptr++, indirect_ptr++)
0263         qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
0264                      xfi_direct_valid, xfi_indirect_valid);
0265 
0266     /* Get XAUI_XFI_HSS_TX register block. */
0267     if (qdev->func & 1) {
0268         direct_ptr =
0269             mpi_coredump->serdes2_xfi_hss_tx;
0270         indirect_ptr =
0271             mpi_coredump->serdes_xfi_hss_tx;
0272     } else {
0273         direct_ptr = mpi_coredump->serdes_xfi_hss_tx;
0274         indirect_ptr =
0275             mpi_coredump->serdes2_xfi_hss_tx;
0276     }
0277     for (i = 0x1c00; i <= 0x1c1f; i++, direct_ptr++, indirect_ptr++)
0278         qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
0279                      xfi_direct_valid, xfi_indirect_valid);
0280 
0281     /* Get XAUI_XFI_HSS_RX register block. */
0282     if (qdev->func & 1) {
0283         direct_ptr =
0284             mpi_coredump->serdes2_xfi_hss_rx;
0285         indirect_ptr =
0286             mpi_coredump->serdes_xfi_hss_rx;
0287     } else {
0288         direct_ptr = mpi_coredump->serdes_xfi_hss_rx;
0289         indirect_ptr =
0290             mpi_coredump->serdes2_xfi_hss_rx;
0291     }
0292 
0293     for (i = 0x1c40; i <= 0x1c5f; i++, direct_ptr++, indirect_ptr++)
0294         qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
0295                      xfi_direct_valid, xfi_indirect_valid);
0296 
0297     /* Get XAUI_XFI_HSS_PLL register block. */
0298     if (qdev->func & 1) {
0299         direct_ptr =
0300             mpi_coredump->serdes2_xfi_hss_pll;
0301         indirect_ptr =
0302             mpi_coredump->serdes_xfi_hss_pll;
0303     } else {
0304         direct_ptr =
0305             mpi_coredump->serdes_xfi_hss_pll;
0306         indirect_ptr =
0307             mpi_coredump->serdes2_xfi_hss_pll;
0308     }
0309     for (i = 0x1e00; i <= 0x1e1f; i++, direct_ptr++, indirect_ptr++)
0310         qlge_get_both_serdes(qdev, i, direct_ptr, indirect_ptr,
0311                      xfi_direct_valid, xfi_indirect_valid);
0312     return 0;
0313 }
0314 
0315 static int qlge_read_other_func_xgmac_reg(struct qlge_adapter *qdev, u32 reg,
0316                       u32 *data)
0317 {
0318     int status = 0;
0319 
0320     /* wait for reg to come ready */
0321     status = qlge_wait_other_func_reg_rdy(qdev, XGMAC_ADDR / 4,
0322                           XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
0323     if (status)
0324         goto exit;
0325 
0326     /* set up for reg read */
0327     qlge_write_other_func_reg(qdev, XGMAC_ADDR / 4, reg | XGMAC_ADDR_R);
0328 
0329     /* wait for reg to come ready */
0330     status = qlge_wait_other_func_reg_rdy(qdev, XGMAC_ADDR / 4,
0331                           XGMAC_ADDR_RDY, XGMAC_ADDR_XME);
0332     if (status)
0333         goto exit;
0334 
0335     /* get the data */
0336     *data = qlge_read_other_func_reg(qdev, XGMAC_DATA / 4);
0337 exit:
0338     return status;
0339 }
0340 
0341 /* Read the 400 xgmac control/statistics registers
0342  * skipping unused locations.
0343  */
0344 static int qlge_get_xgmac_regs(struct qlge_adapter *qdev, u32 *buf,
0345                    unsigned int other_function)
0346 {
0347     int status = 0;
0348     int i;
0349 
0350     for (i = PAUSE_SRC_LO; i < XGMAC_REGISTER_END; i += 4, buf++) {
0351         /* We're reading 400 xgmac registers, but we filter out
0352          * several locations that are non-responsive to reads.
0353          */
0354         if ((i == 0x00000114) ||
0355             (i == 0x00000118) ||
0356             (i == 0x0000013c) ||
0357             (i == 0x00000140) ||
0358             (i > 0x00000150 && i < 0x000001fc) ||
0359             (i > 0x00000278 && i < 0x000002a0) ||
0360             (i > 0x000002c0 && i < 0x000002cf) ||
0361             (i > 0x000002dc && i < 0x000002f0) ||
0362             (i > 0x000003c8 && i < 0x00000400) ||
0363             (i > 0x00000400 && i < 0x00000410) ||
0364             (i > 0x00000410 && i < 0x00000420) ||
0365             (i > 0x00000420 && i < 0x00000430) ||
0366             (i > 0x00000430 && i < 0x00000440) ||
0367             (i > 0x00000440 && i < 0x00000450) ||
0368             (i > 0x00000450 && i < 0x00000500) ||
0369             (i > 0x0000054c && i < 0x00000568) ||
0370             (i > 0x000005c8 && i < 0x00000600)) {
0371             if (other_function)
0372                 status =
0373                 qlge_read_other_func_xgmac_reg(qdev, i, buf);
0374             else
0375                 status = qlge_read_xgmac_reg(qdev, i, buf);
0376 
0377             if (status)
0378                 *buf = 0xdeadbeef;
0379             break;
0380         }
0381     }
0382     return status;
0383 }
0384 
0385 static int qlge_get_ets_regs(struct qlge_adapter *qdev, u32 *buf)
0386 {
0387     int i;
0388 
0389     for (i = 0; i < 8; i++, buf++) {
0390         qlge_write32(qdev, NIC_ETS, i << 29 | 0x08000000);
0391         *buf = qlge_read32(qdev, NIC_ETS);
0392     }
0393 
0394     for (i = 0; i < 2; i++, buf++) {
0395         qlge_write32(qdev, CNA_ETS, i << 29 | 0x08000000);
0396         *buf = qlge_read32(qdev, CNA_ETS);
0397     }
0398 
0399     return 0;
0400 }
0401 
0402 static void qlge_get_intr_states(struct qlge_adapter *qdev, u32 *buf)
0403 {
0404     int i;
0405 
0406     for (i = 0; i < qdev->rx_ring_count; i++, buf++) {
0407         qlge_write32(qdev, INTR_EN,
0408                  qdev->intr_context[i].intr_read_mask);
0409         *buf = qlge_read32(qdev, INTR_EN);
0410     }
0411 }
0412 
0413 static int qlge_get_cam_entries(struct qlge_adapter *qdev, u32 *buf)
0414 {
0415     int i, status;
0416     u32 value[3];
0417 
0418     status = qlge_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
0419     if (status)
0420         return status;
0421 
0422     for (i = 0; i < 16; i++) {
0423         status = qlge_get_mac_addr_reg(qdev,
0424                            MAC_ADDR_TYPE_CAM_MAC, i, value);
0425         if (status) {
0426             netif_err(qdev, drv, qdev->ndev,
0427                   "Failed read of mac index register\n");
0428             goto err;
0429         }
0430         *buf++ = value[0];  /* lower MAC address */
0431         *buf++ = value[1];  /* upper MAC address */
0432         *buf++ = value[2];  /* output */
0433     }
0434     for (i = 0; i < 32; i++) {
0435         status = qlge_get_mac_addr_reg(qdev, MAC_ADDR_TYPE_MULTI_MAC,
0436                            i, value);
0437         if (status) {
0438             netif_err(qdev, drv, qdev->ndev,
0439                   "Failed read of mac index register\n");
0440             goto err;
0441         }
0442         *buf++ = value[0];  /* lower Mcast address */
0443         *buf++ = value[1];  /* upper Mcast address */
0444     }
0445 err:
0446     qlge_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
0447     return status;
0448 }
0449 
0450 static int qlge_get_routing_entries(struct qlge_adapter *qdev, u32 *buf)
0451 {
0452     int status;
0453     u32 value, i;
0454 
0455     status = qlge_sem_spinlock(qdev, SEM_RT_IDX_MASK);
0456     if (status)
0457         return status;
0458 
0459     for (i = 0; i < 16; i++) {
0460         status = qlge_get_routing_reg(qdev, i, &value);
0461         if (status) {
0462             netif_err(qdev, drv, qdev->ndev,
0463                   "Failed read of routing index register\n");
0464             goto err;
0465         } else {
0466             *buf++ = value;
0467         }
0468     }
0469 err:
0470     qlge_sem_unlock(qdev, SEM_RT_IDX_MASK);
0471     return status;
0472 }
0473 
0474 /* Read the MPI Processor shadow registers */
0475 static int qlge_get_mpi_shadow_regs(struct qlge_adapter *qdev, u32 *buf)
0476 {
0477     u32 i;
0478     int status;
0479 
0480     for (i = 0; i < MPI_CORE_SH_REGS_CNT; i++, buf++) {
0481         status = qlge_write_mpi_reg(qdev,
0482                         RISC_124,
0483                         (SHADOW_OFFSET | i << SHADOW_REG_SHIFT));
0484         if (status)
0485             goto end;
0486         status = qlge_read_mpi_reg(qdev, RISC_127, buf);
0487         if (status)
0488             goto end;
0489     }
0490 end:
0491     return status;
0492 }
0493 
0494 /* Read the MPI Processor core registers */
0495 static int qlge_get_mpi_regs(struct qlge_adapter *qdev, u32 *buf,
0496                  u32 offset, u32 count)
0497 {
0498     int i, status = 0;
0499 
0500     for (i = 0; i < count; i++, buf++) {
0501         status = qlge_read_mpi_reg(qdev, offset + i, buf);
0502         if (status)
0503             return status;
0504     }
0505     return status;
0506 }
0507 
0508 /* Read the ASIC probe dump */
0509 static unsigned int *qlge_get_probe(struct qlge_adapter *qdev, u32 clock,
0510                     u32 valid, u32 *buf)
0511 {
0512     u32 module, mux_sel, probe, lo_val, hi_val;
0513 
0514     for (module = 0; module < PRB_MX_ADDR_MAX_MODS; module++) {
0515         if (!((valid >> module) & 1))
0516             continue;
0517         for (mux_sel = 0; mux_sel < PRB_MX_ADDR_MAX_MUX; mux_sel++) {
0518             probe = clock
0519                 | PRB_MX_ADDR_ARE
0520                 | mux_sel
0521                 | (module << PRB_MX_ADDR_MOD_SEL_SHIFT);
0522             qlge_write32(qdev, PRB_MX_ADDR, probe);
0523             lo_val = qlge_read32(qdev, PRB_MX_DATA);
0524             if (mux_sel == 0) {
0525                 *buf = probe;
0526                 buf++;
0527             }
0528             probe |= PRB_MX_ADDR_UP;
0529             qlge_write32(qdev, PRB_MX_ADDR, probe);
0530             hi_val = qlge_read32(qdev, PRB_MX_DATA);
0531             *buf = lo_val;
0532             buf++;
0533             *buf = hi_val;
0534             buf++;
0535         }
0536     }
0537     return buf;
0538 }
0539 
0540 static int qlge_get_probe_dump(struct qlge_adapter *qdev, unsigned int *buf)
0541 {
0542     /* First we have to enable the probe mux */
0543     qlge_write_mpi_reg(qdev, MPI_TEST_FUNC_PRB_CTL, MPI_TEST_FUNC_PRB_EN);
0544     buf = qlge_get_probe(qdev, PRB_MX_ADDR_SYS_CLOCK,
0545                  PRB_MX_ADDR_VALID_SYS_MOD, buf);
0546     buf = qlge_get_probe(qdev, PRB_MX_ADDR_PCI_CLOCK,
0547                  PRB_MX_ADDR_VALID_PCI_MOD, buf);
0548     buf = qlge_get_probe(qdev, PRB_MX_ADDR_XGM_CLOCK,
0549                  PRB_MX_ADDR_VALID_XGM_MOD, buf);
0550     buf = qlge_get_probe(qdev, PRB_MX_ADDR_FC_CLOCK,
0551                  PRB_MX_ADDR_VALID_FC_MOD, buf);
0552     return 0;
0553 }
0554 
0555 /* Read out the routing index registers */
0556 static int qlge_get_routing_index_registers(struct qlge_adapter *qdev, u32 *buf)
0557 {
0558     int status;
0559     u32 type, index, index_max;
0560     u32 result_index;
0561     u32 result_data;
0562     u32 val;
0563 
0564     status = qlge_sem_spinlock(qdev, SEM_RT_IDX_MASK);
0565     if (status)
0566         return status;
0567 
0568     for (type = 0; type < 4; type++) {
0569         if (type < 2)
0570             index_max = 8;
0571         else
0572             index_max = 16;
0573         for (index = 0; index < index_max; index++) {
0574             val = RT_IDX_RS
0575                 | (type << RT_IDX_TYPE_SHIFT)
0576                 | (index << RT_IDX_IDX_SHIFT);
0577             qlge_write32(qdev, RT_IDX, val);
0578             result_index = 0;
0579             while ((result_index & RT_IDX_MR) == 0)
0580                 result_index = qlge_read32(qdev, RT_IDX);
0581             result_data = qlge_read32(qdev, RT_DATA);
0582             *buf = type;
0583             buf++;
0584             *buf = index;
0585             buf++;
0586             *buf = result_index;
0587             buf++;
0588             *buf = result_data;
0589             buf++;
0590         }
0591     }
0592     qlge_sem_unlock(qdev, SEM_RT_IDX_MASK);
0593     return status;
0594 }
0595 
0596 /* Read out the MAC protocol registers */
0597 static void qlge_get_mac_protocol_registers(struct qlge_adapter *qdev, u32 *buf)
0598 {
0599     u32 result_index, result_data;
0600     u32 type;
0601     u32 index;
0602     u32 offset;
0603     u32 val;
0604     u32 initial_val = MAC_ADDR_RS;
0605     u32 max_index;
0606     u32 max_offset;
0607 
0608     for (type = 0; type < MAC_ADDR_TYPE_COUNT; type++) {
0609         switch (type) {
0610         case 0: /* CAM */
0611             initial_val |= MAC_ADDR_ADR;
0612             max_index = MAC_ADDR_MAX_CAM_ENTRIES;
0613             max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
0614             break;
0615         case 1: /* Multicast MAC Address */
0616             max_index = MAC_ADDR_MAX_CAM_WCOUNT;
0617             max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
0618             break;
0619         case 2: /* VLAN filter mask */
0620         case 3: /* MC filter mask */
0621             max_index = MAC_ADDR_MAX_CAM_WCOUNT;
0622             max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
0623             break;
0624         case 4: /* FC MAC addresses */
0625             max_index = MAC_ADDR_MAX_FC_MAC_ENTRIES;
0626             max_offset = MAC_ADDR_MAX_FC_MAC_WCOUNT;
0627             break;
0628         case 5: /* Mgmt MAC addresses */
0629             max_index = MAC_ADDR_MAX_MGMT_MAC_ENTRIES;
0630             max_offset = MAC_ADDR_MAX_MGMT_MAC_WCOUNT;
0631             break;
0632         case 6: /* Mgmt VLAN addresses */
0633             max_index = MAC_ADDR_MAX_MGMT_VLAN_ENTRIES;
0634             max_offset = MAC_ADDR_MAX_MGMT_VLAN_WCOUNT;
0635             break;
0636         case 7: /* Mgmt IPv4 address */
0637             max_index = MAC_ADDR_MAX_MGMT_V4_ENTRIES;
0638             max_offset = MAC_ADDR_MAX_MGMT_V4_WCOUNT;
0639             break;
0640         case 8: /* Mgmt IPv6 address */
0641             max_index = MAC_ADDR_MAX_MGMT_V6_ENTRIES;
0642             max_offset = MAC_ADDR_MAX_MGMT_V6_WCOUNT;
0643             break;
0644         case 9: /* Mgmt TCP/UDP Dest port */
0645             max_index = MAC_ADDR_MAX_MGMT_TU_DP_ENTRIES;
0646             max_offset = MAC_ADDR_MAX_MGMT_TU_DP_WCOUNT;
0647             break;
0648         default:
0649             netdev_err(qdev->ndev, "Bad type!!! 0x%08x\n", type);
0650             max_index = 0;
0651             max_offset = 0;
0652             break;
0653         }
0654         for (index = 0; index < max_index; index++) {
0655             for (offset = 0; offset < max_offset; offset++) {
0656                 val = initial_val
0657                     | (type << MAC_ADDR_TYPE_SHIFT)
0658                     | (index << MAC_ADDR_IDX_SHIFT)
0659                     | (offset);
0660                 qlge_write32(qdev, MAC_ADDR_IDX, val);
0661                 result_index = 0;
0662                 while ((result_index & MAC_ADDR_MR) == 0) {
0663                     result_index = qlge_read32(qdev,
0664                                    MAC_ADDR_IDX);
0665                 }
0666                 result_data = qlge_read32(qdev, MAC_ADDR_DATA);
0667                 *buf = result_index;
0668                 buf++;
0669                 *buf = result_data;
0670                 buf++;
0671             }
0672         }
0673     }
0674 }
0675 
0676 static void qlge_get_sem_registers(struct qlge_adapter *qdev, u32 *buf)
0677 {
0678     u32 func_num, reg, reg_val;
0679     int status;
0680 
0681     for (func_num = 0; func_num < MAX_SEMAPHORE_FUNCTIONS ; func_num++) {
0682         reg = MPI_NIC_REG_BLOCK
0683             | (func_num << MPI_NIC_FUNCTION_SHIFT)
0684             | (SEM / 4);
0685         status = qlge_read_mpi_reg(qdev, reg, &reg_val);
0686         *buf = reg_val;
0687         /* if the read failed then dead fill the element. */
0688         if (!status)
0689             *buf = 0xdeadbeef;
0690         buf++;
0691     }
0692 }
0693 
0694 /* Create a coredump segment header */
0695 static void qlge_build_coredump_seg_header(struct mpi_coredump_segment_header *seg_hdr,
0696                        u32 seg_number, u32 seg_size, u8 *desc)
0697 {
0698     memset(seg_hdr, 0, sizeof(struct mpi_coredump_segment_header));
0699     seg_hdr->cookie = MPI_COREDUMP_COOKIE;
0700     seg_hdr->seg_num = seg_number;
0701     seg_hdr->seg_size = seg_size;
0702     strncpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
0703 }
0704 
0705 /*
0706  * This function should be called when a coredump / probedump
0707  * is to be extracted from the HBA. It is assumed there is a
0708  * qdev structure that contains the base address of the register
0709  * space for this function as well as a coredump structure that
0710  * will contain the dump.
0711  */
0712 int qlge_core_dump(struct qlge_adapter *qdev, struct qlge_mpi_coredump *mpi_coredump)
0713 {
0714     int status;
0715     int i;
0716 
0717     if (!mpi_coredump) {
0718         netif_err(qdev, drv, qdev->ndev, "No memory allocated\n");
0719         return -EINVAL;
0720     }
0721 
0722     /* Try to get the spinlock, but dont worry if
0723      * it isn't available.  If the firmware died it
0724      * might be holding the sem.
0725      */
0726     qlge_sem_spinlock(qdev, SEM_PROC_REG_MASK);
0727 
0728     status = qlge_pause_mpi_risc(qdev);
0729     if (status) {
0730         netif_err(qdev, drv, qdev->ndev,
0731               "Failed RISC pause. Status = 0x%.08x\n", status);
0732         goto err;
0733     }
0734 
0735     /* Insert the global header */
0736     memset(&mpi_coredump->mpi_global_header, 0,
0737            sizeof(struct mpi_coredump_global_header));
0738     mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
0739     mpi_coredump->mpi_global_header.header_size =
0740         sizeof(struct mpi_coredump_global_header);
0741     mpi_coredump->mpi_global_header.image_size =
0742         sizeof(struct qlge_mpi_coredump);
0743     strncpy(mpi_coredump->mpi_global_header.id_string, "MPI Coredump",
0744         sizeof(mpi_coredump->mpi_global_header.id_string));
0745 
0746     /* Get generic NIC reg dump */
0747     qlge_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr,
0748                        NIC1_CONTROL_SEG_NUM,
0749                        sizeof(struct mpi_coredump_segment_header) +
0750                        sizeof(mpi_coredump->nic_regs), "NIC1 Registers");
0751 
0752     qlge_build_coredump_seg_header(&mpi_coredump->nic2_regs_seg_hdr,
0753                        NIC2_CONTROL_SEG_NUM,
0754                        sizeof(struct mpi_coredump_segment_header) +
0755                        sizeof(mpi_coredump->nic2_regs), "NIC2 Registers");
0756 
0757     /* Get XGMac registers. (Segment 18, Rev C. step 21) */
0758     qlge_build_coredump_seg_header(&mpi_coredump->xgmac1_seg_hdr,
0759                        NIC1_XGMAC_SEG_NUM,
0760                        sizeof(struct mpi_coredump_segment_header) +
0761                        sizeof(mpi_coredump->xgmac1), "NIC1 XGMac Registers");
0762 
0763     qlge_build_coredump_seg_header(&mpi_coredump->xgmac2_seg_hdr,
0764                        NIC2_XGMAC_SEG_NUM,
0765                        sizeof(struct mpi_coredump_segment_header) +
0766                        sizeof(mpi_coredump->xgmac2), "NIC2 XGMac Registers");
0767 
0768     if (qdev->func & 1) {
0769         /* Odd means our function is NIC 2 */
0770         for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
0771             mpi_coredump->nic2_regs[i] =
0772                 qlge_read32(qdev, i * sizeof(u32));
0773 
0774         for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
0775             mpi_coredump->nic_regs[i] =
0776                 qlge_read_other_func_reg(qdev, (i * sizeof(u32)) / 4);
0777 
0778         qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac2[0], 0);
0779         qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac1[0], 1);
0780     } else {
0781         /* Even means our function is NIC 1 */
0782         for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
0783             mpi_coredump->nic_regs[i] =
0784                 qlge_read32(qdev, i * sizeof(u32));
0785         for (i = 0; i < NIC_REGS_DUMP_WORD_COUNT; i++)
0786             mpi_coredump->nic2_regs[i] =
0787                 qlge_read_other_func_reg(qdev, (i * sizeof(u32)) / 4);
0788 
0789         qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac1[0], 0);
0790         qlge_get_xgmac_regs(qdev, &mpi_coredump->xgmac2[0], 1);
0791     }
0792 
0793     /* Rev C. Step 20a */
0794     qlge_build_coredump_seg_header(&mpi_coredump->xaui_an_hdr,
0795                        XAUI_AN_SEG_NUM,
0796                        sizeof(struct mpi_coredump_segment_header) +
0797                        sizeof(mpi_coredump->serdes_xaui_an),
0798                        "XAUI AN Registers");
0799 
0800     /* Rev C. Step 20b */
0801     qlge_build_coredump_seg_header(&mpi_coredump->xaui_hss_pcs_hdr,
0802                        XAUI_HSS_PCS_SEG_NUM,
0803                        sizeof(struct mpi_coredump_segment_header) +
0804                        sizeof(mpi_coredump->serdes_xaui_hss_pcs),
0805                        "XAUI HSS PCS Registers");
0806 
0807     qlge_build_coredump_seg_header(&mpi_coredump->xfi_an_hdr, XFI_AN_SEG_NUM,
0808                        sizeof(struct mpi_coredump_segment_header) +
0809                        sizeof(mpi_coredump->serdes_xfi_an),
0810                        "XFI AN Registers");
0811 
0812     qlge_build_coredump_seg_header(&mpi_coredump->xfi_train_hdr,
0813                        XFI_TRAIN_SEG_NUM,
0814                        sizeof(struct mpi_coredump_segment_header) +
0815                        sizeof(mpi_coredump->serdes_xfi_train),
0816                        "XFI TRAIN Registers");
0817 
0818     qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_pcs_hdr,
0819                        XFI_HSS_PCS_SEG_NUM,
0820                        sizeof(struct mpi_coredump_segment_header) +
0821                        sizeof(mpi_coredump->serdes_xfi_hss_pcs),
0822                        "XFI HSS PCS Registers");
0823 
0824     qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_tx_hdr,
0825                        XFI_HSS_TX_SEG_NUM,
0826                        sizeof(struct mpi_coredump_segment_header) +
0827                        sizeof(mpi_coredump->serdes_xfi_hss_tx),
0828                        "XFI HSS TX Registers");
0829 
0830     qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_rx_hdr,
0831                        XFI_HSS_RX_SEG_NUM,
0832                        sizeof(struct mpi_coredump_segment_header) +
0833                        sizeof(mpi_coredump->serdes_xfi_hss_rx),
0834                        "XFI HSS RX Registers");
0835 
0836     qlge_build_coredump_seg_header(&mpi_coredump->xfi_hss_pll_hdr,
0837                        XFI_HSS_PLL_SEG_NUM,
0838                        sizeof(struct mpi_coredump_segment_header) +
0839                        sizeof(mpi_coredump->serdes_xfi_hss_pll),
0840                        "XFI HSS PLL Registers");
0841 
0842     qlge_build_coredump_seg_header(&mpi_coredump->xaui2_an_hdr,
0843                        XAUI2_AN_SEG_NUM,
0844                        sizeof(struct mpi_coredump_segment_header) +
0845                        sizeof(mpi_coredump->serdes2_xaui_an),
0846                        "XAUI2 AN Registers");
0847 
0848     qlge_build_coredump_seg_header(&mpi_coredump->xaui2_hss_pcs_hdr,
0849                        XAUI2_HSS_PCS_SEG_NUM,
0850                        sizeof(struct mpi_coredump_segment_header) +
0851                        sizeof(mpi_coredump->serdes2_xaui_hss_pcs),
0852                        "XAUI2 HSS PCS Registers");
0853 
0854     qlge_build_coredump_seg_header(&mpi_coredump->xfi2_an_hdr,
0855                        XFI2_AN_SEG_NUM,
0856                        sizeof(struct mpi_coredump_segment_header) +
0857                        sizeof(mpi_coredump->serdes2_xfi_an),
0858                        "XFI2 AN Registers");
0859 
0860     qlge_build_coredump_seg_header(&mpi_coredump->xfi2_train_hdr,
0861                        XFI2_TRAIN_SEG_NUM,
0862                        sizeof(struct mpi_coredump_segment_header) +
0863                        sizeof(mpi_coredump->serdes2_xfi_train),
0864                        "XFI2 TRAIN Registers");
0865 
0866     qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_pcs_hdr,
0867                        XFI2_HSS_PCS_SEG_NUM,
0868                        sizeof(struct mpi_coredump_segment_header) +
0869                        sizeof(mpi_coredump->serdes2_xfi_hss_pcs),
0870                        "XFI2 HSS PCS Registers");
0871 
0872     qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_tx_hdr,
0873                        XFI2_HSS_TX_SEG_NUM,
0874                        sizeof(struct mpi_coredump_segment_header) +
0875                        sizeof(mpi_coredump->serdes2_xfi_hss_tx),
0876                        "XFI2 HSS TX Registers");
0877 
0878     qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_rx_hdr,
0879                        XFI2_HSS_RX_SEG_NUM,
0880                        sizeof(struct mpi_coredump_segment_header) +
0881                        sizeof(mpi_coredump->serdes2_xfi_hss_rx),
0882                        "XFI2 HSS RX Registers");
0883 
0884     qlge_build_coredump_seg_header(&mpi_coredump->xfi2_hss_pll_hdr,
0885                        XFI2_HSS_PLL_SEG_NUM,
0886                        sizeof(struct mpi_coredump_segment_header) +
0887                        sizeof(mpi_coredump->serdes2_xfi_hss_pll),
0888                        "XFI2 HSS PLL Registers");
0889 
0890     status = qlge_get_serdes_regs(qdev, mpi_coredump);
0891     if (status) {
0892         netif_err(qdev, drv, qdev->ndev,
0893               "Failed Dump of Serdes Registers. Status = 0x%.08x\n",
0894               status);
0895         goto err;
0896     }
0897 
0898     qlge_build_coredump_seg_header(&mpi_coredump->core_regs_seg_hdr,
0899                        CORE_SEG_NUM,
0900                        sizeof(mpi_coredump->core_regs_seg_hdr) +
0901                        sizeof(mpi_coredump->mpi_core_regs) +
0902                        sizeof(mpi_coredump->mpi_core_sh_regs),
0903                        "Core Registers");
0904 
0905     /* Get the MPI Core Registers */
0906     status = qlge_get_mpi_regs(qdev, &mpi_coredump->mpi_core_regs[0],
0907                    MPI_CORE_REGS_ADDR, MPI_CORE_REGS_CNT);
0908     if (status)
0909         goto err;
0910     /* Get the 16 MPI shadow registers */
0911     status = qlge_get_mpi_shadow_regs(qdev,
0912                       &mpi_coredump->mpi_core_sh_regs[0]);
0913     if (status)
0914         goto err;
0915 
0916     /* Get the Test Logic Registers */
0917     qlge_build_coredump_seg_header(&mpi_coredump->test_logic_regs_seg_hdr,
0918                        TEST_LOGIC_SEG_NUM,
0919                        sizeof(struct mpi_coredump_segment_header)
0920                        + sizeof(mpi_coredump->test_logic_regs),
0921                        "Test Logic Regs");
0922     status = qlge_get_mpi_regs(qdev, &mpi_coredump->test_logic_regs[0],
0923                    TEST_REGS_ADDR, TEST_REGS_CNT);
0924     if (status)
0925         goto err;
0926 
0927     /* Get the RMII Registers */
0928     qlge_build_coredump_seg_header(&mpi_coredump->rmii_regs_seg_hdr,
0929                        RMII_SEG_NUM,
0930                        sizeof(struct mpi_coredump_segment_header)
0931                        + sizeof(mpi_coredump->rmii_regs),
0932                        "RMII Registers");
0933     status = qlge_get_mpi_regs(qdev, &mpi_coredump->rmii_regs[0],
0934                    RMII_REGS_ADDR, RMII_REGS_CNT);
0935     if (status)
0936         goto err;
0937 
0938     /* Get the FCMAC1 Registers */
0939     qlge_build_coredump_seg_header(&mpi_coredump->fcmac1_regs_seg_hdr,
0940                        FCMAC1_SEG_NUM,
0941                        sizeof(struct mpi_coredump_segment_header)
0942                        + sizeof(mpi_coredump->fcmac1_regs),
0943                        "FCMAC1 Registers");
0944     status = qlge_get_mpi_regs(qdev, &mpi_coredump->fcmac1_regs[0],
0945                    FCMAC1_REGS_ADDR, FCMAC_REGS_CNT);
0946     if (status)
0947         goto err;
0948 
0949     /* Get the FCMAC2 Registers */
0950 
0951     qlge_build_coredump_seg_header(&mpi_coredump->fcmac2_regs_seg_hdr,
0952                        FCMAC2_SEG_NUM,
0953                        sizeof(struct mpi_coredump_segment_header)
0954                        + sizeof(mpi_coredump->fcmac2_regs),
0955                        "FCMAC2 Registers");
0956 
0957     status = qlge_get_mpi_regs(qdev, &mpi_coredump->fcmac2_regs[0],
0958                    FCMAC2_REGS_ADDR, FCMAC_REGS_CNT);
0959     if (status)
0960         goto err;
0961 
0962     /* Get the FC1 MBX Registers */
0963     qlge_build_coredump_seg_header(&mpi_coredump->fc1_mbx_regs_seg_hdr,
0964                        FC1_MBOX_SEG_NUM,
0965                        sizeof(struct mpi_coredump_segment_header)
0966                        + sizeof(mpi_coredump->fc1_mbx_regs),
0967                        "FC1 MBox Regs");
0968     status = qlge_get_mpi_regs(qdev, &mpi_coredump->fc1_mbx_regs[0],
0969                    FC1_MBX_REGS_ADDR, FC_MBX_REGS_CNT);
0970     if (status)
0971         goto err;
0972 
0973     /* Get the IDE Registers */
0974     qlge_build_coredump_seg_header(&mpi_coredump->ide_regs_seg_hdr,
0975                        IDE_SEG_NUM,
0976                        sizeof(struct mpi_coredump_segment_header)
0977                        + sizeof(mpi_coredump->ide_regs),
0978                        "IDE Registers");
0979     status = qlge_get_mpi_regs(qdev, &mpi_coredump->ide_regs[0],
0980                    IDE_REGS_ADDR, IDE_REGS_CNT);
0981     if (status)
0982         goto err;
0983 
0984     /* Get the NIC1 MBX Registers */
0985     qlge_build_coredump_seg_header(&mpi_coredump->nic1_mbx_regs_seg_hdr,
0986                        NIC1_MBOX_SEG_NUM,
0987                        sizeof(struct mpi_coredump_segment_header)
0988                        + sizeof(mpi_coredump->nic1_mbx_regs),
0989                        "NIC1 MBox Regs");
0990     status = qlge_get_mpi_regs(qdev, &mpi_coredump->nic1_mbx_regs[0],
0991                    NIC1_MBX_REGS_ADDR, NIC_MBX_REGS_CNT);
0992     if (status)
0993         goto err;
0994 
0995     /* Get the SMBus Registers */
0996     qlge_build_coredump_seg_header(&mpi_coredump->smbus_regs_seg_hdr,
0997                        SMBUS_SEG_NUM,
0998                        sizeof(struct mpi_coredump_segment_header)
0999                        + 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     }
1199 err:
1200     qlge_sem_unlock(qdev, SEM_PROC_REG_MASK); /* does flush too */
1201     return status;
1202 }
1203 
1204 static 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 
1219 static 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 
1294 void 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 }