public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [patch net-next v2 0/6] mlxsw: driver update
@ 2015-11-27 12:45 Jiri Pirko
  2015-11-27 12:45 ` [patch net-next v2 1/6] mlxsw: reg: Add Management LED Control register definition Jiri Pirko
                   ` (6 more replies)
  0 siblings, 7 replies; 18+ messages in thread
From: Jiri Pirko @ 2015-11-27 12:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg

From: Jiri Pirko <jiri@mellanox.com>

This patchset carries support for port identification, monitoring
of ASIC temperature and board fans.

Ido Schimmel (2):
  mlxsw: reg: Add Management LED Control register definition
  mlxsw: spectrum: Add support for port identification

Jiri Pirko (4):
  mlxsw: reg: Add definition of temperature management registers
  mlxsw: core: Implement temperature hwmon interface
  mlxsw: reg: Add definition of fan management registers
  mlxsw: core: Implement fan control using hwmon

 drivers/net/ethernet/mellanox/mlxsw/Kconfig      |   8 +
 drivers/net/ethernet/mellanox/mlxsw/Makefile     |   1 +
 drivers/net/ethernet/mellanox/mlxsw/core.c       |   8 +
 drivers/net/ethernet/mellanox/mlxsw/core.h       |  24 ++
 drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 342 +++++++++++++++++++++++
 drivers/net/ethernet/mellanox/mlxsw/reg.h        | 290 +++++++++++++++++++
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c   |  24 ++
 7 files changed, 697 insertions(+)
 create mode 100644 drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c

-- 
1.9.3

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [patch net-next v2 1/6] mlxsw: reg: Add Management LED Control register definition
  2015-11-27 12:45 [patch net-next v2 0/6] mlxsw: driver update Jiri Pirko
@ 2015-11-27 12:45 ` Jiri Pirko
  2015-11-27 12:45 ` [patch net-next v2 2/6] mlxsw: spectrum: Add support for port identification Jiri Pirko
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 18+ messages in thread
From: Jiri Pirko @ 2015-11-27 12:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg

From: Ido Schimmel <idosch@mellanox.com>

Add the MLCR register, which controls physical port identification LEDs.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h | 46 +++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 236fb5d..fc6839d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -2087,6 +2087,50 @@ static inline void mlxsw_reg_hpkt_pack(char *payload, u8 action, u16 trap_id)
 	mlxsw_reg_hpkt_ctrl_set(payload, MLXSW_REG_HPKT_CTRL_PACKET_DEFAULT);
 }
 
+/* MLCR - Management LED Control Register
+ * --------------------------------------
+ * Controls the system LEDs.
+ */
+#define MLXSW_REG_MLCR_ID 0x902B
+#define MLXSW_REG_MLCR_LEN 0x0C
+
+static const struct mlxsw_reg_info mlxsw_reg_mlcr = {
+	.id = MLXSW_REG_MLCR_ID,
+	.len = MLXSW_REG_MLCR_LEN,
+};
+
+/* reg_mlcr_local_port
+ * Local port number.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mlcr, local_port, 0x00, 16, 8);
+
+#define MLXSW_REG_MLCR_DURATION_MAX 0xFFFF
+
+/* reg_mlcr_beacon_duration
+ * Duration of the beacon to be active, in seconds.
+ * 0x0 - Will turn off the beacon.
+ * 0xFFFF - Will turn on the beacon until explicitly turned off.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mlcr, beacon_duration, 0x04, 0, 16);
+
+/* reg_mlcr_beacon_remain
+ * Remaining duration of the beacon, in seconds.
+ * 0xFFFF indicates an infinite amount of time.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mlcr, beacon_remain, 0x08, 0, 16);
+
+static inline void mlxsw_reg_mlcr_pack(char *payload, u8 local_port,
+				       bool active)
+{
+	MLXSW_REG_ZERO(mlcr, payload);
+	mlxsw_reg_mlcr_local_port_set(payload, local_port);
+	mlxsw_reg_mlcr_beacon_duration_set(payload, active ?
+					   MLXSW_REG_MLCR_DURATION_MAX : 0);
+}
+
 /* SBPR - Shared Buffer Pools Register
  * -----------------------------------
  * The SBPR configures and retrieves the shared buffer pools and configuration.
@@ -2405,6 +2449,8 @@ static inline const char *mlxsw_reg_id_str(u16 reg_id)
 		return "HTGT";
 	case MLXSW_REG_HPKT_ID:
 		return "HPKT";
+	case MLXSW_REG_MLCR_ID:
+		return "MLCR";
 	case MLXSW_REG_SBPR_ID:
 		return "SBPR";
 	case MLXSW_REG_SBCM_ID:
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [patch net-next v2 2/6] mlxsw: spectrum: Add support for port identification
  2015-11-27 12:45 [patch net-next v2 0/6] mlxsw: driver update Jiri Pirko
  2015-11-27 12:45 ` [patch net-next v2 1/6] mlxsw: reg: Add Management LED Control register definition Jiri Pirko
@ 2015-11-27 12:45 ` Jiri Pirko
  2015-11-27 12:45 ` [patch net-next v2 3/6] mlxsw: reg: Add definition of temperature management registers Jiri Pirko
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 18+ messages in thread
From: Jiri Pirko @ 2015-11-27 12:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg

From: Ido Schimmel <idosch@mellanox.com>

Allow a user to flash the port's LED in order to identify it. This is
achieved by setting the Management LED Control Register (MLCR).

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 3be4a23..14a9a9f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -859,6 +859,29 @@ static void mlxsw_sp_port_get_strings(struct net_device *dev,
 	}
 }
 
+static int mlxsw_sp_port_set_phys_id(struct net_device *dev,
+				     enum ethtool_phys_id_state state)
+{
+	struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
+	struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
+	char mlcr_pl[MLXSW_REG_MLCR_LEN];
+	bool active;
+
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		active = true;
+		break;
+	case ETHTOOL_ID_INACTIVE:
+		active = false;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	mlxsw_reg_mlcr_pack(mlcr_pl, mlxsw_sp_port->local_port, active);
+	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mlcr), mlcr_pl);
+}
+
 static void mlxsw_sp_port_get_stats(struct net_device *dev,
 				    struct ethtool_stats *stats, u64 *data)
 {
@@ -1205,6 +1228,7 @@ static const struct ethtool_ops mlxsw_sp_port_ethtool_ops = {
 	.get_drvinfo		= mlxsw_sp_port_get_drvinfo,
 	.get_link		= ethtool_op_get_link,
 	.get_strings		= mlxsw_sp_port_get_strings,
+	.set_phys_id		= mlxsw_sp_port_set_phys_id,
 	.get_ethtool_stats	= mlxsw_sp_port_get_stats,
 	.get_sset_count		= mlxsw_sp_port_get_sset_count,
 	.get_settings		= mlxsw_sp_port_get_settings,
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [patch net-next v2 3/6] mlxsw: reg: Add definition of temperature management registers
  2015-11-27 12:45 [patch net-next v2 0/6] mlxsw: driver update Jiri Pirko
  2015-11-27 12:45 ` [patch net-next v2 1/6] mlxsw: reg: Add Management LED Control register definition Jiri Pirko
  2015-11-27 12:45 ` [patch net-next v2 2/6] mlxsw: spectrum: Add support for port identification Jiri Pirko
@ 2015-11-27 12:45 ` Jiri Pirko
  2015-11-27 12:45 ` [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface Jiri Pirko
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 18+ messages in thread
From: Jiri Pirko @ 2015-11-27 12:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg

From: Jiri Pirko <jiri@mellanox.com>

Add definition of MTCAP and MTMP registers which provide access to
temperature sensors.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h | 111 ++++++++++++++++++++++++++++++
 1 file changed, 111 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index fc6839d..459e0490 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -2087,6 +2087,113 @@ static inline void mlxsw_reg_hpkt_pack(char *payload, u8 action, u16 trap_id)
 	mlxsw_reg_hpkt_ctrl_set(payload, MLXSW_REG_HPKT_CTRL_PACKET_DEFAULT);
 }
 
+/* MTCAP - Management Temperature Capabilities
+ * -------------------------------------------
+ * This register exposes the capabilities of the device and
+ * system temperature sensing.
+ */
+#define MLXSW_REG_MTCAP_ID 0x9009
+#define MLXSW_REG_MTCAP_LEN 0x08
+
+static const struct mlxsw_reg_info mlxsw_reg_mtcap = {
+	.id = MLXSW_REG_MTCAP_ID,
+	.len = MLXSW_REG_MTCAP_LEN,
+};
+
+/* reg_mtcap_sensor_count
+ * Number of sensors supported by the device.
+ * This includes the QSFP module sensors (if exists in the QSFP module).
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mtcap, sensor_count, 0x00, 0, 7);
+
+/* MTMP - Management Temperature
+ * -----------------------------
+ * This register controls the settings of the temperature measurements
+ * and enables reading the temperature measurements. Note that temperature
+ * is in 0.125 degrees Celsius.
+ */
+#define MLXSW_REG_MTMP_ID 0x900A
+#define MLXSW_REG_MTMP_LEN 0x20
+
+static const struct mlxsw_reg_info mlxsw_reg_mtmp = {
+	.id = MLXSW_REG_MTMP_ID,
+	.len = MLXSW_REG_MTMP_LEN,
+};
+
+/* reg_mtmp_sensor_index
+ * Sensors index to access.
+ * 64-127 of sensor_index are mapped to the SFP+/QSFP modules sequentially
+ * (module 0 is mapped to sensor_index 64).
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, mtmp, sensor_index, 0x00, 0, 7);
+
+/* Convert to milli degrees Celsius */
+#define MLXSW_REG_MTMP_TEMP_TO_MC(val) (val * 125)
+
+/* reg_mtmp_temperature
+ * Temperature reading from the sensor. Reading is in 0.125 Celsius
+ * degrees units.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mtmp, temperature, 0x04, 0, 16);
+
+/* reg_mtmp_mte
+ * Max Temperature Enable - enables measuring the max temperature on a sensor.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mtmp, mte, 0x08, 31, 1);
+
+/* reg_mtmp_mtr
+ * Max Temperature Reset - clears the value of the max temperature register.
+ * Access: WO
+ */
+MLXSW_ITEM32(reg, mtmp, mtr, 0x08, 30, 1);
+
+/* reg_mtmp_max_temperature
+ * The highest measured temperature from the sensor.
+ * When the bit mte is cleared, the field max_temperature is reserved.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mtmp, max_temperature, 0x08, 0, 16);
+
+#define MLXSW_REG_MTMP_SENSOR_NAME_SIZE 8
+
+/* reg_mtmp_sensor_name
+ * Sensor Name
+ * Access: RO
+ */
+MLXSW_ITEM_BUF(reg, mtmp, sensor_name, 0x18, MLXSW_REG_MTMP_SENSOR_NAME_SIZE);
+
+static inline void mlxsw_reg_mtmp_pack(char *payload, u8 sensor_index,
+				       bool max_temp_enable,
+				       bool max_temp_reset)
+{
+	MLXSW_REG_ZERO(mtmp, payload);
+	mlxsw_reg_mtmp_sensor_index_set(payload, sensor_index);
+	mlxsw_reg_mtmp_mte_set(payload, max_temp_enable);
+	mlxsw_reg_mtmp_mtr_set(payload, max_temp_reset);
+}
+
+static inline void mlxsw_reg_mtmp_unpack(char *payload, unsigned int *p_temp,
+					 unsigned int *p_max_temp,
+					 char *sensor_name)
+{
+	u16 temp;
+
+	if (p_temp) {
+		temp = mlxsw_reg_mtmp_temperature_get(payload);
+		*p_temp = MLXSW_REG_MTMP_TEMP_TO_MC(temp);
+	}
+	if (p_max_temp) {
+		temp = mlxsw_reg_mtmp_temperature_get(payload);
+		*p_max_temp = MLXSW_REG_MTMP_TEMP_TO_MC(temp);
+	}
+	if (sensor_name)
+		mlxsw_reg_mtmp_sensor_name_memcpy_from(payload, sensor_name);
+}
+
 /* MLCR - Management LED Control Register
  * --------------------------------------
  * Controls the system LEDs.
@@ -2449,6 +2556,10 @@ static inline const char *mlxsw_reg_id_str(u16 reg_id)
 		return "HTGT";
 	case MLXSW_REG_HPKT_ID:
 		return "HPKT";
+	case MLXSW_REG_MTCAP_ID:
+		return "MTCAP";
+	case MLXSW_REG_MTMP_ID:
+		return "MTMP";
 	case MLXSW_REG_MLCR_ID:
 		return "MLCR";
 	case MLXSW_REG_SBPR_ID:
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface
  2015-11-27 12:45 [patch net-next v2 0/6] mlxsw: driver update Jiri Pirko
                   ` (2 preceding siblings ...)
  2015-11-27 12:45 ` [patch net-next v2 3/6] mlxsw: reg: Add definition of temperature management registers Jiri Pirko
@ 2015-11-27 12:45 ` Jiri Pirko
  2015-11-29  9:04   ` Or Gerlitz
  2015-11-27 12:45 ` [patch net-next v2 5/6] mlxsw: reg: Add definition of fan management registers Jiri Pirko
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Jiri Pirko @ 2015-11-27 12:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg

From: Jiri Pirko <jiri@mellanox.com>

ASIC provides access to temperature sensors. Implement their exposure to
userspace using hwmon.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
v1->v2:
- fixed hwmon compile error when it is not set reported by lkp@intel.com
---
 drivers/net/ethernet/mellanox/mlxsw/Kconfig      |   8 +
 drivers/net/ethernet/mellanox/mlxsw/Makefile     |   1 +
 drivers/net/ethernet/mellanox/mlxsw/core.c       |   8 +
 drivers/net/ethernet/mellanox/mlxsw/core.h       |  24 +++
 drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 223 +++++++++++++++++++++++
 5 files changed, 264 insertions(+)
 create mode 100644 drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c

diff --git a/drivers/net/ethernet/mellanox/mlxsw/Kconfig b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
index e36e122..ec8caf8 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
@@ -10,6 +10,14 @@ config MLXSW_CORE
 	  To compile this driver as a module, choose M here: the
 	  module will be called mlxsw_core.
 
+config MLXSW_CORE_HWMON
+	bool "HWMON support for Mellanox Technologies Switch ASICs"
+	depends on MLXSW_CORE && HWMON
+	depends on !(MLXSW_CORE=y && HWMON=m)
+	default y
+	---help---
+	  Say Y here if you want to expose HWMON interface on mlxsw devices.
+
 config MLXSW_PCI
 	tristate "PCI bus implementation for Mellanox Technologies Switch ASICs"
 	depends on PCI && HAS_DMA && HAS_IOMEM && MLXSW_CORE
diff --git a/drivers/net/ethernet/mellanox/mlxsw/Makefile b/drivers/net/ethernet/mellanox/mlxsw/Makefile
index af01581..584cac4 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/Makefile
+++ b/drivers/net/ethernet/mellanox/mlxsw/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_MLXSW_CORE)	+= mlxsw_core.o
 mlxsw_core-objs			:= core.o
+mlxsw_core-$(CONFIG_MLXSW_CORE_HWMON) += core_hwmon.o
 obj-$(CONFIG_MLXSW_PCI)		+= mlxsw_pci.o
 mlxsw_pci-objs			:= pci.o
 obj-$(CONFIG_MLXSW_SWITCHX2)	+= mlxsw_switchx2.o
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index 97f0d93..1ecb4aa 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -105,6 +105,7 @@ struct mlxsw_core {
 		struct debugfs_blob_wrapper vsd_blob;
 		struct debugfs_blob_wrapper psid_blob;
 	} dbg;
+	struct mlxsw_hwmon *hwmon;
 	unsigned long driver_priv[0];
 	/* driver_priv has to be always the last item */
 };
@@ -822,6 +823,10 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
 	if (err)
 		goto err_emad_init;
 
+	err = mlxsw_hwmon_init(mlxsw_core, mlxsw_bus_info, &mlxsw_core->hwmon);
+	if (err)
+		goto err_hwmon_init;
+
 	err = mlxsw_driver->init(mlxsw_core->driver_priv, mlxsw_core,
 				 mlxsw_bus_info);
 	if (err)
@@ -836,6 +841,8 @@ int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
 err_debugfs_init:
 	mlxsw_core->driver->fini(mlxsw_core->driver_priv);
 err_driver_init:
+	mlxsw_hwmon_fini(mlxsw_core->hwmon);
+err_hwmon_init:
 	mlxsw_emad_fini(mlxsw_core);
 err_emad_init:
 	mlxsw_bus->fini(bus_priv);
@@ -855,6 +862,7 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core)
 
 	mlxsw_core_debugfs_fini(mlxsw_core);
 	mlxsw_core->driver->fini(mlxsw_core->driver_priv);
+	mlxsw_hwmon_fini(mlxsw_core->hwmon);
 	mlxsw_emad_fini(mlxsw_core);
 	mlxsw_core->bus->fini(mlxsw_core->bus_priv);
 	free_percpu(mlxsw_core->pcpu_stats);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index 8078273..5ac9529 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -209,4 +209,28 @@ struct mlxsw_bus_info {
 	u8 psid[MLXSW_CMD_BOARDINFO_PSID_LEN];
 };
 
+struct mlxsw_hwmon;
+
+#ifdef CONFIG_MLXSW_CORE_HWMON
+
+int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
+		     const struct mlxsw_bus_info *mlxsw_bus_info,
+		     struct mlxsw_hwmon **p_hwmon);
+void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon);
+
+#else
+
+static inline int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
+				   const struct mlxsw_bus_info *mlxsw_bus_info,
+				   struct mlxsw_hwmon **p_hwmon)
+{
+	return 0;
+}
+
+static inline void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
+{
+}
+
+#endif
+
 #endif
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
new file mode 100644
index 0000000..ec48c28
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
@@ -0,0 +1,223 @@
+/*
+ * drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+ * Copyright (c) 2015 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2015 Jiri Pirko <jiri@mellanox.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the names of the copyright holders nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon.h>
+#include <linux/err.h>
+
+#include "core.h"
+
+#define MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT 127
+#define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT * 4)
+
+struct mlxsw_hwmon_attr {
+	struct device_attribute dev_attr;
+	struct mlxsw_hwmon *hwmon;
+	unsigned int type_index;
+	char name[16];
+};
+
+struct mlxsw_hwmon {
+	struct mlxsw_core *core;
+	const struct mlxsw_bus_info *bus_info;
+	struct device *hwmon_dev;
+	struct attribute_group group;
+	const struct attribute_group *groups[2];
+	struct attribute *attrs[MLXSW_HWMON_ATTR_COUNT + 1];
+	struct mlxsw_hwmon_attr hwmon_attrs[MLXSW_HWMON_ATTR_COUNT];
+	unsigned int attrs_count;
+};
+
+static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
+				     struct device_attribute *attr,
+				     char *buf)
+{
+	struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
+			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
+	struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
+	char mtmp_pl[MLXSW_REG_MTMP_LEN];
+	unsigned int temp;
+	int err;
+
+	mlxsw_reg_mtmp_pack(mtmp_pl, mlwsw_hwmon_attr->type_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");
+		return err;
+	}
+	mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
+	return sprintf(buf, "%u\n", temp);
+}
+
+static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
+			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
+	struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
+	char mtmp_pl[MLXSW_REG_MTMP_LEN];
+	unsigned int temp_max;
+	int err;
+
+	mlxsw_reg_mtmp_pack(mtmp_pl, mlwsw_hwmon_attr->type_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");
+		return err;
+	}
+	mlxsw_reg_mtmp_unpack(mtmp_pl, NULL, &temp_max, NULL);
+	return sprintf(buf, "%u\n", temp_max);
+}
+
+enum mlxsw_hwmon_attr_type {
+	MLXSW_HWMON_ATTR_TYPE_TEMP,
+	MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
+};
+
+static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
+				 enum mlxsw_hwmon_attr_type attr_type,
+				 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];
+
+	switch (attr_type) {
+	case MLXSW_HWMON_ATTR_TYPE_TEMP:
+		mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_show;
+		mlxsw_hwmon_attr->dev_attr.attr.mode = S_IRUGO;
+		snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
+			 "temp%u_input", num + 1);
+		break;
+	case MLXSW_HWMON_ATTR_TYPE_TEMP_MAX:
+		mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_max_show;
+		mlxsw_hwmon_attr->dev_attr.attr.mode = S_IRUGO;
+		snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
+			 "temp%u_highest", num + 1);
+		break;
+	default:
+		BUG();
+	}
+
+	mlxsw_hwmon_attr->type_index = type_index;
+	mlxsw_hwmon_attr->hwmon = mlxsw_hwmon;
+	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++;
+}
+
+static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon)
+{
+	char mtcap_pl[MLXSW_REG_MTCAP_LEN];
+	char mtmp_pl[MLXSW_REG_MTMP_LEN];
+	u8 sensor_count;
+	int i;
+	int err;
+
+	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtcap), mtcap_pl);
+	if (err) {
+		dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get number of temp sensors\n");
+		return err;
+	}
+	sensor_count = mlxsw_reg_mtcap_sensor_count_get(mtcap_pl);
+	for (i = 0; i < sensor_count; i++) {
+		mlxsw_reg_mtmp_pack(mtmp_pl, 0, true, true);
+		err = mlxsw_reg_write(mlxsw_hwmon->core,
+				      MLXSW_REG(mtmp), mtmp_pl);
+		if (err) {
+			dev_err(mlxsw_hwmon->bus_info->dev, "Failed to setup temp sensor number %d\n",
+				i);
+			return err;
+		}
+		mlxsw_hwmon_attr_add(mlxsw_hwmon,
+				     MLXSW_HWMON_ATTR_TYPE_TEMP, i, i);
+		mlxsw_hwmon_attr_add(mlxsw_hwmon,
+				     MLXSW_HWMON_ATTR_TYPE_TEMP_MAX, i, i);
+	}
+	return 0;
+}
+
+int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
+		     const struct mlxsw_bus_info *mlxsw_bus_info,
+		     struct mlxsw_hwmon **p_hwmon)
+{
+	struct mlxsw_hwmon *mlxsw_hwmon;
+	struct device *hwmon_dev;
+	int err;
+
+	mlxsw_hwmon = kzalloc(sizeof(*mlxsw_hwmon), GFP_KERNEL);
+	if (!mlxsw_hwmon)
+		return -ENOMEM;
+	mlxsw_hwmon->core = mlxsw_core;
+	mlxsw_hwmon->bus_info = mlxsw_bus_info;
+
+	err = mlxsw_hwmon_temp_init(mlxsw_hwmon);
+	if (err)
+		goto err_temp_init;
+
+	mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
+	mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
+
+	hwmon_dev = devm_hwmon_device_register_with_groups(mlxsw_bus_info->dev,
+							   "mlxsw",
+							   mlxsw_hwmon,
+							   mlxsw_hwmon->groups);
+	if (IS_ERR(hwmon_dev)) {
+		err = PTR_ERR(hwmon_dev);
+		goto err_hwmon_register;
+	}
+
+	mlxsw_hwmon->hwmon_dev = hwmon_dev;
+	*p_hwmon = mlxsw_hwmon;
+	return 0;
+
+err_hwmon_register:
+err_temp_init:
+	kfree(mlxsw_hwmon);
+	return err;
+}
+
+void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
+{
+	kfree(mlxsw_hwmon);
+}
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [patch net-next v2 5/6] mlxsw: reg: Add definition of fan management registers
  2015-11-27 12:45 [patch net-next v2 0/6] mlxsw: driver update Jiri Pirko
                   ` (3 preceding siblings ...)
  2015-11-27 12:45 ` [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface Jiri Pirko
@ 2015-11-27 12:45 ` Jiri Pirko
  2015-11-27 12:45 ` [patch net-next v2 6/6] mlxsw: core: Implement fan control using hwmon Jiri Pirko
  2015-11-30 20:06 ` [patch net-next v2 0/6] mlxsw: driver update David Miller
  6 siblings, 0 replies; 18+ messages in thread
From: Jiri Pirko @ 2015-11-27 12:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg

From: Jiri Pirko <jiri@mellanox.com>

Add definition of MFCR, MFSC and MFSM which provide possibility to
control and monitor fans.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/reg.h | 133 ++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 459e0490..f894193 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -2087,6 +2087,133 @@ static inline void mlxsw_reg_hpkt_pack(char *payload, u8 action, u16 trap_id)
 	mlxsw_reg_hpkt_ctrl_set(payload, MLXSW_REG_HPKT_CTRL_PACKET_DEFAULT);
 }
 
+/* MFCR - Management Fan Control Register
+ * --------------------------------------
+ * This register controls the settings of the Fan Speed PWM mechanism.
+ */
+#define MLXSW_REG_MFCR_ID 0x9001
+#define MLXSW_REG_MFCR_LEN 0x08
+
+static const struct mlxsw_reg_info mlxsw_reg_mfcr = {
+	.id = MLXSW_REG_MFCR_ID,
+	.len = MLXSW_REG_MFCR_LEN,
+};
+
+enum mlxsw_reg_mfcr_pwm_frequency {
+	MLXSW_REG_MFCR_PWM_FEQ_11HZ = 0x00,
+	MLXSW_REG_MFCR_PWM_FEQ_14_7HZ = 0x01,
+	MLXSW_REG_MFCR_PWM_FEQ_22_1HZ = 0x02,
+	MLXSW_REG_MFCR_PWM_FEQ_1_4KHZ = 0x40,
+	MLXSW_REG_MFCR_PWM_FEQ_5KHZ = 0x41,
+	MLXSW_REG_MFCR_PWM_FEQ_20KHZ = 0x42,
+	MLXSW_REG_MFCR_PWM_FEQ_22_5KHZ = 0x43,
+	MLXSW_REG_MFCR_PWM_FEQ_25KHZ = 0x44,
+};
+
+/* reg_mfcr_pwm_frequency
+ * Controls the frequency of the PWM signal.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mfcr, pwm_frequency, 0x00, 0, 6);
+
+#define MLXSW_MFCR_TACHOS_MAX 10
+
+/* reg_mfcr_tacho_active
+ * Indicates which of the tachometer is active (bit per tachometer).
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mfcr, tacho_active, 0x04, 16, MLXSW_MFCR_TACHOS_MAX);
+
+#define MLXSW_MFCR_PWMS_MAX 5
+
+/* reg_mfcr_pwm_active
+ * Indicates which of the PWM control is active (bit per PWM).
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mfcr, pwm_active, 0x04, 0, MLXSW_MFCR_PWMS_MAX);
+
+static inline void
+mlxsw_reg_mfcr_pack(char *payload,
+		    enum mlxsw_reg_mfcr_pwm_frequency pwm_frequency)
+{
+	MLXSW_REG_ZERO(mfcr, payload);
+	mlxsw_reg_mfcr_pwm_frequency_set(payload, pwm_frequency);
+}
+
+static inline void
+mlxsw_reg_mfcr_unpack(char *payload,
+		      enum mlxsw_reg_mfcr_pwm_frequency *p_pwm_frequency,
+		      u16 *p_tacho_active, u8 *p_pwm_active)
+{
+	*p_pwm_frequency = mlxsw_reg_mfcr_pwm_frequency_get(payload);
+	*p_tacho_active = mlxsw_reg_mfcr_tacho_active_get(payload);
+	*p_pwm_active = mlxsw_reg_mfcr_pwm_active_get(payload);
+}
+
+/* MFSC - Management Fan Speed Control Register
+ * --------------------------------------------
+ * This register controls the settings of the Fan Speed PWM mechanism.
+ */
+#define MLXSW_REG_MFSC_ID 0x9002
+#define MLXSW_REG_MFSC_LEN 0x08
+
+static const struct mlxsw_reg_info mlxsw_reg_mfsc = {
+	.id = MLXSW_REG_MFSC_ID,
+	.len = MLXSW_REG_MFSC_LEN,
+};
+
+/* reg_mfsc_pwm
+ * Fan pwm to control / monitor.
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, mfsc, pwm, 0x00, 24, 3);
+
+/* reg_mfsc_pwm_duty_cycle
+ * Controls the duty cycle of the PWM. Value range from 0..255 to
+ * represent duty cycle of 0%...100%.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, mfsc, pwm_duty_cycle, 0x04, 0, 8);
+
+static inline void mlxsw_reg_mfsc_pack(char *payload, u8 pwm,
+				       u8 pwm_duty_cycle)
+{
+	MLXSW_REG_ZERO(mfsc, payload);
+	mlxsw_reg_mfsc_pwm_set(payload, pwm);
+	mlxsw_reg_mfsc_pwm_duty_cycle_set(payload, pwm_duty_cycle);
+}
+
+/* MFSM - Management Fan Speed Measurement
+ * ---------------------------------------
+ * This register controls the settings of the Tacho measurements and
+ * enables reading the Tachometer measurements.
+ */
+#define MLXSW_REG_MFSM_ID 0x9003
+#define MLXSW_REG_MFSM_LEN 0x08
+
+static const struct mlxsw_reg_info mlxsw_reg_mfsm = {
+	.id = MLXSW_REG_MFSM_ID,
+	.len = MLXSW_REG_MFSM_LEN,
+};
+
+/* reg_mfsm_tacho
+ * Fan tachometer index.
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, mfsm, tacho, 0x00, 24, 4);
+
+/* reg_mfsm_rpm
+ * Fan speed (round per minute).
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mfsm, rpm, 0x04, 0, 16);
+
+static inline void mlxsw_reg_mfsm_pack(char *payload, u8 tacho)
+{
+	MLXSW_REG_ZERO(mfsm, payload);
+	mlxsw_reg_mfsm_tacho_set(payload, tacho);
+}
+
 /* MTCAP - Management Temperature Capabilities
  * -------------------------------------------
  * This register exposes the capabilities of the device and
@@ -2556,6 +2683,12 @@ static inline const char *mlxsw_reg_id_str(u16 reg_id)
 		return "HTGT";
 	case MLXSW_REG_HPKT_ID:
 		return "HPKT";
+	case MLXSW_REG_MFCR_ID:
+		return "MFCR";
+	case MLXSW_REG_MFSC_ID:
+		return "MFSC";
+	case MLXSW_REG_MFSM_ID:
+		return "MFSM";
 	case MLXSW_REG_MTCAP_ID:
 		return "MTCAP";
 	case MLXSW_REG_MTMP_ID:
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [patch net-next v2 6/6] mlxsw: core: Implement fan control using hwmon
  2015-11-27 12:45 [patch net-next v2 0/6] mlxsw: driver update Jiri Pirko
                   ` (4 preceding siblings ...)
  2015-11-27 12:45 ` [patch net-next v2 5/6] mlxsw: reg: Add definition of fan management registers Jiri Pirko
@ 2015-11-27 12:45 ` Jiri Pirko
  2015-11-30 20:06 ` [patch net-next v2 0/6] mlxsw: driver update David Miller
  6 siblings, 0 replies; 18+ messages in thread
From: Jiri Pirko @ 2015-11-27 12:45 UTC (permalink / raw)
  To: netdev; +Cc: davem, idosch, eladr, yotamg

From: Jiri Pirko <jiri@mellanox.com>

ASIC provides access to fans. Implement their exposure to userspace
using hwmon.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 121 ++++++++++++++++++++++-
 1 file changed, 120 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
index ec48c28..ad8b274 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
@@ -42,7 +42,8 @@
 #include "core.h"
 
 #define MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT 127
-#define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT * 4)
+#define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT * 4 + \
+				MLXSW_MFCR_TACHOS_MAX + MLXSW_MFCR_PWMS_MAX)
 
 struct mlxsw_hwmon_attr {
 	struct device_attribute dev_attr;
@@ -106,9 +107,76 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
 	return sprintf(buf, "%u\n", temp_max);
 }
 
+static ssize_t mlxsw_hwmon_fan_rpm_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
+			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
+	struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
+	char mfsm_pl[MLXSW_REG_MFSM_LEN];
+	int err;
+
+	mlxsw_reg_mfsm_pack(mfsm_pl, mlwsw_hwmon_attr->type_index);
+	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfsm), mfsm_pl);
+	if (err) {
+		dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query fan\n");
+		return err;
+	}
+	return sprintf(buf, "%u\n", mlxsw_reg_mfsm_rpm_get(mfsm_pl));
+}
+
+static ssize_t mlxsw_hwmon_pwm_show(struct device *dev,
+				    struct device_attribute *attr,
+				    char *buf)
+{
+	struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
+			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
+	struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
+	char mfsc_pl[MLXSW_REG_MFSC_LEN];
+	int err;
+
+	mlxsw_reg_mfsc_pack(mfsc_pl, mlwsw_hwmon_attr->type_index, 0);
+	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfsc), mfsc_pl);
+	if (err) {
+		dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query PWM\n");
+		return err;
+	}
+	return sprintf(buf, "%u\n",
+		       mlxsw_reg_mfsc_pwm_duty_cycle_get(mfsc_pl));
+}
+
+static ssize_t mlxsw_hwmon_pwm_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t len)
+{
+	struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
+			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
+	struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
+	char mfsc_pl[MLXSW_REG_MFSC_LEN];
+	unsigned long val;
+	int err;
+
+	err = kstrtoul(buf, 10, &val);
+	if (err)
+		return err;
+	if (val > 255)
+		return -EINVAL;
+
+	mlxsw_reg_mfsc_pack(mfsc_pl, mlwsw_hwmon_attr->type_index, val);
+	err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mfsc), mfsc_pl);
+	if (err) {
+		dev_err(mlxsw_hwmon->bus_info->dev, "Failed to write PWM\n");
+		return err;
+	}
+	return err ? err : len;
+}
+
 enum mlxsw_hwmon_attr_type {
 	MLXSW_HWMON_ATTR_TYPE_TEMP,
 	MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
+	MLXSW_HWMON_ATTR_TYPE_FAN_RPM,
+	MLXSW_HWMON_ATTR_TYPE_PWM,
 };
 
 static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
@@ -133,6 +201,19 @@ static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
 		snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
 			 "temp%u_highest", num + 1);
 		break;
+	case MLXSW_HWMON_ATTR_TYPE_FAN_RPM:
+		mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_fan_rpm_show;
+		mlxsw_hwmon_attr->dev_attr.attr.mode = S_IRUGO;
+		snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
+			 "fan%u_input", num + 1);
+		break;
+	case MLXSW_HWMON_ATTR_TYPE_PWM:
+		mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_pwm_show;
+		mlxsw_hwmon_attr->dev_attr.store = mlxsw_hwmon_pwm_store;
+		mlxsw_hwmon_attr->dev_attr.attr.mode = S_IWUSR | S_IRUGO;
+		snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
+			 "pwm%u", num + 1);
+		break;
 	default:
 		BUG();
 	}
@@ -177,6 +258,39 @@ static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon *mlxsw_hwmon)
 	return 0;
 }
 
+static int mlxsw_hwmon_fans_init(struct mlxsw_hwmon *mlxsw_hwmon)
+{
+	char mfcr_pl[MLXSW_REG_MFCR_LEN];
+	enum mlxsw_reg_mfcr_pwm_frequency freq;
+	unsigned int type_index;
+	unsigned int num;
+	u16 tacho_active;
+	u8 pwm_active;
+	int err;
+
+	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mfcr), mfcr_pl);
+	if (err) {
+		dev_err(mlxsw_hwmon->bus_info->dev, "Failed to get to probe PWMs and Tachometers\n");
+		return err;
+	}
+	mlxsw_reg_mfcr_unpack(mfcr_pl, &freq, &tacho_active, &pwm_active);
+	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_TYPE_FAN_RPM,
+					     type_index, num++);
+	}
+	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_TYPE_PWM,
+					     type_index, num++);
+	}
+	return 0;
+}
+
 int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
 		     const struct mlxsw_bus_info *mlxsw_bus_info,
 		     struct mlxsw_hwmon **p_hwmon)
@@ -195,6 +309,10 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
 	if (err)
 		goto err_temp_init;
 
+	err = mlxsw_hwmon_fans_init(mlxsw_hwmon);
+	if (err)
+		goto err_fans_init;
+
 	mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
 	mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
 
@@ -212,6 +330,7 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
 	return 0;
 
 err_hwmon_register:
+err_fans_init:
 err_temp_init:
 	kfree(mlxsw_hwmon);
 	return err;
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface
  2015-11-27 12:45 ` [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface Jiri Pirko
@ 2015-11-29  9:04   ` Or Gerlitz
  2015-11-29 10:49     ` Jiri Pirko
  0 siblings, 1 reply; 18+ messages in thread
From: Or Gerlitz @ 2015-11-29  9:04 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: Linux Netdev List, David Miller, idosch, Elad Raz, yotamg

[..]
> +enum mlxsw_hwmon_attr_type {
> +       MLXSW_HWMON_ATTR_TYPE_TEMP,
> +       MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
> +};
> +
> +static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
> +                                enum mlxsw_hwmon_attr_type attr_type,
> +                                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];
> +
> +       switch (attr_type) {
> +       case MLXSW_HWMON_ATTR_TYPE_TEMP:
> +               mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_show;
> +               mlxsw_hwmon_attr->dev_attr.attr.mode = S_IRUGO;
> +               snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
> +                        "temp%u_input", num + 1);
> +               break;
> +       case MLXSW_HWMON_ATTR_TYPE_TEMP_MAX:
> +               mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_max_show;
> +               mlxsw_hwmon_attr->dev_attr.attr.mode = S_IRUGO;
> +               snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
> +                        "temp%u_highest", num + 1);
> +               break;
> +       default:
> +               BUG();

Guys, do we really have to crash the whole system just b/c somehow an unknown
value propagated here during **init** time?

I don't think so.

> +
> +       mlxsw_hwmon_attr->type_index = type_index;
> +       mlxsw_hwmon_attr->hwmon = mlxsw_hwmon;
> +       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++;
> +}
> +

[...]
> +int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
> +                    const struct mlxsw_bus_info *mlxsw_bus_info,
> +                    struct mlxsw_hwmon **p_hwmon)
> +{
> +       struct mlxsw_hwmon *mlxsw_hwmon;
> +       struct device *hwmon_dev;
> +       int err;
> +
> +       mlxsw_hwmon = kzalloc(sizeof(*mlxsw_hwmon), GFP_KERNEL);
> +       if (!mlxsw_hwmon)
> +               return -ENOMEM;
> +       mlxsw_hwmon->core = mlxsw_core;
> +       mlxsw_hwmon->bus_info = mlxsw_bus_info;
> +
> +       err = mlxsw_hwmon_temp_init(mlxsw_hwmon);
> +       if (err)
> +               goto err_temp_init;
> +
> +       mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
> +       mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
> +
> +       hwmon_dev = devm_hwmon_device_register_with_groups(mlxsw_bus_info->dev,
> +                                                          "mlxsw",
> +                                                          mlxsw_hwmon,
> +                                                          mlxsw_hwmon->groups);
> +       if (IS_ERR(hwmon_dev)) {
> +               err = PTR_ERR(hwmon_dev);
> +               goto err_hwmon_register;
> +       }
> +
> +       mlxsw_hwmon->hwmon_dev = hwmon_dev;
> +       *p_hwmon = mlxsw_hwmon;
> +       return 0;
> +
> +err_hwmon_register:
> +err_temp_init:
> +       kfree(mlxsw_hwmon);
> +       return err;
> +}
> +

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface
  2015-11-29  9:04   ` Or Gerlitz
@ 2015-11-29 10:49     ` Jiri Pirko
  2015-12-02 22:05       ` Or Gerlitz
  0 siblings, 1 reply; 18+ messages in thread
From: Jiri Pirko @ 2015-11-29 10:49 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: Linux Netdev List, David Miller, idosch, Elad Raz, yotamg

Sun, Nov 29, 2015 at 10:04:07AM CET, gerlitz.or@gmail.com wrote:
>[..]
>> +enum mlxsw_hwmon_attr_type {
>> +       MLXSW_HWMON_ATTR_TYPE_TEMP,
>> +       MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
>> +};
>> +
>> +static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
>> +                                enum mlxsw_hwmon_attr_type attr_type,
>> +                                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];
>> +
>> +       switch (attr_type) {
>> +       case MLXSW_HWMON_ATTR_TYPE_TEMP:
>> +               mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_show;
>> +               mlxsw_hwmon_attr->dev_attr.attr.mode = S_IRUGO;
>> +               snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
>> +                        "temp%u_input", num + 1);
>> +               break;
>> +       case MLXSW_HWMON_ATTR_TYPE_TEMP_MAX:
>> +               mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_max_show;
>> +               mlxsw_hwmon_attr->dev_attr.attr.mode = S_IRUGO;
>> +               snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
>> +                        "temp%u_highest", num + 1);
>> +               break;
>> +       default:
>> +               BUG();
>
>Guys, do we really have to crash the whole system just b/c somehow an unknown
>value propagated here during **init** time?
>
>I don't think so.

"default" case simply *cannot* happen. If it happens, it is a stack
corruption or some other fatal problem. I believe that BUG is
appropriate at these cases.

>
>> +
>> +       mlxsw_hwmon_attr->type_index = type_index;
>> +       mlxsw_hwmon_attr->hwmon = mlxsw_hwmon;
>> +       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++;
>> +}
>> +
>
>[...]
>> +int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
>> +                    const struct mlxsw_bus_info *mlxsw_bus_info,
>> +                    struct mlxsw_hwmon **p_hwmon)
>> +{
>> +       struct mlxsw_hwmon *mlxsw_hwmon;
>> +       struct device *hwmon_dev;
>> +       int err;
>> +
>> +       mlxsw_hwmon = kzalloc(sizeof(*mlxsw_hwmon), GFP_KERNEL);
>> +       if (!mlxsw_hwmon)
>> +               return -ENOMEM;
>> +       mlxsw_hwmon->core = mlxsw_core;
>> +       mlxsw_hwmon->bus_info = mlxsw_bus_info;
>> +
>> +       err = mlxsw_hwmon_temp_init(mlxsw_hwmon);
>> +       if (err)
>> +               goto err_temp_init;
>> +
>> +       mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
>> +       mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
>> +
>> +       hwmon_dev = devm_hwmon_device_register_with_groups(mlxsw_bus_info->dev,
>> +                                                          "mlxsw",
>> +                                                          mlxsw_hwmon,
>> +                                                          mlxsw_hwmon->groups);
>> +       if (IS_ERR(hwmon_dev)) {
>> +               err = PTR_ERR(hwmon_dev);
>> +               goto err_hwmon_register;
>> +       }
>> +
>> +       mlxsw_hwmon->hwmon_dev = hwmon_dev;
>> +       *p_hwmon = mlxsw_hwmon;
>> +       return 0;
>> +
>> +err_hwmon_register:
>> +err_temp_init:
>> +       kfree(mlxsw_hwmon);
>> +       return err;
>> +}
>> +

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [patch net-next v2 0/6] mlxsw: driver update
  2015-11-27 12:45 [patch net-next v2 0/6] mlxsw: driver update Jiri Pirko
                   ` (5 preceding siblings ...)
  2015-11-27 12:45 ` [patch net-next v2 6/6] mlxsw: core: Implement fan control using hwmon Jiri Pirko
@ 2015-11-30 20:06 ` David Miller
  6 siblings, 0 replies; 18+ messages in thread
From: David Miller @ 2015-11-30 20:06 UTC (permalink / raw)
  To: jiri; +Cc: netdev, idosch, eladr, yotamg

From: Jiri Pirko <jiri@resnulli.us>
Date: Fri, 27 Nov 2015 13:45:53 +0100

> This patchset carries support for port identification, monitoring
> of ASIC temperature and board fans.

Series applied, thanks Jiri.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface
  2015-11-29 10:49     ` Jiri Pirko
@ 2015-12-02 22:05       ` Or Gerlitz
  2015-12-02 22:25         ` Jiri Pirko
  0 siblings, 1 reply; 18+ messages in thread
From: Or Gerlitz @ 2015-12-02 22:05 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: Linux Netdev List, David Miller

On Sun, Nov 29, 2015 at 12:49 PM, Jiri Pirko <jiri@resnulli.us> wrote:
> Sun, Nov 29, 2015 at 10:04:07AM CET, gerlitz.or@gmail.com wrote:
>>[..]
>>> +enum mlxsw_hwmon_attr_type {
>>> +       MLXSW_HWMON_ATTR_TYPE_TEMP,
>>> +       MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
>>> +};
>>> +
>>> +static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
>>> +                                enum mlxsw_hwmon_attr_type attr_type,
>>> +                                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];
>>> +
>>> +       switch (attr_type) {
>>> +       case MLXSW_HWMON_ATTR_TYPE_TEMP:
>>> +               mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_show;
>>> +               mlxsw_hwmon_attr->dev_attr.attr.mode = S_IRUGO;
>>> +               snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
>>> +                        "temp%u_input", num + 1);
>>> +               break;
>>> +       case MLXSW_HWMON_ATTR_TYPE_TEMP_MAX:
>>> +               mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_max_show;
>>> +               mlxsw_hwmon_attr->dev_attr.attr.mode = S_IRUGO;
>>> +               snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
>>> +                        "temp%u_highest", num + 1);
>>> +               break;
>>> +       default:
>>> +               BUG();
>>
>> Guys, do we really have to crash the whole system just b/c somehow an
>> unknown value propagated here during **init** time?
>>
>> I don't think so.

> "default" case simply *cannot* happen. If it happens, it is a stack
> corruption or some other fatal problem. I believe that BUG is
> appropriate at these cases.

Jiri, as Dave commented today on the LAG series,  BUG_ON() is bad and
is only to ever be used when the kernel's continued operation is
absolutely impossible, can we change here to WARN_ON() or a like?

Or.

>>> +
>>> +       mlxsw_hwmon_attr->type_index = type_index;
>>> +       mlxsw_hwmon_attr->hwmon = mlxsw_hwmon;
>>> +       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++;
>>> +}
>>> +
>>
>>[...]
>>> +int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
>>> +                    const struct mlxsw_bus_info *mlxsw_bus_info,
>>> +                    struct mlxsw_hwmon **p_hwmon)
>>> +{
>>> +       struct mlxsw_hwmon *mlxsw_hwmon;
>>> +       struct device *hwmon_dev;
>>> +       int err;
>>> +
>>> +       mlxsw_hwmon = kzalloc(sizeof(*mlxsw_hwmon), GFP_KERNEL);
>>> +       if (!mlxsw_hwmon)
>>> +               return -ENOMEM;
>>> +       mlxsw_hwmon->core = mlxsw_core;
>>> +       mlxsw_hwmon->bus_info = mlxsw_bus_info;
>>> +
>>> +       err = mlxsw_hwmon_temp_init(mlxsw_hwmon);
>>> +       if (err)
>>> +               goto err_temp_init;
>>> +
>>> +       mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
>>> +       mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
>>> +
>>> +       hwmon_dev = devm_hwmon_device_register_with_groups(mlxsw_bus_info->dev,
>>> +                                                          "mlxsw",
>>> +                                                          mlxsw_hwmon,
>>> +                                                          mlxsw_hwmon->groups);
>>> +       if (IS_ERR(hwmon_dev)) {
>>> +               err = PTR_ERR(hwmon_dev);
>>> +               goto err_hwmon_register;
>>> +       }
>>> +
>>> +       mlxsw_hwmon->hwmon_dev = hwmon_dev;
>>> +       *p_hwmon = mlxsw_hwmon;
>>> +       return 0;
>>> +
>>> +err_hwmon_register:
>>> +err_temp_init:
>>> +       kfree(mlxsw_hwmon);
>>> +       return err;
>>> +}
>>> +

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface
  2015-12-02 22:05       ` Or Gerlitz
@ 2015-12-02 22:25         ` Jiri Pirko
  2015-12-02 22:28           ` David Miller
  0 siblings, 1 reply; 18+ messages in thread
From: Jiri Pirko @ 2015-12-02 22:25 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: Linux Netdev List, David Miller

Wed, Dec 02, 2015 at 11:05:48PM CET, gerlitz.or@gmail.com wrote:
>On Sun, Nov 29, 2015 at 12:49 PM, Jiri Pirko <jiri@resnulli.us> wrote:
>> Sun, Nov 29, 2015 at 10:04:07AM CET, gerlitz.or@gmail.com wrote:
>>>[..]
>>>> +enum mlxsw_hwmon_attr_type {
>>>> +       MLXSW_HWMON_ATTR_TYPE_TEMP,
>>>> +       MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
>>>> +};
>>>> +
>>>> +static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
>>>> +                                enum mlxsw_hwmon_attr_type attr_type,
>>>> +                                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];
>>>> +
>>>> +       switch (attr_type) {
>>>> +       case MLXSW_HWMON_ATTR_TYPE_TEMP:
>>>> +               mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_show;
>>>> +               mlxsw_hwmon_attr->dev_attr.attr.mode = S_IRUGO;
>>>> +               snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
>>>> +                        "temp%u_input", num + 1);
>>>> +               break;
>>>> +       case MLXSW_HWMON_ATTR_TYPE_TEMP_MAX:
>>>> +               mlxsw_hwmon_attr->dev_attr.show = mlxsw_hwmon_temp_max_show;
>>>> +               mlxsw_hwmon_attr->dev_attr.attr.mode = S_IRUGO;
>>>> +               snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
>>>> +                        "temp%u_highest", num + 1);
>>>> +               break;
>>>> +       default:
>>>> +               BUG();
>>>
>>> Guys, do we really have to crash the whole system just b/c somehow an
>>> unknown value propagated here during **init** time?
>>>
>>> I don't think so.
>
>> "default" case simply *cannot* happen. If it happens, it is a stack
>> corruption or some other fatal problem. I believe that BUG is
>> appropriate at these cases.
>
>Jiri, as Dave commented today on the LAG series,  BUG_ON() is bad and
>is only to ever be used when the kernel's continued operation is
>absolutely impossible, can we change here to WARN_ON() or a like?

In this case, I don't know how to bail out correctly, I believe that
bugon is correct here.

Again, there is no possible way to achieve this bugon, other than a
stack corruption. I don't think we should try to cope with a stack
corruption.

Feel free to send a patch if you think otherwise.

Thanks.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface
  2015-12-02 22:25         ` Jiri Pirko
@ 2015-12-02 22:28           ` David Miller
  2015-12-02 22:35             ` Jiri Pirko
  0 siblings, 1 reply; 18+ messages in thread
From: David Miller @ 2015-12-02 22:28 UTC (permalink / raw)
  To: jiri; +Cc: gerlitz.or, netdev

From: Jiri Pirko <jiri@resnulli.us>
Date: Wed, 2 Dec 2015 23:25:52 +0100

> Again, there is no possible way to achieve this bugon, other than a
> stack corruption. I don't think we should try to cope with a stack
> corruption.

Then remove the assertion.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface
  2015-12-02 22:28           ` David Miller
@ 2015-12-02 22:35             ` Jiri Pirko
  2015-12-02 23:37               ` David Miller
  0 siblings, 1 reply; 18+ messages in thread
From: Jiri Pirko @ 2015-12-02 22:35 UTC (permalink / raw)
  To: David Miller; +Cc: gerlitz.or, netdev

Wed, Dec 02, 2015 at 11:28:47PM CET, davem@davemloft.net wrote:
>From: Jiri Pirko <jiri@resnulli.us>
>Date: Wed, 2 Dec 2015 23:25:52 +0100
>
>> Again, there is no possible way to achieve this bugon, other than a
>> stack corruption. I don't think we should try to cope with a stack
>> corruption.
>
>Then remove the assertion.

I thought that in cases like this it is better to just assert and tell
user that something went horribly and non-recoverably wrong.

Why to continue to work if we know that we are making things wrong
(incorrect structure initialization in this case) ? What am I missing?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface
  2015-12-02 22:35             ` Jiri Pirko
@ 2015-12-02 23:37               ` David Miller
  2015-12-03  8:19                 ` Jiri Pirko
  0 siblings, 1 reply; 18+ messages in thread
From: David Miller @ 2015-12-02 23:37 UTC (permalink / raw)
  To: jiri; +Cc: gerlitz.or, netdev

From: Jiri Pirko <jiri@resnulli.us>
Date: Wed, 2 Dec 2015 23:35:31 +0100

> Why to continue to work if we know that we are making things wrong
> (incorrect structure initialization in this case) ? What am I missing?

The user might be able to continue to have connectivity and
report the problem.

BUG_ON() is really a hard hammer.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface
  2015-12-02 23:37               ` David Miller
@ 2015-12-03  8:19                 ` Jiri Pirko
  2015-12-03  9:32                   ` Or Gerlitz
  0 siblings, 1 reply; 18+ messages in thread
From: Jiri Pirko @ 2015-12-03  8:19 UTC (permalink / raw)
  To: David Miller; +Cc: gerlitz.or, netdev

Thu, Dec 03, 2015 at 12:37:58AM CET, davem@davemloft.net wrote:
>From: Jiri Pirko <jiri@resnulli.us>
>Date: Wed, 2 Dec 2015 23:35:31 +0100
>
>> Why to continue to work if we know that we are making things wrong
>> (incorrect structure initialization in this case) ? What am I missing?
>
>The user might be able to continue to have connectivity and
>report the problem.
>
>BUG_ON() is really a hard hammer.

Okay.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface
  2015-12-03  8:19                 ` Jiri Pirko
@ 2015-12-03  9:32                   ` Or Gerlitz
  2015-12-03  9:55                     ` Jiri Pirko
  0 siblings, 1 reply; 18+ messages in thread
From: Or Gerlitz @ 2015-12-03  9:32 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: David Miller, Linux Netdev List

On Thu, Dec 3, 2015 at 10:19 AM, Jiri Pirko <jiri@resnulli.us> wrote:
> Thu, Dec 03, 2015 at 12:37:58AM CET, davem@davemloft.net wrote:
>>From: Jiri Pirko <jiri@resnulli.us>
>>Date: Wed, 2 Dec 2015 23:35:31 +0100
>>
>>> Why to continue to work if we know that we are making things wrong
>>> (incorrect structure initialization in this case) ? What am I missing?
>>
>>The user might be able to continue to have connectivity and
>>report the problem.
>>
>>BUG_ON() is really a hard hammer.
>
> Okay.

So we are  removing this as well, right?

Or.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface
  2015-12-03  9:32                   ` Or Gerlitz
@ 2015-12-03  9:55                     ` Jiri Pirko
  0 siblings, 0 replies; 18+ messages in thread
From: Jiri Pirko @ 2015-12-03  9:55 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: David Miller, Linux Netdev List

Thu, Dec 03, 2015 at 10:32:04AM CET, gerlitz.or@gmail.com wrote:
>On Thu, Dec 3, 2015 at 10:19 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>> Thu, Dec 03, 2015 at 12:37:58AM CET, davem@davemloft.net wrote:
>>>From: Jiri Pirko <jiri@resnulli.us>
>>>Date: Wed, 2 Dec 2015 23:35:31 +0100
>>>
>>>> Why to continue to work if we know that we are making things wrong
>>>> (incorrect structure initialization in this case) ? What am I missing?
>>>
>>>The user might be able to continue to have connectivity and
>>>report the problem.
>>>
>>>BUG_ON() is really a hard hammer.
>>
>> Okay.
>
>So we are  removing this as well, right?

Changing it to WARN:
http://patchwork.ozlabs.org/patch/552087/

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2015-12-03  9:55 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-27 12:45 [patch net-next v2 0/6] mlxsw: driver update Jiri Pirko
2015-11-27 12:45 ` [patch net-next v2 1/6] mlxsw: reg: Add Management LED Control register definition Jiri Pirko
2015-11-27 12:45 ` [patch net-next v2 2/6] mlxsw: spectrum: Add support for port identification Jiri Pirko
2015-11-27 12:45 ` [patch net-next v2 3/6] mlxsw: reg: Add definition of temperature management registers Jiri Pirko
2015-11-27 12:45 ` [patch net-next v2 4/6] mlxsw: core: Implement temperature hwmon interface Jiri Pirko
2015-11-29  9:04   ` Or Gerlitz
2015-11-29 10:49     ` Jiri Pirko
2015-12-02 22:05       ` Or Gerlitz
2015-12-02 22:25         ` Jiri Pirko
2015-12-02 22:28           ` David Miller
2015-12-02 22:35             ` Jiri Pirko
2015-12-02 23:37               ` David Miller
2015-12-03  8:19                 ` Jiri Pirko
2015-12-03  9:32                   ` Or Gerlitz
2015-12-03  9:55                     ` Jiri Pirko
2015-11-27 12:45 ` [patch net-next v2 5/6] mlxsw: reg: Add definition of fan management registers Jiri Pirko
2015-11-27 12:45 ` [patch net-next v2 6/6] mlxsw: core: Implement fan control using hwmon Jiri Pirko
2015-11-30 20:06 ` [patch net-next v2 0/6] mlxsw: driver update David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox