aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlge
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/qlge')
-rw-r--r--drivers/net/qlge/qlge.h149
-rw-r--r--drivers/net/qlge/qlge_dbg.c180
-rw-r--r--drivers/net/qlge/qlge_ethtool.c16
3 files changed, 345 insertions, 0 deletions
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index ba297769920..4b954e13c00 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -1400,6 +1400,153 @@ struct nic_stats {
1400 u64 rx_nic_fifo_drop; 1400 u64 rx_nic_fifo_drop;
1401}; 1401};
1402 1402
1403/* Address/Length pairs for the coredump. */
1404enum {
1405 MPI_CORE_REGS_ADDR = 0x00030000,
1406 MPI_CORE_REGS_CNT = 127,
1407 MPI_CORE_SH_REGS_CNT = 16,
1408 TEST_REGS_ADDR = 0x00001000,
1409 TEST_REGS_CNT = 23,
1410 RMII_REGS_ADDR = 0x00001040,
1411 RMII_REGS_CNT = 64,
1412 FCMAC1_REGS_ADDR = 0x00001080,
1413 FCMAC2_REGS_ADDR = 0x000010c0,
1414 FCMAC_REGS_CNT = 64,
1415 FC1_MBX_REGS_ADDR = 0x00001100,
1416 FC2_MBX_REGS_ADDR = 0x00001240,
1417 FC_MBX_REGS_CNT = 64,
1418 IDE_REGS_ADDR = 0x00001140,
1419 IDE_REGS_CNT = 64,
1420 NIC1_MBX_REGS_ADDR = 0x00001180,
1421 NIC2_MBX_REGS_ADDR = 0x00001280,
1422 NIC_MBX_REGS_CNT = 64,
1423 SMBUS_REGS_ADDR = 0x00001200,
1424 SMBUS_REGS_CNT = 64,
1425 I2C_REGS_ADDR = 0x00001fc0,
1426 I2C_REGS_CNT = 64,
1427 MEMC_REGS_ADDR = 0x00003000,
1428 MEMC_REGS_CNT = 256,
1429 PBUS_REGS_ADDR = 0x00007c00,
1430 PBUS_REGS_CNT = 256,
1431 MDE_REGS_ADDR = 0x00010000,
1432 MDE_REGS_CNT = 6,
1433 CODE_RAM_ADDR = 0x00020000,
1434 CODE_RAM_CNT = 0x2000,
1435 MEMC_RAM_ADDR = 0x00100000,
1436 MEMC_RAM_CNT = 0x2000,
1437};
1438
1439#define MPI_COREDUMP_COOKIE 0x5555aaaa
1440struct mpi_coredump_global_header {
1441 u32 cookie;
1442 u8 idString[16];
1443 u32 timeLo;
1444 u32 timeHi;
1445 u32 imageSize;
1446 u32 headerSize;
1447 u8 info[220];
1448};
1449
1450struct mpi_coredump_segment_header {
1451 u32 cookie;
1452 u32 segNum;
1453 u32 segSize;
1454 u32 extra;
1455 u8 description[16];
1456};
1457
1458/* Reg dump segment numbers. */
1459enum {
1460 CORE_SEG_NUM = 1,
1461 TEST_LOGIC_SEG_NUM = 2,
1462 RMII_SEG_NUM = 3,
1463 FCMAC1_SEG_NUM = 4,
1464 FCMAC2_SEG_NUM = 5,
1465 FC1_MBOX_SEG_NUM = 6,
1466 IDE_SEG_NUM = 7,
1467 NIC1_MBOX_SEG_NUM = 8,
1468 SMBUS_SEG_NUM = 9,
1469 FC2_MBOX_SEG_NUM = 10,
1470 NIC2_MBOX_SEG_NUM = 11,
1471 I2C_SEG_NUM = 12,
1472 MEMC_SEG_NUM = 13,
1473 PBUS_SEG_NUM = 14,
1474 MDE_SEG_NUM = 15,
1475 NIC1_CONTROL_SEG_NUM = 16,
1476 NIC2_CONTROL_SEG_NUM = 17,
1477 NIC1_XGMAC_SEG_NUM = 18,
1478 NIC2_XGMAC_SEG_NUM = 19,
1479 WCS_RAM_SEG_NUM = 20,
1480 MEMC_RAM_SEG_NUM = 21,
1481 XAUI_AN_SEG_NUM = 22,
1482 XAUI_HSS_PCS_SEG_NUM = 23,
1483 XFI_AN_SEG_NUM = 24,
1484 XFI_TRAIN_SEG_NUM = 25,
1485 XFI_HSS_PCS_SEG_NUM = 26,
1486 XFI_HSS_TX_SEG_NUM = 27,
1487 XFI_HSS_RX_SEG_NUM = 28,
1488 XFI_HSS_PLL_SEG_NUM = 29,
1489 MISC_NIC_INFO_SEG_NUM = 30,
1490 INTR_STATES_SEG_NUM = 31,
1491 CAM_ENTRIES_SEG_NUM = 32,
1492 ROUTING_WORDS_SEG_NUM = 33,
1493 ETS_SEG_NUM = 34,
1494 PROBE_DUMP_SEG_NUM = 35,
1495 ROUTING_INDEX_SEG_NUM = 36,
1496 MAC_PROTOCOL_SEG_NUM = 37,
1497 XAUI2_AN_SEG_NUM = 38,
1498 XAUI2_HSS_PCS_SEG_NUM = 39,
1499 XFI2_AN_SEG_NUM = 40,
1500 XFI2_TRAIN_SEG_NUM = 41,
1501 XFI2_HSS_PCS_SEG_NUM = 42,
1502 XFI2_HSS_TX_SEG_NUM = 43,
1503 XFI2_HSS_RX_SEG_NUM = 44,
1504 XFI2_HSS_PLL_SEG_NUM = 45,
1505 SEM_REGS_SEG_NUM = 50
1506
1507};
1508
1509struct ql_nic_misc {
1510 u32 rx_ring_count;
1511 u32 tx_ring_count;
1512 u32 intr_count;
1513 u32 function;
1514};
1515
1516struct ql_reg_dump {
1517
1518 /* segment 0 */
1519 struct mpi_coredump_global_header mpi_global_header;
1520
1521 /* segment 16 */
1522 struct mpi_coredump_segment_header nic_regs_seg_hdr;
1523 u32 nic_regs[64];
1524
1525 /* segment 30 */
1526 struct mpi_coredump_segment_header misc_nic_seg_hdr;
1527 struct ql_nic_misc misc_nic_info;
1528
1529 /* segment 31 */
1530 /* one interrupt state for each CQ */
1531 struct mpi_coredump_segment_header intr_states_seg_hdr;
1532 u32 intr_states[MAX_CPUS];
1533
1534 /* segment 32 */
1535 /* 3 cam words each for 16 unicast,
1536 * 2 cam words for each of 32 multicast.
1537 */
1538 struct mpi_coredump_segment_header cam_entries_seg_hdr;
1539 u32 cam_entries[(16 * 3) + (32 * 3)];
1540
1541 /* segment 33 */
1542 struct mpi_coredump_segment_header nic_routing_words_seg_hdr;
1543 u32 nic_routing_words[16];
1544
1545 /* segment 34 */
1546 struct mpi_coredump_segment_header ets_seg_hdr;
1547 u32 ets[8+2];
1548};
1549
1403/* 1550/*
1404 * intr_context structure is used during initialization 1551 * intr_context structure is used during initialization
1405 * to hook the interrupts. It is also used in a single 1552 * to hook the interrupts. It is also used in a single
@@ -1658,6 +1805,8 @@ int ql_mb_set_mgmnt_traffic_ctl(struct ql_adapter *qdev, u32 control);
1658int ql_mb_get_port_cfg(struct ql_adapter *qdev); 1805int ql_mb_get_port_cfg(struct ql_adapter *qdev);
1659int ql_mb_set_port_cfg(struct ql_adapter *qdev); 1806int ql_mb_set_port_cfg(struct ql_adapter *qdev);
1660int ql_wait_fifo_empty(struct ql_adapter *qdev); 1807int ql_wait_fifo_empty(struct ql_adapter *qdev);
1808void ql_gen_reg_dump(struct ql_adapter *qdev,
1809 struct ql_reg_dump *mpi_coredump);
1661 1810
1662#if 1 1811#if 1
1663#define QL_ALL_DUMP 1812#define QL_ALL_DUMP
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c
index aa88cb3f41c..9f58c471076 100644
--- a/drivers/net/qlge/qlge_dbg.c
+++ b/drivers/net/qlge/qlge_dbg.c
@@ -1,5 +1,185 @@
1#include "qlge.h" 1#include "qlge.h"
2 2
3
4static int ql_get_ets_regs(struct ql_adapter *qdev, u32 * buf)
5{
6 int status = 0;
7 int i;
8
9 for (i = 0; i < 8; i++, buf++) {
10 ql_write32(qdev, NIC_ETS, i << 29 | 0x08000000);
11 *buf = ql_read32(qdev, NIC_ETS);
12 }
13
14 for (i = 0; i < 2; i++, buf++) {
15 ql_write32(qdev, CNA_ETS, i << 29 | 0x08000000);
16 *buf = ql_read32(qdev, CNA_ETS);
17 }
18
19 return status;
20}
21
22static void ql_get_intr_states(struct ql_adapter *qdev, u32 * buf)
23{
24 int i;
25
26 for (i = 0; i < qdev->rx_ring_count; i++, buf++) {
27 ql_write32(qdev, INTR_EN,
28 qdev->intr_context[i].intr_read_mask);
29 *buf = ql_read32(qdev, INTR_EN);
30 }
31}
32
33static int ql_get_cam_entries(struct ql_adapter *qdev, u32 * buf)
34{
35 int i, status;
36 u32 value[3];
37
38 status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
39 if (status)
40 return status;
41
42 for (i = 0; i < 16; i++) {
43 status = ql_get_mac_addr_reg(qdev,
44 MAC_ADDR_TYPE_CAM_MAC, i, value);
45 if (status) {
46 QPRINTK(qdev, DRV, ERR,
47 "Failed read of mac index register.\n");
48 goto err;
49 }
50 *buf++ = value[0]; /* lower MAC address */
51 *buf++ = value[1]; /* upper MAC address */
52 *buf++ = value[2]; /* output */
53 }
54 for (i = 0; i < 32; i++) {
55 status = ql_get_mac_addr_reg(qdev,
56 MAC_ADDR_TYPE_MULTI_MAC, i, value);
57 if (status) {
58 QPRINTK(qdev, DRV, ERR,
59 "Failed read of mac index register.\n");
60 goto err;
61 }
62 *buf++ = value[0]; /* lower Mcast address */
63 *buf++ = value[1]; /* upper Mcast address */
64 }
65err:
66 ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
67 return status;
68}
69
70static int ql_get_routing_entries(struct ql_adapter *qdev, u32 * buf)
71{
72 int status;
73 u32 value, i;
74
75 status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
76 if (status)
77 return status;
78
79 for (i = 0; i < 16; i++) {
80 status = ql_get_routing_reg(qdev, i, &value);
81 if (status) {
82 QPRINTK(qdev, DRV, ERR,
83 "Failed read of routing index register.\n");
84 goto err;
85 } else {
86 *buf++ = value;
87 }
88 }
89err:
90 ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
91 return status;
92}
93
94/* Create a coredump segment header */
95static void ql_build_coredump_seg_header(
96 struct mpi_coredump_segment_header *seg_hdr,
97 u32 seg_number, u32 seg_size, u8 *desc)
98{
99 memset(seg_hdr, 0, sizeof(struct mpi_coredump_segment_header));
100 seg_hdr->cookie = MPI_COREDUMP_COOKIE;
101 seg_hdr->segNum = seg_number;
102 seg_hdr->segSize = seg_size;
103 memcpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
104}
105
106void ql_gen_reg_dump(struct ql_adapter *qdev,
107 struct ql_reg_dump *mpi_coredump)
108{
109 int i, status;
110
111
112 memset(&(mpi_coredump->mpi_global_header), 0,
113 sizeof(struct mpi_coredump_global_header));
114 mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
115 mpi_coredump->mpi_global_header.headerSize =
116 sizeof(struct mpi_coredump_global_header);
117 mpi_coredump->mpi_global_header.imageSize =
118 sizeof(struct ql_reg_dump);
119 memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
120 sizeof(mpi_coredump->mpi_global_header.idString));
121
122
123 /* segment 16 */
124 ql_build_coredump_seg_header(&mpi_coredump->misc_nic_seg_hdr,
125 MISC_NIC_INFO_SEG_NUM,
126 sizeof(struct mpi_coredump_segment_header)
127 + sizeof(mpi_coredump->misc_nic_info),
128 "MISC NIC INFO");
129 mpi_coredump->misc_nic_info.rx_ring_count = qdev->rx_ring_count;
130 mpi_coredump->misc_nic_info.tx_ring_count = qdev->tx_ring_count;
131 mpi_coredump->misc_nic_info.intr_count = qdev->intr_count;
132 mpi_coredump->misc_nic_info.function = qdev->func;
133
134 /* Segment 16, Rev C. Step 18 */
135 ql_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr,
136 NIC1_CONTROL_SEG_NUM,
137 sizeof(struct mpi_coredump_segment_header)
138 + sizeof(mpi_coredump->nic_regs),
139 "NIC Registers");
140 /* Get generic reg dump */
141 for (i = 0; i < 64; i++)
142 mpi_coredump->nic_regs[i] = ql_read32(qdev, i * sizeof(u32));
143
144 /* Segment 31 */
145 /* Get indexed register values. */
146 ql_build_coredump_seg_header(&mpi_coredump->intr_states_seg_hdr,
147 INTR_STATES_SEG_NUM,
148 sizeof(struct mpi_coredump_segment_header)
149 + sizeof(mpi_coredump->intr_states),
150 "INTR States");
151 ql_get_intr_states(qdev, &mpi_coredump->intr_states[0]);
152
153 ql_build_coredump_seg_header(&mpi_coredump->cam_entries_seg_hdr,
154 CAM_ENTRIES_SEG_NUM,
155 sizeof(struct mpi_coredump_segment_header)
156 + sizeof(mpi_coredump->cam_entries),
157 "CAM Entries");
158 status = ql_get_cam_entries(qdev, &mpi_coredump->cam_entries[0]);
159 if (status)
160 return;
161
162 ql_build_coredump_seg_header(&mpi_coredump->nic_routing_words_seg_hdr,
163 ROUTING_WORDS_SEG_NUM,
164 sizeof(struct mpi_coredump_segment_header)
165 + sizeof(mpi_coredump->nic_routing_words),
166 "Routing Words");
167 status = ql_get_routing_entries(qdev,
168 &mpi_coredump->nic_routing_words[0]);
169 if (status)
170 return;
171
172 /* Segment 34 (Rev C. step 23) */
173 ql_build_coredump_seg_header(&mpi_coredump->ets_seg_hdr,
174 ETS_SEG_NUM,
175 sizeof(struct mpi_coredump_segment_header)
176 + sizeof(mpi_coredump->ets),
177 "ETS Registers");
178 status = ql_get_ets_regs(qdev, &mpi_coredump->ets[0]);
179 if (status)
180 return;
181}
182
3#ifdef QL_REG_DUMP 183#ifdef QL_REG_DUMP
4static void ql_dump_intr_states(struct ql_adapter *qdev) 184static void ql_dump_intr_states(struct ql_adapter *qdev)
5{ 185{
diff --git a/drivers/net/qlge/qlge_ethtool.c b/drivers/net/qlge/qlge_ethtool.c
index 019f35fb10c..62c4af05780 100644
--- a/drivers/net/qlge/qlge_ethtool.c
+++ b/drivers/net/qlge/qlge_ethtool.c
@@ -428,6 +428,20 @@ static int ql_phys_id(struct net_device *ndev, u32 data)
428 428
429 return 0; 429 return 0;
430} 430}
431
432static int ql_get_regs_len(struct net_device *ndev)
433{
434 return sizeof(struct ql_reg_dump);
435}
436
437static void ql_get_regs(struct net_device *ndev,
438 struct ethtool_regs *regs, void *p)
439{
440 struct ql_adapter *qdev = netdev_priv(ndev);
441
442 ql_gen_reg_dump(qdev, p);
443}
444
431static int ql_get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) 445static int ql_get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
432{ 446{
433 struct ql_adapter *qdev = netdev_priv(dev); 447 struct ql_adapter *qdev = netdev_priv(dev);
@@ -555,6 +569,8 @@ const struct ethtool_ops qlge_ethtool_ops = {
555 .get_drvinfo = ql_get_drvinfo, 569 .get_drvinfo = ql_get_drvinfo,
556 .get_wol = ql_get_wol, 570 .get_wol = ql_get_wol,
557 .set_wol = ql_set_wol, 571 .set_wol = ql_set_wol,
572 .get_regs_len = ql_get_regs_len,
573 .get_regs = ql_get_regs,
558 .get_msglevel = ql_get_msglevel, 574 .get_msglevel = ql_get_msglevel,
559 .set_msglevel = ql_set_msglevel, 575 .set_msglevel = ql_set_msglevel,
560 .get_link = ethtool_op_get_link, 576 .get_link = ethtool_op_get_link,