bnxt_en: Add extended port statistics support

Gather periodic extended port statistics, if the device is PF and
link is up.

Signed-off-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Vasundhara Volam 2018-03-31 13:54:12 -04:00 committed by David S. Miller
parent 699efed00d
commit 00db3cba35
3 changed files with 81 additions and 2 deletions

View File

@ -3059,12 +3059,21 @@ static void bnxt_free_stats(struct bnxt *bp)
u32 size, i;
struct pci_dev *pdev = bp->pdev;
bp->flags &= ~BNXT_FLAG_PORT_STATS;
bp->flags &= ~BNXT_FLAG_PORT_STATS_EXT;
if (bp->hw_rx_port_stats) {
dma_free_coherent(&pdev->dev, bp->hw_port_stats_size,
bp->hw_rx_port_stats,
bp->hw_rx_port_stats_map);
bp->hw_rx_port_stats = NULL;
bp->flags &= ~BNXT_FLAG_PORT_STATS;
}
if (bp->hw_rx_port_stats_ext) {
dma_free_coherent(&pdev->dev, sizeof(struct rx_port_stats_ext),
bp->hw_rx_port_stats_ext,
bp->hw_rx_port_stats_ext_map);
bp->hw_rx_port_stats_ext = NULL;
}
if (!bp->bnapi)
@ -3120,6 +3129,21 @@ static int bnxt_alloc_stats(struct bnxt *bp)
bp->hw_tx_port_stats_map = bp->hw_rx_port_stats_map +
sizeof(struct rx_port_stats) + 512;
bp->flags |= BNXT_FLAG_PORT_STATS;
/* Display extended statistics only if FW supports it */
if (bp->hwrm_spec_code < 0x10804 ||
bp->hwrm_spec_code == 0x10900)
return 0;
bp->hw_rx_port_stats_ext =
dma_zalloc_coherent(&pdev->dev,
sizeof(struct rx_port_stats_ext),
&bp->hw_rx_port_stats_ext_map,
GFP_KERNEL);
if (!bp->hw_rx_port_stats_ext)
return 0;
bp->flags |= BNXT_FLAG_PORT_STATS_EXT;
}
return 0;
}
@ -5340,6 +5364,21 @@ static int bnxt_hwrm_port_qstats(struct bnxt *bp)
return rc;
}
static int bnxt_hwrm_port_qstats_ext(struct bnxt *bp)
{
struct hwrm_port_qstats_ext_input req = {0};
struct bnxt_pf_info *pf = &bp->pf;
if (!(bp->flags & BNXT_FLAG_PORT_STATS_EXT))
return 0;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_QSTATS_EXT, -1, -1);
req.port_id = cpu_to_le16(pf->port_id);
req.rx_stat_size = cpu_to_le16(sizeof(struct rx_port_stats_ext));
req.rx_stat_host_addr = cpu_to_le64(bp->hw_rx_port_stats_ext_map);
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
}
static void bnxt_hwrm_free_tunnel_ports(struct bnxt *bp)
{
if (bp->vxlan_port_cnt) {
@ -7491,8 +7530,10 @@ static void bnxt_sp_task(struct work_struct *work)
bnxt_hwrm_tunnel_dst_port_free(
bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE);
}
if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event))
if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) {
bnxt_hwrm_port_qstats(bp);
bnxt_hwrm_port_qstats_ext(bp);
}
if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) {
int rc;

View File

@ -1154,6 +1154,7 @@ struct bnxt {
#define BNXT_FLAG_DIM 0x2000000
#define BNXT_FLAG_ROCE_MIRROR_CAP 0x4000000
#define BNXT_FLAG_NEW_RM 0x8000000
#define BNXT_FLAG_PORT_STATS_EXT 0x10000000
#define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA | \
BNXT_FLAG_RFS | \
@ -1273,8 +1274,10 @@ struct bnxt {
struct rx_port_stats *hw_rx_port_stats;
struct tx_port_stats *hw_tx_port_stats;
struct rx_port_stats_ext *hw_rx_port_stats_ext;
dma_addr_t hw_rx_port_stats_map;
dma_addr_t hw_tx_port_stats_map;
dma_addr_t hw_rx_port_stats_ext_map;
int hw_port_stats_size;
u16 hwrm_max_req_len;
@ -1385,6 +1388,9 @@ struct bnxt {
((offsetof(struct tx_port_stats, counter) + \
sizeof(struct rx_port_stats) + 512) / 8)
#define BNXT_RX_STATS_EXT_OFFSET(counter) \
(offsetof(struct rx_port_stats_ext, counter) / 8)
#define I2C_DEV_ADDR_A0 0xa0
#define I2C_DEV_ADDR_A2 0xa2
#define SFP_EEPROM_SFF_8472_COMP_ADDR 0x5e

View File

@ -137,6 +137,9 @@ reset_coalesce:
#define BNXT_TX_STATS_ENTRY(counter) \
{ BNXT_TX_STATS_OFFSET(counter), __stringify(counter) }
#define BNXT_RX_STATS_EXT_ENTRY(counter) \
{ BNXT_RX_STATS_EXT_OFFSET(counter), __stringify(counter) }
static const struct {
long offset;
char string[ETH_GSTRING_LEN];
@ -223,7 +226,19 @@ static const struct {
BNXT_TX_STATS_ENTRY(tx_stat_error),
};
static const struct {
long offset;
char string[ETH_GSTRING_LEN];
} bnxt_port_stats_ext_arr[] = {
BNXT_RX_STATS_EXT_ENTRY(link_down_events),
BNXT_RX_STATS_EXT_ENTRY(continuous_pause_events),
BNXT_RX_STATS_EXT_ENTRY(resume_pause_events),
BNXT_RX_STATS_EXT_ENTRY(continuous_roce_pause_events),
BNXT_RX_STATS_EXT_ENTRY(resume_roce_pause_events),
};
#define BNXT_NUM_PORT_STATS ARRAY_SIZE(bnxt_port_stats_arr)
#define BNXT_NUM_PORT_STATS_EXT ARRAY_SIZE(bnxt_port_stats_ext_arr)
static int bnxt_get_num_stats(struct bnxt *bp)
{
@ -232,6 +247,9 @@ static int bnxt_get_num_stats(struct bnxt *bp)
if (bp->flags & BNXT_FLAG_PORT_STATS)
num_stats += BNXT_NUM_PORT_STATS;
if (bp->flags & BNXT_FLAG_PORT_STATS_EXT)
num_stats += BNXT_NUM_PORT_STATS_EXT;
return num_stats;
}
@ -279,6 +297,14 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
bnxt_port_stats_arr[i].offset));
}
}
if (bp->flags & BNXT_FLAG_PORT_STATS_EXT) {
__le64 *port_stats_ext = (__le64 *)bp->hw_rx_port_stats_ext;
for (i = 0; i < BNXT_NUM_PORT_STATS_EXT; i++, j++) {
buf[j] = le64_to_cpu(*(port_stats_ext +
bnxt_port_stats_ext_arr[i].offset));
}
}
}
static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
@ -339,6 +365,12 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
buf += ETH_GSTRING_LEN;
}
}
if (bp->flags & BNXT_FLAG_PORT_STATS_EXT) {
for (i = 0; i < BNXT_NUM_PORT_STATS_EXT; i++) {
strcpy(buf, bnxt_port_stats_ext_arr[i].string);
buf += ETH_GSTRING_LEN;
}
}
break;
case ETH_SS_TEST:
if (bp->num_tests)