Commit 25f428f9 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mlxsw-line-card-prep'



Ido Schimmel says:

====================
mlxsw: Preparations for line cards support

Currently, mlxsw registers thermal zones as well as hwmon entries for
objects such as transceiver modules and gearboxes. In upcoming modular
systems, these objects are no longer found on the main board (i.e., slot
0), but on plug-able line cards. This patchset prepares mlxsw for such
systems in terms of hwmon, thermal and cable access support.

Patches #1-#3 gradually prepare mlxsw for transceiver modules access
support for line cards by splitting some of the internal structures and
some APIs.

Patches #4-#5 gradually prepare mlxsw for hwmon support for line cards
by splitting some of the internal structures and augmenting them with a
slot index.

Patches #6-#7 do the same for thermal zones.

Patch #8 selects cooling device for binding to a thermal zone by exact
name match to prevent binding to non-relevant devices.

Patch #9 replaces internal define for thermal zone name length with a
common define.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents be52d266 03978fb8
Loading
Loading
Loading
Loading
+314 −159

File changed.

Preview size limit exceeded, changes collapsed.

+26 −17
Original line number Diff line number Diff line
@@ -9,47 +9,56 @@
struct ethtool_modinfo;
struct ethtool_eeprom;

int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
					 int off, int *temp);
int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core,
					 u8 slot_index, int module, int off,
					 int *temp);

int mlxsw_env_get_module_info(struct net_device *netdev,
			      struct mlxsw_core *mlxsw_core, int module,
			      struct ethtool_modinfo *modinfo);
			      struct mlxsw_core *mlxsw_core, u8 slot_index,
			      int module, struct ethtool_modinfo *modinfo);

int mlxsw_env_get_module_eeprom(struct net_device *netdev,
				struct mlxsw_core *mlxsw_core, int module,
				struct ethtool_eeprom *ee, u8 *data);
				struct mlxsw_core *mlxsw_core, u8 slot_index,
				int module, struct ethtool_eeprom *ee,
				u8 *data);

int
mlxsw_env_get_module_eeprom_by_page(struct mlxsw_core *mlxsw_core, u8 module,
mlxsw_env_get_module_eeprom_by_page(struct mlxsw_core *mlxsw_core,
				    u8 slot_index, u8 module,
				    const struct ethtool_module_eeprom *page,
				    struct netlink_ext_ack *extack);

int mlxsw_env_reset_module(struct net_device *netdev,
			   struct mlxsw_core *mlxsw_core, u8 module,
			   u32 *flags);
			   struct mlxsw_core *mlxsw_core, u8 slot_index,
			   u8 module, u32 *flags);

int
mlxsw_env_get_module_power_mode(struct mlxsw_core *mlxsw_core, u8 module,
mlxsw_env_get_module_power_mode(struct mlxsw_core *mlxsw_core, u8 slot_index,
				u8 module,
				struct ethtool_module_power_mode_params *params,
				struct netlink_ext_ack *extack);

int
mlxsw_env_set_module_power_mode(struct mlxsw_core *mlxsw_core, u8 module,
mlxsw_env_set_module_power_mode(struct mlxsw_core *mlxsw_core, u8 slot_index,
				u8 module,
				enum ethtool_module_power_mode_policy policy,
				struct netlink_ext_ack *extack);

int
mlxsw_env_module_overheat_counter_get(struct mlxsw_core *mlxsw_core, u8 module,
				      u64 *p_counter);
mlxsw_env_module_overheat_counter_get(struct mlxsw_core *mlxsw_core, u8 slot_index,
				      u8 module, u64 *p_counter);

void mlxsw_env_module_port_map(struct mlxsw_core *mlxsw_core, u8 module);
void mlxsw_env_module_port_map(struct mlxsw_core *mlxsw_core, u8 slot_index,
			       u8 module);

void mlxsw_env_module_port_unmap(struct mlxsw_core *mlxsw_core, u8 module);
void mlxsw_env_module_port_unmap(struct mlxsw_core *mlxsw_core, u8 slot_index,
				 u8 module);

int mlxsw_env_module_port_up(struct mlxsw_core *mlxsw_core, u8 module);
int mlxsw_env_module_port_up(struct mlxsw_core *mlxsw_core, u8 slot_index,
			     u8 module);

void mlxsw_env_module_port_down(struct mlxsw_core *mlxsw_core, u8 module);
void mlxsw_env_module_port_down(struct mlxsw_core *mlxsw_core, u8 slot_index,
				u8 module);

int mlxsw_env_init(struct mlxsw_core *core, struct mlxsw_env **p_env);
void mlxsw_env_fini(struct mlxsw_env *env);
+132 −85
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@

struct mlxsw_hwmon_attr {
	struct device_attribute dev_attr;
	struct mlxsw_hwmon *hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev;
	unsigned int type_index;
	char name[32];
};
@@ -40,9 +40,8 @@ static int mlxsw_hwmon_get_attr_index(int index, int count)
	return index;
}

struct mlxsw_hwmon {
	struct mlxsw_core *core;
	const struct mlxsw_bus_info *bus_info;
struct mlxsw_hwmon_dev {
	struct mlxsw_hwmon *hwmon;
	struct device *hwmon_dev;
	struct attribute_group group;
	const struct attribute_group *groups[2];
@@ -51,6 +50,13 @@ struct mlxsw_hwmon {
	unsigned int attrs_count;
	u8 sensor_count;
	u8 module_sensor_max;
	u8 slot_index;
};

struct mlxsw_hwmon {
	struct mlxsw_core *core;
	const struct mlxsw_bus_info *bus_info;
	struct mlxsw_hwmon_dev line_cards[];
};

static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
@@ -59,14 +65,16 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char mtmp_pl[MLXSW_REG_MTMP_LEN];
	int temp, index;
	int err;

	index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
					   mlxsw_hwmon->module_sensor_max);
	mlxsw_reg_mtmp_pack(mtmp_pl, 0, index, false, false);
					   mlxsw_hwmon_dev->module_sensor_max);
	mlxsw_reg_mtmp_pack(mtmp_pl, mlxsw_hwmon_dev->slot_index, index, false,
			    false);
	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
	if (err) {
		dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
@@ -82,14 +90,16 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char mtmp_pl[MLXSW_REG_MTMP_LEN];
	int temp_max, index;
	int err;

	index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
					   mlxsw_hwmon->module_sensor_max);
	mlxsw_reg_mtmp_pack(mtmp_pl, 0, index, false, false);
					   mlxsw_hwmon_dev->module_sensor_max);
	mlxsw_reg_mtmp_pack(mtmp_pl, mlxsw_hwmon_dev->slot_index, index, false,
			    false);
	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
	if (err) {
		dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query temp sensor\n");
@@ -105,8 +115,9 @@ static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	char mtmp_pl[MLXSW_REG_MTMP_LEN] = {0};
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char mtmp_pl[MLXSW_REG_MTMP_LEN];
	unsigned long val;
	int index;
	int err;
@@ -118,8 +129,9 @@ static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
		return -EINVAL;

	index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
					   mlxsw_hwmon->module_sensor_max);
					   mlxsw_hwmon_dev->module_sensor_max);

	mlxsw_reg_mtmp_slot_index_set(mtmp_pl, mlxsw_hwmon_dev->slot_index);
	mlxsw_reg_mtmp_sensor_index_set(mtmp_pl, index);
	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
	if (err)
@@ -140,7 +152,8 @@ static ssize_t mlxsw_hwmon_fan_rpm_show(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char mfsm_pl[MLXSW_REG_MFSM_LEN];
	int err;

@@ -159,7 +172,8 @@ static ssize_t mlxsw_hwmon_fan_fault_show(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char fore_pl[MLXSW_REG_FORE_LEN];
	bool fault;
	int err;
@@ -180,7 +194,8 @@ static ssize_t mlxsw_hwmon_pwm_show(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char mfsc_pl[MLXSW_REG_MFSC_LEN];
	int err;

@@ -200,7 +215,8 @@ static ssize_t mlxsw_hwmon_pwm_store(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char mfsc_pl[MLXSW_REG_MFSC_LEN];
	unsigned long val;
	int err;
@@ -226,13 +242,14 @@ static int mlxsw_hwmon_module_temp_get(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char mtmp_pl[MLXSW_REG_MTMP_LEN];
	u8 module;
	int err;

	module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
	mlxsw_reg_mtmp_pack(mtmp_pl, 0,
	module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
	mlxsw_reg_mtmp_pack(mtmp_pl, mlxsw_hwmon_dev->slot_index,
			    MLXSW_REG_MTMP_MODULE_INDEX_MIN + module, false,
			    false);
	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
@@ -264,14 +281,15 @@ static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char mtbr_pl[MLXSW_REG_MTBR_LEN] = {0};
	u8 module, fault;
	u16 temp;
	int err;

	module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
	mlxsw_reg_mtbr_pack(mtbr_pl, 0,
	module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
	mlxsw_reg_mtbr_pack(mtbr_pl, mlxsw_hwmon_dev->slot_index,
			    MLXSW_REG_MTBR_BASE_MODULE_INDEX + module, 1);
	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtbr), mtbr_pl);
	if (err) {
@@ -306,13 +324,16 @@ static int mlxsw_hwmon_module_temp_critical_get(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	u8 module;
	int err;

	module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
	err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
						   SFP_TEMP_HIGH_WARN, p_temp);
	module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
	err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core,
						   mlxsw_hwmon_dev->slot_index,
						   module, SFP_TEMP_HIGH_WARN,
						   p_temp);
	if (err) {
		dev_err(dev, "Failed to query module temperature thresholds\n");
		return err;
@@ -340,13 +361,16 @@ static int mlxsw_hwmon_module_temp_emergency_get(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	u8 module;
	int err;

	module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
	err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
						   SFP_TEMP_HIGH_ALARM, p_temp);
	module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
	err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core,
						   mlxsw_hwmon_dev->slot_index,
						   module, SFP_TEMP_HIGH_ALARM,
						   p_temp);
	if (err) {
		dev_err(dev, "Failed to query module temperature thresholds\n");
		return err;
@@ -388,9 +412,9 @@ mlxsw_hwmon_gbox_temp_label_show(struct device *dev,
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
	struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
	int index = mlxsw_hwmon_attr->type_index -
		    mlxsw_hwmon->module_sensor_max + 1;
		    mlxsw_hwmon_dev->module_sensor_max + 1;

	return sprintf(buf, "gearbox %03u\n", index);
}
@@ -459,14 +483,15 @@ enum mlxsw_hwmon_attr_type {
	MLXSW_HWMON_ATTR_TYPE_TEMP_EMERGENCY_ALARM,
};

static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev,
				 enum mlxsw_hwmon_attr_type attr_type,
				 unsigned int type_index, unsigned int num) {
				 unsigned int type_index, unsigned int num)
{
	struct mlxsw_hwmon_attr *mlxsw_hwmon_attr;
	unsigned int attr_index;

	attr_index = mlxsw_hwmon->attrs_count;
	mlxsw_hwmon_attr = &mlxsw_hwmon->hwmon_attrs[attr_index];
	attr_index = mlxsw_hwmon_dev->attrs_count;
	mlxsw_hwmon_attr = &mlxsw_hwmon_dev->hwmon_attrs[attr_index];

	switch (attr_type) {
	case MLXSW_HWMON_ATTR_TYPE_TEMP:
@@ -566,16 +591,17 @@ static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
	}

	mlxsw_hwmon_attr->type_index = type_index;
	mlxsw_hwmon_attr->hwmon = mlxsw_hwmon;
	mlxsw_hwmon_attr->mlxsw_hwmon_dev = mlxsw_hwmon_dev;
	mlxsw_hwmon_attr->dev_attr.attr.name = mlxsw_hwmon_attr->name;
	sysfs_attr_init(&mlxsw_hwmon_attr->dev_attr.attr);

	mlxsw_hwmon->attrs[attr_index] = &mlxsw_hwmon_attr->dev_attr.attr;
	mlxsw_hwmon->attrs_count++;
	mlxsw_hwmon_dev->attrs[attr_index] = &mlxsw_hwmon_attr->dev_attr.attr;
	mlxsw_hwmon_dev->attrs_count++;
}

static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon)
static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev)
{
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char mtcap_pl[MLXSW_REG_MTCAP_LEN] = {0};
	int i;
	int err;
@@ -585,10 +611,12 @@ static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon)
		dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get number of temp sensors\n");
		return err;
	}
	mlxsw_hwmon->sensor_count = mlxsw_reg_mtcap_sensor_count_get(mtcap_pl);
	for (i = 0; i < mlxsw_hwmon->sensor_count; i++) {
	mlxsw_hwmon_dev->sensor_count = mlxsw_reg_mtcap_sensor_count_get(mtcap_pl);
	for (i = 0; i < mlxsw_hwmon_dev->sensor_count; i++) {
		char mtmp_pl[MLXSW_REG_MTMP_LEN] = {0};

		mlxsw_reg_mtmp_slot_index_set(mtmp_pl,
					      mlxsw_hwmon_dev->slot_index);
		mlxsw_reg_mtmp_sensor_index_set(mtmp_pl, i);
		err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp),
				      mtmp_pl);
@@ -603,18 +631,19 @@ static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon)
				i);
			return err;
		}
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP, i, i);
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_MAX, i, i);
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_RST, i, i);
	}
	return 0;
}

static int mlxsw_hwmon_fans_init(struct mlxsw_hwmon *mlxsw_hwmon)
static int mlxsw_hwmon_fans_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev)
{
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char mfcr_pl[MLXSW_REG_MFCR_LEN] = {0};
	enum mlxsw_reg_mfcr_pwm_frequency freq;
	unsigned int type_index;
@@ -632,10 +661,10 @@ static int mlxsw_hwmon_fans_init(struct mlxsw_hwmon *mlxsw_hwmon)
	num = 0;
	for (type_index = 0; type_index < MLXSW_MFCR_TACHOS_MAX; type_index++) {
		if (tacho_active & BIT(type_index)) {
			mlxsw_hwmon_attr_add(mlxsw_hwmon,
			mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
					     MLXSW_HWMON_ATTR_TYPE_FAN_RPM,
					     type_index, num);
			mlxsw_hwmon_attr_add(mlxsw_hwmon,
			mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
					     MLXSW_HWMON_ATTR_TYPE_FAN_FAULT,
					     type_index, num++);
		}
@@ -643,20 +672,21 @@ static int mlxsw_hwmon_fans_init(struct mlxsw_hwmon *mlxsw_hwmon)
	num = 0;
	for (type_index = 0; type_index < MLXSW_MFCR_PWMS_MAX; type_index++) {
		if (pwm_active & BIT(type_index))
			mlxsw_hwmon_attr_add(mlxsw_hwmon,
			mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
					     MLXSW_HWMON_ATTR_TYPE_PWM,
					     type_index, num++);
	}
	return 0;
}

static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
static int mlxsw_hwmon_module_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev)
{
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	char mgpir_pl[MLXSW_REG_MGPIR_LEN];
	u8 module_sensor_max;
	int i, err;

	mlxsw_reg_mgpir_pack(mgpir_pl, 0);
	mlxsw_reg_mgpir_pack(mgpir_pl, mlxsw_hwmon_dev->slot_index);
	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
	if (err)
		return err;
@@ -669,28 +699,28 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
	 * sensor_count are already utilized by the sensors connected through
	 * mtmp register by mlxsw_hwmon_temp_init().
	 */
	mlxsw_hwmon->module_sensor_max = mlxsw_hwmon->sensor_count +
	mlxsw_hwmon_dev->module_sensor_max = mlxsw_hwmon_dev->sensor_count +
					     module_sensor_max;
	for (i = mlxsw_hwmon->sensor_count;
	     i < mlxsw_hwmon->module_sensor_max; i++) {
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
	for (i = mlxsw_hwmon_dev->sensor_count;
	     i < mlxsw_hwmon_dev->module_sensor_max; i++) {
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE, i, i);
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_FAULT,
				     i, i);
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT, i,
				     i);
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
				     i, i);
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
				     i, i);
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_CRIT_ALARM,
				     i, i);
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_EMERGENCY_ALARM,
				     i, i);
	}
@@ -698,8 +728,9 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
	return 0;
}

static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev)
{
	struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
	enum mlxsw_reg_mgpir_device_type device_type;
	int index, max_index, sensor_index;
	char mgpir_pl[MLXSW_REG_MGPIR_LEN];
@@ -707,7 +738,7 @@ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
	u8 gbox_num;
	int err;

	mlxsw_reg_mgpir_pack(mgpir_pl, 0);
	mlxsw_reg_mgpir_pack(mgpir_pl, mlxsw_hwmon_dev->slot_index);
	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
	if (err)
		return err;
@@ -718,12 +749,13 @@ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
	    !gbox_num)
		return 0;

	index = mlxsw_hwmon->module_sensor_max;
	max_index = mlxsw_hwmon->module_sensor_max + gbox_num;
	index = mlxsw_hwmon_dev->module_sensor_max;
	max_index = mlxsw_hwmon_dev->module_sensor_max + gbox_num;
	while (index < max_index) {
		sensor_index = index % mlxsw_hwmon->module_sensor_max +
		sensor_index = index % mlxsw_hwmon_dev->module_sensor_max +
			       MLXSW_REG_MTMP_GBOX_INDEX_MIN;
		mlxsw_reg_mtmp_pack(mtmp_pl, 0, sensor_index, true, true);
		mlxsw_reg_mtmp_pack(mtmp_pl, mlxsw_hwmon_dev->slot_index,
				    sensor_index, true, true);
		err = mlxsw_reg_write(mlxsw_hwmon->core,
				      MLXSW_REG(mtmp), mtmp_pl);
		if (err) {
@@ -731,15 +763,15 @@ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
				sensor_index);
			return err;
		}
		mlxsw_hwmon_attr_add(mlxsw_hwmon, MLXSW_HWMON_ATTR_TYPE_TEMP,
				     index, index);
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP, index, index);
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_MAX, index,
				     index);
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_RST, index,
				     index);
		mlxsw_hwmon_attr_add(mlxsw_hwmon,
		mlxsw_hwmon_attr_add(mlxsw_hwmon_dev,
				     MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL,
				     index, index);
		index++;
@@ -752,44 +784,59 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
		     const struct mlxsw_bus_info *mlxsw_bus_info,
		     struct mlxsw_hwmon **p_hwmon)
{
	char mgpir_pl[MLXSW_REG_MGPIR_LEN];
	struct mlxsw_hwmon *mlxsw_hwmon;
	struct device *hwmon_dev;
	u8 num_of_slots;
	int err;

	mlxsw_hwmon = kzalloc(sizeof(*mlxsw_hwmon), GFP_KERNEL);
	mlxsw_reg_mgpir_pack(mgpir_pl, 0);
	err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mgpir), mgpir_pl);
	if (err)
		return err;

	mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, NULL,
			       &num_of_slots);

	mlxsw_hwmon = kzalloc(struct_size(mlxsw_hwmon, line_cards,
					  num_of_slots + 1), GFP_KERNEL);
	if (!mlxsw_hwmon)
		return -ENOMEM;

	mlxsw_hwmon->core = mlxsw_core;
	mlxsw_hwmon->bus_info = mlxsw_bus_info;
	mlxsw_hwmon->line_cards[0].hwmon = mlxsw_hwmon;
	mlxsw_hwmon->line_cards[0].slot_index = 0;

	err = mlxsw_hwmon_temp_init(mlxsw_hwmon);
	err = mlxsw_hwmon_temp_init(&mlxsw_hwmon->line_cards[0]);
	if (err)
		goto err_temp_init;

	err = mlxsw_hwmon_fans_init(mlxsw_hwmon);
	err = mlxsw_hwmon_fans_init(&mlxsw_hwmon->line_cards[0]);
	if (err)
		goto err_fans_init;

	err = mlxsw_hwmon_module_init(mlxsw_hwmon);
	err = mlxsw_hwmon_module_init(&mlxsw_hwmon->line_cards[0]);
	if (err)
		goto err_temp_module_init;

	err = mlxsw_hwmon_gearbox_init(mlxsw_hwmon);
	err = mlxsw_hwmon_gearbox_init(&mlxsw_hwmon->line_cards[0]);
	if (err)
		goto err_temp_gearbox_init;

	mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
	mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
	mlxsw_hwmon->line_cards[0].groups[0] = &mlxsw_hwmon->line_cards[0].group;
	mlxsw_hwmon->line_cards[0].group.attrs = mlxsw_hwmon->line_cards[0].attrs;

	hwmon_dev = hwmon_device_register_with_groups(mlxsw_bus_info->dev,
						      "mlxsw", mlxsw_hwmon,
						      mlxsw_hwmon->groups);
						      "mlxsw",
						      &mlxsw_hwmon->line_cards[0],
						      mlxsw_hwmon->line_cards[0].groups);
	if (IS_ERR(hwmon_dev)) {
		err = PTR_ERR(hwmon_dev);
		goto err_hwmon_register;
	}

	mlxsw_hwmon->hwmon_dev = hwmon_dev;
	mlxsw_hwmon->line_cards[0].hwmon_dev = hwmon_dev;
	*p_hwmon = mlxsw_hwmon;
	return 0;

@@ -804,6 +851,6 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,

void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
{
	hwmon_device_unregister(mlxsw_hwmon->hwmon_dev);
	hwmon_device_unregister(mlxsw_hwmon->line_cards[0].hwmon_dev);
	kfree(mlxsw_hwmon);
}
+106 −66

File changed.

Preview size limit exceeded, changes collapsed.

+13 −11
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ static int mlxsw_m_port_open(struct net_device *dev)
	struct mlxsw_m_port *mlxsw_m_port = netdev_priv(dev);
	struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m;

	return mlxsw_env_module_port_up(mlxsw_m->core, mlxsw_m_port->module);
	return mlxsw_env_module_port_up(mlxsw_m->core, 0,
					mlxsw_m_port->module);
}

static int mlxsw_m_port_stop(struct net_device *dev)
@@ -67,7 +68,7 @@ static int mlxsw_m_port_stop(struct net_device *dev)
	struct mlxsw_m_port *mlxsw_m_port = netdev_priv(dev);
	struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m;

	mlxsw_env_module_port_down(mlxsw_m->core, mlxsw_m_port->module);
	mlxsw_env_module_port_down(mlxsw_m->core, 0, mlxsw_m_port->module);
	return 0;
}

@@ -110,7 +111,7 @@ static int mlxsw_m_get_module_info(struct net_device *netdev,
	struct mlxsw_m_port *mlxsw_m_port = netdev_priv(netdev);
	struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;

	return mlxsw_env_get_module_info(netdev, core, mlxsw_m_port->module,
	return mlxsw_env_get_module_info(netdev, core, 0, mlxsw_m_port->module,
					 modinfo);
}

@@ -121,8 +122,8 @@ mlxsw_m_get_module_eeprom(struct net_device *netdev, struct ethtool_eeprom *ee,
	struct mlxsw_m_port *mlxsw_m_port = netdev_priv(netdev);
	struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;

	return mlxsw_env_get_module_eeprom(netdev, core, mlxsw_m_port->module,
					   ee, data);
	return mlxsw_env_get_module_eeprom(netdev, core, 0,
					   mlxsw_m_port->module, ee, data);
}

static int
@@ -133,7 +134,8 @@ mlxsw_m_get_module_eeprom_by_page(struct net_device *netdev,
	struct mlxsw_m_port *mlxsw_m_port = netdev_priv(netdev);
	struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;

	return mlxsw_env_get_module_eeprom_by_page(core, mlxsw_m_port->module,
	return mlxsw_env_get_module_eeprom_by_page(core, 0,
						   mlxsw_m_port->module,
						   page, extack);
}

@@ -142,7 +144,7 @@ static int mlxsw_m_reset(struct net_device *netdev, u32 *flags)
	struct mlxsw_m_port *mlxsw_m_port = netdev_priv(netdev);
	struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;

	return mlxsw_env_reset_module(netdev, core, mlxsw_m_port->module,
	return mlxsw_env_reset_module(netdev, core, 0, mlxsw_m_port->module,
				      flags);
}

@@ -154,7 +156,7 @@ mlxsw_m_get_module_power_mode(struct net_device *netdev,
	struct mlxsw_m_port *mlxsw_m_port = netdev_priv(netdev);
	struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;

	return mlxsw_env_get_module_power_mode(core, mlxsw_m_port->module,
	return mlxsw_env_get_module_power_mode(core, 0, mlxsw_m_port->module,
					       params, extack);
}

@@ -166,7 +168,7 @@ mlxsw_m_set_module_power_mode(struct net_device *netdev,
	struct mlxsw_m_port *mlxsw_m_port = netdev_priv(netdev);
	struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;

	return mlxsw_env_set_module_power_mode(core, mlxsw_m_port->module,
	return mlxsw_env_set_module_power_mode(core, 0, mlxsw_m_port->module,
					       params->policy, extack);
}

@@ -311,7 +313,7 @@ static int mlxsw_m_port_module_map(struct mlxsw_m *mlxsw_m, u16 local_port,

	if (WARN_ON_ONCE(module >= max_ports))
		return -EINVAL;
	mlxsw_env_module_port_map(mlxsw_m->core, module);
	mlxsw_env_module_port_map(mlxsw_m->core, 0, module);
	mlxsw_m->module_to_port[module] = ++mlxsw_m->max_ports;

	return 0;
@@ -320,7 +322,7 @@ static int mlxsw_m_port_module_map(struct mlxsw_m *mlxsw_m, u16 local_port,
static void mlxsw_m_port_module_unmap(struct mlxsw_m *mlxsw_m, u8 module)
{
	mlxsw_m->module_to_port[module] = -1;
	mlxsw_env_module_port_unmap(mlxsw_m->core, module);
	mlxsw_env_module_port_unmap(mlxsw_m->core, 0, module);
}

static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)
Loading