netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/5] mlxsw: Query number of modules from firmware
@ 2019-10-06  6:34 Ido Schimmel
  2019-10-06  6:34 ` [PATCH net-next 1/5] mlxsw: reg: Extend MGPIR register with new field exposing the number of QSFP modules Ido Schimmel
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Ido Schimmel @ 2019-10-06  6:34 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, vadimp, mlxsw, Ido Schimmel

From: Ido Schimmel <idosch@mellanox.com>

Vadim says:

The patchset adds support for a new field "num_of_modules" of Management
General Peripheral Information Register (MGPIR), providing the maximum
number of QSFP modules, which can be supported by the system.

It allows to obtain the number of QSFP modules directly from this field,
as a static data, instead of old method of getting this info through
"network port to QSFP module" mapping. With the old method, in case of
port dynamic re-configuration some modules can logically "disappear" as
a result of port split operations, which can cause some modules to
appear missing.

Such scenario can happen on a system equipped with a BMC card, while PCI
chip driver at host CPU side can perform some ports "split" or "unsplit"
operations, while BMC side I2C chip driver reads the "port-to-module"
mapping.

Add common API for FW "minor" and "subminor" versions validation and
share it between PCI and I2C based drivers.

Add FW version validation for "minimal" driver, because use of new field
"num_of_modules" in MGPIR register is not backward compatible.

Vadim Pasternak (5):
  mlxsw: reg: Extend MGPIR register with new field exposing the number
    of QSFP modules
  mlxsw: hwmon: Provide optimization for QSFP modules number detection
  mlxsw: thermal: Provide optimization for QSFP modules number detection
  mlxsw: core: Push minor/subminor fw version check into helper
  mlxsw: minimal: Add validation for FW version

 drivers/net/ethernet/mellanox/mlxsw/core.c    | 10 +++
 drivers/net/ethernet/mellanox/mlxsw/core.h    |  5 ++
 .../net/ethernet/mellanox/mlxsw/core_hwmon.c  | 66 +++++++++----------
 .../ethernet/mellanox/mlxsw/core_thermal.c    | 40 +++++------
 drivers/net/ethernet/mellanox/mlxsw/minimal.c | 30 +++++++++
 drivers/net/ethernet/mellanox/mlxsw/reg.h     | 10 ++-
 .../net/ethernet/mellanox/mlxsw/spectrum.c    |  4 +-
 7 files changed, 103 insertions(+), 62 deletions(-)

-- 
2.21.0


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

* [PATCH net-next 1/5] mlxsw: reg: Extend MGPIR register with new field exposing the number of QSFP modules
  2019-10-06  6:34 [PATCH net-next 0/5] mlxsw: Query number of modules from firmware Ido Schimmel
@ 2019-10-06  6:34 ` Ido Schimmel
  2019-10-06  6:34 ` [PATCH net-next 2/5] mlxsw: hwmon: Provide optimization for QSFP modules number detection Ido Schimmel
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2019-10-06  6:34 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, vadimp, mlxsw, Ido Schimmel

From: Vadim Pasternak <vadimp@mellanox.com>

Extend MGPIR - Management General Peripheral Information Register
with new field "num_of_modules" exposing the number of modules
supported by specific system.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c   |  2 +-
 drivers/net/ethernet/mellanox/mlxsw/core_thermal.c |  3 ++-
 drivers/net/ethernet/mellanox/mlxsw/reg.h          | 10 +++++++++-
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
index 5b00726c4346..69c192839bf9 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
@@ -590,7 +590,7 @@ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
 	if (err)
 		return err;
 
-	mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, NULL, NULL);
+	mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, NULL, NULL, NULL);
 	if (!gbox_num)
 		return 0;
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
index 35a1dc89c28a..b2c76a95f671 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -913,7 +913,8 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
 	if (err)
 		return err;
 
-	mlxsw_reg_mgpir_unpack(mgpir_pl, &thermal->tz_gearbox_num, NULL, NULL);
+	mlxsw_reg_mgpir_unpack(mgpir_pl, &thermal->tz_gearbox_num, NULL, NULL,
+			       NULL);
 	if (!thermal->tz_gearbox_num)
 		return 0;
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 5494cf93f34c..7b538e698a3d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -9531,6 +9531,12 @@ MLXSW_ITEM32(reg, mgpir, devices_per_flash, 0x00, 16, 8);
  */
 MLXSW_ITEM32(reg, mgpir, num_of_devices, 0x00, 0, 8);
 
+/* num_of_modules
+ * Number of modules.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mgpir, num_of_modules, 0x04, 0, 8);
+
 static inline void mlxsw_reg_mgpir_pack(char *payload)
 {
 	MLXSW_REG_ZERO(mgpir, payload);
@@ -9539,7 +9545,7 @@ static inline void mlxsw_reg_mgpir_pack(char *payload)
 static inline void
 mlxsw_reg_mgpir_unpack(char *payload, u8 *num_of_devices,
 		       enum mlxsw_reg_mgpir_device_type *device_type,
-		       u8 *devices_per_flash)
+		       u8 *devices_per_flash, u8 *num_of_modules)
 {
 	if (num_of_devices)
 		*num_of_devices = mlxsw_reg_mgpir_num_of_devices_get(payload);
@@ -9548,6 +9554,8 @@ mlxsw_reg_mgpir_unpack(char *payload, u8 *num_of_devices,
 	if (devices_per_flash)
 		*devices_per_flash =
 				mlxsw_reg_mgpir_devices_per_flash_get(payload);
+	if (num_of_modules)
+		*num_of_modules = mlxsw_reg_mgpir_num_of_modules_get(payload);
 }
 
 /* TNGCR - Tunneling NVE General Configuration Register
-- 
2.21.0


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

* [PATCH net-next 2/5] mlxsw: hwmon: Provide optimization for QSFP modules number detection
  2019-10-06  6:34 [PATCH net-next 0/5] mlxsw: Query number of modules from firmware Ido Schimmel
  2019-10-06  6:34 ` [PATCH net-next 1/5] mlxsw: reg: Extend MGPIR register with new field exposing the number of QSFP modules Ido Schimmel
@ 2019-10-06  6:34 ` Ido Schimmel
  2019-10-06  6:34 ` [PATCH net-next 3/5] mlxsw: thermal: " Ido Schimmel
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2019-10-06  6:34 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, vadimp, mlxsw, Ido Schimmel

From: Vadim Pasternak <vadimp@mellanox.com>

Use new field "num_of_modules" of MGPIR register for "hwmon" interface
in order to get the number of modules supported by system directly from
the system configuration, instead of getting it from port to module
mapping info.

Reading this info through MGPIR register is faster and does not depend
on possible dynamic re-configuration of ports.
In case of port dynamic re-configuration some modules can logically
"disappear" as a result of port split and un-spilt operations, which
can cause missing of some modules, in case this info is taken from port
to module mapping info.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/core_hwmon.c  | 64 +++++++++----------
 1 file changed, 29 insertions(+), 35 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
index 69c192839bf9..9bf8da5f6daf 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
@@ -41,7 +41,7 @@ struct mlxsw_hwmon {
 	struct mlxsw_hwmon_attr hwmon_attrs[MLXSW_HWMON_ATTR_COUNT];
 	unsigned int attrs_count;
 	u8 sensor_count;
-	u8 module_sensor_count;
+	u8 module_sensor_max;
 };
 
 static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
@@ -56,7 +56,7 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
 	int err;
 
 	index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
-					   mlxsw_hwmon->module_sensor_count);
+					   mlxsw_hwmon->module_sensor_max);
 	mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
 	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
 	if (err) {
@@ -79,7 +79,7 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
 	int err;
 
 	index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
-					   mlxsw_hwmon->module_sensor_count);
+					   mlxsw_hwmon->module_sensor_max);
 	mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
 	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
 	if (err) {
@@ -109,7 +109,7 @@ static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
 		return -EINVAL;
 
 	index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
-					   mlxsw_hwmon->module_sensor_count);
+					   mlxsw_hwmon->module_sensor_max);
 	mlxsw_reg_mtmp_pack(mtmp_pl, index, true, true);
 	err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
 	if (err) {
@@ -336,7 +336,7 @@ mlxsw_hwmon_gbox_temp_label_show(struct device *dev,
 			container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
 	struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
 	int index = mlwsw_hwmon_attr->type_index -
-		    mlxsw_hwmon->module_sensor_count + 1;
+		    mlxsw_hwmon->module_sensor_max + 1;
 
 	return sprintf(buf, "gearbox %03u\n", index);
 }
@@ -528,51 +528,45 @@ static int mlxsw_hwmon_fans_init(struct mlxsw_hwmon *mlxsw_hwmon)
 
 static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
 {
-	unsigned int module_count = mlxsw_core_max_ports(mlxsw_hwmon->core);
-	char pmlp_pl[MLXSW_REG_PMLP_LEN] = {0};
-	int i, index;
-	u8 width;
-	int err;
+	char mgpir_pl[MLXSW_REG_MGPIR_LEN];
+	u8 module_sensor_max;
+	int i, err;
 
 	if (!mlxsw_core_res_query_enabled(mlxsw_hwmon->core))
 		return 0;
 
+	mlxsw_reg_mgpir_pack(mgpir_pl);
+	err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
+	if (err)
+		return err;
+
+	mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL,
+			       &module_sensor_max);
+
 	/* Add extra attributes for module temperature. Sensor index is
 	 * assigned to sensor_count value, while all indexed before
 	 * sensor_count are already utilized by the sensors connected through
 	 * mtmp register by mlxsw_hwmon_temp_init().
 	 */
-	index = mlxsw_hwmon->sensor_count;
-	for (i = 1; i < module_count; i++) {
-		mlxsw_reg_pmlp_pack(pmlp_pl, i);
-		err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(pmlp),
-				      pmlp_pl);
-		if (err) {
-			dev_err(mlxsw_hwmon->bus_info->dev, "Failed to read module index %d\n",
-				i);
-			return err;
-		}
-		width = mlxsw_reg_pmlp_width_get(pmlp_pl);
-		if (!width)
-			continue;
+	mlxsw_hwmon->module_sensor_max = mlxsw_hwmon->sensor_count +
+					 module_sensor_max;
+	for (i = mlxsw_hwmon->sensor_count;
+	     i < mlxsw_hwmon->module_sensor_max; i++) {
 		mlxsw_hwmon_attr_add(mlxsw_hwmon,
-				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE, index,
-				     index);
+				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE, i, i);
 		mlxsw_hwmon_attr_add(mlxsw_hwmon,
 				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_FAULT,
-				     index, index);
+				     i, i);
 		mlxsw_hwmon_attr_add(mlxsw_hwmon,
-				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT,
-				     index, index);
+				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT, i,
+				     i);
 		mlxsw_hwmon_attr_add(mlxsw_hwmon,
 				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
-				     index, index);
+				     i, i);
 		mlxsw_hwmon_attr_add(mlxsw_hwmon,
 				     MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
-				     index, index);
-		index++;
+				     i, i);
 	}
-	mlxsw_hwmon->module_sensor_count = index;
 
 	return 0;
 }
@@ -594,10 +588,10 @@ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
 	if (!gbox_num)
 		return 0;
 
-	index = mlxsw_hwmon->module_sensor_count;
-	max_index = mlxsw_hwmon->module_sensor_count + gbox_num;
+	index = mlxsw_hwmon->module_sensor_max;
+	max_index = mlxsw_hwmon->module_sensor_max + gbox_num;
 	while (index < max_index) {
-		sensor_index = index % mlxsw_hwmon->module_sensor_count +
+		sensor_index = index % mlxsw_hwmon->module_sensor_max +
 			       MLXSW_REG_MTMP_GBOX_INDEX_MIN;
 		mlxsw_reg_mtmp_pack(mtmp_pl, sensor_index, true, true);
 		err = mlxsw_reg_write(mlxsw_hwmon->core,
-- 
2.21.0


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

* [PATCH net-next 3/5] mlxsw: thermal: Provide optimization for QSFP modules number detection
  2019-10-06  6:34 [PATCH net-next 0/5] mlxsw: Query number of modules from firmware Ido Schimmel
  2019-10-06  6:34 ` [PATCH net-next 1/5] mlxsw: reg: Extend MGPIR register with new field exposing the number of QSFP modules Ido Schimmel
  2019-10-06  6:34 ` [PATCH net-next 2/5] mlxsw: hwmon: Provide optimization for QSFP modules number detection Ido Schimmel
@ 2019-10-06  6:34 ` Ido Schimmel
  2019-10-06  6:34 ` [PATCH net-next 4/5] mlxsw: core: Push minor/subminor fw version check into helper Ido Schimmel
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2019-10-06  6:34 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, vadimp, mlxsw, Ido Schimmel

From: Vadim Pasternak <vadimp@mellanox.com>

Use new field "num_of_modules" of MGPIR register for "thermal" interface
in order to get the number of modules supported by system directly from
the system configuration, instead of getting it from port to module
mapping info.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/core_thermal.c    | 37 ++++++++-----------
 1 file changed, 16 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
index b2c76a95f671..c721b171bd8d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -112,6 +112,7 @@ struct mlxsw_thermal {
 	struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
 	enum thermal_device_mode mode;
 	struct mlxsw_thermal_module *tz_module_arr;
+	u8 tz_module_num;
 	struct mlxsw_thermal_module *tz_gearbox_arr;
 	u8 tz_gearbox_num;
 	unsigned int tz_highest_score;
@@ -775,23 +776,10 @@ static void mlxsw_thermal_module_tz_fini(struct thermal_zone_device *tzdev)
 
 static int
 mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
-			  struct mlxsw_thermal *thermal, u8 local_port)
+			  struct mlxsw_thermal *thermal, u8 module)
 {
 	struct mlxsw_thermal_module *module_tz;
-	char pmlp_pl[MLXSW_REG_PMLP_LEN];
-	u8 width, module;
-	int err;
-
-	mlxsw_reg_pmlp_pack(pmlp_pl, local_port);
-	err = mlxsw_reg_query(core, MLXSW_REG(pmlp), pmlp_pl);
-	if (err)
-		return err;
 
-	width = mlxsw_reg_pmlp_width_get(pmlp_pl);
-	if (!width)
-		return 0;
-
-	module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
 	module_tz = &thermal->tz_module_arr[module];
 	/* Skip if parent is already set (case of port split). */
 	if (module_tz->parent)
@@ -819,26 +807,34 @@ static int
 mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
 			   struct mlxsw_thermal *thermal)
 {
-	unsigned int module_count = mlxsw_core_max_ports(core);
 	struct mlxsw_thermal_module *module_tz;
+	char mgpir_pl[MLXSW_REG_MGPIR_LEN];
 	int i, err;
 
 	if (!mlxsw_core_res_query_enabled(core))
 		return 0;
 
-	thermal->tz_module_arr = kcalloc(module_count,
+	mlxsw_reg_mgpir_pack(mgpir_pl);
+	err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
+	if (err)
+		return err;
+
+	mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL,
+			       &thermal->tz_module_num);
+
+	thermal->tz_module_arr = kcalloc(thermal->tz_module_num,
 					 sizeof(*thermal->tz_module_arr),
 					 GFP_KERNEL);
 	if (!thermal->tz_module_arr)
 		return -ENOMEM;
 
-	for (i = 1; i < module_count; i++) {
+	for (i = 0; i < thermal->tz_module_num; i++) {
 		err = mlxsw_thermal_module_init(dev, core, thermal, i);
 		if (err)
 			goto err_unreg_tz_module_arr;
 	}
 
-	for (i = 0; i < module_count - 1; i++) {
+	for (i = 0; i < thermal->tz_module_num; i++) {
 		module_tz = &thermal->tz_module_arr[i];
 		if (!module_tz->parent)
 			continue;
@@ -850,7 +846,7 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
 	return 0;
 
 err_unreg_tz_module_arr:
-	for (i = module_count - 1; i >= 0; i--)
+	for (i = thermal->tz_module_num - 1; i >= 0; i--)
 		mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
 	kfree(thermal->tz_module_arr);
 	return err;
@@ -859,13 +855,12 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
 static void
 mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal)
 {
-	unsigned int module_count = mlxsw_core_max_ports(thermal->core);
 	int i;
 
 	if (!mlxsw_core_res_query_enabled(thermal->core))
 		return;
 
-	for (i = module_count - 1; i >= 0; i--)
+	for (i = thermal->tz_module_num - 1; i >= 0; i--)
 		mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
 	kfree(thermal->tz_module_arr);
 }
-- 
2.21.0


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

* [PATCH net-next 4/5] mlxsw: core: Push minor/subminor fw version check into helper
  2019-10-06  6:34 [PATCH net-next 0/5] mlxsw: Query number of modules from firmware Ido Schimmel
                   ` (2 preceding siblings ...)
  2019-10-06  6:34 ` [PATCH net-next 3/5] mlxsw: thermal: " Ido Schimmel
@ 2019-10-06  6:34 ` Ido Schimmel
  2019-10-06  6:34 ` [PATCH net-next 5/5] mlxsw: minimal: Add validation for FW version Ido Schimmel
  2019-10-06 16:32 ` [PATCH net-next 0/5] mlxsw: Query number of modules from firmware David Miller
  5 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2019-10-06  6:34 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, vadimp, mlxsw, Ido Schimmel

From: Vadim Pasternak <vadimp@mellanox.com>

Add new API for FW "minor" and "subminor" version validation for
sharing it between "spectrum" and "minimal" drivers.
Use it in "spectrum" driver.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlxsw/core.c     | 10 ++++++++++
 drivers/net/ethernet/mellanox/mlxsw/core.h     |  5 +++++
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c |  4 +---
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index 1c29522a2af3..2b59f84b14f9 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -127,6 +127,16 @@ bool mlxsw_core_res_query_enabled(const struct mlxsw_core *mlxsw_core)
 }
 EXPORT_SYMBOL(mlxsw_core_res_query_enabled);
 
+bool
+mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev,
+					  const struct mlxsw_fw_rev *req_rev)
+{
+	return rev->minor > req_rev->minor ||
+	       (rev->minor == req_rev->minor &&
+		rev->subminor >= req_rev->subminor);
+}
+EXPORT_SYMBOL(mlxsw_core_fw_rev_minor_subminor_validate);
+
 struct mlxsw_rx_listener_item {
 	struct list_head list;
 	struct mlxsw_rx_listener rxl;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index 3377a1b39b03..f25037074e2d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -24,6 +24,7 @@ struct mlxsw_core_port;
 struct mlxsw_driver;
 struct mlxsw_bus;
 struct mlxsw_bus_info;
+struct mlxsw_fw_rev;
 
 unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core);
 
@@ -31,6 +32,10 @@ void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core);
 
 bool mlxsw_core_res_query_enabled(const struct mlxsw_core *mlxsw_core);
 
+bool
+mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev,
+					  const struct mlxsw_fw_rev *req_rev);
+
 int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
 void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index c91b8238c8c5..3c5154e559b2 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -409,9 +409,7 @@ static int mlxsw_sp_fw_rev_validate(struct mlxsw_sp *mlxsw_sp)
 	}
 	if (MLXSW_SP_FWREV_MINOR_TO_BRANCH(rev->minor) ==
 	    MLXSW_SP_FWREV_MINOR_TO_BRANCH(req_rev->minor) &&
-	    (rev->minor > req_rev->minor ||
-	     (rev->minor == req_rev->minor &&
-	      rev->subminor >= req_rev->subminor)))
+	    mlxsw_core_fw_rev_minor_subminor_validate(rev, req_rev))
 		return 0;
 
 	dev_info(mlxsw_sp->bus_info->dev, "The firmware version %d.%d.%d is incompatible with the driver\n",
-- 
2.21.0


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

* [PATCH net-next 5/5] mlxsw: minimal: Add validation for FW version
  2019-10-06  6:34 [PATCH net-next 0/5] mlxsw: Query number of modules from firmware Ido Schimmel
                   ` (3 preceding siblings ...)
  2019-10-06  6:34 ` [PATCH net-next 4/5] mlxsw: core: Push minor/subminor fw version check into helper Ido Schimmel
@ 2019-10-06  6:34 ` Ido Schimmel
  2019-10-06 16:32 ` [PATCH net-next 0/5] mlxsw: Query number of modules from firmware David Miller
  5 siblings, 0 replies; 7+ messages in thread
From: Ido Schimmel @ 2019-10-06  6:34 UTC (permalink / raw)
  To: netdev; +Cc: davem, jiri, vadimp, mlxsw, Ido Schimmel

From: Vadim Pasternak <vadimp@mellanox.com>

Add validation for FW version in order to prevent driver initialization
in case FW version is older than expected. FW version validation is
necessary, because use of a new field 'num_of_modules' in MGPIR register
is not backward compatible. FW 'minor' and 'subminor' versions are
expected to be greater than or equal to 2000 and 1886, respectively.

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

diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
index 5edd8de57a24..2b543911ae00 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
@@ -16,6 +16,14 @@
 
 static const char mlxsw_m_driver_name[] = "mlxsw_minimal";
 
+#define MLXSW_M_FWREV_MINOR	2000
+#define MLXSW_M_FWREV_SUBMINOR	1886
+
+static const struct mlxsw_fw_rev mlxsw_m_fw_rev = {
+	.minor = MLXSW_M_FWREV_MINOR,
+	.subminor = MLXSW_M_FWREV_SUBMINOR,
+};
+
 struct mlxsw_m_port;
 
 struct mlxsw_m {
@@ -326,6 +334,24 @@ static void mlxsw_m_ports_remove(struct mlxsw_m *mlxsw_m)
 	kfree(mlxsw_m->ports);
 }
 
+static int mlxsw_m_fw_rev_validate(struct mlxsw_m *mlxsw_m)
+{
+	const struct mlxsw_fw_rev *rev = &mlxsw_m->bus_info->fw_rev;
+
+	/* Validate driver and FW are compatible.
+	 * Do not check major version, since it defines chip type, while
+	 * driver is supposed to support any type.
+	 */
+	if (mlxsw_core_fw_rev_minor_subminor_validate(rev, &mlxsw_m_fw_rev))
+		return 0;
+
+	dev_err(mlxsw_m->bus_info->dev, "The firmware version %d.%d.%d is incompatible with the driver (required >= %d.%d.%d)\n",
+		rev->major, rev->minor, rev->subminor, rev->major,
+		mlxsw_m_fw_rev.minor, mlxsw_m_fw_rev.subminor);
+
+	return -EINVAL;
+}
+
 static int mlxsw_m_init(struct mlxsw_core *mlxsw_core,
 			const struct mlxsw_bus_info *mlxsw_bus_info,
 			struct netlink_ext_ack *extack)
@@ -336,6 +362,10 @@ static int mlxsw_m_init(struct mlxsw_core *mlxsw_core,
 	mlxsw_m->core = mlxsw_core;
 	mlxsw_m->bus_info = mlxsw_bus_info;
 
+	err = mlxsw_m_fw_rev_validate(mlxsw_m);
+	if (err)
+		return err;
+
 	err = mlxsw_m_base_mac_get(mlxsw_m);
 	if (err) {
 		dev_err(mlxsw_m->bus_info->dev, "Failed to get base mac\n");
-- 
2.21.0


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

* Re: [PATCH net-next 0/5] mlxsw: Query number of modules from firmware
  2019-10-06  6:34 [PATCH net-next 0/5] mlxsw: Query number of modules from firmware Ido Schimmel
                   ` (4 preceding siblings ...)
  2019-10-06  6:34 ` [PATCH net-next 5/5] mlxsw: minimal: Add validation for FW version Ido Schimmel
@ 2019-10-06 16:32 ` David Miller
  5 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2019-10-06 16:32 UTC (permalink / raw)
  To: idosch; +Cc: netdev, jiri, vadimp, mlxsw, idosch

From: Ido Schimmel <idosch@idosch.org>
Date: Sun,  6 Oct 2019 09:34:47 +0300

> From: Ido Schimmel <idosch@mellanox.com>
> 
> Vadim says:
> 
> The patchset adds support for a new field "num_of_modules" of Management
> General Peripheral Information Register (MGPIR), providing the maximum
> number of QSFP modules, which can be supported by the system.
> 
> It allows to obtain the number of QSFP modules directly from this field,
> as a static data, instead of old method of getting this info through
> "network port to QSFP module" mapping. With the old method, in case of
> port dynamic re-configuration some modules can logically "disappear" as
> a result of port split operations, which can cause some modules to
> appear missing.
> 
> Such scenario can happen on a system equipped with a BMC card, while PCI
> chip driver at host CPU side can perform some ports "split" or "unsplit"
> operations, while BMC side I2C chip driver reads the "port-to-module"
> mapping.
> 
> Add common API for FW "minor" and "subminor" versions validation and
> share it between PCI and I2C based drivers.
> 
> Add FW version validation for "minimal" driver, because use of new field
> "num_of_modules" in MGPIR register is not backward compatible.

Looks good, series applied.

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

end of thread, other threads:[~2019-10-06 16:33 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-06  6:34 [PATCH net-next 0/5] mlxsw: Query number of modules from firmware Ido Schimmel
2019-10-06  6:34 ` [PATCH net-next 1/5] mlxsw: reg: Extend MGPIR register with new field exposing the number of QSFP modules Ido Schimmel
2019-10-06  6:34 ` [PATCH net-next 2/5] mlxsw: hwmon: Provide optimization for QSFP modules number detection Ido Schimmel
2019-10-06  6:34 ` [PATCH net-next 3/5] mlxsw: thermal: " Ido Schimmel
2019-10-06  6:34 ` [PATCH net-next 4/5] mlxsw: core: Push minor/subminor fw version check into helper Ido Schimmel
2019-10-06  6:34 ` [PATCH net-next 5/5] mlxsw: minimal: Add validation for FW version Ido Schimmel
2019-10-06 16:32 ` [PATCH net-next 0/5] mlxsw: Query number of modules from firmware David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).