net/sfc/base: import monitors statistics
authorAndrew Rybchenko <arybchenko@solarflare.com>
Tue, 29 Nov 2016 16:18:55 +0000 (16:18 +0000)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 17 Jan 2017 18:39:26 +0000 (19:39 +0100)
EFSYS_OPT_MON_STATS should be enabled to use it.

From Solarflare Communications Inc.

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
drivers/net/sfc/base/ef10_ev.c
drivers/net/sfc/base/ef10_nic.c
drivers/net/sfc/base/efx.h
drivers/net/sfc/base/efx_check.h
drivers/net/sfc/base/efx_ev.c
drivers/net/sfc/base/efx_impl.h
drivers/net/sfc/base/efx_mon.c
drivers/net/sfc/base/siena_nic.c

index f58ccc6..e93b458 100644 (file)
@@ -30,6 +30,9 @@
 
 #include "efx.h"
 #include "efx_impl.h"
+#if EFSYS_OPT_MON_STATS
+#include "mcdi_mon.h"
+#endif
 
 #if EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD
 
@@ -1085,6 +1088,23 @@ ef10_ev_mcdi(
        }
 
        case MCDI_EVENT_CODE_SENSOREVT: {
+#if EFSYS_OPT_MON_STATS
+               efx_mon_stat_t id;
+               efx_mon_stat_value_t value;
+               efx_rc_t rc;
+
+               /* Decode monitor stat for MCDI sensor (if supported) */
+               if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0) {
+                       /* Report monitor stat change */
+                       should_abort = eecp->eec_monitor(arg, id, value);
+               } else if (rc == ENOTSUP) {
+                       should_abort = eecp->eec_exception(arg,
+                               EFX_EXCEPTION_UNKNOWN_SENSOREVT,
+                               MCDI_EV_FIELD(eqp, DATA));
+               } else {
+                       EFSYS_ASSERT(rc == ENODEV);     /* Wrong port */
+               }
+#endif
                break;
        }
 
index fec6a69..32706f4 100644 (file)
@@ -1382,10 +1382,22 @@ ef10_nic_probe(
                goto fail6;
 #endif
 
+#if EFSYS_OPT_MON_STATS
+       if ((rc = mcdi_mon_cfg_build(enp)) != 0) {
+               /* Unprivileged functions do not have access to sensors */
+               if (rc != EACCES)
+                       goto fail7;
+       }
+#endif
+
        encp->enc_features = enp->en_features;
 
        return (0);
 
+#if EFSYS_OPT_MON_STATS
+fail7:
+       EFSYS_PROBE(fail7);
+#endif
 #if EFSYS_OPT_LOOPBACK
 fail6:
        EFSYS_PROBE(fail6);
@@ -1781,6 +1793,9 @@ ef10_nic_fini(
 ef10_nic_unprobe(
        __in            efx_nic_t *enp)
 {
+#if EFSYS_OPT_MON_STATS
+       mcdi_mon_cfg_free(enp);
+#endif /* EFSYS_OPT_MON_STATS */
        (void) efx_mcdi_drv_attach(enp, B_FALSE);
 }
 
index 40a7e56..700e45d 100644 (file)
@@ -615,6 +615,125 @@ extern    __checkReturn   efx_rc_t
 efx_mon_init(
        __in            efx_nic_t *enp);
 
+#if EFSYS_OPT_MON_STATS
+
+#define        EFX_MON_STATS_PAGE_SIZE 0x100
+#define        EFX_MON_MASK_ELEMENT_SIZE 32
+
+/* START MKCONFIG GENERATED MonitorHeaderStatsBlock 5d4ee5185e419abe */
+typedef enum efx_mon_stat_e {
+       EFX_MON_STAT_2_5V,
+       EFX_MON_STAT_VCCP1,
+       EFX_MON_STAT_VCC,
+       EFX_MON_STAT_5V,
+       EFX_MON_STAT_12V,
+       EFX_MON_STAT_VCCP2,
+       EFX_MON_STAT_EXT_TEMP,
+       EFX_MON_STAT_INT_TEMP,
+       EFX_MON_STAT_AIN1,
+       EFX_MON_STAT_AIN2,
+       EFX_MON_STAT_INT_COOLING,
+       EFX_MON_STAT_EXT_COOLING,
+       EFX_MON_STAT_1V,
+       EFX_MON_STAT_1_2V,
+       EFX_MON_STAT_1_8V,
+       EFX_MON_STAT_3_3V,
+       EFX_MON_STAT_1_2VA,
+       EFX_MON_STAT_VREF,
+       EFX_MON_STAT_VAOE,
+       EFX_MON_STAT_AOE_TEMP,
+       EFX_MON_STAT_PSU_AOE_TEMP,
+       EFX_MON_STAT_PSU_TEMP,
+       EFX_MON_STAT_FAN0,
+       EFX_MON_STAT_FAN1,
+       EFX_MON_STAT_FAN2,
+       EFX_MON_STAT_FAN3,
+       EFX_MON_STAT_FAN4,
+       EFX_MON_STAT_VAOE_IN,
+       EFX_MON_STAT_IAOE,
+       EFX_MON_STAT_IAOE_IN,
+       EFX_MON_STAT_NIC_POWER,
+       EFX_MON_STAT_0_9V,
+       EFX_MON_STAT_I0_9V,
+       EFX_MON_STAT_I1_2V,
+       EFX_MON_STAT_0_9V_ADC,
+       EFX_MON_STAT_INT_TEMP2,
+       EFX_MON_STAT_VREG_TEMP,
+       EFX_MON_STAT_VREG_0_9V_TEMP,
+       EFX_MON_STAT_VREG_1_2V_TEMP,
+       EFX_MON_STAT_INT_VPTAT,
+       EFX_MON_STAT_INT_ADC_TEMP,
+       EFX_MON_STAT_EXT_VPTAT,
+       EFX_MON_STAT_EXT_ADC_TEMP,
+       EFX_MON_STAT_AMBIENT_TEMP,
+       EFX_MON_STAT_AIRFLOW,
+       EFX_MON_STAT_VDD08D_VSS08D_CSR,
+       EFX_MON_STAT_VDD08D_VSS08D_CSR_EXTADC,
+       EFX_MON_STAT_HOTPOINT_TEMP,
+       EFX_MON_STAT_PHY_POWER_SWITCH_PORT0,
+       EFX_MON_STAT_PHY_POWER_SWITCH_PORT1,
+       EFX_MON_STAT_MUM_VCC,
+       EFX_MON_STAT_0V9_A,
+       EFX_MON_STAT_I0V9_A,
+       EFX_MON_STAT_0V9_A_TEMP,
+       EFX_MON_STAT_0V9_B,
+       EFX_MON_STAT_I0V9_B,
+       EFX_MON_STAT_0V9_B_TEMP,
+       EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY,
+       EFX_MON_STAT_CCOM_AVREG_1V2_SUPPLY_EXT_ADC,
+       EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY,
+       EFX_MON_STAT_CCOM_AVREG_1V8_SUPPLY_EXT_ADC,
+       EFX_MON_STAT_CONTROLLER_MASTER_VPTAT,
+       EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP,
+       EFX_MON_STAT_CONTROLLER_MASTER_VPTAT_EXT_ADC,
+       EFX_MON_STAT_CONTROLLER_MASTER_INTERNAL_TEMP_EXT_ADC,
+       EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT,
+       EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP,
+       EFX_MON_STAT_CONTROLLER_SLAVE_VPTAT_EXT_ADC,
+       EFX_MON_STAT_CONTROLLER_SLAVE_INTERNAL_TEMP_EXT_ADC,
+       EFX_MON_STAT_SODIMM_VOUT,
+       EFX_MON_STAT_SODIMM_0_TEMP,
+       EFX_MON_STAT_SODIMM_1_TEMP,
+       EFX_MON_STAT_PHY0_VCC,
+       EFX_MON_STAT_PHY1_VCC,
+       EFX_MON_STAT_CONTROLLER_TDIODE_TEMP,
+       EFX_MON_STAT_BOARD_FRONT_TEMP,
+       EFX_MON_STAT_BOARD_BACK_TEMP,
+       EFX_MON_NSTATS
+} efx_mon_stat_t;
+
+/* END MKCONFIG GENERATED MonitorHeaderStatsBlock */
+
+typedef enum efx_mon_stat_state_e {
+       EFX_MON_STAT_STATE_OK = 0,
+       EFX_MON_STAT_STATE_WARNING = 1,
+       EFX_MON_STAT_STATE_FATAL = 2,
+       EFX_MON_STAT_STATE_BROKEN = 3,
+       EFX_MON_STAT_STATE_NO_READING = 4,
+} efx_mon_stat_state_t;
+
+typedef struct efx_mon_stat_value_s {
+       uint16_t        emsv_value;
+       uint16_t        emsv_state;
+} efx_mon_stat_value_t;
+
+#if EFSYS_OPT_NAMES
+
+extern                                 const char *
+efx_mon_stat_name(
+       __in                            efx_nic_t *enp,
+       __in                            efx_mon_stat_t id);
+
+#endif /* EFSYS_OPT_NAMES */
+
+extern __checkReturn                   efx_rc_t
+efx_mon_stats_update(
+       __in                            efx_nic_t *enp,
+       __in                            efsys_mem_t *esmp,
+       __inout_ecount(EFX_MON_NSTATS)  efx_mon_stat_value_t *values);
+
+#endif /* EFSYS_OPT_MON_STATS */
+
 extern         void
 efx_mon_fini(
        __in    efx_nic_t *enp);
@@ -973,6 +1092,10 @@ typedef struct efx_nic_cfg_s {
 #endif
        char                    enc_phy_revision[21];
        efx_mon_type_t          enc_mon_type;
+#if EFSYS_OPT_MON_STATS
+       uint32_t                enc_mon_stat_dma_buf_size;
+       uint32_t                enc_mon_stat_mask[(EFX_MON_NSTATS + 31) / 32];
+#endif
        unsigned int            enc_features;
        uint8_t                 enc_mac_addr[6];
        uint8_t                 enc_port;       /* PHY port number */
@@ -1009,6 +1132,10 @@ typedef struct efx_nic_cfg_s {
 #if EFSYS_OPT_PHY_STATS
        uint32_t                enc_mcdi_phy_stat_mask;
 #endif /* EFSYS_OPT_PHY_STATS */
+#if EFSYS_OPT_MON_STATS
+       uint32_t                *enc_mcdi_sensor_maskp;
+       uint32_t                enc_mcdi_sensor_mask_size;
+#endif /* EFSYS_OPT_MON_STATS */
 #endif /* EFSYS_OPT_MCDI */
 #if EFSYS_OPT_BIST
        uint32_t                enc_bist_mask;
@@ -1358,6 +1485,16 @@ typedef __checkReturn    boolean_t
        __in_opt        void *arg,
        __in            efx_link_mode_t link_mode);
 
+#if EFSYS_OPT_MON_STATS
+
+typedef __checkReturn  boolean_t
+(*efx_monitor_ev_t)(
+       __in_opt        void *arg,
+       __in            efx_mon_stat_t id,
+       __in            efx_mon_stat_value_t value);
+
+#endif /* EFSYS_OPT_MON_STATS */
+
 #if EFSYS_OPT_MAC_STATS
 
 typedef __checkReturn  boolean_t
@@ -1381,6 +1518,9 @@ typedef struct efx_ev_callbacks_s {
        efx_wake_up_ev_t                eec_wake_up;
        efx_timer_ev_t                  eec_timer;
        efx_link_change_ev_t            eec_link_change;
+#if EFSYS_OPT_MON_STATS
+       efx_monitor_ev_t                eec_monitor;
+#endif /* EFSYS_OPT_MON_STATS */
 #if EFSYS_OPT_MAC_STATS
        efx_mac_stats_ev_t              eec_mac_stats;
 #endif /* EFSYS_OPT_MAC_STATS */
index 22cf892..3e4e9ba 100644 (file)
 #  error "MON_HUNTINGTON is obsolete (replaced by MON_MCDI)."
 #endif
 
+#if EFSYS_OPT_MON_STATS
+/* Support monitor statistics (voltage/temperature) */
+# if !(EFSYS_OPT_SIENA || EFSYS_OPT_HUNTINGTON || EFSYS_OPT_MEDFORD)
+#  error "MON_STATS requires SIENA or HUNTINGTON or MEDFORD"
+# endif
+#endif /* EFSYS_OPT_MON_STATS */
+
 #if EFSYS_OPT_NAMES
 /* Support printable names for statistics */
 # if !(EFSYS_OPT_LOOPBACK || EFSYS_OPT_MAC_STATS || EFSYS_OPT_MCDI || \
index 9f6a309..ac3ebe3 100644 (file)
@@ -1100,6 +1100,9 @@ siena_ev_mcdi(
 
        EFSYS_ASSERT(eecp->eec_link_change != NULL);
        EFSYS_ASSERT(eecp->eec_exception != NULL);
+#if EFSYS_OPT_MON_STATS
+       EFSYS_ASSERT(eecp->eec_monitor != NULL);
+#endif
 
        EFX_EV_QSTAT_INCR(eep, EV_MCDI_RESPONSE);
 
@@ -1124,7 +1127,22 @@ siena_ev_mcdi(
                break;
        }
        case MCDI_EVENT_CODE_SENSOREVT: {
+#if EFSYS_OPT_MON_STATS
+               efx_mon_stat_t id;
+               efx_mon_stat_value_t value;
+               efx_rc_t rc;
+
+               if ((rc = mcdi_mon_ev(enp, eqp, &id, &value)) == 0)
+                       should_abort = eecp->eec_monitor(arg, id, value);
+               else if (rc == ENOTSUP) {
+                       should_abort = eecp->eec_exception(arg,
+                               EFX_EXCEPTION_UNKNOWN_SENSOREVT,
+                               MCDI_EV_FIELD(eqp, DATA));
+               } else
+                       EFSYS_ASSERT(rc == ENODEV);     /* Wrong port */
+#else
                should_abort = B_FALSE;
+#endif
                break;
        }
        case MCDI_EVENT_CODE_SCHEDERR:
index 12a8a4f..c9d2d11 100644 (file)
@@ -291,6 +291,10 @@ typedef struct efx_port_s {
 } efx_port_t;
 
 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 *);
+#endif /* EFSYS_OPT_MON_STATS */
 } efx_mon_ops_t;
 
 typedef struct efx_mon_s {
index d3ed40d..68314cf 100644 (file)
@@ -100,6 +100,124 @@ fail1:
        return (rc);
 }
 
+#if EFSYS_OPT_MON_STATS
+
+#if EFSYS_OPT_NAMES
+
+/* START MKCONFIG GENERATED MonitorStatNamesBlock 31f437eafb0b0437 */
+static const char * const __mon_stat_name[] = {
+       "value_2_5v",
+       "value_vccp1",
+       "value_vcc",
+       "value_5v",
+       "value_12v",
+       "value_vccp2",
+       "value_ext_temp",
+       "value_int_temp",
+       "value_ain1",
+       "value_ain2",
+       "controller_cooling",
+       "ext_cooling",
+       "1v",
+       "1_2v",
+       "1_8v",
+       "3_3v",
+       "1_2va",
+       "vref",
+       "vaoe",
+       "aoe_temperature",
+       "psu_aoe_temperature",
+       "psu_temperature",
+       "fan0",
+       "fan1",
+       "fan2",
+       "fan3",
+       "fan4",
+       "vaoe_in",
+       "iaoe",
+       "iaoe_in",
+       "nic_power",
+       "0_9v",
+       "i0_9v",
+       "i1_2v",
+       "0_9v_adc",
+       "controller_temperature2",
+       "vreg_temperature",
+       "vreg_0_9v_temperature",
+       "vreg_1_2v_temperature",
+       "int_vptat",
+       "controller_internal_adc_temperature",
+       "ext_vptat",
+       "controller_external_adc_temperature",
+       "ambient_temperature",
+       "airflow",
+       "vdd08d_vss08d_csr",
+       "vdd08d_vss08d_csr_extadc",
+       "hotpoint_temperature",
+       "phy_power_switch_port0",
+       "phy_power_switch_port1",
+       "mum_vcc",
+       "0v9_a",
+       "i0v9_a",
+       "0v9_a_temp",
+       "0v9_b",
+       "i0v9_b",
+       "0v9_b_temp",
+       "ccom_avreg_1v2_supply",
+       "ccom_avreg_1v2_supply_ext_adc",
+       "ccom_avreg_1v8_supply",
+       "ccom_avreg_1v8_supply_ext_adc",
+       "controller_master_vptat",
+       "controller_master_internal_temp",
+       "controller_master_vptat_ext_adc",
+       "controller_master_internal_temp_ext_adc",
+       "controller_slave_vptat",
+       "controller_slave_internal_temp",
+       "controller_slave_vptat_ext_adc",
+       "controller_slave_internal_temp_ext_adc",
+       "sodimm_vout",
+       "sodimm_0_temp",
+       "sodimm_1_temp",
+       "phy0_vcc",
+       "phy1_vcc",
+       "controller_tdiode_temp",
+       "board_front_temp",
+       "board_back_temp",
+};
+
+/* END MKCONFIG GENERATED MonitorStatNamesBlock */
+
+extern                                 const char *
+efx_mon_stat_name(
+       __in                            efx_nic_t *enp,
+       __in                            efx_mon_stat_t id)
+{
+       _NOTE(ARGUNUSED(enp))
+       EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC);
+
+       EFSYS_ASSERT3U(id, <, EFX_MON_NSTATS);
+       return (__mon_stat_name[id]);
+}
+
+#endif /* EFSYS_OPT_NAMES */
+
+       __checkReturn                   efx_rc_t
+efx_mon_stats_update(
+       __in                            efx_nic_t *enp,
+       __in                            efsys_mem_t *esmp,
+       __inout_ecount(EFX_MON_NSTATS)  efx_mon_stat_value_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_stats_update(enp, esmp, values));
+}
+
+#endif /* EFSYS_OPT_MON_STATS */
+
                void
 efx_mon_fini(
        __in    efx_nic_t *enp)
index d28d1d2..5d0f6e8 100644 (file)
@@ -221,10 +221,19 @@ siena_nic_probe(
                goto fail11;
 #endif
 
+#if EFSYS_OPT_MON_STATS
+       if ((rc = mcdi_mon_cfg_build(enp)) != 0)
+               goto fail12;
+#endif
+
        encp->enc_features = enp->en_features;
 
        return (0);
 
+#if EFSYS_OPT_MON_STATS
+fail12:
+       EFSYS_PROBE(fail12);
+#endif
 #if EFSYS_OPT_LOOPBACK
 fail11:
        EFSYS_PROBE(fail11);
@@ -376,6 +385,9 @@ siena_nic_fini(
 siena_nic_unprobe(
        __in            efx_nic_t *enp)
 {
+#if EFSYS_OPT_MON_STATS
+       mcdi_mon_cfg_free(enp);
+#endif /* EFSYS_OPT_MON_STATS */
        (void) efx_mcdi_drv_attach(enp, B_FALSE);
 }