2 * Copyright 2009 Solarflare Communications Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
33 #if EFSYS_OPT_MON_SIENA
40 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
46 siena_mon_reconfigure(
50 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
55 #if EFSYS_OPT_MON_STATS
57 #define SIENA_MON_WRONG_PORT (uint16_t)0xffff
59 static __cs uint16_t __siena_mon_port0_map[] = {
60 EFX_MON_STAT_INT_TEMP, /* MC_CMD_SENSOR_CONTROLLER_TEMP */
61 EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY_COMMON_TEMP */
62 EFX_MON_STAT_INT_COOLING, /* MC_CMD_SENSOR_CONTROLLER_COOLING */
63 EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY0_TEMP */
64 EFX_MON_STAT_EXT_COOLING, /* MC_CMD_SENSOR_PHY0_COOLING */
65 SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY1_TEMP */
66 SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY1_COOLING */
67 EFX_MON_STAT_1V, /* MC_CMD_SENSOR_IN_1V0 */
68 EFX_MON_STAT_1_2V, /* MC_CMD_SENSOR_IN_1V2 */
69 EFX_MON_STAT_1_8V, /* MC_CMD_SENSOR_IN_1V8 */
70 EFX_MON_STAT_2_5V, /* MC_CMD_SENSOR_IN_2V5 */
71 EFX_MON_STAT_3_3V, /* MC_CMD_SENSOR_IN_3V3 */
72 EFX_MON_STAT_12V, /* MC_CMD_SENSOR_IN_12V0 */
75 static __cs uint16_t __siena_mon_port1_map[] = {
76 EFX_MON_STAT_INT_TEMP, /* MC_CMD_SENSOR_CONTROLLER_TEMP */
77 EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY_COMMON_TEMP */
78 EFX_MON_STAT_INT_COOLING, /* MC_CMD_SENSOR_CONTROLLER_COOLING */
79 SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY0_TEMP */
80 SIENA_MON_WRONG_PORT, /* MC_CMD_SENSOR_PHY0_COOLING */
81 EFX_MON_STAT_EXT_TEMP, /* MC_CMD_SENSOR_PHY1_TEMP */
82 EFX_MON_STAT_EXT_COOLING, /* MC_CMD_SENSOR_PHY1_COOLING */
83 EFX_MON_STAT_1V, /* MC_CMD_SENSOR_IN_1V0 */
84 EFX_MON_STAT_1_2V, /* MC_CMD_SENSOR_IN_1V2 */
85 EFX_MON_STAT_1_8V, /* MC_CMD_SENSOR_IN_1V8 */
86 EFX_MON_STAT_2_5V, /* MC_CMD_SENSOR_IN_2V5 */
87 EFX_MON_STAT_3_3V, /* MC_CMD_SENSOR_IN_3V3 */
88 EFX_MON_STAT_12V, /* MC_CMD_SENSOR_IN_12V0 */
91 #define SIENA_STATIC_SENSOR_ASSERT(_field) \
92 EFX_STATIC_ASSERT(MC_CMD_SENSOR_STATE_ ## _field \
93 == EFX_MON_STAT_STATE_ ## _field)
96 siena_mon_decode_stats(
99 __in_opt efsys_mem_t *esmp,
100 __out_opt uint32_t *vmaskp,
101 __out_ecount_opt(EFX_MON_NSTATS) efx_mon_stat_value_t *value)
103 efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
104 uint16_t *sensor_map;
106 size_t mc_sensor_max;
109 /* Assert the MC_CMD_SENSOR and EFX_MON_STATE namespaces agree */
110 SIENA_STATIC_SENSOR_ASSERT(OK);
111 SIENA_STATIC_SENSOR_ASSERT(WARNING);
112 SIENA_STATIC_SENSOR_ASSERT(FATAL);
113 SIENA_STATIC_SENSOR_ASSERT(BROKEN);
115 EFX_STATIC_ASSERT(sizeof (__siena_mon_port1_map)
116 == sizeof (__siena_mon_port0_map));
117 mc_sensor_max = EFX_ARRAY_SIZE(__siena_mon_port0_map);
118 sensor_map = (emip->emi_port == 1)
119 ? __siena_mon_port0_map
120 : __siena_mon_port1_map;
123 * dmask may legitimately contain sensors not understood by the driver
125 for (mc_sensor = 0; mc_sensor < mc_sensor_max; ++mc_sensor) {
126 uint16_t efx_sensor = sensor_map[mc_sensor];
128 if (efx_sensor == SIENA_MON_WRONG_PORT)
130 EFSYS_ASSERT(efx_sensor < EFX_MON_NSTATS);
132 if (~dmask & (1 << mc_sensor))
135 vmask |= (1 << efx_sensor);
136 if (value != NULL && esmp != NULL && !EFSYS_MEM_IS_NULL(esmp)) {
137 efx_mon_stat_value_t *emsvp = value + efx_sensor;
139 EFSYS_MEM_READD(esmp, 4 * mc_sensor, &dword);
141 (uint16_t)EFX_DWORD_FIELD(
143 MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE);
145 (uint16_t)EFX_DWORD_FIELD(
147 MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE);
158 __in efx_qword_t *eqp,
159 __out efx_mon_stat_t *idp,
160 __out efx_mon_stat_value_t *valuep)
162 efx_mcdi_iface_t *emip = &(enp->en_u.siena.enu_mip);
163 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
167 uint16_t *sensor_map;
171 sensor_map = (emip->emi_port == 1)
172 ? __siena_mon_port0_map
173 : __siena_mon_port1_map;
175 ev_monitor = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_MONITOR);
176 ev_state = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_STATE);
177 ev_value = (uint16_t)MCDI_EV_FIELD(eqp, SENSOREVT_VALUE);
179 /* Hardware must support this statistic */
180 EFSYS_ASSERT((1 << ev_monitor) & encp->enc_siena_mon_stat_mask);
182 /* But we don't have to understand it */
183 if (ev_monitor >= EFX_ARRAY_SIZE(__siena_mon_port0_map)) {
188 id = sensor_map[ev_monitor];
189 if (id == SIENA_MON_WRONG_PORT)
191 EFSYS_ASSERT(id < EFX_MON_NSTATS);
194 valuep->emsv_value = ev_value;
195 valuep->emsv_state = ev_state;
200 EFSYS_PROBE1(fail1, int, rc);
206 siena_mon_stats_update(
208 __in efsys_mem_t *esmp,
209 __out_ecount(EFX_MON_NSTATS) efx_mon_stat_value_t *values)
211 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
212 uint32_t dmask = encp->enc_siena_mon_stat_mask;
214 uint8_t payload[MC_CMD_READ_SENSORS_IN_LEN];
218 EFSYS_ASSERT(enp->en_family == EFX_FAMILY_SIENA);
220 req.emr_cmd = MC_CMD_READ_SENSORS;
221 req.emr_in_buf = payload;
222 req.emr_in_length = sizeof (payload);
223 EFX_STATIC_ASSERT(MC_CMD_READ_SENSORS_OUT_LEN == 0);
224 req.emr_out_buf = NULL;
225 req.emr_out_length = 0;
227 MCDI_IN_SET_DWORD(req, READ_SENSORS_IN_DMA_ADDR_LO,
228 EFSYS_MEM_ADDR(esmp) & 0xffffffff);
229 MCDI_IN_SET_DWORD(req, READ_SENSORS_IN_DMA_ADDR_HI,
230 EFSYS_MEM_ADDR(esmp) >> 32);
232 efx_mcdi_execute(enp, &req);
234 if (req.emr_rc != 0) {
239 siena_mon_decode_stats(enp, dmask, esmp, &vmask, values);
240 EFSYS_ASSERT(vmask == encp->enc_mon_stat_mask);
245 EFSYS_PROBE1(fail1, int, rc);
250 #endif /* EFSYS_OPT_MON_STATS */
252 #endif /* EFSYS_OPT_MON_SIENA */