git: fba2468e1633 - stable/14 - bnxt_en: Added support for priority queues extended stats

From: Warner Losh <imp_at_FreeBSD.org>
Date: Mon, 03 Jun 2024 19:25:03 UTC
The branch stable/14 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=fba2468e163370224c4c1ee28328a39cde28986f

commit fba2468e163370224c4c1ee28328a39cde28986f
Author:     Chandrakanth patil <chandrakanth.patil@broadcom.com>
AuthorDate: 2024-04-27 16:26:35 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-06-03 19:23:14 +0000

    bnxt_en: Added support for priority queues extended stats
    
    Below priority queues extended stats are exposed to sysctl:
    
    tx_bytes_pri{0-7}
    rx_bytes_pri{0-7}
    tx_packets_pri{0-7}
    rx_packets_pri{0-7}
    
    Reviewed by:            imp
    Approved by:            imp
    Differential revision:  https://reviews.freebsd.org/D45007
    
    (cherry picked from commit 032899b59c25389e60a0a092a0dad347102a6edc)
---
 sys/dev/bnxt/bnxt_en/bnxt.h        |  23 ++++++
 sys/dev/bnxt/bnxt_en/bnxt_hwrm.c   | 161 +++++++++++++++++++++++++++++++++++--
 sys/dev/bnxt/bnxt_en/bnxt_hwrm.h   |   2 +-
 sys/dev/bnxt/bnxt_en/bnxt_sysctl.c |  98 ++++++++++++++++++++++
 4 files changed, 277 insertions(+), 7 deletions(-)

diff --git a/sys/dev/bnxt/bnxt_en/bnxt.h b/sys/dev/bnxt/bnxt_en/bnxt.h
index ab60ddf74672..d6fe2ce8ddb1 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt.h
+++ b/sys/dev/bnxt/bnxt_en/bnxt.h
@@ -267,6 +267,15 @@
 
 #define BNXT_MIN_FRAME_SIZE	52	/* Frames must be padded to this size for some A0 chips */
 
+#define BNXT_RX_STATS_EXT_OFFSET(counter)		\
+	(offsetof(struct rx_port_stats_ext, counter) / 8)
+
+#define BNXT_RX_STATS_EXT_NUM_LEGACY			\
+	BNXT_RX_STATS_EXT_OFFSET(rx_fec_corrected_blocks)
+
+#define BNXT_TX_STATS_EXT_OFFSET(counter)		\
+	(offsetof(struct tx_port_stats_ext, counter) / 8)
+
 extern const char bnxt_driver_version[];
 typedef void (*bnxt_doorbell_tx)(void *, uint16_t idx);
 typedef void (*bnxt_doorbell_rx)(void *, uint16_t idx);
@@ -910,6 +919,20 @@ struct bnxt_softc {
 	struct tx_port_stats_ext *tx_port_stats_ext;
 	struct rx_port_stats_ext *rx_port_stats_ext;
 
+	uint16_t		fw_rx_stats_ext_size;
+	uint16_t		fw_tx_stats_ext_size;
+	uint16_t		hw_ring_stats_size;
+
+	uint8_t			tx_pri2cos_idx[8];
+	uint8_t			rx_pri2cos_idx[8];
+	bool			pri2cos_valid;
+
+	uint64_t		tx_bytes_pri[8];
+	uint64_t		tx_packets_pri[8];
+	uint64_t		rx_bytes_pri[8];
+	uint64_t		rx_packets_pri[8];
+
+	uint8_t			port_count;
 	int			num_cp_rings;
 
 	struct bnxt_cp_ring	*nq_rings;
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
index 07834aeca363..677869484ace 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
+++ b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
@@ -47,6 +47,38 @@ static void	bnxt_hwrm_set_eee(struct bnxt_softc *softc,
 /* NVRam stuff has a five minute timeout */
 #define BNXT_NVM_TIMEO	(5 * 60 * 1000)
 
+#define BNXT_RX_STATS_PRI_ENTRY(counter, n)		\
+	BNXT_RX_STATS_EXT_OFFSET(counter##_cos0)
+
+#define BNXT_TX_STATS_PRI_ENTRY(counter, n)		\
+	 BNXT_TX_STATS_EXT_OFFSET(counter##_cos0)
+
+#define BNXT_RX_STATS_PRI_ENTRIES(counter)		\
+	BNXT_RX_STATS_PRI_ENTRY(counter, 0),		\
+	BNXT_RX_STATS_PRI_ENTRY(counter, 1),		\
+	BNXT_RX_STATS_PRI_ENTRY(counter, 2),		\
+	BNXT_RX_STATS_PRI_ENTRY(counter, 3),		\
+	BNXT_RX_STATS_PRI_ENTRY(counter, 4),		\
+	BNXT_RX_STATS_PRI_ENTRY(counter, 5),		\
+	BNXT_RX_STATS_PRI_ENTRY(counter, 6),		\
+	BNXT_RX_STATS_PRI_ENTRY(counter, 7)
+
+#define BNXT_TX_STATS_PRI_ENTRIES(counter)		\
+	BNXT_TX_STATS_PRI_ENTRY(counter, 0),		\
+	BNXT_TX_STATS_PRI_ENTRY(counter, 1),		\
+	BNXT_TX_STATS_PRI_ENTRY(counter, 2),		\
+	BNXT_TX_STATS_PRI_ENTRY(counter, 3),		\
+	BNXT_TX_STATS_PRI_ENTRY(counter, 4),		\
+	BNXT_TX_STATS_PRI_ENTRY(counter, 5),		\
+	BNXT_TX_STATS_PRI_ENTRY(counter, 6),		\
+	BNXT_TX_STATS_PRI_ENTRY(counter, 7)
+
+
+long bnxt_rx_bytes_pri_arr_base_off[] = {BNXT_RX_STATS_PRI_ENTRIES(rx_bytes)};
+long bnxt_rx_pkts_pri_arr_base_off[] = {BNXT_RX_STATS_PRI_ENTRIES(rx_packets)};
+long bnxt_tx_bytes_pri_arr_base_off[] = {BNXT_TX_STATS_PRI_ENTRIES(tx_bytes)};
+long bnxt_tx_pkts_pri_arr_base_off[] = {BNXT_TX_STATS_PRI_ENTRIES(tx_packets)};
+
 static int
 bnxt_hwrm_err_map(uint16_t err)
 {
@@ -1734,25 +1766,142 @@ bnxt_hwrm_port_qstats(struct bnxt_softc *softc)
 
 	return rc;
 }
+static int bnxt_hwrm_pri2cos_idx(struct bnxt_softc *softc, uint32_t path_dir)
+{
+	struct hwrm_queue_pri2cos_qcfg_input req = {0};
+	struct hwrm_queue_pri2cos_qcfg_output *resp;
+	uint8_t *pri2cos_idx, *q_ids, max_q;
+	int rc, i, j;
+	uint8_t *pri2cos;
 
-void
+	bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_QUEUE_PRI2COS_QCFG);
+	resp = (void *)softc->hwrm_cmd_resp.idi_vaddr;
+
+	req.flags = htole32(HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_IVLAN |
+			    path_dir);
+	rc = hwrm_send_message(softc, &req, sizeof(req));
+
+	if (rc)
+		return rc;
+
+	if (path_dir == HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_TX) {
+		pri2cos_idx = softc->tx_pri2cos_idx;
+		q_ids = softc->tx_q_ids;
+		max_q = softc->tx_max_q;
+	} else {
+		pri2cos_idx = softc->rx_pri2cos_idx;
+		q_ids = softc->rx_q_ids;
+		max_q = softc->rx_max_q;
+	}
+
+	pri2cos = &resp->pri0_cos_queue_id;
+
+	for (i = 0; i < BNXT_MAX_QUEUE; i++) {
+		uint8_t queue_id = pri2cos[i];
+		uint8_t queue_idx;
+
+		/* Per port queue IDs start from 0, 10, 20, etc */
+		queue_idx = queue_id % 10;
+		if (queue_idx > BNXT_MAX_QUEUE) {
+			softc->pri2cos_valid = false;
+			rc = -EINVAL;
+			return rc;
+		}
+
+		for (j = 0; j < max_q; j++) {
+			if (q_ids[j] == queue_id)
+				pri2cos_idx[i] = queue_idx;
+		}
+	}
+
+	softc->pri2cos_valid = true;
+
+	return rc;
+}
+
+int
 bnxt_hwrm_port_qstats_ext(struct bnxt_softc *softc)
 {
 	struct hwrm_port_qstats_ext_input req = {0};
+	struct hwrm_port_qstats_ext_output *resp;
+	int rc = 0, i;
+	uint32_t tx_stat_size;
 
 	bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_QSTATS_EXT);
+	resp = (void *)softc->hwrm_cmd_resp.idi_vaddr;
 
+	tx_stat_size = sizeof(struct tx_port_stats_ext);
 	req.port_id = htole16(softc->pf.port_id);
-	req.tx_stat_size = htole16(sizeof(struct tx_port_stats_ext));
+	req.tx_stat_size = htole16(tx_stat_size);
 	req.rx_stat_size = htole16(sizeof(struct rx_port_stats_ext));
 	req.rx_stat_host_addr = htole64(softc->hw_rx_port_stats_ext.idi_paddr);
 	req.tx_stat_host_addr = htole64(softc->hw_tx_port_stats_ext.idi_paddr);
 
-	BNXT_HWRM_LOCK(softc);
-	_hwrm_send_message(softc, &req, sizeof(req));
-	BNXT_HWRM_UNLOCK(softc);
+	rc = hwrm_send_message(softc, &req, sizeof(req));
 
-	return;
+	if (!rc) {
+		softc->fw_rx_stats_ext_size =
+			le16toh(resp->rx_stat_size) / 8;
+		if (BNXT_FW_MAJ(softc) < 220 &&
+		    softc->fw_rx_stats_ext_size > BNXT_RX_STATS_EXT_NUM_LEGACY)
+			softc->fw_rx_stats_ext_size = BNXT_RX_STATS_EXT_NUM_LEGACY;
+
+		softc->fw_tx_stats_ext_size = tx_stat_size ?
+			le16toh(resp->tx_stat_size) / 8 : 0;
+	} else {
+		softc->fw_rx_stats_ext_size = 0;
+		softc->fw_tx_stats_ext_size = 0;
+	}
+
+	if (softc->fw_tx_stats_ext_size <=
+	    offsetof(struct tx_port_stats_ext, pfc_pri0_tx_duration_us) / 8) {
+		softc->pri2cos_valid = false;
+		return rc;
+	}
+
+	rc = bnxt_hwrm_pri2cos_idx(softc, HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_TX);
+	if (rc)
+		return rc;
+
+	if (softc->is_asym_q) {
+		rc = bnxt_hwrm_pri2cos_idx(softc, HWRM_QUEUE_PRI2COS_QCFG_INPUT_FLAGS_PATH_RX);
+		if (rc)
+			return rc;
+	} else {
+		memcpy(softc->rx_pri2cos_idx, softc->tx_pri2cos_idx, sizeof(softc->rx_pri2cos_idx));
+	}
+
+	u64 *rx_port_stats_ext = (u64 *)softc->hw_rx_port_stats_ext.idi_vaddr;
+	u64 *tx_port_stats_ext = (u64 *)softc->hw_tx_port_stats_ext.idi_vaddr;
+
+	if (softc->pri2cos_valid) {
+		for (i = 0; i < 8; i++) {
+			long n = bnxt_rx_bytes_pri_arr_base_off[i] +
+				 softc->rx_pri2cos_idx[i];
+
+			softc->rx_bytes_pri[i] = *(rx_port_stats_ext + n);
+		}
+		for (i = 0; i < 8; i++) {
+			long n = bnxt_rx_pkts_pri_arr_base_off[i] +
+				 softc->rx_pri2cos_idx[i];
+
+			softc->rx_packets_pri[i] = *(rx_port_stats_ext + n);
+		}
+		for (i = 0; i < 8; i++) {
+			long n = bnxt_tx_bytes_pri_arr_base_off[i] +
+				 softc->tx_pri2cos_idx[i];
+
+			softc->tx_bytes_pri[i] = *(tx_port_stats_ext + n);
+		}
+		for (i = 0; i < 8; i++) {
+			long n = bnxt_tx_pkts_pri_arr_base_off[i] +
+				 softc->tx_pri2cos_idx[i];
+
+			softc->tx_packets_pri[i] = *(tx_port_stats_ext + n);
+		}
+	}
+
+	return rc;
 }
 
 int
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.h b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.h
index 35a974fe3438..766556f9904c 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt_hwrm.h
+++ b/sys/dev/bnxt/bnxt_en/bnxt_hwrm.h
@@ -66,7 +66,7 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt_softc *softc, struct bnxt_cp_ring *cpr,
     uint64_t paddr);
 int bnxt_hwrm_stat_ctx_free(struct bnxt_softc *softc, struct bnxt_cp_ring *cpr);
 int bnxt_hwrm_port_qstats(struct bnxt_softc *softc);
-void bnxt_hwrm_port_qstats_ext(struct bnxt_softc *softc);
+int bnxt_hwrm_port_qstats_ext(struct bnxt_softc *softc);
 int bnxt_hwrm_ring_grp_alloc(struct bnxt_softc *softc,
     struct bnxt_grp_info *grp);
 int bnxt_hwrm_ring_grp_free(struct bnxt_softc *softc, struct bnxt_grp_info *gr);
diff --git a/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c b/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c
index 9ee555dac72f..b850a4d47f9c 100644
--- a/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c
+++ b/sys/dev/bnxt/bnxt_en/bnxt_sysctl.c
@@ -599,6 +599,55 @@ bnxt_create_port_stats_sysctls(struct bnxt_softc *softc)
 		    "tx_packets_cos7", CTLFLAG_RD,
 		    &softc->tx_port_stats_ext->tx_packets_cos7, "Transmitted packets count cos7");
 
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_bytes_pri0", CTLFLAG_RD,
+		    &softc->tx_bytes_pri[0], "Transmitted bytes count pri0");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_packets_pri0", CTLFLAG_RD,
+		    &softc->tx_packets_pri[0], "Transmitted packets count pri0");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_bytes_pri1", CTLFLAG_RD,
+		    &softc->tx_bytes_pri[1], "Transmitted bytes count pri1");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_packets_pri1", CTLFLAG_RD,
+		    &softc->tx_packets_pri[1], "Transmitted packets count pri1");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_bytes_pri2", CTLFLAG_RD,
+		    &softc->tx_bytes_pri[2], "Transmitted bytes count pri2");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_packets_pri2", CTLFLAG_RD,
+		    &softc->tx_packets_pri[2], "Transmitted packets count pri2");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_bytes_pri3", CTLFLAG_RD,
+		    &softc->tx_bytes_pri[3], "Transmitted bytes count pri3");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_packets_pri3", CTLFLAG_RD,
+		    &softc->tx_packets_pri[3], "Transmitted packets count pri3");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_bytes_pri4", CTLFLAG_RD,
+		    &softc->tx_bytes_pri[4], "Transmitted bytes count pri4");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_packets_pri4", CTLFLAG_RD,
+		    &softc->tx_packets_pri[4], "Transmitted packets count pri4");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_bytes_pri5", CTLFLAG_RD,
+		    &softc->tx_bytes_pri[5], "Transmitted bytes count pri5");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_packets_pri5", CTLFLAG_RD,
+		    &softc->tx_packets_pri[5], "Transmitted packets count pri5");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_bytes_pri6", CTLFLAG_RD,
+		    &softc->tx_bytes_pri[6], "Transmitted bytes count pri6");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_packets_pri6", CTLFLAG_RD,
+		    &softc->tx_packets_pri[6], "Transmitted packets count pri6");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_bytes_pri7", CTLFLAG_RD,
+		    &softc->tx_bytes_pri[7], "Transmitted bytes count pri7");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "tx_packets_pri7", CTLFLAG_RD,
+		    &softc->tx_packets_pri[7], "Transmitted packets count pri7");
+
 		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
 		    "pfc_pri0_tx_duration_us", CTLFLAG_RD,
 		    &softc->tx_port_stats_ext->pfc_pri0_tx_duration_us, "Time duration between"
@@ -732,6 +781,55 @@ bnxt_create_port_stats_sysctls(struct bnxt_softc *softc)
 		    "rx_packets_cos7", CTLFLAG_RD,
 		    &softc->rx_port_stats_ext->rx_packets_cos7, "Received packets count cos7");
 
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_bytes_pri0", CTLFLAG_RD,
+		    &softc->rx_bytes_pri[0], "Received bytes count pri0");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_packets_pri0", CTLFLAG_RD,
+		    &softc->rx_packets_pri[0], "Received packets count pri0");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_bytes_pri1", CTLFLAG_RD,
+		    &softc->rx_bytes_pri[1], "Received bytes count pri1");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_packets_pri1", CTLFLAG_RD,
+		    &softc->rx_packets_pri[1], "Received packets count pri1");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_bytes_pri2", CTLFLAG_RD,
+		    &softc->rx_bytes_pri[2], "Received bytes count pri2");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_packets_pri2", CTLFLAG_RD,
+		    &softc->rx_packets_pri[2], "Received packets count pri2");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_bytes_pri3", CTLFLAG_RD,
+		    &softc->rx_bytes_pri[3], "Received bytes count pri3");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_packets_pri3", CTLFLAG_RD,
+		    &softc->rx_packets_pri[3], "Received packets count pri3");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_bytes_pri4", CTLFLAG_RD,
+		    &softc->rx_bytes_pri[4], "Received bytes count pri4");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_packets_pri4", CTLFLAG_RD,
+		    &softc->rx_packets_pri[4], "Received packets count pri4");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_bytes_pri5", CTLFLAG_RD,
+		    &softc->rx_bytes_pri[5], "Received bytes count pri5");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_packets_pri5", CTLFLAG_RD,
+		    &softc->rx_packets_pri[5], "Received packets count pri5");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_bytes_pri6", CTLFLAG_RD,
+		    &softc->rx_bytes_pri[6], "Received bytes count pri6");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_packets_pri6", CTLFLAG_RD,
+		    &softc->rx_packets_pri[6], "Received packets count pri6");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_bytes_pri7", CTLFLAG_RD,
+		    &softc->rx_bytes_pri[7], "Received bytes count pri7");
+		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
+		    "rx_packets_pri7", CTLFLAG_RD,
+		    &softc->rx_packets_pri[7], "Received packets count pri7");
+
 		SYSCTL_ADD_QUAD(&softc->hw_stats, SYSCTL_CHILDREN(oid), OID_AUTO,
 		    "pfc_pri0_rx_duration_us", CTLFLAG_RD,
 		    &softc->rx_port_stats_ext->pfc_pri0_rx_duration_us, "Time duration in receiving"