Date: Thu, 29 Dec 2016 06:54:40 +0000 (UTC) From: Andrew Rybchenko <arybchik@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r310747 - head/sys/dev/sfxge/common Message-ID: <201612290654.uBT6serO050087@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: arybchik Date: Thu Dec 29 06:54:40 2016 New Revision: 310747 URL: https://svnweb.freebsd.org/changeset/base/310747 Log: sfxge(4): provide a way to find out which MAC stats are supported Reviewed by: gnn Sponsored by: Solarflare Communications, Inc. MFC after: 2 days Differential Revision: https://reviews.freebsd.org/D8944 Modified: head/sys/dev/sfxge/common/ef10_impl.h head/sys/dev/sfxge/common/ef10_mac.c head/sys/dev/sfxge/common/ef10_nic.c head/sys/dev/sfxge/common/efx.h head/sys/dev/sfxge/common/efx_impl.h head/sys/dev/sfxge/common/efx_mac.c head/sys/dev/sfxge/common/siena_impl.h head/sys/dev/sfxge/common/siena_mac.c Modified: head/sys/dev/sfxge/common/ef10_impl.h ============================================================================== --- head/sys/dev/sfxge/common/ef10_impl.h Thu Dec 29 06:52:42 2016 (r310746) +++ head/sys/dev/sfxge/common/ef10_impl.h Thu Dec 29 06:54:40 2016 (r310747) @@ -273,6 +273,12 @@ ef10_mac_loopback_set( #if EFSYS_OPT_MAC_STATS extern __checkReturn efx_rc_t +ef10_mac_stats_get_mask( + __in efx_nic_t *enp, + __inout_bcount(mask_size) uint32_t *maskp, + __in size_t mask_size); + +extern __checkReturn efx_rc_t ef10_mac_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, Modified: head/sys/dev/sfxge/common/ef10_mac.c ============================================================================== --- head/sys/dev/sfxge/common/ef10_mac.c Thu Dec 29 06:52:42 2016 (r310746) +++ head/sys/dev/sfxge/common/ef10_mac.c Thu Dec 29 06:54:40 2016 (r310747) @@ -484,6 +484,89 @@ fail1: #if EFSYS_OPT_MAC_STATS + __checkReturn efx_rc_t +ef10_mac_stats_get_mask( + __in efx_nic_t *enp, + __inout_bcount(mask_size) uint32_t *maskp, + __in size_t mask_size) +{ + const struct efx_mac_stats_range ef10_common[] = { + { EFX_MAC_RX_OCTETS, EFX_MAC_RX_GE_15XX_PKTS }, + { EFX_MAC_RX_FCS_ERRORS, EFX_MAC_RX_DROP_EVENTS }, + { EFX_MAC_RX_JABBER_PKTS, EFX_MAC_RX_JABBER_PKTS }, + { EFX_MAC_RX_NODESC_DROP_CNT, EFX_MAC_TX_PAUSE_PKTS }, + }; + const struct efx_mac_stats_range ef10_tx_size_bins[] = { + { EFX_MAC_TX_LE_64_PKTS, EFX_MAC_TX_GE_15XX_PKTS }, + }; + efx_nic_cfg_t *encp = &(enp->en_nic_cfg); + efx_port_t *epp = &(enp->en_port); + efx_rc_t rc; + + if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, + ef10_common, EFX_ARRAY_SIZE(ef10_common))) != 0) + goto fail1; + + if (epp->ep_phy_cap_mask & (1 << MC_CMD_PHY_CAP_40000FDX_LBN)) { + const struct efx_mac_stats_range ef10_40g_extra[] = { + { EFX_MAC_RX_ALIGN_ERRORS, EFX_MAC_RX_ALIGN_ERRORS }, + }; + + if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, + ef10_40g_extra, EFX_ARRAY_SIZE(ef10_40g_extra))) != 0) + goto fail2; + + if (encp->enc_mac_stats_40g_tx_size_bins) { + if ((rc = efx_mac_stats_mask_add_ranges(maskp, + mask_size, ef10_tx_size_bins, + EFX_ARRAY_SIZE(ef10_tx_size_bins))) != 0) + goto fail3; + } + } else { + if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, + ef10_tx_size_bins, EFX_ARRAY_SIZE(ef10_tx_size_bins))) != 0) + goto fail4; + } + + if (encp->enc_pm_and_rxdp_counters) { + const struct efx_mac_stats_range ef10_pm_and_rxdp[] = { + { EFX_MAC_PM_TRUNC_BB_OVERFLOW, EFX_MAC_RXDP_HLB_WAIT }, + }; + + if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, + ef10_pm_and_rxdp, EFX_ARRAY_SIZE(ef10_pm_and_rxdp))) != 0) + goto fail5; + } + + if (encp->enc_datapath_cap_evb) { + const struct efx_mac_stats_range ef10_vadaptor[] = { + { EFX_MAC_VADAPTER_RX_UNICAST_PACKETS, + EFX_MAC_VADAPTER_TX_OVERFLOW }, + }; + + if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, + ef10_vadaptor, EFX_ARRAY_SIZE(ef10_vadaptor))) != 0) + goto fail6; + } + + return (0); + +fail6: + EFSYS_PROBE(fail6); +fail5: + EFSYS_PROBE(fail5); +fail4: + EFSYS_PROBE(fail4); +fail3: + EFSYS_PROBE(fail3); +fail2: + EFSYS_PROBE(fail2); +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + #define EF10_MAC_STAT_READ(_esmp, _field, _eqp) \ EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp) Modified: head/sys/dev/sfxge/common/ef10_nic.c ============================================================================== --- head/sys/dev/sfxge/common/ef10_nic.c Thu Dec 29 06:52:42 2016 (r310746) +++ head/sys/dev/sfxge/common/ef10_nic.c Thu Dec 29 06:54:40 2016 (r310747) @@ -1091,6 +1091,20 @@ ef10_get_datapath_caps( encp->enc_init_evq_v2_supported = CAP_FLAG2(flags2, INIT_EVQ_V2) ? B_TRUE : B_FALSE; + /* + * Check if firmware provides packet memory and Rx datapath + * counters. + */ + encp->enc_pm_and_rxdp_counters = + CAP_FLAG(flags, PM_AND_RXDP_COUNTERS) ? B_TRUE : B_FALSE; + + /* + * Check if the 40G MAC hardware is capable of reporting + * statistics for Tx size bins. + */ + encp->enc_mac_stats_40g_tx_size_bins = + CAP_FLAG2(flags2, MAC_STATS_40G_TX_SIZE_BINS) ? B_TRUE : B_FALSE; + #undef CAP_FLAG #undef CAP_FLAG2 Modified: head/sys/dev/sfxge/common/efx.h ============================================================================== --- head/sys/dev/sfxge/common/efx.h Thu Dec 29 06:52:42 2016 (r310746) +++ head/sys/dev/sfxge/common/efx.h Thu Dec 29 06:54:40 2016 (r310747) @@ -535,6 +535,29 @@ efx_mac_stat_name( #endif /* EFSYS_OPT_NAMES */ +#define EFX_MAC_STATS_MASK_BITS_PER_PAGE (8 * sizeof (uint32_t)) + +#define EFX_MAC_STATS_MASK_NPAGES \ + (P2ROUNDUP(EFX_MAC_NSTATS, EFX_MAC_STATS_MASK_BITS_PER_PAGE) / \ + EFX_MAC_STATS_MASK_BITS_PER_PAGE) + +/* + * Get mask of MAC statistics supported by the hardware. + * + * If mask_size is insufficient to return the mask, EINVAL error is + * returned. EFX_MAC_STATS_MASK_NPAGES multiplied by size of the page + * (which is sizeof (uint32_t)) is sufficient. + */ +extern __checkReturn efx_rc_t +efx_mac_stats_get_mask( + __in efx_nic_t *enp, + __out_bcount(mask_size) uint32_t *maskp, + __in size_t mask_size); + +#define EFX_MAC_STAT_SUPPORTED(_mask, _stat) \ + ((_mask)[(_stat) / EFX_MAC_STATS_MASK_BITS_PER_PAGE] & \ + (1ULL << ((_stat) & (EFX_MAC_STATS_MASK_BITS_PER_PAGE - 1)))) + #define EFX_MAC_STATS_SIZE 0x400 /* @@ -1150,6 +1173,8 @@ typedef struct efx_nic_cfg_s { boolean_t enc_allow_set_mac_with_installed_filters; boolean_t enc_enhanced_set_mac_supported; boolean_t enc_init_evq_v2_supported; + boolean_t enc_pm_and_rxdp_counters; + boolean_t enc_mac_stats_40g_tx_size_bins; /* External port identifier */ uint8_t enc_external_port; uint32_t enc_mcdi_max_payload_length; Modified: head/sys/dev/sfxge/common/efx_impl.h ============================================================================== --- head/sys/dev/sfxge/common/efx_impl.h Thu Dec 29 06:52:42 2016 (r310746) +++ head/sys/dev/sfxge/common/efx_impl.h Thu Dec 29 06:54:40 2016 (r310747) @@ -194,6 +194,7 @@ typedef struct efx_mac_ops_s { efx_loopback_type_t); #endif /* EFSYS_OPT_LOOPBACK */ #if EFSYS_OPT_MAC_STATS + efx_rc_t (*emo_stats_get_mask)(efx_nic_t *, uint32_t *, size_t); efx_rc_t (*emo_stats_upload)(efx_nic_t *, efsys_mem_t *); efx_rc_t (*emo_stats_periodic)(efx_nic_t *, efsys_mem_t *, uint16_t, boolean_t); @@ -1155,6 +1156,27 @@ efx_mcdi_get_workarounds( #endif /* EFSYS_OPT_MCDI */ +#if EFSYS_OPT_MAC_STATS + +/* + * Closed range of stats (i.e. the first and the last are included). + * The last must be greater or equal (if the range is one item only) to + * the first. + */ +struct efx_mac_stats_range { + efx_mac_stat_t first; + efx_mac_stat_t last; +}; + +extern efx_rc_t +efx_mac_stats_mask_add_ranges( + __inout_bcount(mask_size) uint32_t *maskp, + __in size_t mask_size, + __in_ecount(rng_count) const struct efx_mac_stats_range *rngp, + __in unsigned int rng_count); + +#endif /* EFSYS_OPT_MAC_STATS */ + #ifdef __cplusplus } #endif Modified: head/sys/dev/sfxge/common/efx_mac.c ============================================================================== --- head/sys/dev/sfxge/common/efx_mac.c Thu Dec 29 06:52:42 2016 (r310746) +++ head/sys/dev/sfxge/common/efx_mac.c Thu Dec 29 06:54:40 2016 (r310747) @@ -57,6 +57,7 @@ static const efx_mac_ops_t __efx_siena_m siena_mac_loopback_set, /* emo_loopback_set */ #endif /* EFSYS_OPT_LOOPBACK */ #if EFSYS_OPT_MAC_STATS + siena_mac_stats_get_mask, /* emo_stats_get_mask */ efx_mcdi_mac_stats_upload, /* emo_stats_upload */ efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */ siena_mac_stats_update /* emo_stats_update */ @@ -80,6 +81,7 @@ static const efx_mac_ops_t __efx_ef10_ma ef10_mac_loopback_set, /* emo_loopback_set */ #endif /* EFSYS_OPT_LOOPBACK */ #if EFSYS_OPT_MAC_STATS + ef10_mac_stats_get_mask, /* emo_stats_get_mask */ efx_mcdi_mac_stats_upload, /* emo_stats_upload */ efx_mcdi_mac_stats_periodic, /* emo_stats_periodic */ ef10_mac_stats_update /* emo_stats_update */ @@ -615,6 +617,105 @@ efx_mac_stat_name( #endif /* EFSYS_OPT_NAMES */ +static efx_rc_t +efx_mac_stats_mask_add_range( + __inout_bcount(mask_size) uint32_t *maskp, + __in size_t mask_size, + __in const struct efx_mac_stats_range *rngp) +{ + unsigned int mask_npages = mask_size / sizeof (*maskp); + unsigned int el; + unsigned int el_min; + unsigned int el_max; + unsigned int low; + unsigned int high; + unsigned int width; + efx_rc_t rc; + + if ((mask_npages * EFX_MAC_STATS_MASK_BITS_PER_PAGE) <= + (unsigned int)rngp->last) { + rc = EINVAL; + goto fail1; + } + + EFSYS_ASSERT3U(rngp->first, <=, rngp->last); + EFSYS_ASSERT3U(rngp->last, <, EFX_MAC_NSTATS); + + for (el = 0; el < mask_npages; ++el) { + el_min = el * EFX_MAC_STATS_MASK_BITS_PER_PAGE; + el_max = + el_min + (EFX_MAC_STATS_MASK_BITS_PER_PAGE - 1); + if ((unsigned int)rngp->first > el_max || + (unsigned int)rngp->last < el_min) + continue; + low = MAX((unsigned int)rngp->first, el_min); + high = MIN((unsigned int)rngp->last, el_max); + width = high - low + 1; + maskp[el] |= + (width == EFX_MAC_STATS_MASK_BITS_PER_PAGE) ? + (~0ULL) : (((1ULL << width) - 1) << (low - el_min)); + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + + efx_rc_t +efx_mac_stats_mask_add_ranges( + __inout_bcount(mask_size) uint32_t *maskp, + __in size_t mask_size, + __in_ecount(rng_count) const struct efx_mac_stats_range *rngp, + __in unsigned int rng_count) +{ + unsigned int i; + efx_rc_t rc; + + for (i = 0; i < rng_count; ++i) { + if ((rc = efx_mac_stats_mask_add_range(maskp, mask_size, + &rngp[i])) != 0) + goto fail1; + } + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + + __checkReturn efx_rc_t +efx_mac_stats_get_mask( + __in efx_nic_t *enp, + __out_bcount(mask_size) uint32_t *maskp, + __in size_t mask_size) +{ + efx_port_t *epp = &(enp->en_port); + const efx_mac_ops_t *emop = epp->ep_emop; + efx_rc_t rc; + + EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); + EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); + EFSYS_ASSERT(maskp != NULL); + EFSYS_ASSERT(mask_size % sizeof (maskp[0]) == 0); + + (void) memset(maskp, 0, mask_size); + + if ((rc = emop->emo_stats_get_mask(enp, maskp, mask_size)) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + __checkReturn efx_rc_t efx_mac_stats_upload( __in efx_nic_t *enp, Modified: head/sys/dev/sfxge/common/siena_impl.h ============================================================================== --- head/sys/dev/sfxge/common/siena_impl.h Thu Dec 29 06:52:42 2016 (r310746) +++ head/sys/dev/sfxge/common/siena_impl.h Thu Dec 29 06:54:40 2016 (r310747) @@ -406,6 +406,12 @@ siena_mac_loopback_set( #if EFSYS_OPT_MAC_STATS extern __checkReturn efx_rc_t +siena_mac_stats_get_mask( + __in efx_nic_t *enp, + __inout_bcount(mask_size) uint32_t *maskp, + __in size_t mask_size); + +extern __checkReturn efx_rc_t siena_mac_stats_update( __in efx_nic_t *enp, __in efsys_mem_t *esmp, Modified: head/sys/dev/sfxge/common/siena_mac.c ============================================================================== --- head/sys/dev/sfxge/common/siena_mac.c Thu Dec 29 06:52:42 2016 (r310746) +++ head/sys/dev/sfxge/common/siena_mac.c Thu Dec 29 06:54:40 2016 (r310747) @@ -235,6 +235,33 @@ fail1: #if EFSYS_OPT_MAC_STATS + __checkReturn efx_rc_t +siena_mac_stats_get_mask( + __in efx_nic_t *enp, + __inout_bcount(mask_size) uint32_t *maskp, + __in size_t mask_size) +{ + const struct efx_mac_stats_range siena_stats[] = { + { EFX_MAC_RX_OCTETS, EFX_MAC_RX_GE_15XX_PKTS }, + /* EFX_MAC_RX_ERRORS is not supported */ + { EFX_MAC_RX_FCS_ERRORS, EFX_MAC_TX_EX_DEF_PKTS }, + }; + efx_rc_t rc; + + _NOTE(ARGUNUSED(enp)) + + if ((rc = efx_mac_stats_mask_add_ranges(maskp, mask_size, + siena_stats, EFX_ARRAY_SIZE(siena_stats))) != 0) + goto fail1; + + return (0); + +fail1: + EFSYS_PROBE1(fail1, efx_rc_t, rc); + + return (rc); +} + #define SIENA_MAC_STAT_READ(_esmp, _field, _eqp) \ EFSYS_MEM_READQ((_esmp), (_field) * sizeof (efx_qword_t), _eqp)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201612290654.uBT6serO050087>