Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 00db3cba authored by Vasundhara Volam's avatar Vasundhara Volam Committed by David S. Miller
Browse files

bnxt_en: Add extended port statistics support



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

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 699efed0
Loading
Loading
Loading
Loading
+43 −2
Original line number Original line Diff line number Diff line
@@ -3059,12 +3059,21 @@ static void bnxt_free_stats(struct bnxt *bp)
	u32 size, i;
	u32 size, i;
	struct pci_dev *pdev = bp->pdev;
	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) {
	if (bp->hw_rx_port_stats) {
		dma_free_coherent(&pdev->dev, bp->hw_port_stats_size,
		dma_free_coherent(&pdev->dev, bp->hw_port_stats_size,
				  bp->hw_rx_port_stats,
				  bp->hw_rx_port_stats,
				  bp->hw_rx_port_stats_map);
				  bp->hw_rx_port_stats_map);
		bp->hw_rx_port_stats = NULL;
		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)
	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 +
		bp->hw_tx_port_stats_map = bp->hw_rx_port_stats_map +
					   sizeof(struct rx_port_stats) + 512;
					   sizeof(struct rx_port_stats) + 512;
		bp->flags |= BNXT_FLAG_PORT_STATS;
		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;
	return 0;
}
}
@@ -5340,6 +5364,21 @@ static int bnxt_hwrm_port_qstats(struct bnxt *bp)
	return rc;
	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)
static void bnxt_hwrm_free_tunnel_ports(struct bnxt *bp)
{
{
	if (bp->vxlan_port_cnt) {
	if (bp->vxlan_port_cnt) {
@@ -7491,8 +7530,10 @@ static void bnxt_sp_task(struct work_struct *work)
		bnxt_hwrm_tunnel_dst_port_free(
		bnxt_hwrm_tunnel_dst_port_free(
			bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE);
			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(bp);
		bnxt_hwrm_port_qstats_ext(bp);
	}


	if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) {
	if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) {
		int rc;
		int rc;
+6 −0
Original line number Original line Diff line number Diff line
@@ -1154,6 +1154,7 @@ struct bnxt {
	#define BNXT_FLAG_DIM		0x2000000
	#define BNXT_FLAG_DIM		0x2000000
	#define BNXT_FLAG_ROCE_MIRROR_CAP	0x4000000
	#define BNXT_FLAG_ROCE_MIRROR_CAP	0x4000000
	#define BNXT_FLAG_NEW_RM	0x8000000
	#define BNXT_FLAG_NEW_RM	0x8000000
	#define BNXT_FLAG_PORT_STATS_EXT	0x10000000


	#define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA |		\
	#define BNXT_FLAG_ALL_CONFIG_FEATS (BNXT_FLAG_TPA |		\
					    BNXT_FLAG_RFS |		\
					    BNXT_FLAG_RFS |		\
@@ -1273,8 +1274,10 @@ struct bnxt {


	struct rx_port_stats	*hw_rx_port_stats;
	struct rx_port_stats	*hw_rx_port_stats;
	struct tx_port_stats	*hw_tx_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_rx_port_stats_map;
	dma_addr_t		hw_tx_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;
	int			hw_port_stats_size;


	u16			hwrm_max_req_len;
	u16			hwrm_max_req_len;
@@ -1385,6 +1388,9 @@ struct bnxt {
	((offsetof(struct tx_port_stats, counter) +	\
	((offsetof(struct tx_port_stats, counter) +	\
	  sizeof(struct rx_port_stats) + 512) / 8)
	  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_A0				0xa0
#define I2C_DEV_ADDR_A2				0xa2
#define I2C_DEV_ADDR_A2				0xa2
#define SFP_EEPROM_SFF_8472_COMP_ADDR		0x5e
#define SFP_EEPROM_SFF_8472_COMP_ADDR		0x5e
+32 −0
Original line number Original line Diff line number Diff line
@@ -137,6 +137,9 @@ static int bnxt_set_coalesce(struct net_device *dev,
#define BNXT_TX_STATS_ENTRY(counter)	\
#define BNXT_TX_STATS_ENTRY(counter)	\
	{ BNXT_TX_STATS_OFFSET(counter), __stringify(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 {
static const struct {
	long offset;
	long offset;
	char string[ETH_GSTRING_LEN];
	char string[ETH_GSTRING_LEN];
@@ -223,7 +226,19 @@ static const struct {
	BNXT_TX_STATS_ENTRY(tx_stat_error),
	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 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)
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)
	if (bp->flags & BNXT_FLAG_PORT_STATS)
		num_stats += BNXT_NUM_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;
	return num_stats;
}
}


@@ -279,6 +297,14 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
					       bnxt_port_stats_arr[i].offset));
					       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)
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;
				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;
		break;
	case ETH_SS_TEST:
	case ETH_SS_TEST:
		if (bp->num_tests)
		if (bp->num_tests)