DPDK patches and discussions
 help / color / mirror / Atom feed
From: Andrew Rybchenko <arybchenko@solarflare.com>
To: <dev@dpdk.org>
Cc: Martin Harvey <mharvey@solarflare.com>
Subject: [dpdk-dev] [PATCH 17/37] net/sfc/base: add API to retrieve sensor limits
Date: Mon, 10 Sep 2018 10:33:16 +0100	[thread overview]
Message-ID: <1536572016-18134-18-git-send-email-arybchenko@solarflare.com> (raw)
In-Reply-To: <1536572016-18134-1-git-send-email-arybchenko@solarflare.com>

From: Martin Harvey <mharvey@solarflare.com>

Signed-off-by: Martin Harvey <mharvey@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/efx.h      |  12 +++
 drivers/net/sfc/base/efx_impl.h |   2 +
 drivers/net/sfc/base/efx_mon.c  |  17 +++-
 drivers/net/sfc/base/mcdi_mon.c | 171 ++++++++++++++++++++++++++++++++
 drivers/net/sfc/base/mcdi_mon.h |   5 +
 5 files changed, 206 insertions(+), 1 deletion(-)

diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index dae90bd6e..099f9df67 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -774,6 +774,13 @@ typedef struct efx_mon_stat_value_s {
 	efx_mon_stat_unit_t	emsv_unit;
 } efx_mon_stat_value_t;
 
+typedef struct efx_mon_limit_value_s {
+	uint16_t			emlv_warning_min;
+	uint16_t			emlv_warning_max;
+	uint16_t			emlv_fatal_min;
+	uint16_t			emlv_fatal_max;
+} efx_mon_stat_limits_t;
+
 typedef enum efx_mon_stat_portmask_e {
 	EFX_MON_STAT_PORTMAP_NONE = 0,
 	EFX_MON_STAT_PORTMAP_PORT0 = 1,
@@ -819,6 +826,11 @@ efx_mon_stats_update(
 	__in				efsys_mem_t *esmp,
 	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_value_t *values);
 
+extern	__checkReturn			efx_rc_t
+efx_mon_limits_update(
+	__in				efx_nic_t *enp,
+	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_limits_t *values);
+
 #endif	/* EFSYS_OPT_MON_STATS */
 
 extern		void
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index 637e31e0c..0764df5de 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -317,6 +317,8 @@ typedef struct efx_mon_ops_s {
 #if EFSYS_OPT_MON_STATS
 	efx_rc_t	(*emo_stats_update)(efx_nic_t *, efsys_mem_t *,
 					    efx_mon_stat_value_t *);
+	efx_rc_t	(*emo_limits_update)(efx_nic_t *,
+					     efx_mon_stat_limits_t *);
 #endif	/* EFSYS_OPT_MON_STATS */
 } efx_mon_ops_t;
 
diff --git a/drivers/net/sfc/base/efx_mon.c b/drivers/net/sfc/base/efx_mon.c
index 91fa16ca0..f28775d04 100644
--- a/drivers/net/sfc/base/efx_mon.c
+++ b/drivers/net/sfc/base/efx_mon.c
@@ -38,7 +38,8 @@ efx_mon_name(
 #if EFSYS_OPT_MON_MCDI
 static const efx_mon_ops_t	__efx_mon_mcdi_ops = {
 #if EFSYS_OPT_MON_STATS
-	mcdi_mon_stats_update		/* emo_stats_update */
+	mcdi_mon_stats_update,		/* emo_stats_update */
+	mcdi_mon_limits_update,		/* emo_limits_update */
 #endif	/* EFSYS_OPT_MON_STATS */
 };
 #endif
@@ -815,6 +816,20 @@ efx_mon_stats_update(
 	return (emop->emo_stats_update(enp, esmp, values));
 }
 
+	__checkReturn			efx_rc_t
+efx_mon_limits_update(
+	__in				efx_nic_t *enp,
+	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_limits_t *values)
+{
+	efx_mon_t *emp = &(enp->en_mon);
+	const efx_mon_ops_t *emop = emp->em_emop;
+
+	EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+	EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_MON);
+
+	return (emop->emo_limits_update(enp, values));
+}
+
 #endif	/* EFSYS_OPT_MON_STATS */
 
 		void
diff --git a/drivers/net/sfc/base/mcdi_mon.c b/drivers/net/sfc/base/mcdi_mon.c
index 68bbc575d..0e860168a 100644
--- a/drivers/net/sfc/base/mcdi_mon.c
+++ b/drivers/net/sfc/base/mcdi_mon.c
@@ -334,6 +334,87 @@ efx_mcdi_sensor_info(
 	return (rc);
 }
 
+static	__checkReturn		efx_rc_t
+efx_mcdi_sensor_info_page(
+	__in			efx_nic_t *enp,
+	__in			uint32_t page,
+	__out			uint32_t *mask_part,
+	__out_ecount((sizeof (*mask_part) * 8) - 1)
+				efx_mon_stat_limits_t *limits)
+{
+	efx_mcdi_req_t req;
+	uint8_t payload[MAX(MC_CMD_SENSOR_INFO_EXT_IN_LEN,
+		MC_CMD_SENSOR_INFO_OUT_LENMAX)];
+	efx_rc_t rc;
+	uint32_t mask_copy;
+	efx_dword_t *maskp;
+	efx_qword_t *limit_info;
+
+	EFSYS_ASSERT(mask_part != NULL);
+	EFSYS_ASSERT(limits != NULL);
+
+	memset(limits, 0,
+	    ((sizeof (*mask_part) * 8) - 1) * sizeof (efx_mon_stat_limits_t));
+
+	(void) memset(payload, 0, sizeof (payload));
+	req.emr_cmd = MC_CMD_SENSOR_INFO;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_SENSOR_INFO_EXT_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_SENSOR_INFO_OUT_LENMAX;
+
+	MCDI_IN_SET_DWORD(req, SENSOR_INFO_EXT_IN_PAGE, page);
+
+	efx_mcdi_execute(enp, &req);
+
+	rc = req.emr_rc;
+
+	if (rc != 0)
+		goto fail1;
+
+	EFSYS_ASSERT(sizeof (*limit_info) ==
+	    MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_LEN);
+	maskp = MCDI_OUT2(req, efx_dword_t, SENSOR_INFO_OUT_MASK);
+	limit_info = (efx_qword_t *)(maskp + 1);
+
+	*mask_part = maskp->ed_u32[0];
+	mask_copy = *mask_part;
+
+	/* Copy an entry for all but the highest bit set. */
+	while (mask_copy) {
+
+		if (mask_copy == (1U << MC_CMD_SENSOR_PAGE0_NEXT)) {
+			/* Only next page bit set. */
+			mask_copy = 0;
+		} else {
+			/* Clear lowest bit */
+			mask_copy = mask_copy & ~(mask_copy ^ (mask_copy - 1));
+			/* And copy out limit entry into buffer */
+			limits->emlv_warning_min = EFX_QWORD_FIELD(*limit_info,
+			    MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1);
+
+			limits->emlv_warning_max = EFX_QWORD_FIELD(*limit_info,
+			    MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1);
+
+			limits->emlv_fatal_min = EFX_QWORD_FIELD(*limit_info,
+			    MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2);
+
+			limits->emlv_fatal_max = EFX_QWORD_FIELD(*limit_info,
+			    MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2);
+
+			limits++;
+			limit_info++;
+		}
+	}
+
+	return (rc);
+
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
 	__checkReturn			efx_rc_t
 mcdi_mon_stats_update(
 	__in				efx_nic_t *enp,
@@ -356,6 +437,96 @@ mcdi_mon_stats_update(
 
 	return (0);
 
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+static		void
+lowest_set_bit(
+	__in	uint32_t input_mask,
+	__out	uint32_t *lowest_bit_mask,
+	__out	uint32_t *lowest_bit_num
+)
+{
+	uint32_t x;
+	uint32_t set_bit, bit_index;
+
+	x = (input_mask ^ (input_mask - 1));
+	set_bit = (x + 1) >> 1;
+	if (!set_bit)
+		set_bit = (1U << 31U);
+
+	bit_index = 0;
+	if (set_bit & 0xFFFF0000)
+		bit_index += 16;
+	if (set_bit & 0xFF00FF00)
+		bit_index += 8;
+	if (set_bit & 0xF0F0F0F0)
+		bit_index += 4;
+	if (set_bit & 0xCCCCCCCC)
+		bit_index += 2;
+	if (set_bit & 0xAAAAAAAA)
+		bit_index += 1;
+
+	*lowest_bit_mask = set_bit;
+	*lowest_bit_num = bit_index;
+}
+
+	__checkReturn			efx_rc_t
+mcdi_mon_limits_update(
+	__in				efx_nic_t *enp,
+	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_limits_t *values)
+{
+	efx_rc_t rc;
+	uint32_t page;
+	uint32_t page_mask;
+	uint32_t limit_index;
+	efx_mon_stat_limits_t limits[sizeof (page_mask) * 8];
+	efx_mon_stat_t stat;
+
+	page = 0;
+	page--;
+	do {
+		page++;
+
+		rc = efx_mcdi_sensor_info_page(enp, page, &page_mask, limits);
+		if (rc != 0)
+			goto fail1;
+
+		limit_index = 0;
+		while (page_mask) {
+			uint32_t set_bit;
+			uint32_t page_index;
+			uint32_t mcdi_index;
+
+			if (page_mask == (1U << MC_CMD_SENSOR_PAGE0_NEXT))
+				break;
+
+			lowest_set_bit(page_mask, &set_bit, &page_index);
+			page_mask = page_mask & ~set_bit;
+
+			mcdi_index =
+			    page_index + (sizeof (page_mask) * 8 * page);
+
+			/*
+			 * This can fail if MCDI reports newer stats than the
+			 * drivers understand, or the bit is the next page bit.
+			 *
+			 * Driver needs to be tolerant of this.
+			 */
+			if (!efx_mon_mcdi_to_efx_stat(mcdi_index, &stat))
+				continue;
+
+			values[stat] = limits[limit_index];
+			limit_index++;
+		}
+
+	} while (page_mask & (1U << MC_CMD_SENSOR_PAGE0_NEXT));
+
+	return (rc);
+
 fail1:
 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
diff --git a/drivers/net/sfc/base/mcdi_mon.h b/drivers/net/sfc/base/mcdi_mon.h
index 5aa6a6a27..5eba09018 100644
--- a/drivers/net/sfc/base/mcdi_mon.h
+++ b/drivers/net/sfc/base/mcdi_mon.h
@@ -39,6 +39,11 @@ mcdi_mon_stats_update(
 	__in				efsys_mem_t *esmp,
 	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_value_t *values);
 
+extern	__checkReturn			efx_rc_t
+mcdi_mon_limits_update(
+	__in				efx_nic_t *enp,
+	__inout_ecount(EFX_MON_NSTATS)	efx_mon_stat_limits_t *values);
+
 #endif	/* EFSYS_OPT_MON_STATS */
 
 #endif /* EFSYS_OPT_MON_MCDI */
-- 
2.17.1

  parent reply	other threads:[~2018-09-10  9:33 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-10  9:32 [dpdk-dev] [PATCH 00/37] net/sfc: update base driver Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 01/37] net/sfc/base: fix PreFAST warnings because of unused return Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 02/37] net/sfc/base: fix invalid order of memset arguments Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 03/37] net/sfc/base: fix output buffer SAL annotation Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 04/37] net/sfc/base: highlight that image layout header generated Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 05/37] net/sfc/base: fix erroneous SAL annotation for input buffers Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 06/37] net/sfc/base: properly align on line continuation Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 07/37] net/sfc/base: add space after sizeof Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 08/37] net/sfc/base: fix build failure because of no declaration Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 09/37] net/sfc/base: add more definitions of partitions Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 10/37] net/sfc/base: fix outer IPID field in TSO option descriptors Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 11/37] net/sfc/base: move empty efsys definitions to EFX headers Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 12/37] net/sfc/base: add check for TUNNEL module in NIC reset API Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 13/37] net/sfc/base: refactor monitors support Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 14/37] net/sfc/base: remove probes when a Tx queue is too full Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 15/37] net/sfc/base: add generated description of sensors Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 16/37] net/sfc/base: check size of memory to read sensors data to Andrew Rybchenko
2018-09-10  9:33 ` Andrew Rybchenko [this message]
2018-09-10  9:33 ` [dpdk-dev] [PATCH 18/37] net/sfc/base: add buffer editing functions to boot config Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 19/37] net/sfc/base: add accessor for default port mode Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 20/37] net/sfc/base: generalise EF10 NVRAM buffer interface Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 21/37] net/sfc/base: avoid usage of too big arrays on stack Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 22/37] net/sfc/base: add information if TSO workaround is required Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 23/37] net/sfc/base: fix out of bounds read when dereferencing sdup Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 24/37] net/sfc/base: add routine to check for hardware presence Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 25/37] net/sfc/base: add API to inform libefx of hardware removal Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 26/37] net/sfc/base: fix ID retrival in v3 licensing Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 27/37] net/sfc/base: prevent access to the NIC config before probe Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 28/37] net/sfc/base: fix name of the argument to store RSS flags Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 29/37] net/sfc/base: fix a typo in unicast filter insertion comment Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 30/37] net/sfc/base: add support to get active FEC type Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 31/37] net/sfc/base: use simpler code to check hash algorithm type Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 32/37] net/sfc/base: check buffer size for hash flags Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 33/37] net/sfc/base: simplify the code to parse RSS hash type Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 34/37] net/sfc/base: improve handling of legacy RSS hash flags Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 35/37] net/sfc/base: modify phy caps to indicate FEC request Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 36/37] net/sfc/base: fix MAC Tx stats for less or equal to 64 bytes Andrew Rybchenko
2018-09-10  9:33 ` [dpdk-dev] [PATCH 37/37] net/sfc/base: add helper API to make Geneve filter spec Andrew Rybchenko
2018-09-21 10:28 ` [dpdk-dev] [PATCH 00/37] net/sfc: update base driver Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1536572016-18134-18-git-send-email-arybchenko@solarflare.com \
    --to=arybchenko@solarflare.com \
    --cc=dev@dpdk.org \
    --cc=mharvey@solarflare.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).