From patchwork Mon Sep 10 09:33:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 44488 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id AB5EB6CC3; Mon, 10 Sep 2018 11:34:30 +0200 (CEST) Received: from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com [67.231.154.164]) by dpdk.org (Postfix) with ESMTP id DB3044CA1 for ; Mon, 10 Sep 2018 11:33:52 +0200 (CEST) X-Virus-Scanned: Proofpoint Essentials engine Received: from webmail.solarflare.com (webmail.solarflare.com [12.187.104.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mx1-us1.ppe-hosted.com (Proofpoint Essentials ESMTP Server) with ESMTPS id 15049780061 for ; Mon, 10 Sep 2018 09:33:52 +0000 (UTC) Received: from ocex03.SolarFlarecom.com (10.20.40.36) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 10 Sep 2018 02:33:47 -0700 Received: from opal.uk.solarflarecom.com (10.17.10.1) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1395.4 via Frontend Transport; Mon, 10 Sep 2018 02:33:47 -0700 Received: from ukv-loginhost.uk.solarflarecom.com (ukv-loginhost.uk.solarflarecom.com [10.17.10.39]) by opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id w8A9Xk7j023811; Mon, 10 Sep 2018 10:33:46 +0100 Received: from ukv-loginhost.uk.solarflarecom.com (localhost [127.0.0.1]) by ukv-loginhost.uk.solarflarecom.com (Postfix) with ESMTP id EE3941626D2; Mon, 10 Sep 2018 10:33:45 +0100 (BST) From: Andrew Rybchenko To: CC: Martin Harvey Date: Mon, 10 Sep 2018 10:33:16 +0100 Message-ID: <1536572016-18134-18-git-send-email-arybchenko@solarflare.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1536572016-18134-1-git-send-email-arybchenko@solarflare.com> References: <1536572016-18134-1-git-send-email-arybchenko@solarflare.com> MIME-Version: 1.0 X-TM-AS-Product-Ver: SMEX-12.5.0.1300-8.5.1010-24084.005 X-TM-AS-Result: No-5.641500-4.000000-10 X-TMASE-MatchedRID: Nvm1MLOUqr7W5rPMDq6HbymjEOrcO6AyTJDl9FKHbrkTb/3sT17MXHki bXePECZYe34lX7pl/2ME3q8dNdfi6vOb9yKIiNyMSjc25srXNgjt/okBLaEo+KLVgbkZxM5PJct vrvYE+FmMYg2Zw8PzyiB2k0U0PNUdlBLWHauU8Z51e7Xbb6Im2hZO94uK1VSB82HMiBe0UlXX3K 7cUnXcAdIZKUQ/D7gnZrBrMCNPw7vcK0Sw5NnG4p4CIKY/Hg3AGdQnQSTrKGPEQdG7H66TyH4gK q42LRYkOSrNNGL5LTBo+wVBtGiMDN7wkJAEeVdT+ac4+1df1dF+3BndfXUhXQ== X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-TMASE-Result: 10--5.641500-4.000000 X-TMASE-Version: SMEX-12.5.0.1300-8.5.1010-24084.005 X-MDID: 1536572032-A36FFOdYe68X Subject: [dpdk-dev] [PATCH 17/37] net/sfc/base: add API to retrieve sensor limits X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Martin Harvey Signed-off-by: Martin Harvey Signed-off-by: Andrew Rybchenko --- 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 */