mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-05-09 00:33:51 +00:00
qlge: Add ethtool register dump function.
Signed-off-by: Ron Mercer <ron.mercer@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
bc083ce98e
commit
a61f802613
3 changed files with 345 additions and 0 deletions
|
@ -1400,6 +1400,153 @@ struct nic_stats {
|
||||||
u64 rx_nic_fifo_drop;
|
u64 rx_nic_fifo_drop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Address/Length pairs for the coredump. */
|
||||||
|
enum {
|
||||||
|
MPI_CORE_REGS_ADDR = 0x00030000,
|
||||||
|
MPI_CORE_REGS_CNT = 127,
|
||||||
|
MPI_CORE_SH_REGS_CNT = 16,
|
||||||
|
TEST_REGS_ADDR = 0x00001000,
|
||||||
|
TEST_REGS_CNT = 23,
|
||||||
|
RMII_REGS_ADDR = 0x00001040,
|
||||||
|
RMII_REGS_CNT = 64,
|
||||||
|
FCMAC1_REGS_ADDR = 0x00001080,
|
||||||
|
FCMAC2_REGS_ADDR = 0x000010c0,
|
||||||
|
FCMAC_REGS_CNT = 64,
|
||||||
|
FC1_MBX_REGS_ADDR = 0x00001100,
|
||||||
|
FC2_MBX_REGS_ADDR = 0x00001240,
|
||||||
|
FC_MBX_REGS_CNT = 64,
|
||||||
|
IDE_REGS_ADDR = 0x00001140,
|
||||||
|
IDE_REGS_CNT = 64,
|
||||||
|
NIC1_MBX_REGS_ADDR = 0x00001180,
|
||||||
|
NIC2_MBX_REGS_ADDR = 0x00001280,
|
||||||
|
NIC_MBX_REGS_CNT = 64,
|
||||||
|
SMBUS_REGS_ADDR = 0x00001200,
|
||||||
|
SMBUS_REGS_CNT = 64,
|
||||||
|
I2C_REGS_ADDR = 0x00001fc0,
|
||||||
|
I2C_REGS_CNT = 64,
|
||||||
|
MEMC_REGS_ADDR = 0x00003000,
|
||||||
|
MEMC_REGS_CNT = 256,
|
||||||
|
PBUS_REGS_ADDR = 0x00007c00,
|
||||||
|
PBUS_REGS_CNT = 256,
|
||||||
|
MDE_REGS_ADDR = 0x00010000,
|
||||||
|
MDE_REGS_CNT = 6,
|
||||||
|
CODE_RAM_ADDR = 0x00020000,
|
||||||
|
CODE_RAM_CNT = 0x2000,
|
||||||
|
MEMC_RAM_ADDR = 0x00100000,
|
||||||
|
MEMC_RAM_CNT = 0x2000,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MPI_COREDUMP_COOKIE 0x5555aaaa
|
||||||
|
struct mpi_coredump_global_header {
|
||||||
|
u32 cookie;
|
||||||
|
u8 idString[16];
|
||||||
|
u32 timeLo;
|
||||||
|
u32 timeHi;
|
||||||
|
u32 imageSize;
|
||||||
|
u32 headerSize;
|
||||||
|
u8 info[220];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mpi_coredump_segment_header {
|
||||||
|
u32 cookie;
|
||||||
|
u32 segNum;
|
||||||
|
u32 segSize;
|
||||||
|
u32 extra;
|
||||||
|
u8 description[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Reg dump segment numbers. */
|
||||||
|
enum {
|
||||||
|
CORE_SEG_NUM = 1,
|
||||||
|
TEST_LOGIC_SEG_NUM = 2,
|
||||||
|
RMII_SEG_NUM = 3,
|
||||||
|
FCMAC1_SEG_NUM = 4,
|
||||||
|
FCMAC2_SEG_NUM = 5,
|
||||||
|
FC1_MBOX_SEG_NUM = 6,
|
||||||
|
IDE_SEG_NUM = 7,
|
||||||
|
NIC1_MBOX_SEG_NUM = 8,
|
||||||
|
SMBUS_SEG_NUM = 9,
|
||||||
|
FC2_MBOX_SEG_NUM = 10,
|
||||||
|
NIC2_MBOX_SEG_NUM = 11,
|
||||||
|
I2C_SEG_NUM = 12,
|
||||||
|
MEMC_SEG_NUM = 13,
|
||||||
|
PBUS_SEG_NUM = 14,
|
||||||
|
MDE_SEG_NUM = 15,
|
||||||
|
NIC1_CONTROL_SEG_NUM = 16,
|
||||||
|
NIC2_CONTROL_SEG_NUM = 17,
|
||||||
|
NIC1_XGMAC_SEG_NUM = 18,
|
||||||
|
NIC2_XGMAC_SEG_NUM = 19,
|
||||||
|
WCS_RAM_SEG_NUM = 20,
|
||||||
|
MEMC_RAM_SEG_NUM = 21,
|
||||||
|
XAUI_AN_SEG_NUM = 22,
|
||||||
|
XAUI_HSS_PCS_SEG_NUM = 23,
|
||||||
|
XFI_AN_SEG_NUM = 24,
|
||||||
|
XFI_TRAIN_SEG_NUM = 25,
|
||||||
|
XFI_HSS_PCS_SEG_NUM = 26,
|
||||||
|
XFI_HSS_TX_SEG_NUM = 27,
|
||||||
|
XFI_HSS_RX_SEG_NUM = 28,
|
||||||
|
XFI_HSS_PLL_SEG_NUM = 29,
|
||||||
|
MISC_NIC_INFO_SEG_NUM = 30,
|
||||||
|
INTR_STATES_SEG_NUM = 31,
|
||||||
|
CAM_ENTRIES_SEG_NUM = 32,
|
||||||
|
ROUTING_WORDS_SEG_NUM = 33,
|
||||||
|
ETS_SEG_NUM = 34,
|
||||||
|
PROBE_DUMP_SEG_NUM = 35,
|
||||||
|
ROUTING_INDEX_SEG_NUM = 36,
|
||||||
|
MAC_PROTOCOL_SEG_NUM = 37,
|
||||||
|
XAUI2_AN_SEG_NUM = 38,
|
||||||
|
XAUI2_HSS_PCS_SEG_NUM = 39,
|
||||||
|
XFI2_AN_SEG_NUM = 40,
|
||||||
|
XFI2_TRAIN_SEG_NUM = 41,
|
||||||
|
XFI2_HSS_PCS_SEG_NUM = 42,
|
||||||
|
XFI2_HSS_TX_SEG_NUM = 43,
|
||||||
|
XFI2_HSS_RX_SEG_NUM = 44,
|
||||||
|
XFI2_HSS_PLL_SEG_NUM = 45,
|
||||||
|
SEM_REGS_SEG_NUM = 50
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ql_nic_misc {
|
||||||
|
u32 rx_ring_count;
|
||||||
|
u32 tx_ring_count;
|
||||||
|
u32 intr_count;
|
||||||
|
u32 function;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ql_reg_dump {
|
||||||
|
|
||||||
|
/* segment 0 */
|
||||||
|
struct mpi_coredump_global_header mpi_global_header;
|
||||||
|
|
||||||
|
/* segment 16 */
|
||||||
|
struct mpi_coredump_segment_header nic_regs_seg_hdr;
|
||||||
|
u32 nic_regs[64];
|
||||||
|
|
||||||
|
/* segment 30 */
|
||||||
|
struct mpi_coredump_segment_header misc_nic_seg_hdr;
|
||||||
|
struct ql_nic_misc misc_nic_info;
|
||||||
|
|
||||||
|
/* segment 31 */
|
||||||
|
/* one interrupt state for each CQ */
|
||||||
|
struct mpi_coredump_segment_header intr_states_seg_hdr;
|
||||||
|
u32 intr_states[MAX_CPUS];
|
||||||
|
|
||||||
|
/* segment 32 */
|
||||||
|
/* 3 cam words each for 16 unicast,
|
||||||
|
* 2 cam words for each of 32 multicast.
|
||||||
|
*/
|
||||||
|
struct mpi_coredump_segment_header cam_entries_seg_hdr;
|
||||||
|
u32 cam_entries[(16 * 3) + (32 * 3)];
|
||||||
|
|
||||||
|
/* segment 33 */
|
||||||
|
struct mpi_coredump_segment_header nic_routing_words_seg_hdr;
|
||||||
|
u32 nic_routing_words[16];
|
||||||
|
|
||||||
|
/* segment 34 */
|
||||||
|
struct mpi_coredump_segment_header ets_seg_hdr;
|
||||||
|
u32 ets[8+2];
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* intr_context structure is used during initialization
|
* intr_context structure is used during initialization
|
||||||
* to hook the interrupts. It is also used in a single
|
* 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);
|
||||||
int ql_mb_get_port_cfg(struct ql_adapter *qdev);
|
int ql_mb_get_port_cfg(struct ql_adapter *qdev);
|
||||||
int ql_mb_set_port_cfg(struct ql_adapter *qdev);
|
int ql_mb_set_port_cfg(struct ql_adapter *qdev);
|
||||||
int ql_wait_fifo_empty(struct ql_adapter *qdev);
|
int ql_wait_fifo_empty(struct ql_adapter *qdev);
|
||||||
|
void ql_gen_reg_dump(struct ql_adapter *qdev,
|
||||||
|
struct ql_reg_dump *mpi_coredump);
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
#define QL_ALL_DUMP
|
#define QL_ALL_DUMP
|
||||||
|
|
|
@ -1,5 +1,185 @@
|
||||||
#include "qlge.h"
|
#include "qlge.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int ql_get_ets_regs(struct ql_adapter *qdev, u32 * buf)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++, buf++) {
|
||||||
|
ql_write32(qdev, NIC_ETS, i << 29 | 0x08000000);
|
||||||
|
*buf = ql_read32(qdev, NIC_ETS);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++, buf++) {
|
||||||
|
ql_write32(qdev, CNA_ETS, i << 29 | 0x08000000);
|
||||||
|
*buf = ql_read32(qdev, CNA_ETS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ql_get_intr_states(struct ql_adapter *qdev, u32 * buf)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < qdev->rx_ring_count; i++, buf++) {
|
||||||
|
ql_write32(qdev, INTR_EN,
|
||||||
|
qdev->intr_context[i].intr_read_mask);
|
||||||
|
*buf = ql_read32(qdev, INTR_EN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ql_get_cam_entries(struct ql_adapter *qdev, u32 * buf)
|
||||||
|
{
|
||||||
|
int i, status;
|
||||||
|
u32 value[3];
|
||||||
|
|
||||||
|
status = ql_sem_spinlock(qdev, SEM_MAC_ADDR_MASK);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
status = ql_get_mac_addr_reg(qdev,
|
||||||
|
MAC_ADDR_TYPE_CAM_MAC, i, value);
|
||||||
|
if (status) {
|
||||||
|
QPRINTK(qdev, DRV, ERR,
|
||||||
|
"Failed read of mac index register.\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
*buf++ = value[0]; /* lower MAC address */
|
||||||
|
*buf++ = value[1]; /* upper MAC address */
|
||||||
|
*buf++ = value[2]; /* output */
|
||||||
|
}
|
||||||
|
for (i = 0; i < 32; i++) {
|
||||||
|
status = ql_get_mac_addr_reg(qdev,
|
||||||
|
MAC_ADDR_TYPE_MULTI_MAC, i, value);
|
||||||
|
if (status) {
|
||||||
|
QPRINTK(qdev, DRV, ERR,
|
||||||
|
"Failed read of mac index register.\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
*buf++ = value[0]; /* lower Mcast address */
|
||||||
|
*buf++ = value[1]; /* upper Mcast address */
|
||||||
|
}
|
||||||
|
err:
|
||||||
|
ql_sem_unlock(qdev, SEM_MAC_ADDR_MASK);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ql_get_routing_entries(struct ql_adapter *qdev, u32 * buf)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
u32 value, i;
|
||||||
|
|
||||||
|
status = ql_sem_spinlock(qdev, SEM_RT_IDX_MASK);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++) {
|
||||||
|
status = ql_get_routing_reg(qdev, i, &value);
|
||||||
|
if (status) {
|
||||||
|
QPRINTK(qdev, DRV, ERR,
|
||||||
|
"Failed read of routing index register.\n");
|
||||||
|
goto err;
|
||||||
|
} else {
|
||||||
|
*buf++ = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err:
|
||||||
|
ql_sem_unlock(qdev, SEM_RT_IDX_MASK);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a coredump segment header */
|
||||||
|
static void ql_build_coredump_seg_header(
|
||||||
|
struct mpi_coredump_segment_header *seg_hdr,
|
||||||
|
u32 seg_number, u32 seg_size, u8 *desc)
|
||||||
|
{
|
||||||
|
memset(seg_hdr, 0, sizeof(struct mpi_coredump_segment_header));
|
||||||
|
seg_hdr->cookie = MPI_COREDUMP_COOKIE;
|
||||||
|
seg_hdr->segNum = seg_number;
|
||||||
|
seg_hdr->segSize = seg_size;
|
||||||
|
memcpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ql_gen_reg_dump(struct ql_adapter *qdev,
|
||||||
|
struct ql_reg_dump *mpi_coredump)
|
||||||
|
{
|
||||||
|
int i, status;
|
||||||
|
|
||||||
|
|
||||||
|
memset(&(mpi_coredump->mpi_global_header), 0,
|
||||||
|
sizeof(struct mpi_coredump_global_header));
|
||||||
|
mpi_coredump->mpi_global_header.cookie = MPI_COREDUMP_COOKIE;
|
||||||
|
mpi_coredump->mpi_global_header.headerSize =
|
||||||
|
sizeof(struct mpi_coredump_global_header);
|
||||||
|
mpi_coredump->mpi_global_header.imageSize =
|
||||||
|
sizeof(struct ql_reg_dump);
|
||||||
|
memcpy(mpi_coredump->mpi_global_header.idString, "MPI Coredump",
|
||||||
|
sizeof(mpi_coredump->mpi_global_header.idString));
|
||||||
|
|
||||||
|
|
||||||
|
/* segment 16 */
|
||||||
|
ql_build_coredump_seg_header(&mpi_coredump->misc_nic_seg_hdr,
|
||||||
|
MISC_NIC_INFO_SEG_NUM,
|
||||||
|
sizeof(struct mpi_coredump_segment_header)
|
||||||
|
+ sizeof(mpi_coredump->misc_nic_info),
|
||||||
|
"MISC NIC INFO");
|
||||||
|
mpi_coredump->misc_nic_info.rx_ring_count = qdev->rx_ring_count;
|
||||||
|
mpi_coredump->misc_nic_info.tx_ring_count = qdev->tx_ring_count;
|
||||||
|
mpi_coredump->misc_nic_info.intr_count = qdev->intr_count;
|
||||||
|
mpi_coredump->misc_nic_info.function = qdev->func;
|
||||||
|
|
||||||
|
/* Segment 16, Rev C. Step 18 */
|
||||||
|
ql_build_coredump_seg_header(&mpi_coredump->nic_regs_seg_hdr,
|
||||||
|
NIC1_CONTROL_SEG_NUM,
|
||||||
|
sizeof(struct mpi_coredump_segment_header)
|
||||||
|
+ sizeof(mpi_coredump->nic_regs),
|
||||||
|
"NIC Registers");
|
||||||
|
/* Get generic reg dump */
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
mpi_coredump->nic_regs[i] = ql_read32(qdev, i * sizeof(u32));
|
||||||
|
|
||||||
|
/* Segment 31 */
|
||||||
|
/* Get indexed register values. */
|
||||||
|
ql_build_coredump_seg_header(&mpi_coredump->intr_states_seg_hdr,
|
||||||
|
INTR_STATES_SEG_NUM,
|
||||||
|
sizeof(struct mpi_coredump_segment_header)
|
||||||
|
+ sizeof(mpi_coredump->intr_states),
|
||||||
|
"INTR States");
|
||||||
|
ql_get_intr_states(qdev, &mpi_coredump->intr_states[0]);
|
||||||
|
|
||||||
|
ql_build_coredump_seg_header(&mpi_coredump->cam_entries_seg_hdr,
|
||||||
|
CAM_ENTRIES_SEG_NUM,
|
||||||
|
sizeof(struct mpi_coredump_segment_header)
|
||||||
|
+ sizeof(mpi_coredump->cam_entries),
|
||||||
|
"CAM Entries");
|
||||||
|
status = ql_get_cam_entries(qdev, &mpi_coredump->cam_entries[0]);
|
||||||
|
if (status)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ql_build_coredump_seg_header(&mpi_coredump->nic_routing_words_seg_hdr,
|
||||||
|
ROUTING_WORDS_SEG_NUM,
|
||||||
|
sizeof(struct mpi_coredump_segment_header)
|
||||||
|
+ sizeof(mpi_coredump->nic_routing_words),
|
||||||
|
"Routing Words");
|
||||||
|
status = ql_get_routing_entries(qdev,
|
||||||
|
&mpi_coredump->nic_routing_words[0]);
|
||||||
|
if (status)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Segment 34 (Rev C. step 23) */
|
||||||
|
ql_build_coredump_seg_header(&mpi_coredump->ets_seg_hdr,
|
||||||
|
ETS_SEG_NUM,
|
||||||
|
sizeof(struct mpi_coredump_segment_header)
|
||||||
|
+ sizeof(mpi_coredump->ets),
|
||||||
|
"ETS Registers");
|
||||||
|
status = ql_get_ets_regs(qdev, &mpi_coredump->ets[0]);
|
||||||
|
if (status)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef QL_REG_DUMP
|
#ifdef QL_REG_DUMP
|
||||||
static void ql_dump_intr_states(struct ql_adapter *qdev)
|
static void ql_dump_intr_states(struct ql_adapter *qdev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -428,6 +428,20 @@ static int ql_phys_id(struct net_device *ndev, u32 data)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ql_get_regs_len(struct net_device *ndev)
|
||||||
|
{
|
||||||
|
return sizeof(struct ql_reg_dump);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ql_get_regs(struct net_device *ndev,
|
||||||
|
struct ethtool_regs *regs, void *p)
|
||||||
|
{
|
||||||
|
struct ql_adapter *qdev = netdev_priv(ndev);
|
||||||
|
|
||||||
|
ql_gen_reg_dump(qdev, p);
|
||||||
|
}
|
||||||
|
|
||||||
static int ql_get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
|
static int ql_get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
|
||||||
{
|
{
|
||||||
struct ql_adapter *qdev = netdev_priv(dev);
|
struct ql_adapter *qdev = netdev_priv(dev);
|
||||||
|
@ -555,6 +569,8 @@ const struct ethtool_ops qlge_ethtool_ops = {
|
||||||
.get_drvinfo = ql_get_drvinfo,
|
.get_drvinfo = ql_get_drvinfo,
|
||||||
.get_wol = ql_get_wol,
|
.get_wol = ql_get_wol,
|
||||||
.set_wol = ql_set_wol,
|
.set_wol = ql_set_wol,
|
||||||
|
.get_regs_len = ql_get_regs_len,
|
||||||
|
.get_regs = ql_get_regs,
|
||||||
.get_msglevel = ql_get_msglevel,
|
.get_msglevel = ql_get_msglevel,
|
||||||
.set_msglevel = ql_set_msglevel,
|
.set_msglevel = ql_set_msglevel,
|
||||||
.get_link = ethtool_op_get_link,
|
.get_link = ethtool_op_get_link,
|
||||||
|
|
Loading…
Add table
Reference in a new issue