0001
0002 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0003
0004 #include <linux/slab.h>
0005
0006 #include "qlge.h"
0007
0008
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, ®_val);
0021 if (status != 0)
0022 return 0xffffffff;
0023
0024 return reg_val;
0025 }
0026
0027
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
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
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
0072 qlge_write_other_func_reg(qdev, XG_SERDES_ADDR / 4, reg | PROC_ADDR_R);
0073
0074
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
0081 *data = qlge_read_other_func_reg(qdev, (XG_SERDES_DATA / 4));
0082 exit:
0083 return status;
0084 }
0085
0086
0087 static int qlge_read_serdes_reg(struct qlge_adapter *qdev, u32 reg, u32 *data)
0088 {
0089 int status;
0090
0091
0092 status = qlge_wait_reg_rdy(qdev, XG_SERDES_ADDR, XG_SERDES_ADDR_RDY, 0);
0093 if (status)
0094 goto exit;
0095
0096
0097 qlge_write32(qdev, XG_SERDES_ADDR, reg | PROC_ADDR_R);
0098
0099
0100 status = qlge_wait_reg_rdy(qdev, XG_SERDES_ADDR, XG_SERDES_ADDR_RDY, 0);
0101 if (status)
0102 goto exit;
0103
0104
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
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
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
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
0164
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
0173 if (qdev->func & 1)
0174
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
0182 if (qdev->func & 1)
0183
0184 xfi_direct_valid = true;
0185 else
0186 xfi_indirect_valid = true;
0187 }
0188
0189
0190 if (qdev->func & 1) {
0191
0192 direct_ptr = mpi_coredump->serdes2_xaui_an;
0193 indirect_ptr = mpi_coredump->serdes_xaui_an;
0194 } else {
0195
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
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
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
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
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
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
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
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
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
0327 qlge_write_other_func_reg(qdev, XGMAC_ADDR / 4, reg | XGMAC_ADDR_R);
0328
0329
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
0336 *data = qlge_read_other_func_reg(qdev, XGMAC_DATA / 4);
0337 exit:
0338 return status;
0339 }
0340
0341
0342
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
0352
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];
0431 *buf++ = value[1];
0432 *buf++ = value[2];
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];
0443 *buf++ = value[1];
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
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
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
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
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
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
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:
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:
0616 max_index = MAC_ADDR_MAX_CAM_WCOUNT;
0617 max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
0618 break;
0619 case 2:
0620 case 3:
0621 max_index = MAC_ADDR_MAX_CAM_WCOUNT;
0622 max_offset = MAC_ADDR_MAX_CAM_WCOUNT;
0623 break;
0624 case 4:
0625 max_index = MAC_ADDR_MAX_FC_MAC_ENTRIES;
0626 max_offset = MAC_ADDR_MAX_FC_MAC_WCOUNT;
0627 break;
0628 case 5:
0629 max_index = MAC_ADDR_MAX_MGMT_MAC_ENTRIES;
0630 max_offset = MAC_ADDR_MAX_MGMT_MAC_WCOUNT;
0631 break;
0632 case 6:
0633 max_index = MAC_ADDR_MAX_MGMT_VLAN_ENTRIES;
0634 max_offset = MAC_ADDR_MAX_MGMT_VLAN_WCOUNT;
0635 break;
0636 case 7:
0637 max_index = MAC_ADDR_MAX_MGMT_V4_ENTRIES;
0638 max_offset = MAC_ADDR_MAX_MGMT_V4_WCOUNT;
0639 break;
0640 case 8:
0641 max_index = MAC_ADDR_MAX_MGMT_V6_ENTRIES;
0642 max_offset = MAC_ADDR_MAX_MGMT_V6_WCOUNT;
0643 break;
0644 case 9:
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, ®_val);
0686 *buf = reg_val;
0687
0688 if (!status)
0689 *buf = 0xdeadbeef;
0690 buf++;
0691 }
0692 }
0693
0694
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
0707
0708
0709
0710
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
0723
0724
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
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
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
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
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
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
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
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
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
0911 status = qlge_get_mpi_shadow_regs(qdev,
0912 &mpi_coredump->mpi_core_sh_regs[0]);
0913 if (status)
0914 goto err;
0915
0916
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
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
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
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
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
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
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
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
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
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
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
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
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
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
1083
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
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
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
1153 qlge_write_mpi_reg(qdev, MPI_TEST_FUNC_RST_STS, MPI_TEST_FUNC_RST_FRC);
1154
1155
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
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
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);
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
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
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
1252 for (i = 0; i < 64; i++)
1253 mpi_coredump->nic_regs[i] = qlge_read32(qdev, i * sizeof(u32));
1254
1255
1256
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
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
1298
1299
1300
1301
1302
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 }