Commit b5d600b0 authored by Vasundhara Volam's avatar Vasundhara Volam Committed by David S. Miller

bnxt_en: Add support for 'ethtool -d'

Add support to dump PXP registers and PCIe statistics.
Signed-off-by: default avatarVasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a0c30621
......@@ -10228,6 +10228,38 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features)
return rc;
}
int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words,
u32 *reg_buf)
{
struct hwrm_dbg_read_direct_output *resp = bp->hwrm_cmd_resp_addr;
struct hwrm_dbg_read_direct_input req = {0};
__le32 *dbg_reg_buf;
dma_addr_t mapping;
int rc, i;
dbg_reg_buf = dma_alloc_coherent(&bp->pdev->dev, num_words * 4,
&mapping, GFP_KERNEL);
if (!dbg_reg_buf)
return -ENOMEM;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_DBG_READ_DIRECT, -1, -1);
req.host_dest_addr = cpu_to_le64(mapping);
req.read_addr = cpu_to_le32(reg_off + CHIMP_REG_VIEW_ADDR);
req.read_len32 = cpu_to_le32(num_words);
mutex_lock(&bp->hwrm_cmd_lock);
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc || resp->error_code) {
rc = -EIO;
goto dbg_rd_reg_exit;
}
for (i = 0; i < num_words; i++)
reg_buf[i] = le32_to_cpu(dbg_reg_buf[i]);
dbg_rd_reg_exit:
mutex_unlock(&bp->hwrm_cmd_lock);
dma_free_coherent(&bp->pdev->dev, num_words * 4, dbg_reg_buf, mapping);
return rc;
}
static int bnxt_dbg_hwrm_ring_info_get(struct bnxt *bp, u8 ring_type,
u32 ring_id, u32 *prod, u32 *cons)
{
......
......@@ -1304,6 +1304,9 @@ struct bnxt_test_info {
char string[BNXT_MAX_TEST][ETH_GSTRING_LEN];
};
#define CHIMP_REG_VIEW_ADDR \
((bp->flags & BNXT_FLAG_CHIP_P5) ? 0x80000000 : 0xb1000000)
#define BNXT_GRCPF_REG_CHIMP_COMM 0x0
#define BNXT_GRCPF_REG_CHIMP_COMM_TRIGGER 0x100
#define BNXT_GRCPF_REG_WINDOW_BASE_OUT 0x400
......@@ -2117,6 +2120,8 @@ int bnxt_open_nic(struct bnxt *, bool, bool);
int bnxt_half_open_nic(struct bnxt *bp);
void bnxt_half_close_nic(struct bnxt *bp);
int bnxt_close_nic(struct bnxt *, bool, bool);
int bnxt_dbg_hwrm_rd_reg(struct bnxt *bp, u32 reg_off, u16 num_words,
u32 *reg_buf);
void bnxt_fw_exception(struct bnxt *bp);
void bnxt_fw_reset(struct bnxt *bp);
int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
......
......@@ -1324,6 +1324,59 @@ static void bnxt_get_drvinfo(struct net_device *dev,
info->regdump_len = 0;
}
static int bnxt_get_regs_len(struct net_device *dev)
{
struct bnxt *bp = netdev_priv(dev);
int reg_len;
reg_len = BNXT_PXP_REG_LEN;
if (bp->fw_cap & BNXT_FW_CAP_PCIE_STATS_SUPPORTED)
reg_len += sizeof(struct pcie_ctx_hw_stats);
return reg_len;
}
static void bnxt_get_regs(struct net_device *dev, struct ethtool_regs *regs,
void *_p)
{
struct pcie_ctx_hw_stats *hw_pcie_stats;
struct hwrm_pcie_qstats_input req = {0};
struct bnxt *bp = netdev_priv(dev);
dma_addr_t hw_pcie_stats_addr;
int rc;
regs->version = 0;
bnxt_dbg_hwrm_rd_reg(bp, 0, BNXT_PXP_REG_LEN / 4, _p);
if (!(bp->fw_cap & BNXT_FW_CAP_PCIE_STATS_SUPPORTED))
return;
hw_pcie_stats = dma_alloc_coherent(&bp->pdev->dev,
sizeof(*hw_pcie_stats),
&hw_pcie_stats_addr, GFP_KERNEL);
if (!hw_pcie_stats)
return;
regs->version = 1;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PCIE_QSTATS, -1, -1);
req.pcie_stat_size = cpu_to_le16(sizeof(*hw_pcie_stats));
req.pcie_stat_host_addr = cpu_to_le64(hw_pcie_stats_addr);
mutex_lock(&bp->hwrm_cmd_lock);
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (!rc) {
__le64 *src = (__le64 *)hw_pcie_stats;
u64 *dst = (u64 *)(_p + BNXT_PXP_REG_LEN);
int i;
for (i = 0; i < sizeof(*hw_pcie_stats) / sizeof(__le64); i++)
dst[i] = le64_to_cpu(src[i]);
}
mutex_unlock(&bp->hwrm_cmd_lock);
dma_free_coherent(&bp->pdev->dev, sizeof(*hw_pcie_stats), hw_pcie_stats,
hw_pcie_stats_addr);
}
static void bnxt_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct bnxt *bp = netdev_priv(dev);
......@@ -3599,6 +3652,8 @@ const struct ethtool_ops bnxt_ethtool_ops = {
.get_pauseparam = bnxt_get_pauseparam,
.set_pauseparam = bnxt_set_pauseparam,
.get_drvinfo = bnxt_get_drvinfo,
.get_regs_len = bnxt_get_regs_len,
.get_regs = bnxt_get_regs,
.get_wol = bnxt_get_wol,
.set_wol = bnxt_set_wol,
.get_coalesce = bnxt_get_coalesce,
......
......@@ -84,6 +84,8 @@ struct hwrm_dbg_cmn_output {
ETH_RESET_PHY | ETH_RESET_RAM) \
<< ETH_RESET_SHARED_SHIFT)
#define BNXT_PXP_REG_LEN 0x3110
extern const struct ethtool_ops bnxt_ethtool_ops;
u32 bnxt_get_rxfh_indir_size(struct net_device *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment