Add support for reading temperature in mlx5en(4).

MFC after:	1 week
Sponsored by:	Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2020-04-27 14:35:39 +00:00
parent 21d3be9105
commit decb087cc2
4 changed files with 238 additions and 0 deletions

View file

@ -728,6 +728,8 @@ struct mlx5e_params_ethtool {
u16 fec_avail_50x[MLX5E_MAX_FEC_50X];
u32 fec_mode_active;
u32 hw_mtu_msb;
s32 hw_val_temp[MLX5_MAX_TEMPERATURE];
u32 hw_num_temp;
};
struct mlx5e_cq {
@ -1199,6 +1201,7 @@ void mlx5e_update_sq_inline(struct mlx5e_sq *sq);
void mlx5e_refresh_sq_inline(struct mlx5e_priv *priv);
int mlx5e_update_buf_lossy(struct mlx5e_priv *priv);
int mlx5e_fec_update(struct mlx5e_priv *priv);
int mlx5e_hw_temperature_update(struct mlx5e_priv *priv);
if_snd_tag_alloc_t mlx5e_ul_snd_tag_alloc;
if_snd_tag_modify_t mlx5e_ul_snd_tag_modify;

View file

@ -821,6 +821,65 @@ mlx5e_cable_length_handler(SYSCTL_HANDLER_ARGS)
return (error);
}
static int
mlx5e_hw_temperature_handler(SYSCTL_HANDLER_ARGS)
{
struct mlx5e_priv *priv = arg1;
int err;
PRIV_LOCK(priv);
err = SYSCTL_OUT(req, priv->params_ethtool.hw_val_temp,
sizeof(priv->params_ethtool.hw_val_temp[0]) *
priv->params_ethtool.hw_num_temp);
if (err == 0 && req->newptr != NULL)
err = EOPNOTSUPP;
PRIV_UNLOCK(priv);
return (err);
}
int
mlx5e_hw_temperature_update(struct mlx5e_priv *priv)
{
int err;
u32 x;
if (priv->params_ethtool.hw_num_temp == 0) {
u32 out_cap[MLX5_ST_SZ_DW(mtcap)] = {};
const int sz_cap = MLX5_ST_SZ_BYTES(mtcap);
u32 value;
err = -mlx5_core_access_reg(priv->mdev, NULL, 0, out_cap, sz_cap,
MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTCAP, 0, 0);
if (err)
goto done;
value = MLX5_GET(mtcap, out_cap, sensor_count);
if (value == 0)
return (0);
if (value > MLX5_MAX_TEMPERATURE)
value = MLX5_MAX_TEMPERATURE;
/* update number of temperature sensors */
priv->params_ethtool.hw_num_temp = value;
}
for (x = 0; x != priv->params_ethtool.hw_num_temp; x++) {
u32 out_sensor[MLX5_ST_SZ_DW(mtmp_reg)] = {};
const int sz_sensor = MLX5_ST_SZ_BYTES(mtmp_reg);
MLX5_SET(mtmp_reg, out_sensor, sensor_index, x);
err = -mlx5_core_access_reg(priv->mdev, out_sensor, sz_sensor,
out_sensor, sz_sensor,
MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTMP, 0, 0);
if (err)
goto done;
/* convert from 0.125 celcius to millicelcius */
priv->params_ethtool.hw_val_temp[x] =
(s16)MLX5_GET(mtmp_reg, out_sensor, temperature) * 125;
}
done:
return (err);
}
#define MLX5_PARAM_OFFSET(n) \
__offsetof(struct mlx5e_priv, params_ethtool.n)
@ -1563,4 +1622,12 @@ mlx5e_create_ethtool(struct mlx5e_priv *priv)
priv, 0, mlx5e_cable_length_handler, "IU",
"Set cable length in meters for xoff threshold calculation");
}
if (mlx5e_hw_temperature_update(priv) == 0) {
SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
OID_AUTO, "hw_temperature",
CTLTYPE_S32 | CTLFLAG_RD | CTLFLAG_MPSAFE,
priv, 0, mlx5e_hw_temperature_handler, "I",
"HW temperature in millicelcius");
}
}

View file

@ -1042,6 +1042,15 @@ free_out:
mlx5_en_err(priv->ifp,
"Updating FEC failed: %d\n", error);
}
/* Update temperature, if any */
if (priv->params_ethtool.hw_num_temp != 0) {
error = mlx5e_hw_temperature_update(priv);
if (error != 0 && error != EOPNOTSUPP) {
mlx5_en_err(priv->ifp,
"Updating temperature failed: %d\n", error);
}
}
}
static void

View file

@ -10607,4 +10607,163 @@ struct mlx5_ifc_mfrl_reg_bits {
u8 reset_level[0x8];
};
enum {
MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTCAP = 0x9009,
MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTECR = 0x9109,
MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTMP = 0x900a,
MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTWE = 0x900b,
MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTBR = 0x900f,
MLX5_ACCESS_REG_SUMMARY_CTRL_ID_MTEWE = 0x910b,
MLX5_MAX_TEMPERATURE = 16,
};
struct mlx5_ifc_mtbr_temp_record_bits {
u8 max_temperature[0x10];
u8 temperature[0x10];
};
struct mlx5_ifc_mtbr_reg_bits {
u8 reserved_at_0[0x14];
u8 base_sensor_index[0xc];
u8 reserved_at_20[0x18];
u8 num_rec[0x8];
u8 reserved_at_40[0x40];
struct mlx5_ifc_mtbr_temp_record_bits temperature_record[MLX5_MAX_TEMPERATURE];
};
struct mlx5_ifc_mtbr_reg_ext_bits {
u8 reserved_at_0[0x14];
u8 base_sensor_index[0xc];
u8 reserved_at_20[0x18];
u8 num_rec[0x8];
u8 reserved_at_40[0x40];
struct mlx5_ifc_mtbr_temp_record_bits temperature_record[MLX5_MAX_TEMPERATURE];
};
struct mlx5_ifc_mtcap_bits {
u8 reserved_at_0[0x19];
u8 sensor_count[0x7];
u8 reserved_at_20[0x19];
u8 internal_sensor_count[0x7];
u8 sensor_map[0x40];
};
struct mlx5_ifc_mtcap_ext_bits {
u8 reserved_at_0[0x19];
u8 sensor_count[0x7];
u8 reserved_at_20[0x20];
u8 sensor_map[0x40];
};
struct mlx5_ifc_mtecr_bits {
u8 reserved_at_0[0x4];
u8 last_sensor[0xc];
u8 reserved_at_10[0x4];
u8 sensor_count[0xc];
u8 reserved_at_20[0x19];
u8 internal_sensor_count[0x7];
u8 sensor_map_0[0x20];
u8 reserved_at_60[0x2a0];
};
struct mlx5_ifc_mtecr_ext_bits {
u8 reserved_at_0[0x4];
u8 last_sensor[0xc];
u8 reserved_at_10[0x4];
u8 sensor_count[0xc];
u8 reserved_at_20[0x20];
u8 sensor_map_0[0x20];
u8 reserved_at_60[0x2a0];
};
struct mlx5_ifc_mtewe_bits {
u8 reserved_at_0[0x4];
u8 last_sensor[0xc];
u8 reserved_at_10[0x4];
u8 sensor_count[0xc];
u8 sensor_warning_0[0x20];
u8 reserved_at_40[0x2a0];
};
struct mlx5_ifc_mtewe_ext_bits {
u8 reserved_at_0[0x4];
u8 last_sensor[0xc];
u8 reserved_at_10[0x4];
u8 sensor_count[0xc];
u8 sensor_warning_0[0x20];
u8 reserved_at_40[0x2a0];
};
struct mlx5_ifc_mtmp_bits {
u8 reserved_at_0[0x14];
u8 sensor_index[0xc];
u8 reserved_at_20[0x10];
u8 temperature[0x10];
u8 mte[0x1];
u8 mtr[0x1];
u8 reserved_at_42[0xe];
u8 max_temperature[0x10];
u8 tee[0x2];
u8 reserved_at_62[0xe];
u8 temperature_threshold_hi[0x10];
u8 reserved_at_80[0x10];
u8 temperature_threshold_lo[0x10];
u8 reserved_at_a0[0x20];
u8 sensor_name_hi[0x20];
u8 sensor_name_lo[0x20];
};
struct mlx5_ifc_mtmp_ext_bits {
u8 reserved_at_0[0x14];
u8 sensor_index[0xc];
u8 reserved_at_20[0x10];
u8 temperature[0x10];
u8 mte[0x1];
u8 mtr[0x1];
u8 reserved_at_42[0xe];
u8 max_temperature[0x10];
u8 tee[0x2];
u8 reserved_at_62[0xe];
u8 temperature_threshold_hi[0x10];
u8 reserved_at_80[0x10];
u8 temperature_threshold_lo[0x10];
u8 reserved_at_a0[0x20];
u8 sensor_name_hi[0x20];
u8 sensor_name_lo[0x20];
};
#endif /* MLX5_IFC_H */