aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_main.c
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2009-03-02 03:01:12 -0500
committerDavid S. Miller <davem@davemloft.net>2009-03-03 01:32:48 -0500
commit0a64ea57486acd9e17b80bb70b966e81d904b61c (patch)
tree54c1ba2cf230f8c51f6d73bb27e40767e33ebeef /drivers/net/bnx2x_main.c
parentc3eefaf676646281c07f93cb523a7be4eab67f8c (diff)
bnx2x: Register dump
Adding "ethtool -d" support. Due to the complexity of the FW and HW, there are a lot of different regions in the chip - to keep the code as clean as possible, the ranges were put in an H file. Some areas cannot be read if the driver is running - so by default, the driver will not access those areas - but any programmer facing a problem will be able to easily manipulate the driver to extract full dump. The full dump can also be used with kernel dump modules in case of kernel panic. Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r--drivers/net/bnx2x_main.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index e5952c57b40d..09d802ab0041 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -53,6 +53,7 @@
53 53
54#include "bnx2x.h" 54#include "bnx2x.h"
55#include "bnx2x_init.h" 55#include "bnx2x_init.h"
56#include "bnx2x_dump.h"
56 57
57#define DRV_MODULE_VERSION "1.48.102" 58#define DRV_MODULE_VERSION "1.48.102"
58#define DRV_MODULE_RELDATE "2009/02/12" 59#define DRV_MODULE_RELDATE "2009/02/12"
@@ -8471,6 +8472,84 @@ static void bnx2x_get_drvinfo(struct net_device *dev,
8471 info->regdump_len = 0; 8472 info->regdump_len = 0;
8472} 8473}
8473 8474
8475#define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE)
8476#define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE)
8477
8478static int bnx2x_get_regs_len(struct net_device *dev)
8479{
8480 static u32 regdump_len;
8481 struct bnx2x *bp = netdev_priv(dev);
8482 int i;
8483
8484 if (regdump_len)
8485 return regdump_len;
8486
8487 if (CHIP_IS_E1(bp)) {
8488 for (i = 0; i < REGS_COUNT; i++)
8489 if (IS_E1_ONLINE(reg_addrs[i].info))
8490 regdump_len += reg_addrs[i].size;
8491
8492 for (i = 0; i < WREGS_COUNT_E1; i++)
8493 if (IS_E1_ONLINE(wreg_addrs_e1[i].info))
8494 regdump_len += wreg_addrs_e1[i].size *
8495 (1 + wreg_addrs_e1[i].read_regs_count);
8496
8497 } else { /* E1H */
8498 for (i = 0; i < REGS_COUNT; i++)
8499 if (IS_E1H_ONLINE(reg_addrs[i].info))
8500 regdump_len += reg_addrs[i].size;
8501
8502 for (i = 0; i < WREGS_COUNT_E1H; i++)
8503 if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info))
8504 regdump_len += wreg_addrs_e1h[i].size *
8505 (1 + wreg_addrs_e1h[i].read_regs_count);
8506 }
8507 regdump_len *= 4;
8508 regdump_len += sizeof(struct dump_hdr);
8509
8510 return regdump_len;
8511}
8512
8513static void bnx2x_get_regs(struct net_device *dev,
8514 struct ethtool_regs *regs, void *_p)
8515{
8516 u32 *p = _p, i, j;
8517 struct bnx2x *bp = netdev_priv(dev);
8518 struct dump_hdr dump_hdr = {0};
8519
8520 regs->version = 0;
8521 memset(p, 0, regs->len);
8522
8523 if (!netif_running(bp->dev))
8524 return;
8525
8526 dump_hdr.hdr_size = (sizeof(struct dump_hdr) / 4) - 1;
8527 dump_hdr.dump_sign = dump_sign_all;
8528 dump_hdr.xstorm_waitp = REG_RD(bp, XSTORM_WAITP_ADDR);
8529 dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR);
8530 dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR);
8531 dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR);
8532 dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE;
8533
8534 memcpy(p, &dump_hdr, sizeof(struct dump_hdr));
8535 p += dump_hdr.hdr_size + 1;
8536
8537 if (CHIP_IS_E1(bp)) {
8538 for (i = 0; i < REGS_COUNT; i++)
8539 if (IS_E1_ONLINE(reg_addrs[i].info))
8540 for (j = 0; j < reg_addrs[i].size; j++)
8541 *p++ = REG_RD(bp,
8542 reg_addrs[i].addr + j*4);
8543
8544 } else { /* E1H */
8545 for (i = 0; i < REGS_COUNT; i++)
8546 if (IS_E1H_ONLINE(reg_addrs[i].info))
8547 for (j = 0; j < reg_addrs[i].size; j++)
8548 *p++ = REG_RD(bp,
8549 reg_addrs[i].addr + j*4);
8550 }
8551}
8552
8474static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) 8553static void bnx2x_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
8475{ 8554{
8476 struct bnx2x *bp = netdev_priv(dev); 8555 struct bnx2x *bp = netdev_priv(dev);
@@ -9926,6 +10005,8 @@ static struct ethtool_ops bnx2x_ethtool_ops = {
9926 .get_settings = bnx2x_get_settings, 10005 .get_settings = bnx2x_get_settings,
9927 .set_settings = bnx2x_set_settings, 10006 .set_settings = bnx2x_set_settings,
9928 .get_drvinfo = bnx2x_get_drvinfo, 10007 .get_drvinfo = bnx2x_get_drvinfo,
10008 .get_regs_len = bnx2x_get_regs_len,
10009 .get_regs = bnx2x_get_regs,
9929 .get_wol = bnx2x_get_wol, 10010 .get_wol = bnx2x_get_wol,
9930 .set_wol = bnx2x_set_wol, 10011 .set_wol = bnx2x_set_wol,
9931 .get_msglevel = bnx2x_get_msglevel, 10012 .get_msglevel = bnx2x_get_msglevel,