Made non-upstream patch design order aware
Signed-off-by: Vivek Reddy Karri <vkarri@nvidia.com>
This commit is contained in:
parent
be6cdf0877
commit
c09bc46ddc
@ -1,31 +1,29 @@
|
||||
## Mellanox non-upstream linux kernel patches ##
|
||||
|
||||
To include non-upstream patches into the sonic-linux image during build time, this folder must contain a patch archive.
|
||||
To include non-upstream patches into the sonic-linux image during build time, the directory pointed by EXTERNAL_KERNEL_PATCH_LOC must follow the following structure
|
||||
|
||||
### Structure of the patch archive
|
||||
### Directory Structure
|
||||
|
||||
1. It should contain a file named series. series should provide an order in which the patches have to be applied
|
||||
```
|
||||
admin@build-server:/sonic-buildimage/src/sonic-linux-kernel$ cat linux-5.10.103/non_upstream_patches/series
|
||||
mlx5-Refactor-module-EEPROM-query.patch
|
||||
mlx5-Implement-get_module_eeprom_by_page.patch
|
||||
mlx5-Add-support-for-DSFP-module-EEPROM-dumps.patch
|
||||
```
|
||||
2. All the patches should be present in the same folder where series resides.
|
||||
```
|
||||
EXTERNAL_KERNEL_PATCH_LOC/
|
||||
├──── patches/
|
||||
├── 0001-mlx5-Refactor-module-EEPROM-query.patch.patch
|
||||
├── 0002-mlx5-Implement-get_module_eeprom_by_page.patch.patch
|
||||
├── 0005-mlx5-Add-support-for-DSFP-module-EEPROM-dumps.patch
|
||||
├── .............
|
||||
├──── series.patch
|
||||
```
|
||||
|
||||
1. It should contain a file named series.patch. This should contain a diff that is applied on the sonic-linux-kernel/patch/series file. The diff should include all the non-upstream patches.
|
||||
2. All the patches should be present in the patches folder
|
||||
3. Developers should make sure patches apply cleanly over the existing patches present in the src/sonic-linux-kernel .
|
||||
4. Name of the tarball should match with the one specified under EXTERNAL_KERNEL_PATCH_TAR
|
||||
|
||||
#### Example
|
||||
```
|
||||
admin@build-server:/sonic-buildimage/platform/mellanox/non-upstream-patches$ tar -tf patches.tar.gz
|
||||
./
|
||||
./mlx5-Implement-get_module_eeprom_by_page.patch
|
||||
./mlx5-Add-support-for-DSFP-module-EEPROM-dumps.patch
|
||||
./series
|
||||
./mlx5-Refactor-module-EEPROM-query.patch
|
||||
```
|
||||
|
||||
### Include the archive while building sonic linux kernel
|
||||
### Include the non upstream patches while building sonic linux kernel
|
||||
|
||||
Set `INCLUDE_EXTERNAL_PATCH_TAR=y` using `SONIC_OVERRIDE_BUILD_VARS` to include these changes before building the kernel.
|
||||
- Eg: `NOJESSIE=1 NOSTRETCH=1 NOBUSTER=1 make SONIC_OVERRIDE_BUILD_VARS=' INCLUDE_EXTERNAL_PATCH_TAR=y ' target/debs/bullseye/linux-headers-5.10.0-12-2-common_5.10.103-1_all.deb`
|
||||
Set `INCLUDE_EXTERNAL_PATCHES=y` using `SONIC_OVERRIDE_BUILD_VARS` to include these changes before building the kernel.
|
||||
- Eg: `NOJESSIE=1 NOSTRETCH=1 NOBUSTER=1 make SONIC_OVERRIDE_BUILD_VARS=' INCLUDE_EXTERNAL_PATCHES=y ' target/debs/bullseye/linux-headers-5.10.0-12-2-common_5.10.103-1_all.deb`
|
||||
|
||||
### Downloading the non upstream patch tar while building sonic linux kernel
|
||||
|
||||
To download a publicly accessible tar of the non-upstream patches with the directory structure explained above, use the `EXTERNAL_KERNEL_PATCH_TAR` variable.
|
||||
|
Binary file not shown.
@ -0,0 +1,255 @@
|
||||
From 45dc72bca025600611d6d08e00758618ddb5d7d0 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:41 +0200
|
||||
Subject: [PATCH] mlxsw: core_hwmon: Fix variable names for hwmon attributes
|
||||
|
||||
Replace all local variables 'mlwsw_hwmon_attr' by 'mlxsw_hwmon_attr'.
|
||||
All variable prefixes should start with 'mlxsw' according to the naming
|
||||
convention, so 'mlwsw' is changed to 'mlxsw'.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_hwmon.c | 76 +++++++++----------
|
||||
1 file changed, 38 insertions(+), 38 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
index d41afdfbd..3788d02b5 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
@@ -57,14 +57,14 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
- struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
char mtmp_pl[MLXSW_REG_MTMP_LEN];
|
||||
int temp, index;
|
||||
int err;
|
||||
|
||||
- index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
|
||||
+ index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
|
||||
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);
|
||||
@@ -80,14 +80,14 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
- struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
char mtmp_pl[MLXSW_REG_MTMP_LEN];
|
||||
int temp_max, index;
|
||||
int err;
|
||||
|
||||
- index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
|
||||
+ index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
|
||||
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);
|
||||
@@ -103,9 +103,9 @@ static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
- struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
char mtmp_pl[MLXSW_REG_MTMP_LEN] = {0};
|
||||
unsigned long val;
|
||||
int index;
|
||||
@@ -117,7 +117,7 @@ static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
|
||||
if (val != 1)
|
||||
return -EINVAL;
|
||||
|
||||
- index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
|
||||
+ index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
|
||||
mlxsw_hwmon->module_sensor_max);
|
||||
|
||||
mlxsw_reg_mtmp_sensor_index_set(mtmp_pl, index);
|
||||
@@ -138,13 +138,13 @@ static ssize_t mlxsw_hwmon_fan_rpm_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
- struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
char mfsm_pl[MLXSW_REG_MFSM_LEN];
|
||||
int err;
|
||||
|
||||
- mlxsw_reg_mfsm_pack(mfsm_pl, mlwsw_hwmon_attr->type_index);
|
||||
+ mlxsw_reg_mfsm_pack(mfsm_pl, mlxsw_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");
|
||||
@@ -157,9 +157,9 @@ static ssize_t mlxsw_hwmon_fan_fault_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
- struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
char fore_pl[MLXSW_REG_FORE_LEN];
|
||||
bool fault;
|
||||
int err;
|
||||
@@ -169,7 +169,7 @@ static ssize_t mlxsw_hwmon_fan_fault_show(struct device *dev,
|
||||
dev_err(mlxsw_hwmon->bus_info->dev, "Failed to query fan\n");
|
||||
return err;
|
||||
}
|
||||
- mlxsw_reg_fore_unpack(fore_pl, mlwsw_hwmon_attr->type_index, &fault);
|
||||
+ mlxsw_reg_fore_unpack(fore_pl, mlxsw_hwmon_attr->type_index, &fault);
|
||||
|
||||
return sprintf(buf, "%u\n", fault);
|
||||
}
|
||||
@@ -178,13 +178,13 @@ static ssize_t mlxsw_hwmon_pwm_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
- struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
char mfsc_pl[MLXSW_REG_MFSC_LEN];
|
||||
int err;
|
||||
|
||||
- mlxsw_reg_mfsc_pack(mfsc_pl, mlwsw_hwmon_attr->type_index, 0);
|
||||
+ mlxsw_reg_mfsc_pack(mfsc_pl, mlxsw_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");
|
||||
@@ -198,9 +198,9 @@ 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 =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
- struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
char mfsc_pl[MLXSW_REG_MFSC_LEN];
|
||||
unsigned long val;
|
||||
int err;
|
||||
@@ -211,7 +211,7 @@ static ssize_t mlxsw_hwmon_pwm_store(struct device *dev,
|
||||
if (val > 255)
|
||||
return -EINVAL;
|
||||
|
||||
- mlxsw_reg_mfsc_pack(mfsc_pl, mlwsw_hwmon_attr->type_index, val);
|
||||
+ mlxsw_reg_mfsc_pack(mfsc_pl, mlxsw_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");
|
||||
@@ -224,14 +224,14 @@ static int mlxsw_hwmon_module_temp_get(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
int *p_temp)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
- struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
char mtmp_pl[MLXSW_REG_MTMP_LEN];
|
||||
u8 module;
|
||||
int err;
|
||||
|
||||
- module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
+ module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
|
||||
false, false);
|
||||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
@@ -261,15 +261,15 @@ static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
- struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
char mtbr_pl[MLXSW_REG_MTBR_LEN] = {0};
|
||||
u8 module, fault;
|
||||
u16 temp;
|
||||
int err;
|
||||
|
||||
- module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
+ module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
mlxsw_reg_mtbr_pack(mtbr_pl, MLXSW_REG_MTBR_BASE_MODULE_INDEX + module,
|
||||
1);
|
||||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtbr), mtbr_pl);
|
||||
@@ -303,13 +303,13 @@ static int mlxsw_hwmon_module_temp_critical_get(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
int *p_temp)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
- struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
u8 module;
|
||||
int err;
|
||||
|
||||
- module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
+ 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);
|
||||
if (err) {
|
||||
@@ -337,13 +337,13 @@ static int mlxsw_hwmon_module_temp_emergency_get(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
int *p_temp)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
- struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
u8 module;
|
||||
int err;
|
||||
|
||||
- module = mlwsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
+ 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);
|
||||
if (err) {
|
||||
@@ -373,11 +373,11 @@ mlxsw_hwmon_module_temp_label_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
|
||||
|
||||
return sprintf(buf, "front panel %03u\n",
|
||||
- mlwsw_hwmon_attr->type_index);
|
||||
+ mlxsw_hwmon_attr->type_index);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@@ -385,10 +385,10 @@ mlxsw_hwmon_gbox_temp_label_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
- struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
|
||||
+ struct mlxsw_hwmon_attr *mlxsw_hwmon_attr =
|
||||
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 -
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_attr->hwmon;
|
||||
+ int index = mlxsw_hwmon_attr->type_index -
|
||||
mlxsw_hwmon->module_sensor_max + 1;
|
||||
|
||||
return sprintf(buf, "gearbox %03u\n", index);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,162 @@
|
||||
From d2d0080ec104f01fbf0d6b4750f70f1ebe013495 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:42 +0200
|
||||
Subject: [PATCH] mlxsw: core_thermal: Rename labels according to naming
|
||||
convention
|
||||
|
||||
Rename labels for error flow handling in order to align with naming
|
||||
convention used in rest of 'mlxsw' code.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../ethernet/mellanox/mlxsw/core_thermal.c | 43 ++++++++++---------
|
||||
1 file changed, 23 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
index cc4cddbdb..e5997b6a0 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -401,11 +401,11 @@ static int mlxsw_thermal_module_bind(struct thermal_zone_device *tzdev,
|
||||
trip->min_state,
|
||||
THERMAL_WEIGHT_DEFAULT);
|
||||
if (err < 0)
|
||||
- goto err_bind_cooling_device;
|
||||
+ goto err_thermal_zone_bind_cooling_device;
|
||||
}
|
||||
return 0;
|
||||
|
||||
-err_bind_cooling_device:
|
||||
+err_thermal_zone_bind_cooling_device:
|
||||
for (j = i - 1; j >= 0; j--)
|
||||
thermal_zone_unbind_cooling_device(tzdev, j, cdev);
|
||||
return err;
|
||||
@@ -807,7 +807,7 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
|
||||
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;
|
||||
+ goto err_thermal_module_init;
|
||||
}
|
||||
|
||||
for (i = 0; i < thermal->tz_module_num; i++) {
|
||||
@@ -816,12 +816,13 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
|
||||
continue;
|
||||
err = mlxsw_thermal_module_tz_init(module_tz);
|
||||
if (err)
|
||||
- goto err_unreg_tz_module_arr;
|
||||
+ goto err_thermal_module_tz_init;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
-err_unreg_tz_module_arr:
|
||||
+err_thermal_module_tz_init:
|
||||
+err_thermal_module_init:
|
||||
for (i = thermal->tz_module_num - 1; i >= 0; i--)
|
||||
mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
|
||||
kfree(thermal->tz_module_arr);
|
||||
@@ -912,12 +913,12 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
gearbox_tz->parent = thermal;
|
||||
err = mlxsw_thermal_gearbox_tz_init(gearbox_tz);
|
||||
if (err)
|
||||
- goto err_unreg_tz_gearbox;
|
||||
+ goto err_thermal_gearbox_tz_init;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
-err_unreg_tz_gearbox:
|
||||
+err_thermal_gearbox_tz_init:
|
||||
for (i--; i >= 0; i--)
|
||||
mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
|
||||
kfree(thermal->tz_gearbox_arr);
|
||||
@@ -961,7 +962,7 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to probe PWMs\n");
|
||||
- goto err_free_thermal;
|
||||
+ goto err_reg_query;
|
||||
}
|
||||
mlxsw_reg_mfcr_unpack(mfcr_pl, &freq, &tacho_active, &pwm_active);
|
||||
|
||||
@@ -975,14 +976,14 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfsl),
|
||||
mfsl_pl);
|
||||
if (err)
|
||||
- goto err_free_thermal;
|
||||
+ goto err_reg_query;
|
||||
|
||||
/* set the minimal RPMs to 0 */
|
||||
mlxsw_reg_mfsl_tach_min_set(mfsl_pl, 0);
|
||||
err = mlxsw_reg_write(thermal->core, MLXSW_REG(mfsl),
|
||||
mfsl_pl);
|
||||
if (err)
|
||||
- goto err_free_thermal;
|
||||
+ goto err_reg_write;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++) {
|
||||
@@ -995,7 +996,7 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
if (IS_ERR(cdev)) {
|
||||
err = PTR_ERR(cdev);
|
||||
dev_err(dev, "Failed to register cooling device\n");
|
||||
- goto err_unreg_cdevs;
|
||||
+ goto err_thermal_cooling_device_register;
|
||||
}
|
||||
thermal->cdevs[i] = cdev;
|
||||
}
|
||||
@@ -1020,38 +1021,40 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
if (IS_ERR(thermal->tzdev)) {
|
||||
err = PTR_ERR(thermal->tzdev);
|
||||
dev_err(dev, "Failed to register thermal zone\n");
|
||||
- goto err_unreg_cdevs;
|
||||
+ goto err_thermal_zone_device_register;
|
||||
}
|
||||
|
||||
err = mlxsw_thermal_modules_init(dev, core, thermal);
|
||||
if (err)
|
||||
- goto err_unreg_tzdev;
|
||||
+ goto err_thermal_modules_init;
|
||||
|
||||
err = mlxsw_thermal_gearboxes_init(dev, core, thermal);
|
||||
if (err)
|
||||
- goto err_unreg_modules_tzdev;
|
||||
+ goto err_thermal_gearboxes_init;
|
||||
|
||||
err = thermal_zone_device_enable(thermal->tzdev);
|
||||
if (err)
|
||||
- goto err_unreg_gearboxes;
|
||||
+ goto err_thermal_zone_device_enable;
|
||||
|
||||
*p_thermal = thermal;
|
||||
return 0;
|
||||
|
||||
-err_unreg_gearboxes:
|
||||
+err_thermal_zone_device_enable:
|
||||
mlxsw_thermal_gearboxes_fini(thermal);
|
||||
-err_unreg_modules_tzdev:
|
||||
+err_thermal_gearboxes_init:
|
||||
mlxsw_thermal_modules_fini(thermal);
|
||||
-err_unreg_tzdev:
|
||||
+err_thermal_modules_init:
|
||||
if (thermal->tzdev) {
|
||||
thermal_zone_device_unregister(thermal->tzdev);
|
||||
thermal->tzdev = NULL;
|
||||
}
|
||||
-err_unreg_cdevs:
|
||||
+err_thermal_zone_device_register:
|
||||
+err_thermal_cooling_device_register:
|
||||
for (i = 0; i < MLXSW_MFCR_PWMS_MAX; i++)
|
||||
if (thermal->cdevs[i])
|
||||
thermal_cooling_device_unregister(thermal->cdevs[i]);
|
||||
-err_free_thermal:
|
||||
+err_reg_write:
|
||||
+err_reg_query:
|
||||
devm_kfree(dev, thermal);
|
||||
return err;
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,110 @@
|
||||
From 1186332d9cbf3f7cbd2ed52dfcb594ce4e2d2df8 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:43 +0200
|
||||
Subject: [PATCH] mlxsw: core_thermal: Remove obsolete API for query resource
|
||||
|
||||
Remove obsolete API mlxsw_core_res_query_enabled(), which is only
|
||||
relevant for end-of-life SwitchX-2 ASICs. Support for these ASICs was
|
||||
removed in commit b0d80c013b04 ("mlxsw: Remove Mellanox SwitchX-2 ASIC
|
||||
support").
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.c | 6 ------
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.h | 2 --
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 3 ---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 12 ------------
|
||||
4 files changed, 23 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
index 7938bad70..0b1888318 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
@@ -129,12 +129,6 @@ void *mlxsw_core_driver_priv(struct mlxsw_core *mlxsw_core)
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_core_driver_priv);
|
||||
|
||||
-bool mlxsw_core_res_query_enabled(const struct mlxsw_core *mlxsw_core)
|
||||
-{
|
||||
- return mlxsw_core->driver->res_query_enabled;
|
||||
-}
|
||||
-EXPORT_SYMBOL(mlxsw_core_res_query_enabled);
|
||||
-
|
||||
bool mlxsw_core_temp_warn_enabled(const struct mlxsw_core *mlxsw_core)
|
||||
{
|
||||
return mlxsw_core->driver->temp_warn_enabled;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
index 56efb8e48..0ceb7dae9 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
@@ -30,8 +30,6 @@ unsigned int mlxsw_core_max_ports(const struct mlxsw_core *mlxsw_core);
|
||||
|
||||
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_temp_warn_enabled(const struct mlxsw_core *mlxsw_core);
|
||||
|
||||
bool
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
index 3788d02b5..8b170ad92 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
@@ -655,9 +655,6 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
|
||||
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)
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
index e5997b6a0..9b0cd6f79 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -787,9 +787,6 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
|
||||
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
int i, err;
|
||||
|
||||
- if (!mlxsw_core_res_query_enabled(core))
|
||||
- return 0;
|
||||
-
|
||||
mlxsw_reg_mgpir_pack(mgpir_pl);
|
||||
err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
|
||||
if (err)
|
||||
@@ -834,9 +831,6 @@ mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal)
|
||||
{
|
||||
int i;
|
||||
|
||||
- if (!mlxsw_core_res_query_enabled(thermal->core))
|
||||
- return;
|
||||
-
|
||||
for (i = thermal->tz_module_num - 1; i >= 0; i--)
|
||||
mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
|
||||
kfree(thermal->tz_module_arr);
|
||||
@@ -884,9 +878,6 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
int i;
|
||||
int err;
|
||||
|
||||
- if (!mlxsw_core_res_query_enabled(core))
|
||||
- return 0;
|
||||
-
|
||||
mlxsw_reg_mgpir_pack(mgpir_pl);
|
||||
err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
|
||||
if (err)
|
||||
@@ -930,9 +921,6 @@ mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal)
|
||||
{
|
||||
int i;
|
||||
|
||||
- if (!mlxsw_core_res_query_enabled(thermal->core))
|
||||
- return;
|
||||
-
|
||||
for (i = thermal->tz_gearbox_num - 1; i >= 0; i--)
|
||||
mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
|
||||
kfree(thermal->tz_gearbox_arr);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,51 @@
|
||||
From ad972c6b6591023ddc7547bbcbc5c5e1941b29c5 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:44 +0200
|
||||
Subject: [PATCH] mlxsw: reg: Add "mgpir_" prefix to MGPIR fields comments
|
||||
|
||||
Do the same as for other registers and have "mgpir_" prefix for the
|
||||
MGPIR fields.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index a9119451d..7f7cdb3fc 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -10131,24 +10131,24 @@ enum mlxsw_reg_mgpir_device_type {
|
||||
MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE,
|
||||
};
|
||||
|
||||
-/* device_type
|
||||
+/* mgpir_device_type
|
||||
* Access: RO
|
||||
*/
|
||||
MLXSW_ITEM32(reg, mgpir, device_type, 0x00, 24, 4);
|
||||
|
||||
-/* devices_per_flash
|
||||
+/* mgpir_devices_per_flash
|
||||
* Number of devices of device_type per flash (can be shared by few devices).
|
||||
* Access: RO
|
||||
*/
|
||||
MLXSW_ITEM32(reg, mgpir, devices_per_flash, 0x00, 16, 8);
|
||||
|
||||
-/* num_of_devices
|
||||
+/* mgpir_num_of_devices
|
||||
* Number of devices of device_type.
|
||||
* Access: RO
|
||||
*/
|
||||
MLXSW_ITEM32(reg, mgpir, num_of_devices, 0x00, 0, 8);
|
||||
|
||||
-/* num_of_modules
|
||||
+/* mgpir_num_of_modules
|
||||
* Number of modules.
|
||||
* Access: RO
|
||||
*/
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,102 @@
|
||||
From 4392d92a40328fe18d1152fae6fada74f46fa1a3 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 7 Dec 2021 16:07:31 +0200
|
||||
Subject: [PATCH] mlxsw: core: Remove unnecessary asserts
|
||||
|
||||
Remove unnecessary asserts for module index validation. Leave only one
|
||||
that is actually necessary in mlxsw_env_pmpe_listener_func() where the
|
||||
module index is directly read from the firmware event.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_env.c | 24 -------------------
|
||||
1 file changed, 24 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index 61f7a40c0..4cbed2e3b 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -416,9 +416,6 @@ int mlxsw_env_reset_module(struct net_device *netdev,
|
||||
!(req & (ETH_RESET_PHY << ETH_RESET_SHARED_SHIFT)))
|
||||
return 0;
|
||||
|
||||
- if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
|
||||
- return -EINVAL;
|
||||
-
|
||||
mutex_lock(&mlxsw_env->module_info_lock);
|
||||
|
||||
if (mlxsw_env->module_info[module].num_ports_up) {
|
||||
@@ -458,9 +455,6 @@ mlxsw_env_get_module_power_mode(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
u32 status_bits;
|
||||
int err;
|
||||
|
||||
- if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
|
||||
- return -EINVAL;
|
||||
-
|
||||
mutex_lock(&mlxsw_env->module_info_lock);
|
||||
|
||||
params->policy = mlxsw_env->module_info[module].power_mode_policy;
|
||||
@@ -562,9 +556,6 @@ mlxsw_env_set_module_power_mode(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
bool low_power;
|
||||
int err = 0;
|
||||
|
||||
- if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
|
||||
- return -EINVAL;
|
||||
-
|
||||
if (policy != ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH &&
|
||||
policy != ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Unsupported power mode policy");
|
||||
@@ -903,9 +894,6 @@ mlxsw_env_module_overheat_counter_get(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
|
||||
- if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
|
||||
- return -EINVAL;
|
||||
-
|
||||
mutex_lock(&mlxsw_env->module_info_lock);
|
||||
*p_counter = mlxsw_env->module_info[module].module_overheat_counter;
|
||||
mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
@@ -918,9 +906,6 @@ void mlxsw_env_module_port_map(struct mlxsw_core *mlxsw_core, u8 module)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
|
||||
- if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
|
||||
- return;
|
||||
-
|
||||
mutex_lock(&mlxsw_env->module_info_lock);
|
||||
mlxsw_env->module_info[module].num_ports_mapped++;
|
||||
mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
@@ -931,9 +916,6 @@ void mlxsw_env_module_port_unmap(struct mlxsw_core *mlxsw_core, u8 module)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
|
||||
- if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
|
||||
- return;
|
||||
-
|
||||
mutex_lock(&mlxsw_env->module_info_lock);
|
||||
mlxsw_env->module_info[module].num_ports_mapped--;
|
||||
mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
@@ -945,9 +927,6 @@ int mlxsw_env_module_port_up(struct mlxsw_core *mlxsw_core, u8 module)
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
int err = 0;
|
||||
|
||||
- if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
|
||||
- return -EINVAL;
|
||||
-
|
||||
mutex_lock(&mlxsw_env->module_info_lock);
|
||||
|
||||
if (mlxsw_env->module_info[module].power_mode_policy !=
|
||||
@@ -977,9 +956,6 @@ void mlxsw_env_module_port_down(struct mlxsw_core *mlxsw_core, u8 module)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
|
||||
- if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
|
||||
- return;
|
||||
-
|
||||
mutex_lock(&mlxsw_env->module_info_lock);
|
||||
|
||||
mlxsw_env->module_info[module].num_ports_up--;
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,146 @@
|
||||
From 5c2fb60aa437b4858f15bb8bfb02d9df43b4dd95 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:45 +0200
|
||||
Subject: [PATCH] mlxsw: reg: Extend MTMP register with new slot number field
|
||||
|
||||
Extend MTMP (Management Temperature Register) with new field specifying
|
||||
the slot index. The purpose of this field is to support access to MTMP
|
||||
register for reading temperature sensors on modular systems.
|
||||
For non-modular systems the 'sensor_index' uniquely identifies the cage
|
||||
sensors, while 'slot_index' is always 0. For modular systems the
|
||||
sensors are identified by:
|
||||
- 'slot_index', specifying the slot index, where line card is located;
|
||||
- 'sensor_index', specifying cage sensor within the line card.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_env.c | 2 +-
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 11 ++++++-----
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 6 +++---
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 11 +++++++++--
|
||||
4 files changed, 19 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index 4cbed2e3b..0b43029b2 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -143,7 +143,7 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
|
||||
int page;
|
||||
int err;
|
||||
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
|
||||
+ mlxsw_reg_mtmp_pack(mtmp_pl, 0, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
|
||||
false, false);
|
||||
err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err)
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
index 8b170ad92..71ca3b561 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
@@ -66,7 +66,7 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
|
||||
|
||||
index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
|
||||
mlxsw_hwmon->module_sensor_max);
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
|
||||
+ mlxsw_reg_mtmp_pack(mtmp_pl, 0, 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");
|
||||
@@ -89,7 +89,7 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
|
||||
|
||||
index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
|
||||
mlxsw_hwmon->module_sensor_max);
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
|
||||
+ mlxsw_reg_mtmp_pack(mtmp_pl, 0, 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");
|
||||
@@ -232,8 +232,9 @@ static int mlxsw_hwmon_module_temp_get(struct device *dev,
|
||||
int err;
|
||||
|
||||
module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
|
||||
- false, false);
|
||||
+ mlxsw_reg_mtmp_pack(mtmp_pl, 0,
|
||||
+ MLXSW_REG_MTMP_MODULE_INDEX_MIN + module, false,
|
||||
+ false);
|
||||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to query module temperature\n");
|
||||
@@ -721,7 +722,7 @@ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
|
||||
while (index < max_index) {
|
||||
sensor_index = index % mlxsw_hwmon->module_sensor_max +
|
||||
MLXSW_REG_MTMP_GBOX_INDEX_MIN;
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, sensor_index, true, true);
|
||||
+ mlxsw_reg_mtmp_pack(mtmp_pl, 0, sensor_index, true, true);
|
||||
err = mlxsw_reg_write(mlxsw_hwmon->core,
|
||||
MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err) {
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
index 9b0cd6f79..8d88633c9 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -280,7 +280,7 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
|
||||
int temp;
|
||||
int err;
|
||||
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, 0, false, false);
|
||||
+ mlxsw_reg_mtmp_pack(mtmp_pl, 0, 0, false, false);
|
||||
|
||||
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err) {
|
||||
@@ -440,7 +440,7 @@ mlxsw_thermal_module_temp_and_thresholds_get(struct mlxsw_core *core,
|
||||
int err;
|
||||
|
||||
/* Read module temperature and thresholds. */
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, sensor_index, false, false);
|
||||
+ mlxsw_reg_mtmp_pack(mtmp_pl, 0, sensor_index, false, false);
|
||||
err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err) {
|
||||
/* Set temperature and thresholds to zero to avoid passing
|
||||
@@ -585,7 +585,7 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
|
||||
int err;
|
||||
|
||||
index = MLXSW_REG_MTMP_GBOX_INDEX_MIN + tz->module;
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
|
||||
+ mlxsw_reg_mtmp_pack(mtmp_pl, 0, index, false, false);
|
||||
|
||||
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err)
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index 7f7cdb3fc..52cb58c6d 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -8541,6 +8541,12 @@ MLXSW_ITEM32(reg, mtcap, sensor_count, 0x00, 0, 7);
|
||||
|
||||
MLXSW_REG_DEFINE(mtmp, MLXSW_REG_MTMP_ID, MLXSW_REG_MTMP_LEN);
|
||||
|
||||
+/* reg_mtmp_slot_index
|
||||
+ * Slot index (0: Main board).
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mtmp, slot_index, 0x00, 16, 4);
|
||||
+
|
||||
#define MLXSW_REG_MTMP_MODULE_INDEX_MIN 64
|
||||
#define MLXSW_REG_MTMP_GBOX_INDEX_MIN 256
|
||||
/* reg_mtmp_sensor_index
|
||||
@@ -8630,11 +8636,12 @@ MLXSW_ITEM32(reg, mtmp, temperature_threshold_lo, 0x10, 0, 16);
|
||||
*/
|
||||
MLXSW_ITEM_BUF(reg, mtmp, sensor_name, 0x18, MLXSW_REG_MTMP_SENSOR_NAME_SIZE);
|
||||
|
||||
-static inline void mlxsw_reg_mtmp_pack(char *payload, u16 sensor_index,
|
||||
- bool max_temp_enable,
|
||||
+static inline void mlxsw_reg_mtmp_pack(char *payload, u8 slot_index,
|
||||
+ u16 sensor_index, bool max_temp_enable,
|
||||
bool max_temp_reset)
|
||||
{
|
||||
MLXSW_REG_ZERO(mtmp, payload);
|
||||
+ mlxsw_reg_mtmp_slot_index_set(payload, slot_index);
|
||||
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);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,87 @@
|
||||
From c9c0ae28ab85836ee15920ddafaa3ba45e0dcaeb Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:46 +0200
|
||||
Subject: [PATCH] mlxsw: reg: Extend MTBR register with new slot number field
|
||||
|
||||
Extend MTBR (Management Temperature Bulk Register) with new field
|
||||
specifying the slot number. The purpose of this field is to support
|
||||
access to MTBR register for reading temperature sensors on modular
|
||||
system. For non-modular systems the 'sensor_index' uniquely identifies
|
||||
the cage sensors. For modular systems the sensors are identified by two
|
||||
indexes:
|
||||
- 'slot_index', specifying the slot number, where line card is located;
|
||||
- 'sensor_index', specifying cage sensor within the line card.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_env.c | 4 ++--
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 4 ++--
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 11 +++++++++--
|
||||
3 files changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index 0b43029b2..7feefb38b 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -593,8 +593,8 @@ static int mlxsw_env_module_has_temp_sensor(struct mlxsw_core *mlxsw_core,
|
||||
u16 temp;
|
||||
int err;
|
||||
|
||||
- mlxsw_reg_mtbr_pack(mtbr_pl, MLXSW_REG_MTBR_BASE_MODULE_INDEX + module,
|
||||
- 1);
|
||||
+ mlxsw_reg_mtbr_pack(mtbr_pl, 0,
|
||||
+ MLXSW_REG_MTBR_BASE_MODULE_INDEX + module, 1);
|
||||
err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mtbr), mtbr_pl);
|
||||
if (err)
|
||||
return err;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
index 71ca3b561..f4bc711a1 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
@@ -271,8 +271,8 @@ static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
|
||||
int err;
|
||||
|
||||
module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon->sensor_count;
|
||||
- mlxsw_reg_mtbr_pack(mtbr_pl, MLXSW_REG_MTBR_BASE_MODULE_INDEX + module,
|
||||
- 1);
|
||||
+ mlxsw_reg_mtbr_pack(mtbr_pl, 0,
|
||||
+ MLXSW_REG_MTBR_BASE_MODULE_INDEX + module, 1);
|
||||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtbr), mtbr_pl);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to query module temperature sensor\n");
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index 52cb58c6d..56927c772 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -8707,6 +8707,12 @@ MLXSW_ITEM_BIT_ARRAY(reg, mtwe, sensor_warning, 0x0, 0x10, 1);
|
||||
|
||||
MLXSW_REG_DEFINE(mtbr, MLXSW_REG_MTBR_ID, MLXSW_REG_MTBR_LEN);
|
||||
|
||||
+/* reg_mtbr_slot_index
|
||||
+ * Slot index (0: Main board).
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mtbr, slot_index, 0x00, 16, 4);
|
||||
+
|
||||
/* reg_mtbr_base_sensor_index
|
||||
* Base sensors index to access (0 - ASIC sensor, 1-63 - ambient sensors,
|
||||
* 64-127 are mapped to the SFP+/QSFP modules sequentially).
|
||||
@@ -8739,10 +8745,11 @@ MLXSW_ITEM32_INDEXED(reg, mtbr, rec_max_temp, MLXSW_REG_MTBR_BASE_LEN, 16,
|
||||
MLXSW_ITEM32_INDEXED(reg, mtbr, rec_temp, MLXSW_REG_MTBR_BASE_LEN, 0, 16,
|
||||
MLXSW_REG_MTBR_REC_LEN, 0x00, false);
|
||||
|
||||
-static inline void mlxsw_reg_mtbr_pack(char *payload, u16 base_sensor_index,
|
||||
- u8 num_rec)
|
||||
+static inline void mlxsw_reg_mtbr_pack(char *payload, u8 slot_index,
|
||||
+ u16 base_sensor_index, u8 num_rec)
|
||||
{
|
||||
MLXSW_REG_ZERO(mtbr, payload);
|
||||
+ mlxsw_reg_mtbr_slot_index_set(payload, slot_index);
|
||||
mlxsw_reg_mtbr_base_sensor_index_set(payload, base_sensor_index);
|
||||
mlxsw_reg_mtbr_num_rec_set(payload, num_rec);
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,108 @@
|
||||
From d494bb0c59dd1f6150f189e2878babf53b67e111 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:47 +0200
|
||||
Subject: [PATCH] mlxsw: reg: Extend MCIA register with new slot number field
|
||||
|
||||
Extend MCIA (Management Cable Info Access Register) with new field
|
||||
specifying the slot number. The purpose of this field is to support
|
||||
access to MCIA register for reading cage cable information on modular
|
||||
system. For non-modular systems the 'module' number uniquely identifies
|
||||
the transceiver location. For modular systems the transceivers are
|
||||
identified by two indexes:
|
||||
- 'slot_index', specifying the slot number, where line card is located;
|
||||
- 'module', specifying cage transceiver within the line card.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_env.c | 13 +++++++------
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 14 +++++++++++---
|
||||
2 files changed, 18 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index 7feefb38b..21eacbe0a 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -35,8 +35,8 @@ static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id,
|
||||
u8 ident;
|
||||
int err;
|
||||
|
||||
- mlxsw_reg_mcia_pack(mcia_pl, id, 0, MLXSW_REG_MCIA_PAGE0_LO_OFF, 0, 1,
|
||||
- MLXSW_REG_MCIA_I2C_ADDR_LOW);
|
||||
+ mlxsw_reg_mcia_pack(mcia_pl, 0, id, 0, MLXSW_REG_MCIA_PAGE0_LO_OFF, 0,
|
||||
+ 1, MLXSW_REG_MCIA_I2C_ADDR_LOW);
|
||||
err = mlxsw_reg_query(core, MLXSW_REG(mcia), mcia_pl);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -111,7 +111,8 @@ mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module,
|
||||
}
|
||||
}
|
||||
|
||||
- mlxsw_reg_mcia_pack(mcia_pl, module, 0, page, offset, size, i2c_addr);
|
||||
+ mlxsw_reg_mcia_pack(mcia_pl, 0, module, 0, page, offset, size,
|
||||
+ i2c_addr);
|
||||
|
||||
err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mcia), mcia_pl);
|
||||
if (err)
|
||||
@@ -185,12 +186,12 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
|
||||
page = MLXSW_REG_MCIA_TH_PAGE_CMIS_NUM;
|
||||
else
|
||||
page = MLXSW_REG_MCIA_TH_PAGE_NUM;
|
||||
- mlxsw_reg_mcia_pack(mcia_pl, module, 0, page,
|
||||
+ mlxsw_reg_mcia_pack(mcia_pl, 0, module, 0, page,
|
||||
MLXSW_REG_MCIA_TH_PAGE_OFF + off,
|
||||
MLXSW_REG_MCIA_TH_ITEM_SIZE,
|
||||
MLXSW_REG_MCIA_I2C_ADDR_LOW);
|
||||
} else {
|
||||
- mlxsw_reg_mcia_pack(mcia_pl, module, 0,
|
||||
+ mlxsw_reg_mcia_pack(mcia_pl, 0, module, 0,
|
||||
MLXSW_REG_MCIA_PAGE0_LO,
|
||||
off, MLXSW_REG_MCIA_TH_ITEM_SIZE,
|
||||
MLXSW_REG_MCIA_I2C_ADDR_HIGH);
|
||||
@@ -371,7 +372,7 @@ mlxsw_env_get_module_eeprom_by_page(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
size = min_t(u8, page->length - bytes_read,
|
||||
MLXSW_REG_MCIA_EEPROM_SIZE);
|
||||
|
||||
- mlxsw_reg_mcia_pack(mcia_pl, module, 0, page->page,
|
||||
+ mlxsw_reg_mcia_pack(mcia_pl, 0, module, 0, page->page,
|
||||
device_addr + bytes_read, size,
|
||||
page->i2c_address);
|
||||
mlxsw_reg_mcia_bank_number_set(mcia_pl, page->bank);
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index 56927c772..2714e316c 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -8798,6 +8798,12 @@ MLXSW_ITEM32(reg, mcia, l, 0x00, 31, 1);
|
||||
*/
|
||||
MLXSW_ITEM32(reg, mcia, module, 0x00, 16, 8);
|
||||
|
||||
+/* reg_mcia_slot_index
|
||||
+ * Slot index (0: Main board)
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mcia, slot, 0x00, 12, 4);
|
||||
+
|
||||
enum {
|
||||
MLXSW_REG_MCIA_STATUS_GOOD = 0,
|
||||
/* No response from module's EEPROM. */
|
||||
@@ -8897,11 +8903,13 @@ MLXSW_ITEM_BUF(reg, mcia, eeprom, 0x10, MLXSW_REG_MCIA_EEPROM_SIZE);
|
||||
MLXSW_REG_MCIA_EEPROM_PAGE_LENGTH) / \
|
||||
MLXSW_REG_MCIA_EEPROM_UP_PAGE_LENGTH + 1)
|
||||
|
||||
-static inline void mlxsw_reg_mcia_pack(char *payload, u8 module, u8 lock,
|
||||
- u8 page_number, u16 device_addr,
|
||||
- u8 size, u8 i2c_device_addr)
|
||||
+static inline void mlxsw_reg_mcia_pack(char *payload, u8 slot_index, u8 module,
|
||||
+ u8 lock, u8 page_number,
|
||||
+ u16 device_addr, u8 size,
|
||||
+ u8 i2c_device_addr)
|
||||
{
|
||||
MLXSW_REG_ZERO(mcia, payload);
|
||||
+ mlxsw_reg_mcia_slot_set(payload, slot_index);
|
||||
mlxsw_reg_mcia_module_set(payload, module);
|
||||
mlxsw_reg_mcia_l_set(payload, lock);
|
||||
mlxsw_reg_mcia_page_number_set(payload, page_number);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,68 @@
|
||||
From 9c4ce1a56515e927399a87b63deeacd77ada6b3b Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:50 +0200
|
||||
Subject: [PATCH] mlxsw: reg: Extend MCION register with new slot number field
|
||||
|
||||
Extend MCION (Management Cable IO and Notifications Register) with new
|
||||
field specifying the slot number. The purpose of this field is to
|
||||
support access to MCION register for query cage transceiver on modular
|
||||
system.
|
||||
|
||||
For non-modular systems the 'module' number uniquely identifies the
|
||||
transceiver location. For modular systems the transceivers are
|
||||
identified by two indexes:
|
||||
- 'slot_index', specifying the slot number, where line card is located;
|
||||
- 'module', specifying cage transceiver within the line card.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_env.c | 2 +-
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 9 ++++++++-
|
||||
2 files changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index 21eacbe0a..d88033ec6 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -460,7 +460,7 @@ mlxsw_env_get_module_power_mode(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
|
||||
params->policy = mlxsw_env->module_info[module].power_mode_policy;
|
||||
|
||||
- mlxsw_reg_mcion_pack(mcion_pl, module);
|
||||
+ mlxsw_reg_mcion_pack(mcion_pl, 0, module);
|
||||
err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mcion), mcion_pl);
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to retrieve module's power mode");
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index 2714e316c..243d91f1d 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -9328,6 +9328,12 @@ MLXSW_REG_DEFINE(mcion, MLXSW_REG_MCION_ID, MLXSW_REG_MCION_LEN);
|
||||
*/
|
||||
MLXSW_ITEM32(reg, mcion, module, 0x00, 16, 8);
|
||||
|
||||
+/* reg_mcion_slot_index
|
||||
+ * Slot index.
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mcion, slot_index, 0x00, 12, 4);
|
||||
+
|
||||
enum {
|
||||
MLXSW_REG_MCION_MODULE_STATUS_BITS_PRESENT_MASK = BIT(0),
|
||||
MLXSW_REG_MCION_MODULE_STATUS_BITS_LOW_POWER_MASK = BIT(8),
|
||||
@@ -9339,9 +9345,10 @@ enum {
|
||||
*/
|
||||
MLXSW_ITEM32(reg, mcion, module_status_bits, 0x04, 0, 16);
|
||||
|
||||
-static inline void mlxsw_reg_mcion_pack(char *payload, u8 module)
|
||||
+static inline void mlxsw_reg_mcion_pack(char *payload, u8 slot_index, u8 module)
|
||||
{
|
||||
MLXSW_REG_ZERO(mcion, payload);
|
||||
+ mlxsw_reg_mcion_slot_index_set(payload, slot_index);
|
||||
mlxsw_reg_mcion_module_set(payload, module);
|
||||
}
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,67 @@
|
||||
From d707ce17ce596c2deb97b481dffb24b8c4537fa2 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:51 +0200
|
||||
Subject: [PATCH] mlxsw: reg: Extend PMMP register with new slot number field
|
||||
|
||||
Extend PMMP (Port Module Memory Map Properties Register) with new
|
||||
field specifying the slot number. The purpose of this field is to
|
||||
enable overriding the cable/module memory map advertisement.
|
||||
|
||||
For non-modular systems the 'module' number uniquely identifies the
|
||||
transceiver location. For modular systems the transceivers are
|
||||
identified by two indexes:
|
||||
- 'slot_index', specifying the slot number, where line card is located;
|
||||
- 'module', specifying cage transceiver within the line card.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_env.c | 2 +-
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 9 ++++++++-
|
||||
2 files changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index d88033ec6..49c58197b 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -503,7 +503,7 @@ static int mlxsw_env_module_low_power_set(struct mlxsw_core *mlxsw_core,
|
||||
u16 eeprom_override_mask, eeprom_override;
|
||||
char pmmp_pl[MLXSW_REG_PMMP_LEN];
|
||||
|
||||
- mlxsw_reg_pmmp_pack(pmmp_pl, module);
|
||||
+ mlxsw_reg_pmmp_pack(pmmp_pl, 0, module);
|
||||
mlxsw_reg_pmmp_sticky_set(pmmp_pl, true);
|
||||
/* Mask all the bits except low power mode. */
|
||||
eeprom_override_mask = ~MLXSW_REG_PMMP_EEPROM_OVERRIDE_LOW_POWER_MASK;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index 243d91f1d..c19db16bf 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -5633,6 +5633,12 @@ MLXSW_REG_DEFINE(pmmp, MLXSW_REG_PMMP_ID, MLXSW_REG_PMMP_LEN);
|
||||
*/
|
||||
MLXSW_ITEM32(reg, pmmp, module, 0x00, 16, 8);
|
||||
|
||||
+/* reg_pmmp_slot_index
|
||||
+ * Slot index.
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, pmmp, slot_index, 0x00, 24, 4);
|
||||
+
|
||||
/* reg_pmmp_sticky
|
||||
* When set, will keep eeprom_override values after plug-out event.
|
||||
* Access: OP
|
||||
@@ -5660,9 +5666,10 @@ enum {
|
||||
*/
|
||||
MLXSW_ITEM32(reg, pmmp, eeprom_override, 0x04, 0, 16);
|
||||
|
||||
-static inline void mlxsw_reg_pmmp_pack(char *payload, u8 module)
|
||||
+static inline void mlxsw_reg_pmmp_pack(char *payload, u8 slot_index, u8 module)
|
||||
{
|
||||
MLXSW_REG_ZERO(pmmp, payload);
|
||||
+ mlxsw_reg_pmmp_slot_index_set(payload, slot_index);
|
||||
mlxsw_reg_pmmp_module_set(payload, module);
|
||||
}
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,198 @@
|
||||
From 1373ed22ae41e92c081bb80df4b3c4c0630edbb9 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Wed, 22 Dec 2021 06:11:50 +0000
|
||||
Subject: [PATCH] mlxsw: reg: Extend MGPIR register with new slot fields
|
||||
|
||||
Extend MGPIR (Management General Peripheral Information Register) with
|
||||
new fields specifying the slot number and number of the slots available
|
||||
on system. The purpose of these fields is:
|
||||
- to support access to MPGIR register on modular system for getting the
|
||||
number of cages, equipped on the line card, inserted at specified
|
||||
slot. In case slot number is set zero, MGPIR will provide the
|
||||
information for the main board. For Top of the Rack (non-modular)
|
||||
system it will provide the same as before.
|
||||
- to provide the number of slots supported by system. This data is
|
||||
relevant only in case slot number is set zero.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_env.c | 4 ++--
|
||||
.../net/ethernet/mellanox/mlxsw/core_hwmon.c | 9 +++++----
|
||||
.../ethernet/mellanox/mlxsw/core_thermal.c | 8 ++++----
|
||||
drivers/net/ethernet/mellanox/mlxsw/minimal.c | 4 ++--
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 20 +++++++++++++++++--
|
||||
5 files changed, 31 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index 49c58197b..b1a1204e7 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -985,12 +985,12 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
|
||||
u8 module_count;
|
||||
int i, err;
|
||||
|
||||
- mlxsw_reg_mgpir_pack(mgpir_pl);
|
||||
+ 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, &module_count);
|
||||
+ mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, &module_count, NULL);
|
||||
|
||||
env = kzalloc(struct_size(env, module_info, module_count), GFP_KERNEL);
|
||||
if (!env)
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
index f4bc711a1..2bc4c4556 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
@@ -656,13 +656,13 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
|
||||
u8 module_sensor_max;
|
||||
int i, err;
|
||||
|
||||
- mlxsw_reg_mgpir_pack(mgpir_pl);
|
||||
+ mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
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);
|
||||
+ &module_sensor_max, NULL);
|
||||
|
||||
/* Add extra attributes for module temperature. Sensor index is
|
||||
* assigned to sensor_count value, while all indexed before
|
||||
@@ -707,12 +707,13 @@ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
|
||||
u8 gbox_num;
|
||||
int err;
|
||||
|
||||
- mlxsw_reg_mgpir_pack(mgpir_pl);
|
||||
+ mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL, NULL);
|
||||
+ mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL, NULL,
|
||||
+ NULL);
|
||||
if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE ||
|
||||
!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 8d88633c9..56e0291f1 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -787,13 +787,13 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
|
||||
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
int i, err;
|
||||
|
||||
- mlxsw_reg_mgpir_pack(mgpir_pl);
|
||||
+ mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
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_num, NULL);
|
||||
|
||||
thermal->tz_module_arr = kcalloc(thermal->tz_module_num,
|
||||
sizeof(*thermal->tz_module_arr),
|
||||
@@ -878,13 +878,13 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
int i;
|
||||
int err;
|
||||
|
||||
- mlxsw_reg_mgpir_pack(mgpir_pl);
|
||||
+ mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL,
|
||||
- NULL);
|
||||
+ NULL, NULL);
|
||||
if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE ||
|
||||
!gbox_num)
|
||||
return 0;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
index 3d07c2dcf..b2ffcfda8 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
@@ -280,13 +280,13 @@ static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)
|
||||
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
int i, err;
|
||||
|
||||
- mlxsw_reg_mgpir_pack(mgpir_pl);
|
||||
+ mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
err = mlxsw_reg_query(mlxsw_m->core, MLXSW_REG(mgpir), mgpir_pl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL,
|
||||
- &mlxsw_m->max_ports);
|
||||
+ &mlxsw_m->max_ports, NULL);
|
||||
if (!mlxsw_m->max_ports)
|
||||
return 0;
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index c19db16bf..e981630fd 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -10167,6 +10167,12 @@ enum mlxsw_reg_mgpir_device_type {
|
||||
MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE,
|
||||
};
|
||||
|
||||
+/* mgpir_slot_index
|
||||
+ * Slot index (0: Main board).
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mgpir, slot_index, 0x00, 28, 4);
|
||||
+
|
||||
/* mgpir_device_type
|
||||
* Access: RO
|
||||
*/
|
||||
@@ -10184,21 +10190,29 @@ MLXSW_ITEM32(reg, mgpir, devices_per_flash, 0x00, 16, 8);
|
||||
*/
|
||||
MLXSW_ITEM32(reg, mgpir, num_of_devices, 0x00, 0, 8);
|
||||
|
||||
+/* mgpir_num_of_slots
|
||||
+ * Number of slots in the system.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mgpir, num_of_slots, 0x04, 8, 8);
|
||||
+
|
||||
/* mgpir_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)
|
||||
+static inline void mlxsw_reg_mgpir_pack(char *payload, u8 slot_index)
|
||||
{
|
||||
MLXSW_REG_ZERO(mgpir, payload);
|
||||
+ mlxsw_reg_mgpir_slot_index_set(payload, slot_index);
|
||||
}
|
||||
|
||||
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 *num_of_modules)
|
||||
+ u8 *devices_per_flash, u8 *num_of_modules,
|
||||
+ u8 *num_of_slots)
|
||||
{
|
||||
if (num_of_devices)
|
||||
*num_of_devices = mlxsw_reg_mgpir_num_of_devices_get(payload);
|
||||
@@ -10209,6 +10223,8 @@ mlxsw_reg_mgpir_unpack(char *payload, u8 *num_of_devices,
|
||||
mlxsw_reg_mgpir_devices_per_flash_get(payload);
|
||||
if (num_of_modules)
|
||||
*num_of_modules = mlxsw_reg_mgpir_num_of_modules_get(payload);
|
||||
+ if (num_of_slots)
|
||||
+ *num_of_slots = mlxsw_reg_mgpir_num_of_slots_get(payload);
|
||||
}
|
||||
|
||||
/* MFDE - Monitoring FW Debug Register
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,66 @@
|
||||
From 562fe3c68c9dbcff172eeae8b4f0a84484b5e3e9 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:52 +0200
|
||||
Subject: [PATCH] mlxsw: core_env: Pass slot index during PMAOS register write
|
||||
call
|
||||
|
||||
Pass the slot index down to PMAOS pack helper alongside with the module.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_env.c | 6 +++---
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 3 ++-
|
||||
2 files changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index b1a1204e7..45058d4cf 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -400,7 +400,7 @@ static int mlxsw_env_module_reset(struct mlxsw_core *mlxsw_core, u8 module)
|
||||
{
|
||||
char pmaos_pl[MLXSW_REG_PMAOS_LEN];
|
||||
|
||||
- mlxsw_reg_pmaos_pack(pmaos_pl, module);
|
||||
+ mlxsw_reg_pmaos_pack(pmaos_pl, 0, module);
|
||||
mlxsw_reg_pmaos_rst_set(pmaos_pl, true);
|
||||
|
||||
return mlxsw_reg_write(mlxsw_core, MLXSW_REG(pmaos), pmaos_pl);
|
||||
@@ -488,7 +488,7 @@ static int mlxsw_env_module_enable_set(struct mlxsw_core *mlxsw_core,
|
||||
enum mlxsw_reg_pmaos_admin_status admin_status;
|
||||
char pmaos_pl[MLXSW_REG_PMAOS_LEN];
|
||||
|
||||
- mlxsw_reg_pmaos_pack(pmaos_pl, module);
|
||||
+ mlxsw_reg_pmaos_pack(pmaos_pl, 0, module);
|
||||
admin_status = enable ? MLXSW_REG_PMAOS_ADMIN_STATUS_ENABLED :
|
||||
MLXSW_REG_PMAOS_ADMIN_STATUS_DISABLED;
|
||||
mlxsw_reg_pmaos_admin_status_set(pmaos_pl, admin_status);
|
||||
@@ -878,7 +878,7 @@ mlxsw_env_module_oper_state_event_enable(struct mlxsw_core *mlxsw_core,
|
||||
for (i = 0; i < module_count; i++) {
|
||||
char pmaos_pl[MLXSW_REG_PMAOS_LEN];
|
||||
|
||||
- mlxsw_reg_pmaos_pack(pmaos_pl, i);
|
||||
+ mlxsw_reg_pmaos_pack(pmaos_pl, 0, i);
|
||||
mlxsw_reg_pmaos_e_set(pmaos_pl,
|
||||
MLXSW_REG_PMAOS_E_GENERATE_EVENT);
|
||||
mlxsw_reg_pmaos_ee_set(pmaos_pl, true);
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index e981630fd..748a22ec4 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -5481,9 +5481,10 @@ enum mlxsw_reg_pmaos_e {
|
||||
*/
|
||||
MLXSW_ITEM32(reg, pmaos, e, 0x04, 0, 2);
|
||||
|
||||
-static inline void mlxsw_reg_pmaos_pack(char *payload, u8 module)
|
||||
+static inline void mlxsw_reg_pmaos_pack(char *payload, u8 slot_index, u8 module)
|
||||
{
|
||||
MLXSW_REG_ZERO(pmaos, payload);
|
||||
+ mlxsw_reg_pmaos_slot_index_set(payload, slot_index);
|
||||
mlxsw_reg_pmaos_module_set(payload, module);
|
||||
}
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,38 @@
|
||||
From fe27f006de6b428fe59acb1960373b32e59adf0b Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:49 +0200
|
||||
Subject: [PATCH] mlxsw: reg: Add new field to Management General Peripheral
|
||||
Information Register
|
||||
|
||||
Add new field 'max_modules_per_slot' to provide maximum number of
|
||||
modules that can be connected per slot. This field will always be zero,
|
||||
if 'slot_index' in query request is set to non-zero value, otherwise
|
||||
value in this field will provide maximum modules number, which can be
|
||||
equipped on device inserted at any slot.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index 748a22ec4..9de037b9a 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -10191,6 +10191,12 @@ MLXSW_ITEM32(reg, mgpir, devices_per_flash, 0x00, 16, 8);
|
||||
*/
|
||||
MLXSW_ITEM32(reg, mgpir, num_of_devices, 0x00, 0, 8);
|
||||
|
||||
+/* max_modules_per_slot
|
||||
+ * Maximum number of modules that can be connected per slot.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mgpir, max_modules_per_slot, 0x04, 16, 8);
|
||||
+
|
||||
/* mgpir_num_of_slots
|
||||
* Number of slots in the system.
|
||||
* Access: RO
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,828 @@
|
||||
From 5577988f783619b9d55f19c983ee8667f52165b7 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Fri, 3 Dec 2021 11:48:53 +0200
|
||||
Subject: [PATCH] mlxsw: core: Extend interfaces for cable info access with
|
||||
slot argument
|
||||
|
||||
Extend all cable info APIs with 'slot_index' argument.
|
||||
|
||||
For main board, slot will always be set to zero and these APIs will work
|
||||
as before. If reading cable information is required from cages located
|
||||
on line cards, slot should be set to the physical slot number, where
|
||||
line card is located in modular systems.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_env.c | 172 +++++++++++-------
|
||||
.../net/ethernet/mellanox/mlxsw/core_env.h | 43 +++--
|
||||
.../net/ethernet/mellanox/mlxsw/core_hwmon.c | 10 +-
|
||||
.../ethernet/mellanox/mlxsw/core_thermal.c | 4 +-
|
||||
drivers/net/ethernet/mellanox/mlxsw/minimal.c | 21 ++-
|
||||
.../net/ethernet/mellanox/mlxsw/spectrum.c | 2 +-
|
||||
.../mellanox/mlxsw/spectrum_ethtool.c | 10 +-
|
||||
7 files changed, 155 insertions(+), 107 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index 45058d4cf..fefb9bb02 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -27,16 +27,18 @@ struct mlxsw_env {
|
||||
struct mlxsw_env_module_info module_info[];
|
||||
};
|
||||
|
||||
-static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id,
|
||||
- bool *qsfp, bool *cmis)
|
||||
+static int
|
||||
+mlxsw_env_validate_cable_ident(struct mlxsw_core *core, u8 slot_index, int id,
|
||||
+ bool *qsfp, bool *cmis)
|
||||
{
|
||||
char mcia_pl[MLXSW_REG_MCIA_LEN];
|
||||
char *eeprom_tmp;
|
||||
u8 ident;
|
||||
int err;
|
||||
|
||||
- mlxsw_reg_mcia_pack(mcia_pl, 0, id, 0, MLXSW_REG_MCIA_PAGE0_LO_OFF, 0,
|
||||
- 1, MLXSW_REG_MCIA_I2C_ADDR_LOW);
|
||||
+ mlxsw_reg_mcia_pack(mcia_pl, slot_index, id, 0,
|
||||
+ MLXSW_REG_MCIA_PAGE0_LO_OFF, 0, 1,
|
||||
+ MLXSW_REG_MCIA_I2C_ADDR_LOW);
|
||||
err = mlxsw_reg_query(core, MLXSW_REG(mcia), mcia_pl);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -65,8 +67,8 @@ static int mlxsw_env_validate_cable_ident(struct mlxsw_core *core, int id,
|
||||
}
|
||||
|
||||
static int
|
||||
-mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module,
|
||||
- u16 offset, u16 size, void *data,
|
||||
+mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ int module, u16 offset, u16 size, void *data,
|
||||
bool qsfp, unsigned int *p_read_size)
|
||||
{
|
||||
char mcia_pl[MLXSW_REG_MCIA_LEN];
|
||||
@@ -111,7 +113,7 @@ mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module,
|
||||
}
|
||||
}
|
||||
|
||||
- mlxsw_reg_mcia_pack(mcia_pl, 0, module, 0, page, offset, size,
|
||||
+ mlxsw_reg_mcia_pack(mcia_pl, slot_index, module, 0, page, offset, size,
|
||||
i2c_addr);
|
||||
|
||||
err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mcia), mcia_pl);
|
||||
@@ -129,8 +131,9 @@ mlxsw_env_query_module_eeprom(struct mlxsw_core *mlxsw_core, int module,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-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)
|
||||
{
|
||||
unsigned int module_temp, module_crit, module_emerg;
|
||||
union {
|
||||
@@ -144,8 +147,9 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
|
||||
int page;
|
||||
int err;
|
||||
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, 0, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
|
||||
- false, false);
|
||||
+ mlxsw_reg_mtmp_pack(mtmp_pl, slot_index,
|
||||
+ MLXSW_REG_MTMP_MODULE_INDEX_MIN + module, false,
|
||||
+ false);
|
||||
err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err)
|
||||
return err;
|
||||
@@ -174,7 +178,8 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
|
||||
*/
|
||||
|
||||
/* Validate module identifier value. */
|
||||
- err = mlxsw_env_validate_cable_ident(core, module, &qsfp, &cmis);
|
||||
+ err = mlxsw_env_validate_cable_ident(core, slot_index, module, &qsfp,
|
||||
+ &cmis);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -186,12 +191,12 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
|
||||
page = MLXSW_REG_MCIA_TH_PAGE_CMIS_NUM;
|
||||
else
|
||||
page = MLXSW_REG_MCIA_TH_PAGE_NUM;
|
||||
- mlxsw_reg_mcia_pack(mcia_pl, 0, module, 0, page,
|
||||
+ mlxsw_reg_mcia_pack(mcia_pl, slot_index, module, 0, page,
|
||||
MLXSW_REG_MCIA_TH_PAGE_OFF + off,
|
||||
MLXSW_REG_MCIA_TH_ITEM_SIZE,
|
||||
MLXSW_REG_MCIA_I2C_ADDR_LOW);
|
||||
} else {
|
||||
- mlxsw_reg_mcia_pack(mcia_pl, 0, module, 0,
|
||||
+ mlxsw_reg_mcia_pack(mcia_pl, slot_index, module, 0,
|
||||
MLXSW_REG_MCIA_PAGE0_LO,
|
||||
off, MLXSW_REG_MCIA_TH_ITEM_SIZE,
|
||||
MLXSW_REG_MCIA_I2C_ADDR_HIGH);
|
||||
@@ -208,8 +213,8 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, int module,
|
||||
- struct ethtool_modinfo *modinfo)
|
||||
+int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ int module, struct ethtool_modinfo *modinfo)
|
||||
{
|
||||
u8 module_info[MLXSW_REG_MCIA_EEPROM_MODULE_INFO_SIZE];
|
||||
u16 offset = MLXSW_REG_MCIA_EEPROM_MODULE_INFO_SIZE;
|
||||
@@ -217,8 +222,9 @@ int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, int module,
|
||||
unsigned int read_size;
|
||||
int err;
|
||||
|
||||
- err = mlxsw_env_query_module_eeprom(mlxsw_core, module, 0, offset,
|
||||
- module_info, false, &read_size);
|
||||
+ err = mlxsw_env_query_module_eeprom(mlxsw_core, slot_index, module, 0,
|
||||
+ offset, module_info, false,
|
||||
+ &read_size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -247,9 +253,10 @@ int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, int module,
|
||||
break;
|
||||
case MLXSW_REG_MCIA_EEPROM_MODULE_INFO_ID_SFP:
|
||||
/* Verify if transceiver provides diagnostic monitoring page */
|
||||
- err = mlxsw_env_query_module_eeprom(mlxsw_core, module,
|
||||
- SFP_DIAGMON, 1, &diag_mon,
|
||||
- false, &read_size);
|
||||
+ err = mlxsw_env_query_module_eeprom(mlxsw_core, slot_index,
|
||||
+ module, SFP_DIAGMON, 1,
|
||||
+ &diag_mon, false,
|
||||
+ &read_size);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -288,8 +295,9 @@ int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, int module,
|
||||
EXPORT_SYMBOL(mlxsw_env_get_module_info);
|
||||
|
||||
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 offset = ee->offset;
|
||||
unsigned int read_size;
|
||||
@@ -302,12 +310,14 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev,
|
||||
|
||||
memset(data, 0, ee->len);
|
||||
/* Validate module identifier value. */
|
||||
- err = mlxsw_env_validate_cable_ident(mlxsw_core, module, &qsfp, &cmis);
|
||||
+ err = mlxsw_env_validate_cable_ident(mlxsw_core, slot_index, module,
|
||||
+ &qsfp, &cmis);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
while (i < ee->len) {
|
||||
- err = mlxsw_env_query_module_eeprom(mlxsw_core, module, offset,
|
||||
+ err = mlxsw_env_query_module_eeprom(mlxsw_core, slot_index,
|
||||
+ module, offset,
|
||||
ee->len - i, data + i,
|
||||
qsfp, &read_size);
|
||||
if (err) {
|
||||
@@ -353,7 +363,8 @@ static int mlxsw_env_mcia_status_process(const char *mcia_pl,
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -372,7 +383,7 @@ mlxsw_env_get_module_eeprom_by_page(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
size = min_t(u8, page->length - bytes_read,
|
||||
MLXSW_REG_MCIA_EEPROM_SIZE);
|
||||
|
||||
- mlxsw_reg_mcia_pack(mcia_pl, 0, module, 0, page->page,
|
||||
+ mlxsw_reg_mcia_pack(mcia_pl, slot_index, module, 0, page->page,
|
||||
device_addr + bytes_read, size,
|
||||
page->i2c_address);
|
||||
mlxsw_reg_mcia_bank_number_set(mcia_pl, page->bank);
|
||||
@@ -396,18 +407,20 @@ mlxsw_env_get_module_eeprom_by_page(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_get_module_eeprom_by_page);
|
||||
|
||||
-static int mlxsw_env_module_reset(struct mlxsw_core *mlxsw_core, u8 module)
|
||||
+static int mlxsw_env_module_reset(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ u8 module)
|
||||
{
|
||||
char pmaos_pl[MLXSW_REG_PMAOS_LEN];
|
||||
|
||||
- mlxsw_reg_pmaos_pack(pmaos_pl, 0, module);
|
||||
+ mlxsw_reg_pmaos_pack(pmaos_pl, slot_index, module);
|
||||
mlxsw_reg_pmaos_rst_set(pmaos_pl, true);
|
||||
|
||||
return mlxsw_reg_write(mlxsw_core, MLXSW_REG(pmaos), pmaos_pl);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
u32 req = *flags;
|
||||
@@ -432,7 +445,7 @@ int mlxsw_env_reset_module(struct net_device *netdev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- err = mlxsw_env_module_reset(mlxsw_core, module);
|
||||
+ err = mlxsw_env_module_reset(mlxsw_core, slot_index, module);
|
||||
if (err) {
|
||||
netdev_err(netdev, "Failed to reset module\n");
|
||||
goto out;
|
||||
@@ -447,7 +460,8 @@ int mlxsw_env_reset_module(struct net_device *netdev,
|
||||
EXPORT_SYMBOL(mlxsw_env_reset_module);
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -460,7 +474,7 @@ mlxsw_env_get_module_power_mode(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
|
||||
params->policy = mlxsw_env->module_info[module].power_mode_policy;
|
||||
|
||||
- mlxsw_reg_mcion_pack(mcion_pl, 0, module);
|
||||
+ mlxsw_reg_mcion_pack(mcion_pl, slot_index, module);
|
||||
err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mcion), mcion_pl);
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to retrieve module's power mode");
|
||||
@@ -483,12 +497,12 @@ mlxsw_env_get_module_power_mode(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
EXPORT_SYMBOL(mlxsw_env_get_module_power_mode);
|
||||
|
||||
static int mlxsw_env_module_enable_set(struct mlxsw_core *mlxsw_core,
|
||||
- u8 module, bool enable)
|
||||
+ u8 slot_index, u8 module, bool enable)
|
||||
{
|
||||
enum mlxsw_reg_pmaos_admin_status admin_status;
|
||||
char pmaos_pl[MLXSW_REG_PMAOS_LEN];
|
||||
|
||||
- mlxsw_reg_pmaos_pack(pmaos_pl, 0, module);
|
||||
+ mlxsw_reg_pmaos_pack(pmaos_pl, slot_index, module);
|
||||
admin_status = enable ? MLXSW_REG_PMAOS_ADMIN_STATUS_ENABLED :
|
||||
MLXSW_REG_PMAOS_ADMIN_STATUS_DISABLED;
|
||||
mlxsw_reg_pmaos_admin_status_set(pmaos_pl, admin_status);
|
||||
@@ -498,12 +512,13 @@ static int mlxsw_env_module_enable_set(struct mlxsw_core *mlxsw_core,
|
||||
}
|
||||
|
||||
static int mlxsw_env_module_low_power_set(struct mlxsw_core *mlxsw_core,
|
||||
- u8 module, bool low_power)
|
||||
+ u8 slot_index, u8 module,
|
||||
+ bool low_power)
|
||||
{
|
||||
u16 eeprom_override_mask, eeprom_override;
|
||||
char pmmp_pl[MLXSW_REG_PMMP_LEN];
|
||||
|
||||
- mlxsw_reg_pmmp_pack(pmmp_pl, 0, module);
|
||||
+ mlxsw_reg_pmmp_pack(pmmp_pl, slot_index, module);
|
||||
mlxsw_reg_pmmp_sticky_set(pmmp_pl, true);
|
||||
/* Mask all the bits except low power mode. */
|
||||
eeprom_override_mask = ~MLXSW_REG_PMMP_EEPROM_OVERRIDE_LOW_POWER_MASK;
|
||||
@@ -516,24 +531,26 @@ static int mlxsw_env_module_low_power_set(struct mlxsw_core *mlxsw_core,
|
||||
}
|
||||
|
||||
static int __mlxsw_env_set_module_power_mode(struct mlxsw_core *mlxsw_core,
|
||||
- u8 module, bool low_power,
|
||||
+ u8 slot_index, u8 module,
|
||||
+ bool low_power,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
int err;
|
||||
|
||||
- err = mlxsw_env_module_enable_set(mlxsw_core, module, false);
|
||||
+ err = mlxsw_env_module_enable_set(mlxsw_core, slot_index, module, false);
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to disable module");
|
||||
return err;
|
||||
}
|
||||
|
||||
- err = mlxsw_env_module_low_power_set(mlxsw_core, module, low_power);
|
||||
+ err = mlxsw_env_module_low_power_set(mlxsw_core, slot_index, module,
|
||||
+ low_power);
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to set module's power mode");
|
||||
goto err_module_low_power_set;
|
||||
}
|
||||
|
||||
- err = mlxsw_env_module_enable_set(mlxsw_core, module, true);
|
||||
+ err = mlxsw_env_module_enable_set(mlxsw_core, slot_index, module, true);
|
||||
if (err) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to enable module");
|
||||
goto err_module_enable_set;
|
||||
@@ -542,14 +559,16 @@ static int __mlxsw_env_set_module_power_mode(struct mlxsw_core *mlxsw_core,
|
||||
return 0;
|
||||
|
||||
err_module_enable_set:
|
||||
- mlxsw_env_module_low_power_set(mlxsw_core, module, !low_power);
|
||||
+ mlxsw_env_module_low_power_set(mlxsw_core, slot_index, module,
|
||||
+ !low_power);
|
||||
err_module_low_power_set:
|
||||
- mlxsw_env_module_enable_set(mlxsw_core, module, true);
|
||||
+ mlxsw_env_module_enable_set(mlxsw_core, slot_index, module, true);
|
||||
return err;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -573,8 +592,8 @@ mlxsw_env_set_module_power_mode(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
goto out_set_policy;
|
||||
|
||||
low_power = policy == ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO;
|
||||
- err = __mlxsw_env_set_module_power_mode(mlxsw_core, module, low_power,
|
||||
- extack);
|
||||
+ err = __mlxsw_env_set_module_power_mode(mlxsw_core, slot_index, module,
|
||||
+ low_power, extack);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@@ -587,14 +606,14 @@ mlxsw_env_set_module_power_mode(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
EXPORT_SYMBOL(mlxsw_env_set_module_power_mode);
|
||||
|
||||
static int mlxsw_env_module_has_temp_sensor(struct mlxsw_core *mlxsw_core,
|
||||
- u8 module,
|
||||
+ u8 slot_index, u8 module,
|
||||
bool *p_has_temp_sensor)
|
||||
{
|
||||
char mtbr_pl[MLXSW_REG_MTBR_LEN];
|
||||
u16 temp;
|
||||
int err;
|
||||
|
||||
- mlxsw_reg_mtbr_pack(mtbr_pl, 0,
|
||||
+ mlxsw_reg_mtbr_pack(mtbr_pl, slot_index,
|
||||
MLXSW_REG_MTBR_BASE_MODULE_INDEX + module, 1);
|
||||
err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mtbr), mtbr_pl);
|
||||
if (err)
|
||||
@@ -615,13 +634,15 @@ static int mlxsw_env_module_has_temp_sensor(struct mlxsw_core *mlxsw_core,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int mlxsw_env_temp_event_set(struct mlxsw_core *mlxsw_core,
|
||||
- u16 sensor_index, bool enable)
|
||||
+static int
|
||||
+mlxsw_env_temp_event_set(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ u16 sensor_index, bool enable)
|
||||
{
|
||||
char mtmp_pl[MLXSW_REG_MTMP_LEN] = {0};
|
||||
enum mlxsw_reg_mtmp_tee tee;
|
||||
int err, threshold_hi;
|
||||
|
||||
+ mlxsw_reg_mtmp_slot_index_set(mtmp_pl, slot_index);
|
||||
mlxsw_reg_mtmp_sensor_index_set(mtmp_pl, sensor_index);
|
||||
err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err)
|
||||
@@ -629,6 +650,7 @@ static int mlxsw_env_temp_event_set(struct mlxsw_core *mlxsw_core,
|
||||
|
||||
if (enable) {
|
||||
err = mlxsw_env_module_temp_thresholds_get(mlxsw_core,
|
||||
+ slot_index,
|
||||
sensor_index -
|
||||
MLXSW_REG_MTMP_MODULE_INDEX_MIN,
|
||||
SFP_TEMP_HIGH_WARN,
|
||||
@@ -656,14 +678,14 @@ static int mlxsw_env_temp_event_set(struct mlxsw_core *mlxsw_core,
|
||||
}
|
||||
|
||||
static int mlxsw_env_module_temp_event_enable(struct mlxsw_core *mlxsw_core,
|
||||
- u8 module_count)
|
||||
+ u8 slot_index, u8 module_count)
|
||||
{
|
||||
int i, err, sensor_index;
|
||||
bool has_temp_sensor;
|
||||
|
||||
for (i = 0; i < module_count; i++) {
|
||||
- err = mlxsw_env_module_has_temp_sensor(mlxsw_core, i,
|
||||
- &has_temp_sensor);
|
||||
+ err = mlxsw_env_module_has_temp_sensor(mlxsw_core, slot_index,
|
||||
+ i, &has_temp_sensor);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -671,7 +693,8 @@ static int mlxsw_env_module_temp_event_enable(struct mlxsw_core *mlxsw_core,
|
||||
continue;
|
||||
|
||||
sensor_index = i + MLXSW_REG_MTMP_MODULE_INDEX_MIN;
|
||||
- err = mlxsw_env_temp_event_set(mlxsw_core, sensor_index, true);
|
||||
+ err = mlxsw_env_temp_event_set(mlxsw_core, slot_index,
|
||||
+ sensor_index, true);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@@ -778,6 +801,7 @@ static void mlxsw_env_temp_warn_event_unregister(struct mlxsw_env *mlxsw_env)
|
||||
|
||||
struct mlxsw_env_module_plug_unplug_event {
|
||||
struct mlxsw_env *mlxsw_env;
|
||||
+ u8 slot_index;
|
||||
u8 module;
|
||||
struct work_struct work;
|
||||
};
|
||||
@@ -798,7 +822,9 @@ static void mlxsw_env_pmpe_event_work(struct work_struct *work)
|
||||
mlxsw_env->module_info[event->module].is_overheat = false;
|
||||
mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
|
||||
- err = mlxsw_env_module_has_temp_sensor(mlxsw_env->core, event->module,
|
||||
+ err = mlxsw_env_module_has_temp_sensor(mlxsw_env->core,
|
||||
+ event->slot_index,
|
||||
+ event->module,
|
||||
&has_temp_sensor);
|
||||
/* Do not disable events on modules without sensors or faulty sensors
|
||||
* because FW returns errors.
|
||||
@@ -810,7 +836,8 @@ static void mlxsw_env_pmpe_event_work(struct work_struct *work)
|
||||
goto out;
|
||||
|
||||
sensor_index = event->module + MLXSW_REG_MTMP_MODULE_INDEX_MIN;
|
||||
- mlxsw_env_temp_event_set(mlxsw_env->core, sensor_index, true);
|
||||
+ mlxsw_env_temp_event_set(mlxsw_env->core, event->slot_index,
|
||||
+ sensor_index, true);
|
||||
|
||||
out:
|
||||
kfree(event);
|
||||
@@ -837,6 +864,7 @@ mlxsw_env_pmpe_listener_func(const struct mlxsw_reg_info *reg, char *pmpe_pl,
|
||||
return;
|
||||
|
||||
event->mlxsw_env = mlxsw_env;
|
||||
+ event->slot_index = 0;
|
||||
event->module = module;
|
||||
INIT_WORK(&event->work, mlxsw_env_pmpe_event_work);
|
||||
mlxsw_core_schedule_work(&event->work);
|
||||
@@ -871,14 +899,14 @@ mlxsw_env_module_plug_event_unregister(struct mlxsw_env *mlxsw_env)
|
||||
|
||||
static int
|
||||
mlxsw_env_module_oper_state_event_enable(struct mlxsw_core *mlxsw_core,
|
||||
- u8 module_count)
|
||||
+ u8 slot_index, u8 module_count)
|
||||
{
|
||||
int i, err;
|
||||
|
||||
for (i = 0; i < module_count; i++) {
|
||||
char pmaos_pl[MLXSW_REG_PMAOS_LEN];
|
||||
|
||||
- mlxsw_reg_pmaos_pack(pmaos_pl, 0, i);
|
||||
+ mlxsw_reg_pmaos_pack(pmaos_pl, slot_index, i);
|
||||
mlxsw_reg_pmaos_e_set(pmaos_pl,
|
||||
MLXSW_REG_PMAOS_E_GENERATE_EVENT);
|
||||
mlxsw_reg_pmaos_ee_set(pmaos_pl, true);
|
||||
@@ -890,8 +918,8 @@ mlxsw_env_module_oper_state_event_enable(struct mlxsw_core *mlxsw_core,
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
|
||||
@@ -903,7 +931,8 @@ mlxsw_env_module_overheat_counter_get(struct mlxsw_core *mlxsw_core, u8 module,
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_module_overheat_counter_get);
|
||||
|
||||
-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)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
|
||||
@@ -913,7 +942,8 @@ void mlxsw_env_module_port_map(struct mlxsw_core *mlxsw_core, u8 module)
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_module_port_map);
|
||||
|
||||
-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)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
|
||||
@@ -923,7 +953,8 @@ void mlxsw_env_module_port_unmap(struct mlxsw_core *mlxsw_core, u8 module)
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_module_port_unmap);
|
||||
|
||||
-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)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
int err = 0;
|
||||
@@ -940,8 +971,8 @@ int mlxsw_env_module_port_up(struct mlxsw_core *mlxsw_core, u8 module)
|
||||
/* Transition to high power mode following first port using the module
|
||||
* being put administratively up.
|
||||
*/
|
||||
- err = __mlxsw_env_set_module_power_mode(mlxsw_core, module, false,
|
||||
- NULL);
|
||||
+ err = __mlxsw_env_set_module_power_mode(mlxsw_core, slot_index, module,
|
||||
+ false, NULL);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
|
||||
@@ -953,7 +984,8 @@ int mlxsw_env_module_port_up(struct mlxsw_core *mlxsw_core, u8 module)
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_module_port_up);
|
||||
|
||||
-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)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
|
||||
@@ -971,7 +1003,8 @@ void mlxsw_env_module_port_down(struct mlxsw_core *mlxsw_core, u8 module)
|
||||
/* Transition to low power mode following last port using the module
|
||||
* being put administratively down.
|
||||
*/
|
||||
- __mlxsw_env_set_module_power_mode(mlxsw_core, module, true, NULL);
|
||||
+ __mlxsw_env_set_module_power_mode(mlxsw_core, slot_index, module, true,
|
||||
+ NULL);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
@@ -1016,12 +1049,13 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
|
||||
if (err)
|
||||
goto err_module_plug_event_register;
|
||||
|
||||
- err = mlxsw_env_module_oper_state_event_enable(mlxsw_core,
|
||||
+ err = mlxsw_env_module_oper_state_event_enable(mlxsw_core, 0,
|
||||
env->module_count);
|
||||
if (err)
|
||||
goto err_oper_state_event_enable;
|
||||
|
||||
- err = mlxsw_env_module_temp_event_enable(mlxsw_core, env->module_count);
|
||||
+ err = mlxsw_env_module_temp_event_enable(mlxsw_core, 0,
|
||||
+ env->module_count);
|
||||
if (err)
|
||||
goto err_temp_event_enable;
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.h b/drivers/net/ethernet/mellanox/mlxsw/core_env.h
|
||||
index da121b1a8..03d027870 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.h
|
||||
@@ -9,46 +9,55 @@
|
||||
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 mlxsw_core *mlxsw_core, int module,
|
||||
- struct ethtool_modinfo *modinfo);
|
||||
+int mlxsw_env_get_module_info(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);
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
index 2bc4c4556..5df54a5bf 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
@@ -311,8 +311,9 @@ static int mlxsw_hwmon_module_temp_critical_get(struct device *dev,
|
||||
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);
|
||||
+ err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, 0,
|
||||
+ module, SFP_TEMP_HIGH_WARN,
|
||||
+ p_temp);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to query module temperature thresholds\n");
|
||||
return err;
|
||||
@@ -345,8 +346,9 @@ static int mlxsw_hwmon_module_temp_emergency_get(struct device *dev,
|
||||
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);
|
||||
+ err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, 0,
|
||||
+ module, SFP_TEMP_HIGH_ALARM,
|
||||
+ p_temp);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to query module temperature thresholds\n");
|
||||
return err;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
index 56e0291f1..3f9062f1c 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -159,13 +159,13 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
|
||||
* EEPROM if we got valid thresholds from MTMP.
|
||||
*/
|
||||
if (!emerg_temp || !crit_temp) {
|
||||
- err = mlxsw_env_module_temp_thresholds_get(core, tz->module,
|
||||
+ err = mlxsw_env_module_temp_thresholds_get(core, 0, tz->module,
|
||||
SFP_TEMP_HIGH_WARN,
|
||||
&crit_temp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- err = mlxsw_env_module_temp_thresholds_get(core, tz->module,
|
||||
+ err = mlxsw_env_module_temp_thresholds_get(core, 0, tz->module,
|
||||
SFP_TEMP_HIGH_ALARM,
|
||||
&emerg_temp);
|
||||
if (err)
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
index b2ffcfda8..104f1ba02 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
@@ -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,8 @@ 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(core, mlxsw_m_port->module, modinfo);
|
||||
+ return mlxsw_env_get_module_info(core, 0, mlxsw_m_port->module,
|
||||
+ modinfo);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -120,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
|
||||
@@ -132,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);
|
||||
}
|
||||
|
||||
@@ -141,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);
|
||||
}
|
||||
|
||||
@@ -153,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);
|
||||
}
|
||||
|
||||
@@ -165,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);
|
||||
}
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
|
||||
index 9f068c030..5066fcc46 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
|
||||
@@ -1377,7 +1377,7 @@ static int mlxsw_sp_port_overheat_init_val_set(struct mlxsw_sp_port *mlxsw_sp_po
|
||||
u64 overheat_counter;
|
||||
int err;
|
||||
|
||||
- err = mlxsw_env_module_overheat_counter_get(mlxsw_sp->core, module,
|
||||
+ err = mlxsw_env_module_overheat_counter_get(mlxsw_sp->core, 0, module,
|
||||
&overheat_counter);
|
||||
if (err)
|
||||
return err;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c
|
||||
index 369b9d0dc..c9298b236 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c
|
||||
@@ -566,7 +566,7 @@ mlxsw_sp_port_get_transceiver_overheat_stats(struct mlxsw_sp_port *mlxsw_sp_port
|
||||
u64 stats;
|
||||
int err;
|
||||
|
||||
- err = mlxsw_env_module_overheat_counter_get(mlxsw_core,
|
||||
+ err = mlxsw_env_module_overheat_counter_get(mlxsw_core, 0,
|
||||
port_mapping.module,
|
||||
&stats);
|
||||
if (err)
|
||||
@@ -1032,7 +1032,7 @@ static int mlxsw_sp_get_module_info(struct net_device *netdev,
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
int err;
|
||||
|
||||
- err = mlxsw_env_get_module_info(mlxsw_sp->core,
|
||||
+ err = mlxsw_env_get_module_info(mlxsw_sp->core, 0,
|
||||
mlxsw_sp_port->mapping.module,
|
||||
modinfo);
|
||||
|
||||
@@ -1046,7 +1046,7 @@ static int mlxsw_sp_get_module_eeprom(struct net_device *netdev,
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
int err;
|
||||
|
||||
- err = mlxsw_env_get_module_eeprom(netdev, mlxsw_sp->core,
|
||||
+ err = mlxsw_env_get_module_eeprom(netdev, mlxsw_sp->core, 0,
|
||||
mlxsw_sp_port->mapping.module, ee,
|
||||
data);
|
||||
|
||||
@@ -1062,8 +1062,8 @@ mlxsw_sp_get_module_eeprom_by_page(struct net_device *dev,
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
u8 module = mlxsw_sp_port->mapping.module;
|
||||
|
||||
- return mlxsw_env_get_module_eeprom_by_page(mlxsw_sp->core, module, page,
|
||||
- extack);
|
||||
+ return mlxsw_env_get_module_eeprom_by_page(mlxsw_sp->core, 0, module,
|
||||
+ page, extack);
|
||||
}
|
||||
|
||||
static int
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,520 @@
|
||||
From 8e7c606209b97b89b58d21a2c33c319ade1ba867 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:27 +0200
|
||||
Subject: [PATCH] mlxsw: core: Extend port module data structures for line
|
||||
cards
|
||||
|
||||
The port module core is tasked with module operations such as setting
|
||||
power mode policy and reset. The per-module information is currently
|
||||
stored in one large array suited for non-modular systems where only the
|
||||
main board is present (i.e., slot index 0).
|
||||
|
||||
As a preparation for line cards support, allocate a per line card array
|
||||
according to the queried number of slots in the system. For each line
|
||||
card, allocate a module array according to the queried maximum number of
|
||||
modules per-slot.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_env.c | 223 ++++++++++++------
|
||||
1 file changed, 157 insertions(+), 66 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index fefb9bb02..2a6630547 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -20,13 +20,19 @@ struct mlxsw_env_module_info {
|
||||
enum ethtool_module_power_mode_policy power_mode_policy;
|
||||
};
|
||||
|
||||
-struct mlxsw_env {
|
||||
- struct mlxsw_core *core;
|
||||
+struct mlxsw_env_module_line_cards {
|
||||
u8 module_count;
|
||||
- struct mutex module_info_lock; /* Protects 'module_info'. */
|
||||
struct mlxsw_env_module_info module_info[];
|
||||
};
|
||||
|
||||
+struct mlxsw_env {
|
||||
+ struct mlxsw_core *core;
|
||||
+ u8 max_module_count; /* Maximum number of modules per-slot. */
|
||||
+ u8 num_of_slots; /* Including the main board. */
|
||||
+ struct mutex line_cards_lock; /* Protects line cards. */
|
||||
+ struct mlxsw_env_module_line_cards *line_cards[];
|
||||
+};
|
||||
+
|
||||
static int
|
||||
mlxsw_env_validate_cable_ident(struct mlxsw_core *core, u8 slot_index, int id,
|
||||
bool *qsfp, bool *cmis)
|
||||
@@ -407,6 +413,15 @@ mlxsw_env_get_module_eeprom_by_page(struct mlxsw_core *mlxsw_core,
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_get_module_eeprom_by_page);
|
||||
|
||||
+static struct
|
||||
+mlxsw_env_module_info *mlxsw_env_module_info_get(struct mlxsw_core *mlxsw_core,
|
||||
+ u8 slot_index, u8 module)
|
||||
+{
|
||||
+ struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
+
|
||||
+ return &mlxsw_env->line_cards[slot_index]->module_info[module];
|
||||
+}
|
||||
+
|
||||
static int mlxsw_env_module_reset(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
u8 module)
|
||||
{
|
||||
@@ -423,6 +438,7 @@ int mlxsw_env_reset_module(struct net_device *netdev,
|
||||
u8 module, u32 *flags)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
+ struct mlxsw_env_module_info *module_info;
|
||||
u32 req = *flags;
|
||||
int err;
|
||||
|
||||
@@ -430,15 +446,16 @@ int mlxsw_env_reset_module(struct net_device *netdev,
|
||||
!(req & (ETH_RESET_PHY << ETH_RESET_SHARED_SHIFT)))
|
||||
return 0;
|
||||
|
||||
- mutex_lock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_lock(&mlxsw_env->line_cards_lock);
|
||||
|
||||
- if (mlxsw_env->module_info[module].num_ports_up) {
|
||||
+ module_info = mlxsw_env_module_info_get(mlxsw_core, slot_index, module);
|
||||
+ if (module_info->num_ports_up) {
|
||||
netdev_err(netdev, "Cannot reset module when ports using it are administratively up\n");
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if (mlxsw_env->module_info[module].num_ports_mapped > 1 &&
|
||||
+ if (module_info->num_ports_mapped > 1 &&
|
||||
!(req & (ETH_RESET_PHY << ETH_RESET_SHARED_SHIFT))) {
|
||||
netdev_err(netdev, "Cannot reset module without \"phy-shared\" flag when shared by multiple ports\n");
|
||||
err = -EINVAL;
|
||||
@@ -454,7 +471,7 @@ int mlxsw_env_reset_module(struct net_device *netdev,
|
||||
*flags &= ~(ETH_RESET_PHY | (ETH_RESET_PHY << ETH_RESET_SHARED_SHIFT));
|
||||
|
||||
out:
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_reset_module);
|
||||
@@ -466,13 +483,15 @@ mlxsw_env_get_module_power_mode(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
+ struct mlxsw_env_module_info *module_info;
|
||||
char mcion_pl[MLXSW_REG_MCION_LEN];
|
||||
u32 status_bits;
|
||||
int err;
|
||||
|
||||
- mutex_lock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_lock(&mlxsw_env->line_cards_lock);
|
||||
|
||||
- params->policy = mlxsw_env->module_info[module].power_mode_policy;
|
||||
+ module_info = mlxsw_env_module_info_get(mlxsw_core, slot_index, module);
|
||||
+ params->policy = module_info->power_mode_policy;
|
||||
|
||||
mlxsw_reg_mcion_pack(mcion_pl, slot_index, module);
|
||||
err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mcion), mcion_pl);
|
||||
@@ -491,7 +510,7 @@ mlxsw_env_get_module_power_mode(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
params->mode = ETHTOOL_MODULE_POWER_MODE_HIGH;
|
||||
|
||||
out:
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_get_module_power_mode);
|
||||
@@ -573,6 +592,7 @@ mlxsw_env_set_module_power_mode(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
+ struct mlxsw_env_module_info *module_info;
|
||||
bool low_power;
|
||||
int err = 0;
|
||||
|
||||
@@ -582,13 +602,14 @@ mlxsw_env_set_module_power_mode(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
- mutex_lock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_lock(&mlxsw_env->line_cards_lock);
|
||||
|
||||
- if (mlxsw_env->module_info[module].power_mode_policy == policy)
|
||||
+ module_info = mlxsw_env_module_info_get(mlxsw_core, slot_index, module);
|
||||
+ if (module_info->power_mode_policy == policy)
|
||||
goto out;
|
||||
|
||||
/* If any ports are up, we are already in high power mode. */
|
||||
- if (mlxsw_env->module_info[module].num_ports_up)
|
||||
+ if (module_info->num_ports_up)
|
||||
goto out_set_policy;
|
||||
|
||||
low_power = policy == ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO;
|
||||
@@ -598,9 +619,9 @@ mlxsw_env_set_module_power_mode(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
goto out;
|
||||
|
||||
out_set_policy:
|
||||
- mlxsw_env->module_info[module].power_mode_policy = policy;
|
||||
+ module_info->power_mode_policy = policy;
|
||||
out:
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_set_module_power_mode);
|
||||
@@ -711,6 +732,7 @@ struct mlxsw_env_module_temp_warn_event {
|
||||
static void mlxsw_env_mtwe_event_work(struct work_struct *work)
|
||||
{
|
||||
struct mlxsw_env_module_temp_warn_event *event;
|
||||
+ struct mlxsw_env_module_info *module_info;
|
||||
struct mlxsw_env *mlxsw_env;
|
||||
int i, sensor_warning;
|
||||
bool is_overheat;
|
||||
@@ -719,7 +741,7 @@ static void mlxsw_env_mtwe_event_work(struct work_struct *work)
|
||||
work);
|
||||
mlxsw_env = event->mlxsw_env;
|
||||
|
||||
- for (i = 0; i < mlxsw_env->module_count; i++) {
|
||||
+ for (i = 0; i < mlxsw_env->max_module_count; i++) {
|
||||
/* 64-127 of sensor_index are mapped to the port modules
|
||||
* sequentially (module 0 is mapped to sensor_index 64,
|
||||
* module 1 to sensor_index 65 and so on)
|
||||
@@ -727,9 +749,10 @@ static void mlxsw_env_mtwe_event_work(struct work_struct *work)
|
||||
sensor_warning =
|
||||
mlxsw_reg_mtwe_sensor_warning_get(event->mtwe_pl,
|
||||
i + MLXSW_REG_MTMP_MODULE_INDEX_MIN);
|
||||
- mutex_lock(&mlxsw_env->module_info_lock);
|
||||
- is_overheat =
|
||||
- mlxsw_env->module_info[i].is_overheat;
|
||||
+ mutex_lock(&mlxsw_env->line_cards_lock);
|
||||
+ /* MTWE only supports main board. */
|
||||
+ module_info = mlxsw_env_module_info_get(mlxsw_env->core, 0, i);
|
||||
+ is_overheat = module_info->is_overheat;
|
||||
|
||||
if ((is_overheat && sensor_warning) ||
|
||||
(!is_overheat && !sensor_warning)) {
|
||||
@@ -737,21 +760,21 @@ static void mlxsw_env_mtwe_event_work(struct work_struct *work)
|
||||
* warning OR current state in "no warning" and MTWE
|
||||
* does not report warning.
|
||||
*/
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
continue;
|
||||
} else if (is_overheat && !sensor_warning) {
|
||||
/* MTWE reports "no warning", turn is_overheat off.
|
||||
*/
|
||||
- mlxsw_env->module_info[i].is_overheat = false;
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ module_info->is_overheat = false;
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
} else {
|
||||
/* Current state is "no warning" and MTWE reports
|
||||
* "warning", increase the counter and turn is_overheat
|
||||
* on.
|
||||
*/
|
||||
- mlxsw_env->module_info[i].is_overheat = true;
|
||||
- mlxsw_env->module_info[i].module_overheat_counter++;
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ module_info->is_overheat = true;
|
||||
+ module_info->module_overheat_counter++;
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -809,6 +832,7 @@ struct mlxsw_env_module_plug_unplug_event {
|
||||
static void mlxsw_env_pmpe_event_work(struct work_struct *work)
|
||||
{
|
||||
struct mlxsw_env_module_plug_unplug_event *event;
|
||||
+ struct mlxsw_env_module_info *module_info;
|
||||
struct mlxsw_env *mlxsw_env;
|
||||
bool has_temp_sensor;
|
||||
u16 sensor_index;
|
||||
@@ -818,9 +842,12 @@ static void mlxsw_env_pmpe_event_work(struct work_struct *work)
|
||||
work);
|
||||
mlxsw_env = event->mlxsw_env;
|
||||
|
||||
- mutex_lock(&mlxsw_env->module_info_lock);
|
||||
- mlxsw_env->module_info[event->module].is_overheat = false;
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_lock(&mlxsw_env->line_cards_lock);
|
||||
+ module_info = mlxsw_env_module_info_get(mlxsw_env->core,
|
||||
+ event->slot_index,
|
||||
+ event->module);
|
||||
+ module_info->is_overheat = false;
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
|
||||
err = mlxsw_env_module_has_temp_sensor(mlxsw_env->core,
|
||||
event->slot_index,
|
||||
@@ -847,12 +874,14 @@ static void
|
||||
mlxsw_env_pmpe_listener_func(const struct mlxsw_reg_info *reg, char *pmpe_pl,
|
||||
void *priv)
|
||||
{
|
||||
+ u8 slot_index = mlxsw_reg_pmpe_slot_index_get(pmpe_pl);
|
||||
struct mlxsw_env_module_plug_unplug_event *event;
|
||||
enum mlxsw_reg_pmpe_module_status module_status;
|
||||
u8 module = mlxsw_reg_pmpe_module_get(pmpe_pl);
|
||||
struct mlxsw_env *mlxsw_env = priv;
|
||||
|
||||
- if (WARN_ON_ONCE(module >= mlxsw_env->module_count))
|
||||
+ if (WARN_ON_ONCE(module >= mlxsw_env->max_module_count ||
|
||||
+ slot_index >= mlxsw_env->num_of_slots))
|
||||
return;
|
||||
|
||||
module_status = mlxsw_reg_pmpe_module_status_get(pmpe_pl);
|
||||
@@ -864,7 +893,7 @@ mlxsw_env_pmpe_listener_func(const struct mlxsw_reg_info *reg, char *pmpe_pl,
|
||||
return;
|
||||
|
||||
event->mlxsw_env = mlxsw_env;
|
||||
- event->slot_index = 0;
|
||||
+ event->slot_index = slot_index;
|
||||
event->module = module;
|
||||
INIT_WORK(&event->work, mlxsw_env_pmpe_event_work);
|
||||
mlxsw_core_schedule_work(&event->work);
|
||||
@@ -922,10 +951,12 @@ mlxsw_env_module_overheat_counter_get(struct mlxsw_core *mlxsw_core, u8 slot_ind
|
||||
u8 module, u64 *p_counter)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
+ struct mlxsw_env_module_info *module_info;
|
||||
|
||||
- mutex_lock(&mlxsw_env->module_info_lock);
|
||||
- *p_counter = mlxsw_env->module_info[module].module_overheat_counter;
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_lock(&mlxsw_env->line_cards_lock);
|
||||
+ module_info = mlxsw_env_module_info_get(mlxsw_core, slot_index, module);
|
||||
+ *p_counter = module_info->module_overheat_counter;
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -935,10 +966,12 @@ void mlxsw_env_module_port_map(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
u8 module)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
+ struct mlxsw_env_module_info *module_info;
|
||||
|
||||
- mutex_lock(&mlxsw_env->module_info_lock);
|
||||
- mlxsw_env->module_info[module].num_ports_mapped++;
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_lock(&mlxsw_env->line_cards_lock);
|
||||
+ module_info = mlxsw_env_module_info_get(mlxsw_core, slot_index, module);
|
||||
+ module_info->num_ports_mapped++;
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_module_port_map);
|
||||
|
||||
@@ -946,10 +979,12 @@ void mlxsw_env_module_port_unmap(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
u8 module)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
+ struct mlxsw_env_module_info *module_info;
|
||||
|
||||
- mutex_lock(&mlxsw_env->module_info_lock);
|
||||
- mlxsw_env->module_info[module].num_ports_mapped--;
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_lock(&mlxsw_env->line_cards_lock);
|
||||
+ module_info = mlxsw_env_module_info_get(mlxsw_core, slot_index, module);
|
||||
+ module_info->num_ports_mapped--;
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_module_port_unmap);
|
||||
|
||||
@@ -957,15 +992,17 @@ int mlxsw_env_module_port_up(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
u8 module)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
+ struct mlxsw_env_module_info *module_info;
|
||||
int err = 0;
|
||||
|
||||
- mutex_lock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_lock(&mlxsw_env->line_cards_lock);
|
||||
|
||||
- if (mlxsw_env->module_info[module].power_mode_policy !=
|
||||
+ module_info = mlxsw_env_module_info_get(mlxsw_core, slot_index, module);
|
||||
+ if (module_info->power_mode_policy !=
|
||||
ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO)
|
||||
goto out_inc;
|
||||
|
||||
- if (mlxsw_env->module_info[module].num_ports_up != 0)
|
||||
+ if (module_info->num_ports_up != 0)
|
||||
goto out_inc;
|
||||
|
||||
/* Transition to high power mode following first port using the module
|
||||
@@ -977,9 +1014,9 @@ int mlxsw_env_module_port_up(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
goto out_unlock;
|
||||
|
||||
out_inc:
|
||||
- mlxsw_env->module_info[module].num_ports_up++;
|
||||
+ module_info->num_ports_up++;
|
||||
out_unlock:
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_module_port_up);
|
||||
@@ -988,16 +1025,18 @@ void mlxsw_env_module_port_down(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
u8 module)
|
||||
{
|
||||
struct mlxsw_env *mlxsw_env = mlxsw_core_env(mlxsw_core);
|
||||
+ struct mlxsw_env_module_info *module_info;
|
||||
|
||||
- mutex_lock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_lock(&mlxsw_env->line_cards_lock);
|
||||
|
||||
- mlxsw_env->module_info[module].num_ports_up--;
|
||||
+ module_info = mlxsw_env_module_info_get(mlxsw_core, slot_index, module);
|
||||
+ module_info->num_ports_up--;
|
||||
|
||||
- if (mlxsw_env->module_info[module].power_mode_policy !=
|
||||
+ if (module_info->power_mode_policy !=
|
||||
ETHTOOL_MODULE_POWER_MODE_POLICY_AUTO)
|
||||
goto out_unlock;
|
||||
|
||||
- if (mlxsw_env->module_info[module].num_ports_up != 0)
|
||||
+ if (module_info->num_ports_up != 0)
|
||||
goto out_unlock;
|
||||
|
||||
/* Transition to low power mode following last port using the module
|
||||
@@ -1007,38 +1046,83 @@ void mlxsw_env_module_port_down(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
NULL);
|
||||
|
||||
out_unlock:
|
||||
- mutex_unlock(&mlxsw_env->module_info_lock);
|
||||
+ mutex_unlock(&mlxsw_env->line_cards_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_module_port_down);
|
||||
|
||||
+static int mlxsw_env_line_cards_alloc(struct mlxsw_env *env)
|
||||
+{
|
||||
+ struct mlxsw_env_module_info *module_info;
|
||||
+ int i, j;
|
||||
+
|
||||
+ for (i = 0; i < env->num_of_slots; i++) {
|
||||
+ env->line_cards[i] = kzalloc(struct_size(env->line_cards[i],
|
||||
+ module_info,
|
||||
+ env->max_module_count),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!env->line_cards[i])
|
||||
+ goto kzalloc_err;
|
||||
+
|
||||
+ /* Firmware defaults to high power mode policy where modules
|
||||
+ * are transitioned to high power mode following plug-in.
|
||||
+ */
|
||||
+ for (j = 0; j < env->max_module_count; j++) {
|
||||
+ module_info = &env->line_cards[i]->module_info[j];
|
||||
+ module_info->power_mode_policy =
|
||||
+ ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+kzalloc_err:
|
||||
+ for (i--; i >= 0; i--)
|
||||
+ kfree(env->line_cards[i]);
|
||||
+ return -ENOMEM;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_env_line_cards_free(struct mlxsw_env *env)
|
||||
+{
|
||||
+ int i = env->num_of_slots;
|
||||
+
|
||||
+ for (i--; i >= 0; i--)
|
||||
+ kfree(env->line_cards[i]);
|
||||
+}
|
||||
+
|
||||
int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
|
||||
{
|
||||
+ u8 module_count, num_of_slots, max_module_count;
|
||||
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
struct mlxsw_env *env;
|
||||
- u8 module_count;
|
||||
- int i, err;
|
||||
+ int err;
|
||||
|
||||
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, &module_count, NULL);
|
||||
+ mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, &module_count,
|
||||
+ &num_of_slots);
|
||||
+ /* If the system is modular, get the maximum number of modules per-slot.
|
||||
+ * Otherwise, get the maximum number of modules on the main board.
|
||||
+ */
|
||||
+ max_module_count = num_of_slots ?
|
||||
+ mlxsw_reg_mgpir_max_modules_per_slot_get(mgpir_pl) :
|
||||
+ module_count;
|
||||
|
||||
- env = kzalloc(struct_size(env, module_info, module_count), GFP_KERNEL);
|
||||
+ env = kzalloc(struct_size(env, line_cards, num_of_slots + 1),
|
||||
+ GFP_KERNEL);
|
||||
if (!env)
|
||||
return -ENOMEM;
|
||||
|
||||
- /* Firmware defaults to high power mode policy where modules are
|
||||
- * transitioned to high power mode following plug-in.
|
||||
- */
|
||||
- for (i = 0; i < module_count; i++)
|
||||
- env->module_info[i].power_mode_policy =
|
||||
- ETHTOOL_MODULE_POWER_MODE_POLICY_HIGH;
|
||||
-
|
||||
- mutex_init(&env->module_info_lock);
|
||||
env->core = mlxsw_core;
|
||||
- env->module_count = module_count;
|
||||
+ env->num_of_slots = num_of_slots + 1;
|
||||
+ env->max_module_count = max_module_count;
|
||||
+ err = mlxsw_env_line_cards_alloc(env);
|
||||
+ if (err)
|
||||
+ goto err_mlxsw_env_line_cards_alloc;
|
||||
+
|
||||
+ mutex_init(&env->line_cards_lock);
|
||||
*p_env = env;
|
||||
|
||||
err = mlxsw_env_temp_warn_event_register(mlxsw_core);
|
||||
@@ -1049,13 +1133,17 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
|
||||
if (err)
|
||||
goto err_module_plug_event_register;
|
||||
|
||||
+ /* Set 'module_count' only for main board. Actual count for line card
|
||||
+ * is to be set after line card is activated.
|
||||
+ */
|
||||
+ env->line_cards[0]->module_count = num_of_slots ? 0 : module_count;
|
||||
err = mlxsw_env_module_oper_state_event_enable(mlxsw_core, 0,
|
||||
- env->module_count);
|
||||
+ module_count);
|
||||
if (err)
|
||||
goto err_oper_state_event_enable;
|
||||
|
||||
err = mlxsw_env_module_temp_event_enable(mlxsw_core, 0,
|
||||
- env->module_count);
|
||||
+ module_count);
|
||||
if (err)
|
||||
goto err_temp_event_enable;
|
||||
|
||||
@@ -1067,7 +1155,9 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
|
||||
err_module_plug_event_register:
|
||||
mlxsw_env_temp_warn_event_unregister(env);
|
||||
err_temp_warn_event_register:
|
||||
- mutex_destroy(&env->module_info_lock);
|
||||
+ mutex_destroy(&env->line_cards_lock);
|
||||
+ mlxsw_env_line_cards_free(env);
|
||||
+err_mlxsw_env_line_cards_alloc:
|
||||
kfree(env);
|
||||
return err;
|
||||
}
|
||||
@@ -1078,6 +1168,7 @@ void mlxsw_env_fini(struct mlxsw_env *env)
|
||||
/* Make sure there is no more event work scheduled. */
|
||||
mlxsw_core_flush_owq();
|
||||
mlxsw_env_temp_warn_event_unregister(env);
|
||||
- mutex_destroy(&env->module_info_lock);
|
||||
+ mutex_destroy(&env->line_cards_lock);
|
||||
+ mlxsw_env_line_cards_free(env);
|
||||
kfree(env);
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,92 @@
|
||||
From 9eb9b3172a238d5818d2925e2db6b0f686b31411 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:28 +0200
|
||||
Subject: [PATCH] mlxsw: core: Move port module events enablement to a separate
|
||||
function
|
||||
|
||||
Use a separate function for enablement of port module events such
|
||||
plug/unplug and temperature threshold crossing. The motivation is to
|
||||
reuse the function for line cards.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_env.c | 44 ++++++++++++++-----
|
||||
1 file changed, 34 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index 2a6630547..94d44db1a 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -1089,6 +1089,32 @@ static void mlxsw_env_line_cards_free(struct mlxsw_env *env)
|
||||
kfree(env->line_cards[i]);
|
||||
}
|
||||
|
||||
+static int
|
||||
+mlxsw_env_module_event_enable(struct mlxsw_env *mlxsw_env, u8 slot_index)
|
||||
+{
|
||||
+ u8 module_count;
|
||||
+ int err;
|
||||
+
|
||||
+ module_count = mlxsw_env->line_cards[slot_index]->module_count;
|
||||
+ err = mlxsw_env_module_oper_state_event_enable(mlxsw_env->core,
|
||||
+ slot_index,
|
||||
+ module_count);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ err = mlxsw_env_module_temp_event_enable(mlxsw_env->core, slot_index,
|
||||
+ module_count);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mlxsw_env_module_event_disable(struct mlxsw_env *mlxsw_env, u8 slot_index)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
|
||||
{
|
||||
u8 module_count, num_of_slots, max_module_count;
|
||||
@@ -1137,20 +1163,17 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
|
||||
* is to be set after line card is activated.
|
||||
*/
|
||||
env->line_cards[0]->module_count = num_of_slots ? 0 : module_count;
|
||||
- err = mlxsw_env_module_oper_state_event_enable(mlxsw_core, 0,
|
||||
- module_count);
|
||||
- if (err)
|
||||
- goto err_oper_state_event_enable;
|
||||
-
|
||||
- err = mlxsw_env_module_temp_event_enable(mlxsw_core, 0,
|
||||
- module_count);
|
||||
+ /* Enable events only for main board. Line card events are to be
|
||||
+ * configured only after line card is activated. Before that, access to
|
||||
+ * modules on line cards is not allowed.
|
||||
+ */
|
||||
+ err = mlxsw_env_module_event_enable(env, 0);
|
||||
if (err)
|
||||
- goto err_temp_event_enable;
|
||||
+ goto err_mlxsw_env_module_event_enable;
|
||||
|
||||
return 0;
|
||||
|
||||
-err_temp_event_enable:
|
||||
-err_oper_state_event_enable:
|
||||
+err_mlxsw_env_module_event_enable:
|
||||
mlxsw_env_module_plug_event_unregister(env);
|
||||
err_module_plug_event_register:
|
||||
mlxsw_env_temp_warn_event_unregister(env);
|
||||
@@ -1164,6 +1187,7 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
|
||||
|
||||
void mlxsw_env_fini(struct mlxsw_env *env)
|
||||
{
|
||||
+ mlxsw_env_module_event_disable(env, 0);
|
||||
mlxsw_env_module_plug_event_unregister(env);
|
||||
/* Make sure there is no more event work scheduled. */
|
||||
mlxsw_core_flush_owq();
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,121 @@
|
||||
From 4d15dd7f69b89a370731b08cb3f13e5dd591c189 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:29 +0200
|
||||
Subject: [PATCH] mlxsw: core_hwmon: Split gearbox initialization
|
||||
|
||||
Split gearbox initialization in two functions - the first one is to be
|
||||
used for gearbox configuration validation, the second for creation of
|
||||
gearbox related hwmon attributes, if any.
|
||||
|
||||
Currently, mlxsw supports gearbox hwmon attributes corresponding to the
|
||||
objects discovered on the main board. Same hwmon attributes could be
|
||||
also discovered on line cards. While the initialization flow for main
|
||||
board and for line cards is the same, the configuration flow is
|
||||
different.
|
||||
|
||||
The purpose of this patch is to allow reusing of initialization flow by
|
||||
main board and line cards.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_hwmon.c | 43 ++++++++++++++-----
|
||||
1 file changed, 33 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
index 5df54a5bf..7061c18b7 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
@@ -700,13 +700,11 @@ 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_main_init(struct mlxsw_hwmon *mlxsw_hwmon, u8 *gbox_num)
|
||||
{
|
||||
enum mlxsw_reg_mgpir_device_type device_type;
|
||||
- int index, max_index, sensor_index;
|
||||
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
- char mtmp_pl[MLXSW_REG_MTMP_LEN];
|
||||
- u8 gbox_num;
|
||||
int err;
|
||||
|
||||
mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
@@ -714,10 +712,27 @@ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL, NULL,
|
||||
+ mlxsw_reg_mgpir_unpack(mgpir_pl, gbox_num, &device_type, NULL, NULL,
|
||||
NULL);
|
||||
- if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE ||
|
||||
- !gbox_num)
|
||||
+ if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE)
|
||||
+ *gbox_num = 0;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mlxsw_hwmon_gearbox_main_fini(struct mlxsw_hwmon *mlxsw_hwmon)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon, u8 gbox_num)
|
||||
+{
|
||||
+ int index, max_index, sensor_index;
|
||||
+ char mtmp_pl[MLXSW_REG_MTMP_LEN];
|
||||
+ int err;
|
||||
+
|
||||
+ if (!gbox_num)
|
||||
return 0;
|
||||
|
||||
index = mlxsw_hwmon->module_sensor_max;
|
||||
@@ -756,6 +771,7 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
|
||||
{
|
||||
struct mlxsw_hwmon *mlxsw_hwmon;
|
||||
struct device *hwmon_dev;
|
||||
+ u8 gbox_num;
|
||||
int err;
|
||||
|
||||
mlxsw_hwmon = kzalloc(sizeof(*mlxsw_hwmon), GFP_KERNEL);
|
||||
@@ -776,9 +792,13 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
|
||||
if (err)
|
||||
goto err_temp_module_init;
|
||||
|
||||
- err = mlxsw_hwmon_gearbox_init(mlxsw_hwmon);
|
||||
+ err = mlxsw_hwmon_gearbox_main_init(mlxsw_hwmon, &gbox_num);
|
||||
+ if (err)
|
||||
+ goto err_gearbox_main_init;
|
||||
+
|
||||
+ err = mlxsw_hwmon_gearbox_init(mlxsw_hwmon, gbox_num);
|
||||
if (err)
|
||||
- goto err_temp_gearbox_init;
|
||||
+ goto err_gearbox_init;
|
||||
|
||||
mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
|
||||
mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
|
||||
@@ -796,7 +816,9 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
|
||||
return 0;
|
||||
|
||||
err_hwmon_register:
|
||||
-err_temp_gearbox_init:
|
||||
+err_gearbox_init:
|
||||
+ mlxsw_hwmon_gearbox_main_fini(mlxsw_hwmon);
|
||||
+err_gearbox_main_init:
|
||||
err_temp_module_init:
|
||||
err_fans_init:
|
||||
err_temp_init:
|
||||
@@ -807,5 +829,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);
|
||||
+ mlxsw_hwmon_gearbox_main_fini(mlxsw_hwmon);
|
||||
kfree(mlxsw_hwmon);
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,541 @@
|
||||
From 9780cd7afe3455d0ee428f5009514780e858c133 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:30 +0200
|
||||
Subject: [PATCH] mlxsw: core_hwmon: Extend internal structures to support
|
||||
multi hwmon objects
|
||||
|
||||
Currently, mlxsw supports a single hwmon device and registers it with
|
||||
attributes corresponding to the various objects found on the main
|
||||
board such as fans and gearboxes.
|
||||
|
||||
Line cards can have the same objects, but unlike the main board they
|
||||
can be added and removed while the system is running. The various
|
||||
hwmon objects found on these line cards should be created when the
|
||||
line card becomes available and destroyed when the line card becomes
|
||||
unavailable.
|
||||
|
||||
The above can be achieved by representing each line card as a
|
||||
different hwmon device and registering / unregistering it when the
|
||||
line card becomes available / unavailable.
|
||||
|
||||
Prepare for multi hwmon device support by splitting
|
||||
'struct mlxsw_hwmon' into 'struct mlxsw_hwmon' and
|
||||
'struct mlxsw_hwmon_dev'. The first will hold information relevant to
|
||||
all hwmon devices, whereas the second will hold per-hwmon device
|
||||
information.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_hwmon.c | 192 ++++++++++--------
|
||||
1 file changed, 112 insertions(+), 80 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
index 7061c18b7..31b370862 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
@@ -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];
|
||||
@@ -53,19 +52,26 @@ struct mlxsw_hwmon {
|
||||
u8 module_sensor_max;
|
||||
};
|
||||
|
||||
+struct mlxsw_hwmon {
|
||||
+ struct mlxsw_core *core;
|
||||
+ const struct mlxsw_bus_info *bus_info;
|
||||
+ struct mlxsw_hwmon_dev *main;
|
||||
+};
|
||||
+
|
||||
static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
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_hwmon_dev->module_sensor_max);
|
||||
mlxsw_reg_mtmp_pack(mtmp_pl, 0, index, false, false);
|
||||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err) {
|
||||
@@ -82,13 +88,14 @@ 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_hwmon_dev->module_sensor_max);
|
||||
mlxsw_reg_mtmp_pack(mtmp_pl, 0, index, false, false);
|
||||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err) {
|
||||
@@ -105,8 +112,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,7 +126,7 @@ 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_sensor_index_set(mtmp_pl, index);
|
||||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
@@ -140,7 +148,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 +168,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 +190,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 +211,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,12 +238,13 @@ 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;
|
||||
+ module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
|
||||
mlxsw_reg_mtmp_pack(mtmp_pl, 0,
|
||||
MLXSW_REG_MTMP_MODULE_INDEX_MIN + module, false,
|
||||
false);
|
||||
@@ -264,15 +277,16 @@ 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,
|
||||
- MLXSW_REG_MTBR_BASE_MODULE_INDEX + module, 1);
|
||||
+ module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
|
||||
+ mlxsw_reg_mtbr_pack(mtbr_pl, 0, MLXSW_REG_MTBR_BASE_MODULE_INDEX + module,
|
||||
+ 1);
|
||||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtbr), mtbr_pl);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to query module temperature sensor\n");
|
||||
@@ -306,11 +320,12 @@ 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;
|
||||
+ module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
|
||||
err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, 0,
|
||||
module, SFP_TEMP_HIGH_WARN,
|
||||
p_temp);
|
||||
@@ -341,11 +356,12 @@ 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;
|
||||
+ module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
|
||||
err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, 0,
|
||||
module, SFP_TEMP_HIGH_ALARM,
|
||||
p_temp);
|
||||
@@ -390,9 +406,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);
|
||||
}
|
||||
@@ -461,14 +477,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:
|
||||
@@ -568,16 +585,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;
|
||||
@@ -587,8 +605,8 @@ 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_sensor_index_set(mtmp_pl, i);
|
||||
@@ -605,18 +623,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;
|
||||
@@ -634,10 +653,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++);
|
||||
}
|
||||
@@ -645,15 +664,16 @@ 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;
|
||||
@@ -671,28 +691,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 +
|
||||
- module_sensor_max;
|
||||
- for (i = mlxsw_hwmon->sensor_count;
|
||||
- i < mlxsw_hwmon->module_sensor_max; i++) {
|
||||
- mlxsw_hwmon_attr_add(mlxsw_hwmon,
|
||||
+ mlxsw_hwmon_dev->module_sensor_max = mlxsw_hwmon_dev->sensor_count +
|
||||
+ module_sensor_max;
|
||||
+ 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);
|
||||
}
|
||||
@@ -701,8 +721,10 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
|
||||
}
|
||||
|
||||
static int
|
||||
-mlxsw_hwmon_gearbox_main_init(struct mlxsw_hwmon *mlxsw_hwmon, u8 *gbox_num)
|
||||
+mlxsw_hwmon_gearbox_main_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev,
|
||||
+ u8 *gbox_num)
|
||||
{
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
|
||||
enum mlxsw_reg_mgpir_device_type device_type;
|
||||
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
int err;
|
||||
@@ -721,13 +743,14 @@ mlxsw_hwmon_gearbox_main_init(struct mlxsw_hwmon *mlxsw_hwmon, u8 *gbox_num)
|
||||
}
|
||||
|
||||
static void
|
||||
-mlxsw_hwmon_gearbox_main_fini(struct mlxsw_hwmon *mlxsw_hwmon)
|
||||
+mlxsw_hwmon_gearbox_main_fini(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev)
|
||||
{
|
||||
}
|
||||
|
||||
static int
|
||||
-mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon, u8 gbox_num)
|
||||
+mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev, u8 gbox_num)
|
||||
{
|
||||
+ struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
|
||||
int index, max_index, sensor_index;
|
||||
char mtmp_pl[MLXSW_REG_MTMP_LEN];
|
||||
int err;
|
||||
@@ -735,10 +758,10 @@ mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon, u8 gbox_num)
|
||||
if (!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);
|
||||
err = mlxsw_reg_write(mlxsw_hwmon->core,
|
||||
@@ -748,15 +771,15 @@ mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon, u8 gbox_num)
|
||||
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++;
|
||||
@@ -777,58 +800,67 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
|
||||
mlxsw_hwmon = kzalloc(sizeof(*mlxsw_hwmon), GFP_KERNEL);
|
||||
if (!mlxsw_hwmon)
|
||||
return -ENOMEM;
|
||||
+ mlxsw_hwmon->main = kzalloc(sizeof(*mlxsw_hwmon->main), GFP_KERNEL);
|
||||
+ if (!mlxsw_hwmon->main) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_hwmon_main_init;
|
||||
+ }
|
||||
mlxsw_hwmon->core = mlxsw_core;
|
||||
mlxsw_hwmon->bus_info = mlxsw_bus_info;
|
||||
+ mlxsw_hwmon->main->hwmon = mlxsw_hwmon;
|
||||
|
||||
- err = mlxsw_hwmon_temp_init(mlxsw_hwmon);
|
||||
+ err = mlxsw_hwmon_temp_init(mlxsw_hwmon->main);
|
||||
if (err)
|
||||
goto err_temp_init;
|
||||
|
||||
- err = mlxsw_hwmon_fans_init(mlxsw_hwmon);
|
||||
+ err = mlxsw_hwmon_fans_init(mlxsw_hwmon->main);
|
||||
if (err)
|
||||
goto err_fans_init;
|
||||
|
||||
- err = mlxsw_hwmon_module_init(mlxsw_hwmon);
|
||||
+ err = mlxsw_hwmon_module_init(mlxsw_hwmon->main);
|
||||
if (err)
|
||||
goto err_temp_module_init;
|
||||
|
||||
- err = mlxsw_hwmon_gearbox_main_init(mlxsw_hwmon, &gbox_num);
|
||||
+ err = mlxsw_hwmon_gearbox_main_init(mlxsw_hwmon->main, &gbox_num);
|
||||
if (err)
|
||||
goto err_gearbox_main_init;
|
||||
|
||||
- err = mlxsw_hwmon_gearbox_init(mlxsw_hwmon, gbox_num);
|
||||
+ err = mlxsw_hwmon_gearbox_init(mlxsw_hwmon->main, gbox_num);
|
||||
if (err)
|
||||
goto err_gearbox_init;
|
||||
|
||||
- mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
|
||||
- mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
|
||||
+ mlxsw_hwmon->main->groups[0] = &mlxsw_hwmon->main->group;
|
||||
+ mlxsw_hwmon->main->group.attrs = mlxsw_hwmon->main->attrs;
|
||||
|
||||
hwmon_dev = hwmon_device_register_with_groups(mlxsw_bus_info->dev,
|
||||
- "mlxsw", mlxsw_hwmon,
|
||||
- mlxsw_hwmon->groups);
|
||||
+ "mlxsw", mlxsw_hwmon->main,
|
||||
+ mlxsw_hwmon->main->groups);
|
||||
if (IS_ERR(hwmon_dev)) {
|
||||
err = PTR_ERR(hwmon_dev);
|
||||
goto err_hwmon_register;
|
||||
}
|
||||
|
||||
- mlxsw_hwmon->hwmon_dev = hwmon_dev;
|
||||
+ mlxsw_hwmon->main->hwmon_dev = hwmon_dev;
|
||||
*p_hwmon = mlxsw_hwmon;
|
||||
return 0;
|
||||
|
||||
err_hwmon_register:
|
||||
err_gearbox_init:
|
||||
- mlxsw_hwmon_gearbox_main_fini(mlxsw_hwmon);
|
||||
+ mlxsw_hwmon_gearbox_main_fini(mlxsw_hwmon->main);
|
||||
err_gearbox_main_init:
|
||||
err_temp_module_init:
|
||||
err_fans_init:
|
||||
err_temp_init:
|
||||
+ kfree(mlxsw_hwmon->main);
|
||||
+err_hwmon_main_init:
|
||||
kfree(mlxsw_hwmon);
|
||||
return err;
|
||||
}
|
||||
|
||||
void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
|
||||
{
|
||||
- hwmon_device_unregister(mlxsw_hwmon->hwmon_dev);
|
||||
- mlxsw_hwmon_gearbox_main_fini(mlxsw_hwmon);
|
||||
+ hwmon_device_unregister(mlxsw_hwmon->main->hwmon_dev);
|
||||
+ mlxsw_hwmon_gearbox_main_fini(mlxsw_hwmon->main);
|
||||
+ kfree(mlxsw_hwmon->main);
|
||||
kfree(mlxsw_hwmon);
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,129 @@
|
||||
From aa8cdb2df37cbfb7bb37f90879d385428e32ae23 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:31 +0200
|
||||
Subject: [PATCH] mlxsw: core_hwmon: Introduce slot parameter in hwmon
|
||||
interfaces
|
||||
|
||||
Add 'slot' parameter to 'mlxsw_hwmon_dev' structure. Use this parameter
|
||||
in mlxsw_reg_mtmp_pack(), mlxsw_reg_mtbr_pack() and
|
||||
Use mlxsw_reg_mtmp_slot_index_set() routines.
|
||||
For main board it'll always be zero, for line cards it'll be set to
|
||||
the physical slot number in modular systems.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_hwmon.c | 26 +++++++++++++------
|
||||
1 file changed, 18 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
index 31b370862..0d7edabf1 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
@@ -50,6 +50,7 @@ struct mlxsw_hwmon_dev {
|
||||
unsigned int attrs_count;
|
||||
u8 sensor_count;
|
||||
u8 module_sensor_max;
|
||||
+ u8 slot_index;
|
||||
};
|
||||
|
||||
struct mlxsw_hwmon {
|
||||
@@ -72,7 +73,8 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
|
||||
|
||||
index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
|
||||
mlxsw_hwmon_dev->module_sensor_max);
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, 0, index, false, false);
|
||||
+ 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");
|
||||
@@ -96,7 +98,8 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
|
||||
|
||||
index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
|
||||
mlxsw_hwmon_dev->module_sensor_max);
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, 0, index, false, false);
|
||||
+ 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");
|
||||
@@ -128,6 +131,7 @@ static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
|
||||
index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
|
||||
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)
|
||||
@@ -245,7 +249,7 @@ static int mlxsw_hwmon_module_temp_get(struct device *dev,
|
||||
int err;
|
||||
|
||||
module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, 0,
|
||||
+ 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);
|
||||
@@ -285,8 +289,8 @@ static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
|
||||
int err;
|
||||
|
||||
module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
|
||||
- mlxsw_reg_mtbr_pack(mtbr_pl, 0, MLXSW_REG_MTBR_BASE_MODULE_INDEX + module,
|
||||
- 1);
|
||||
+ 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) {
|
||||
dev_err(dev, "Failed to query module temperature sensor\n");
|
||||
@@ -326,7 +330,8 @@ static int mlxsw_hwmon_module_temp_critical_get(struct device *dev,
|
||||
int err;
|
||||
|
||||
module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
|
||||
- err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, 0,
|
||||
+ err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core,
|
||||
+ mlxsw_hwmon_dev->slot_index,
|
||||
module, SFP_TEMP_HIGH_WARN,
|
||||
p_temp);
|
||||
if (err) {
|
||||
@@ -362,7 +367,8 @@ static int mlxsw_hwmon_module_temp_emergency_get(struct device *dev,
|
||||
int err;
|
||||
|
||||
module = mlxsw_hwmon_attr->type_index - mlxsw_hwmon_dev->sensor_count;
|
||||
- err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, 0,
|
||||
+ err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core,
|
||||
+ mlxsw_hwmon_dev->slot_index,
|
||||
module, SFP_TEMP_HIGH_ALARM,
|
||||
p_temp);
|
||||
if (err) {
|
||||
@@ -609,6 +615,8 @@ static int mlxsw_hwmon_temp_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev)
|
||||
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);
|
||||
@@ -763,7 +771,8 @@ mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev, u8 gbox_num)
|
||||
while (index < max_index) {
|
||||
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) {
|
||||
@@ -808,6 +817,7 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
|
||||
mlxsw_hwmon->core = mlxsw_core;
|
||||
mlxsw_hwmon->bus_info = mlxsw_bus_info;
|
||||
mlxsw_hwmon->main->hwmon = mlxsw_hwmon;
|
||||
+ mlxsw_hwmon->main->slot_index = 0;
|
||||
|
||||
err = mlxsw_hwmon_temp_init(mlxsw_hwmon->main);
|
||||
if (err)
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,136 @@
|
||||
From 94d3b63c64fc202bfe525cc3b500c23e92d38fbf Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:32 +0200
|
||||
Subject: [PATCH] mlxsw: core_hwmon: Extend hwmon device with gearbox mapping
|
||||
field
|
||||
|
||||
Add gearbox mapping field to 'mlxsw_hwmon_dev' structure. It should
|
||||
provide the mapping for gearbox sensor indexes, given gearbox number.
|
||||
For main board mapping is supposed to be always sequential, while for
|
||||
line cards on modular system it could be non-sequential.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_hwmon.c | 40 ++++++++++++++-----
|
||||
1 file changed, 31 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
index 0d7edabf1..6af23f472 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
@@ -32,10 +32,11 @@ struct mlxsw_hwmon_attr {
|
||||
char name[32];
|
||||
};
|
||||
|
||||
-static int mlxsw_hwmon_get_attr_index(int index, int count)
|
||||
+static int
|
||||
+mlxsw_hwmon_get_attr_index(int index, int count, u16 *gearbox_sensor_map)
|
||||
{
|
||||
if (index >= count)
|
||||
- return index % count + MLXSW_REG_MTMP_GBOX_INDEX_MIN;
|
||||
+ return gearbox_sensor_map[index % count];
|
||||
|
||||
return index;
|
||||
}
|
||||
@@ -50,6 +51,7 @@ struct mlxsw_hwmon_dev {
|
||||
unsigned int attrs_count;
|
||||
u8 sensor_count;
|
||||
u8 module_sensor_max;
|
||||
+ u16 *gearbox_sensor_map;
|
||||
u8 slot_index;
|
||||
};
|
||||
|
||||
@@ -72,7 +74,8 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
|
||||
int err;
|
||||
|
||||
index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
|
||||
- mlxsw_hwmon_dev->module_sensor_max);
|
||||
+ mlxsw_hwmon_dev->module_sensor_max,
|
||||
+ mlxsw_hwmon_dev->gearbox_sensor_map);
|
||||
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);
|
||||
@@ -97,7 +100,8 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
|
||||
int err;
|
||||
|
||||
index = mlxsw_hwmon_get_attr_index(mlxsw_hwmon_attr->type_index,
|
||||
- mlxsw_hwmon_dev->module_sensor_max);
|
||||
+ mlxsw_hwmon_dev->module_sensor_max,
|
||||
+ mlxsw_hwmon_dev->gearbox_sensor_map);
|
||||
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);
|
||||
@@ -129,7 +133,8 @@ 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_dev->module_sensor_max);
|
||||
+ mlxsw_hwmon_dev->module_sensor_max,
|
||||
+ mlxsw_hwmon_dev->gearbox_sensor_map);
|
||||
|
||||
mlxsw_reg_mtmp_slot_index_set(mtmp_pl, mlxsw_hwmon_dev->slot_index);
|
||||
mlxsw_reg_mtmp_sensor_index_set(mtmp_pl, index);
|
||||
@@ -735,7 +740,7 @@ mlxsw_hwmon_gearbox_main_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;
|
||||
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
- int err;
|
||||
+ int i, err;
|
||||
|
||||
mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
|
||||
@@ -747,12 +752,30 @@ mlxsw_hwmon_gearbox_main_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev,
|
||||
if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE)
|
||||
*gbox_num = 0;
|
||||
|
||||
+ /* Skip gearbox sensor mapping array allocation, if no gearboxes are
|
||||
+ * available.
|
||||
+ */
|
||||
+ if (!*gbox_num)
|
||||
+ return 0;
|
||||
+
|
||||
+ mlxsw_hwmon_dev->gearbox_sensor_map = kmalloc_array(*gbox_num,
|
||||
+ sizeof(u16),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!mlxsw_hwmon_dev->gearbox_sensor_map)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /* Fill out gearbox sensor mapping array. */
|
||||
+ for (i = 0; i < *gbox_num; i++)
|
||||
+ mlxsw_hwmon_dev->gearbox_sensor_map[i] =
|
||||
+ MLXSW_REG_MTMP_GBOX_INDEX_MIN + i;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mlxsw_hwmon_gearbox_main_fini(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev)
|
||||
{
|
||||
+ kfree(mlxsw_hwmon_dev->gearbox_sensor_map);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -761,7 +784,7 @@ mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev, u8 gbox_num)
|
||||
struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
|
||||
int index, max_index, sensor_index;
|
||||
char mtmp_pl[MLXSW_REG_MTMP_LEN];
|
||||
- int err;
|
||||
+ int i = 0, err;
|
||||
|
||||
if (!gbox_num)
|
||||
return 0;
|
||||
@@ -769,8 +792,7 @@ mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev, u8 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_dev->module_sensor_max +
|
||||
- MLXSW_REG_MTMP_GBOX_INDEX_MIN;
|
||||
+ sensor_index = mlxsw_hwmon_dev->gearbox_sensor_map[i++];
|
||||
mlxsw_reg_mtmp_pack(mtmp_pl, mlxsw_hwmon_dev->slot_index,
|
||||
sensor_index, true, true);
|
||||
err = mlxsw_reg_write(mlxsw_hwmon->core,
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,367 @@
|
||||
From ab0f9b9dd1f7326242eee0b0a643d6d34e557ae3 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:33 +0200
|
||||
Subject: [PATCH] mlxsw: core_thermal: Extend internal structures to support
|
||||
multi thermal areas
|
||||
|
||||
Introduce intermediate level for thermal zones areas.
|
||||
Currently all thermal zones are associated with thermal objects located
|
||||
within the main board. Such objects are created during driver
|
||||
initialization and removed during driver de-initialization.
|
||||
|
||||
For line cards in modular system the thermal zones are to be associated
|
||||
with the specific line card. They should be created whenever new line
|
||||
card is available (inserted, validated, powered and enabled) and
|
||||
removed, when line card is getting unavailable.
|
||||
The thermal objects found on the line card #n are accessed by setting
|
||||
slot index to #n, while for access to objects found on the main board
|
||||
slot index should be set to default value zero.
|
||||
|
||||
Each thermal area contains the set of thermal zones associated with
|
||||
particular slot index.
|
||||
Thus introduction of thermal zone areas allows to use the same APIs for
|
||||
the main board and line cards, by adding slot index argument.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../ethernet/mellanox/mlxsw/core_thermal.c | 134 +++++++++++-------
|
||||
1 file changed, 83 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
index 3f9062f1c..77a484a55 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -91,6 +91,15 @@ struct mlxsw_thermal_module {
|
||||
struct thermal_zone_device *tzdev;
|
||||
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
|
||||
int module; /* Module or gearbox number */
|
||||
+ u8 slot_index;
|
||||
+};
|
||||
+
|
||||
+struct mlxsw_thermal_area {
|
||||
+ struct mlxsw_thermal_module *tz_module_arr;
|
||||
+ u8 tz_module_num;
|
||||
+ struct mlxsw_thermal_module *tz_gearbox_arr;
|
||||
+ u8 tz_gearbox_num;
|
||||
+ u8 slot_index;
|
||||
};
|
||||
|
||||
struct mlxsw_thermal {
|
||||
@@ -101,10 +110,7 @@ struct mlxsw_thermal {
|
||||
struct thermal_cooling_device *cdevs[MLXSW_MFCR_PWMS_MAX];
|
||||
u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
|
||||
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
|
||||
- struct mlxsw_thermal_module *tz_module_arr;
|
||||
- u8 tz_module_num;
|
||||
- struct mlxsw_thermal_module *tz_gearbox_arr;
|
||||
- u8 tz_gearbox_num;
|
||||
+ struct mlxsw_thermal_area *main;
|
||||
unsigned int tz_highest_score;
|
||||
struct thermal_zone_device *tz_highest_dev;
|
||||
};
|
||||
@@ -159,13 +165,15 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
|
||||
* EEPROM if we got valid thresholds from MTMP.
|
||||
*/
|
||||
if (!emerg_temp || !crit_temp) {
|
||||
- err = mlxsw_env_module_temp_thresholds_get(core, 0, tz->module,
|
||||
+ err = mlxsw_env_module_temp_thresholds_get(core, tz->slot_index,
|
||||
+ tz->module,
|
||||
SFP_TEMP_HIGH_WARN,
|
||||
&crit_temp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- err = mlxsw_env_module_temp_thresholds_get(core, 0, tz->module,
|
||||
+ err = mlxsw_env_module_temp_thresholds_get(core, tz->slot_index,
|
||||
+ tz->module,
|
||||
SFP_TEMP_HIGH_ALARM,
|
||||
&emerg_temp);
|
||||
if (err)
|
||||
@@ -432,15 +440,16 @@ static int mlxsw_thermal_module_unbind(struct thermal_zone_device *tzdev,
|
||||
|
||||
static void
|
||||
mlxsw_thermal_module_temp_and_thresholds_get(struct mlxsw_core *core,
|
||||
- u16 sensor_index, int *p_temp,
|
||||
- int *p_crit_temp,
|
||||
+ u8 slot_index, u16 sensor_index,
|
||||
+ int *p_temp, int *p_crit_temp,
|
||||
int *p_emerg_temp)
|
||||
{
|
||||
char mtmp_pl[MLXSW_REG_MTMP_LEN];
|
||||
int err;
|
||||
|
||||
/* Read module temperature and thresholds. */
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, 0, sensor_index, false, false);
|
||||
+ mlxsw_reg_mtmp_pack(mtmp_pl, slot_index, sensor_index,
|
||||
+ false, false);
|
||||
err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err) {
|
||||
/* Set temperature and thresholds to zero to avoid passing
|
||||
@@ -471,6 +480,7 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
|
||||
|
||||
/* Read module temperature and thresholds. */
|
||||
mlxsw_thermal_module_temp_and_thresholds_get(thermal->core,
|
||||
+ tz->slot_index,
|
||||
sensor_index, &temp,
|
||||
&crit_temp, &emerg_temp);
|
||||
*p_temp = temp;
|
||||
@@ -585,7 +595,7 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
|
||||
int err;
|
||||
|
||||
index = MLXSW_REG_MTMP_GBOX_INDEX_MIN + tz->module;
|
||||
- mlxsw_reg_mtmp_pack(mtmp_pl, 0, index, false, false);
|
||||
+ mlxsw_reg_mtmp_pack(mtmp_pl, tz->slot_index, index, false, false);
|
||||
|
||||
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
if (err)
|
||||
@@ -745,25 +755,28 @@ 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 module)
|
||||
+ struct mlxsw_thermal *thermal,
|
||||
+ struct mlxsw_thermal_area *area, u8 module)
|
||||
{
|
||||
struct mlxsw_thermal_module *module_tz;
|
||||
int dummy_temp, crit_temp, emerg_temp;
|
||||
u16 sensor_index;
|
||||
|
||||
sensor_index = MLXSW_REG_MTMP_MODULE_INDEX_MIN + module;
|
||||
- module_tz = &thermal->tz_module_arr[module];
|
||||
+ module_tz = &area->tz_module_arr[module];
|
||||
/* Skip if parent is already set (case of port split). */
|
||||
if (module_tz->parent)
|
||||
return 0;
|
||||
module_tz->module = module;
|
||||
+ module_tz->slot_index = area->slot_index;
|
||||
module_tz->parent = thermal;
|
||||
memcpy(module_tz->trips, default_thermal_trips,
|
||||
sizeof(thermal->trips));
|
||||
/* Initialize all trip point. */
|
||||
mlxsw_thermal_module_trips_reset(module_tz);
|
||||
/* Read module temperature and thresholds. */
|
||||
- mlxsw_thermal_module_temp_and_thresholds_get(core, sensor_index, &dummy_temp,
|
||||
+ mlxsw_thermal_module_temp_and_thresholds_get(core, area->slot_index,
|
||||
+ sensor_index, &dummy_temp,
|
||||
&crit_temp, &emerg_temp);
|
||||
/* Update trip point according to the module data. */
|
||||
return mlxsw_thermal_module_trips_update(dev, core, module_tz,
|
||||
@@ -781,34 +794,39 @@ static void mlxsw_thermal_module_fini(struct mlxsw_thermal_module *module_tz)
|
||||
|
||||
static int
|
||||
mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
|
||||
- struct mlxsw_thermal *thermal)
|
||||
+ struct mlxsw_thermal *thermal,
|
||||
+ struct mlxsw_thermal_area *area)
|
||||
{
|
||||
struct mlxsw_thermal_module *module_tz;
|
||||
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
int i, err;
|
||||
|
||||
- mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
+ mlxsw_reg_mgpir_pack(mgpir_pl, area->slot_index);
|
||||
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, NULL);
|
||||
+ &area->tz_module_num, NULL);
|
||||
|
||||
- thermal->tz_module_arr = kcalloc(thermal->tz_module_num,
|
||||
- sizeof(*thermal->tz_module_arr),
|
||||
- GFP_KERNEL);
|
||||
- if (!thermal->tz_module_arr)
|
||||
+ /* For modular system module counter could be zero. */
|
||||
+ if (!area->tz_module_num)
|
||||
+ return 0;
|
||||
+
|
||||
+ area->tz_module_arr = kcalloc(area->tz_module_num,
|
||||
+ sizeof(*area->tz_module_arr),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!area->tz_module_arr)
|
||||
return -ENOMEM;
|
||||
|
||||
- for (i = 0; i < thermal->tz_module_num; i++) {
|
||||
- err = mlxsw_thermal_module_init(dev, core, thermal, i);
|
||||
+ for (i = 0; i < area->tz_module_num; i++) {
|
||||
+ err = mlxsw_thermal_module_init(dev, core, thermal, area, i);
|
||||
if (err)
|
||||
goto err_thermal_module_init;
|
||||
}
|
||||
|
||||
- for (i = 0; i < thermal->tz_module_num; i++) {
|
||||
- module_tz = &thermal->tz_module_arr[i];
|
||||
+ for (i = 0; i < area->tz_module_num; i++) {
|
||||
+ module_tz = &area->tz_module_arr[i];
|
||||
if (!module_tz->parent)
|
||||
continue;
|
||||
err = mlxsw_thermal_module_tz_init(module_tz);
|
||||
@@ -820,20 +838,21 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
|
||||
|
||||
err_thermal_module_tz_init:
|
||||
err_thermal_module_init:
|
||||
- for (i = thermal->tz_module_num - 1; i >= 0; i--)
|
||||
- mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
|
||||
- kfree(thermal->tz_module_arr);
|
||||
+ for (i = area->tz_module_num - 1; i >= 0; i--)
|
||||
+ mlxsw_thermal_module_fini(&area->tz_module_arr[i]);
|
||||
+ kfree(area->tz_module_arr);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
-mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal)
|
||||
+mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal,
|
||||
+ struct mlxsw_thermal_area *area)
|
||||
{
|
||||
int 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);
|
||||
+ for (i = area->tz_module_num - 1; i >= 0; i--)
|
||||
+ mlxsw_thermal_module_fini(&area->tz_module_arr[i]);
|
||||
+ kfree(area->tz_module_arr);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -869,7 +888,8 @@ mlxsw_thermal_gearbox_tz_fini(struct mlxsw_thermal_module *gearbox_tz)
|
||||
|
||||
static int
|
||||
mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
- struct mlxsw_thermal *thermal)
|
||||
+ struct mlxsw_thermal *thermal,
|
||||
+ struct mlxsw_thermal_area *area)
|
||||
{
|
||||
enum mlxsw_reg_mgpir_device_type device_type;
|
||||
struct mlxsw_thermal_module *gearbox_tz;
|
||||
@@ -889,19 +909,20 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
!gbox_num)
|
||||
return 0;
|
||||
|
||||
- thermal->tz_gearbox_num = gbox_num;
|
||||
- thermal->tz_gearbox_arr = kcalloc(thermal->tz_gearbox_num,
|
||||
- sizeof(*thermal->tz_gearbox_arr),
|
||||
- GFP_KERNEL);
|
||||
- if (!thermal->tz_gearbox_arr)
|
||||
+ area->tz_gearbox_num = gbox_num;
|
||||
+ area->tz_gearbox_arr = kcalloc(area->tz_gearbox_num,
|
||||
+ sizeof(*area->tz_gearbox_arr),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!area->tz_gearbox_arr)
|
||||
return -ENOMEM;
|
||||
|
||||
- for (i = 0; i < thermal->tz_gearbox_num; i++) {
|
||||
- gearbox_tz = &thermal->tz_gearbox_arr[i];
|
||||
+ for (i = 0; i < area->tz_gearbox_num; i++) {
|
||||
+ gearbox_tz = &area->tz_gearbox_arr[i];
|
||||
memcpy(gearbox_tz->trips, default_thermal_trips,
|
||||
sizeof(thermal->trips));
|
||||
gearbox_tz->module = i;
|
||||
gearbox_tz->parent = thermal;
|
||||
+ gearbox_tz->slot_index = area->slot_index;
|
||||
err = mlxsw_thermal_gearbox_tz_init(gearbox_tz);
|
||||
if (err)
|
||||
goto err_thermal_gearbox_tz_init;
|
||||
@@ -911,19 +932,20 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
|
||||
err_thermal_gearbox_tz_init:
|
||||
for (i--; i >= 0; i--)
|
||||
- mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
|
||||
- kfree(thermal->tz_gearbox_arr);
|
||||
+ mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]);
|
||||
+ kfree(area->tz_gearbox_arr);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
-mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal)
|
||||
+mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal,
|
||||
+ struct mlxsw_thermal_area *area)
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = thermal->tz_gearbox_num - 1; i >= 0; i--)
|
||||
- mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
|
||||
- kfree(thermal->tz_gearbox_arr);
|
||||
+ for (i = area->tz_gearbox_num - 1; i >= 0; i--)
|
||||
+ mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]);
|
||||
+ kfree(area->tz_gearbox_arr);
|
||||
}
|
||||
|
||||
int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
@@ -943,9 +965,16 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
if (!thermal)
|
||||
return -ENOMEM;
|
||||
|
||||
+ thermal->main = devm_kzalloc(dev, sizeof(*thermal->main), GFP_KERNEL);
|
||||
+ if (!thermal->main) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_devm_kzalloc;
|
||||
+ }
|
||||
+
|
||||
thermal->core = core;
|
||||
thermal->bus_info = bus_info;
|
||||
memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips));
|
||||
+ thermal->main->slot_index = 0;
|
||||
|
||||
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl);
|
||||
if (err) {
|
||||
@@ -1012,11 +1041,11 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
goto err_thermal_zone_device_register;
|
||||
}
|
||||
|
||||
- err = mlxsw_thermal_modules_init(dev, core, thermal);
|
||||
+ err = mlxsw_thermal_modules_init(dev, core, thermal, thermal->main);
|
||||
if (err)
|
||||
goto err_thermal_modules_init;
|
||||
|
||||
- err = mlxsw_thermal_gearboxes_init(dev, core, thermal);
|
||||
+ err = mlxsw_thermal_gearboxes_init(dev, core, thermal, thermal->main);
|
||||
if (err)
|
||||
goto err_thermal_gearboxes_init;
|
||||
|
||||
@@ -1028,9 +1057,9 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
return 0;
|
||||
|
||||
err_thermal_zone_device_enable:
|
||||
- mlxsw_thermal_gearboxes_fini(thermal);
|
||||
+ mlxsw_thermal_gearboxes_fini(thermal, thermal->main);
|
||||
err_thermal_gearboxes_init:
|
||||
- mlxsw_thermal_modules_fini(thermal);
|
||||
+ mlxsw_thermal_modules_fini(thermal, thermal->main);
|
||||
err_thermal_modules_init:
|
||||
if (thermal->tzdev) {
|
||||
thermal_zone_device_unregister(thermal->tzdev);
|
||||
@@ -1043,6 +1072,8 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
thermal_cooling_device_unregister(thermal->cdevs[i]);
|
||||
err_reg_write:
|
||||
err_reg_query:
|
||||
+ devm_kfree(dev, thermal->main);
|
||||
+err_devm_kzalloc:
|
||||
devm_kfree(dev, thermal);
|
||||
return err;
|
||||
}
|
||||
@@ -1051,8 +1082,8 @@ void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
|
||||
{
|
||||
int i;
|
||||
|
||||
- mlxsw_thermal_gearboxes_fini(thermal);
|
||||
- mlxsw_thermal_modules_fini(thermal);
|
||||
+ mlxsw_thermal_gearboxes_fini(thermal, thermal->main);
|
||||
+ mlxsw_thermal_modules_fini(thermal, thermal->main);
|
||||
if (thermal->tzdev) {
|
||||
thermal_zone_device_unregister(thermal->tzdev);
|
||||
thermal->tzdev = NULL;
|
||||
@@ -1065,5 +1096,6 @@ void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
|
||||
}
|
||||
}
|
||||
|
||||
+ devm_kfree(thermal->bus_info->dev, thermal->main);
|
||||
devm_kfree(thermal->bus_info->dev, thermal);
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,137 @@
|
||||
From 219381cde0a7294834aff7e3f30584182b26a2b6 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:34 +0200
|
||||
Subject: [PATCH] mlxsw: core_thermal: Split gearbox initialization
|
||||
|
||||
Split gearbox initialization in two routines - the first one is to be
|
||||
used for gearbox configuration validation, the second for creation of
|
||||
gearbox related thermal zones if any.
|
||||
|
||||
Currently, mlxsw supports gearbox thermal zones corresponding to the
|
||||
main board. For system equipped with the line cards assembled with the
|
||||
gearboxes, thermal zones will be associated with the gearboxes found on
|
||||
those line cards.
|
||||
|
||||
While the initialization flow for main board and for line cards is the
|
||||
same, the configuration flow is different.
|
||||
|
||||
The purpose of this patch is to allow reusing of initialization flow by
|
||||
main board and line cards.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../ethernet/mellanox/mlxsw/core_thermal.c | 43 +++++++++++++++----
|
||||
1 file changed, 34 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
index 77a484a55..a8ecd8fea 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -887,15 +887,12 @@ mlxsw_thermal_gearbox_tz_fini(struct mlxsw_thermal_module *gearbox_tz)
|
||||
}
|
||||
|
||||
static int
|
||||
-mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
- struct mlxsw_thermal *thermal,
|
||||
- struct mlxsw_thermal_area *area)
|
||||
+mlxsw_thermal_gearboxes_main_init(struct device *dev, struct mlxsw_core *core,
|
||||
+ struct mlxsw_thermal_area *area)
|
||||
{
|
||||
enum mlxsw_reg_mgpir_device_type device_type;
|
||||
- struct mlxsw_thermal_module *gearbox_tz;
|
||||
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
u8 gbox_num;
|
||||
- int i;
|
||||
int err;
|
||||
|
||||
mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
@@ -905,8 +902,11 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
|
||||
mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL,
|
||||
NULL, NULL);
|
||||
- if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE ||
|
||||
- !gbox_num)
|
||||
+ if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE)
|
||||
+ gbox_num = 0;
|
||||
+
|
||||
+ /* Skip gearbox sensor array allocation, if no gearboxes are available. */
|
||||
+ if (!gbox_num)
|
||||
return 0;
|
||||
|
||||
area->tz_gearbox_num = gbox_num;
|
||||
@@ -916,6 +916,26 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
if (!area->tz_gearbox_arr)
|
||||
return -ENOMEM;
|
||||
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mlxsw_thermal_gearboxes_main_fini(struct mlxsw_thermal_area *area)
|
||||
+{
|
||||
+ kfree(area->tz_gearbox_arr);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
+ struct mlxsw_thermal *thermal,
|
||||
+ struct mlxsw_thermal_area *area)
|
||||
+{
|
||||
+ struct mlxsw_thermal_module *gearbox_tz;
|
||||
+ int i, err;
|
||||
+
|
||||
+ if (!area->tz_gearbox_num)
|
||||
+ return 0;
|
||||
+
|
||||
for (i = 0; i < area->tz_gearbox_num; i++) {
|
||||
gearbox_tz = &area->tz_gearbox_arr[i];
|
||||
memcpy(gearbox_tz->trips, default_thermal_trips,
|
||||
@@ -933,7 +953,6 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
err_thermal_gearbox_tz_init:
|
||||
for (i--; i >= 0; i--)
|
||||
mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]);
|
||||
- kfree(area->tz_gearbox_arr);
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -945,7 +964,6 @@ mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal,
|
||||
|
||||
for (i = area->tz_gearbox_num - 1; i >= 0; i--)
|
||||
mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]);
|
||||
- kfree(area->tz_gearbox_arr);
|
||||
}
|
||||
|
||||
int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
@@ -1045,6 +1063,10 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
if (err)
|
||||
goto err_thermal_modules_init;
|
||||
|
||||
+ err = mlxsw_thermal_gearboxes_main_init(dev, core, thermal->main);
|
||||
+ if (err)
|
||||
+ goto err_thermal_gearboxes_main_init;
|
||||
+
|
||||
err = mlxsw_thermal_gearboxes_init(dev, core, thermal, thermal->main);
|
||||
if (err)
|
||||
goto err_thermal_gearboxes_init;
|
||||
@@ -1059,6 +1081,8 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
err_thermal_zone_device_enable:
|
||||
mlxsw_thermal_gearboxes_fini(thermal, thermal->main);
|
||||
err_thermal_gearboxes_init:
|
||||
+ mlxsw_thermal_gearboxes_main_fini(thermal->main);
|
||||
+err_thermal_gearboxes_main_init:
|
||||
mlxsw_thermal_modules_fini(thermal, thermal->main);
|
||||
err_thermal_modules_init:
|
||||
if (thermal->tzdev) {
|
||||
@@ -1083,6 +1107,7 @@ void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
|
||||
int i;
|
||||
|
||||
mlxsw_thermal_gearboxes_fini(thermal, thermal->main);
|
||||
+ mlxsw_thermal_gearboxes_main_fini(thermal->main);
|
||||
mlxsw_thermal_modules_fini(thermal, thermal->main);
|
||||
if (thermal->tzdev) {
|
||||
thermal_zone_device_unregister(thermal->tzdev);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,127 @@
|
||||
From 9c8482e7c487a0a19f0d6d5df06c70aa529d3023 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:35 +0200
|
||||
Subject: [PATCH] mlxsw: core_thermal: Extend thermal area with gearbox mapping
|
||||
field
|
||||
|
||||
Add gearbox mapping field 'gearbox_sensor_map' to
|
||||
'mlxsw_thermal_module' structure. It should provide the mapping for
|
||||
gearbox sensor indexes, given gearbox number. For main board mapping is
|
||||
supposed to be always sequential, while for line cards on modular
|
||||
system it could be non-sequential.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../ethernet/mellanox/mlxsw/core_thermal.c | 33 ++++++++++++++-----
|
||||
1 file changed, 25 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
index a8ecd8fea..2efedd35b 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -85,9 +85,11 @@ static const struct mlxsw_thermal_trip default_thermal_trips[] = {
|
||||
#define MLXSW_THERMAL_TRIP_MASK (BIT(MLXSW_THERMAL_NUM_TRIPS) - 1)
|
||||
|
||||
struct mlxsw_thermal;
|
||||
+struct mlxsw_thermal_area;
|
||||
|
||||
struct mlxsw_thermal_module {
|
||||
struct mlxsw_thermal *parent;
|
||||
+ struct mlxsw_thermal_area *area;
|
||||
struct thermal_zone_device *tzdev;
|
||||
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
|
||||
int module; /* Module or gearbox number */
|
||||
@@ -100,6 +102,7 @@ struct mlxsw_thermal_area {
|
||||
struct mlxsw_thermal_module *tz_gearbox_arr;
|
||||
u8 tz_gearbox_num;
|
||||
u8 slot_index;
|
||||
+ u16 *gearbox_sensor_map;
|
||||
};
|
||||
|
||||
struct mlxsw_thermal {
|
||||
@@ -594,7 +597,7 @@ static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
|
||||
int temp;
|
||||
int err;
|
||||
|
||||
- index = MLXSW_REG_MTMP_GBOX_INDEX_MIN + tz->module;
|
||||
+ index = tz->area->gearbox_sensor_map[tz->module];
|
||||
mlxsw_reg_mtmp_pack(mtmp_pl, tz->slot_index, index, false, false);
|
||||
|
||||
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
|
||||
@@ -768,6 +771,7 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
|
||||
if (module_tz->parent)
|
||||
return 0;
|
||||
module_tz->module = module;
|
||||
+ module_tz->area = area;
|
||||
module_tz->slot_index = area->slot_index;
|
||||
module_tz->parent = thermal;
|
||||
memcpy(module_tz->trips, default_thermal_trips,
|
||||
@@ -892,36 +896,48 @@ mlxsw_thermal_gearboxes_main_init(struct device *dev, struct mlxsw_core *core,
|
||||
{
|
||||
enum mlxsw_reg_mgpir_device_type device_type;
|
||||
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
- u8 gbox_num;
|
||||
- int err;
|
||||
+ int i = 0, err;
|
||||
|
||||
mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL,
|
||||
- NULL, NULL);
|
||||
+ mlxsw_reg_mgpir_unpack(mgpir_pl, &area->tz_gearbox_num, &device_type,
|
||||
+ NULL, NULL, NULL);
|
||||
if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE)
|
||||
- gbox_num = 0;
|
||||
+ area->tz_gearbox_num = 0;
|
||||
|
||||
/* Skip gearbox sensor array allocation, if no gearboxes are available. */
|
||||
- if (!gbox_num)
|
||||
+ if (!area->tz_gearbox_num)
|
||||
return 0;
|
||||
|
||||
- area->tz_gearbox_num = gbox_num;
|
||||
area->tz_gearbox_arr = kcalloc(area->tz_gearbox_num,
|
||||
sizeof(*area->tz_gearbox_arr),
|
||||
GFP_KERNEL);
|
||||
if (!area->tz_gearbox_arr)
|
||||
return -ENOMEM;
|
||||
|
||||
+ area->gearbox_sensor_map = kmalloc_array(area->tz_gearbox_num,
|
||||
+ sizeof(u16), GFP_KERNEL);
|
||||
+ if (!area->gearbox_sensor_map)
|
||||
+ goto mlxsw_thermal_gearbox_sensor_map;
|
||||
+
|
||||
+ /* Fill out gearbox sensor mapping array. */
|
||||
+ for (i = 0; i < area->tz_gearbox_num; i++)
|
||||
+ area->gearbox_sensor_map[i] = MLXSW_REG_MTMP_GBOX_INDEX_MIN + i;
|
||||
+
|
||||
return 0;
|
||||
+
|
||||
+mlxsw_thermal_gearbox_sensor_map:
|
||||
+ kfree(area->tz_gearbox_arr);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static void
|
||||
mlxsw_thermal_gearboxes_main_fini(struct mlxsw_thermal_area *area)
|
||||
{
|
||||
+ kfree(area->gearbox_sensor_map);
|
||||
kfree(area->tz_gearbox_arr);
|
||||
}
|
||||
|
||||
@@ -942,6 +958,7 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
|
||||
sizeof(thermal->trips));
|
||||
gearbox_tz->module = i;
|
||||
gearbox_tz->parent = thermal;
|
||||
+ gearbox_tz->area = area;
|
||||
gearbox_tz->slot_index = area->slot_index;
|
||||
err = mlxsw_thermal_gearbox_tz_init(gearbox_tz);
|
||||
if (err)
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,59 @@
|
||||
From 3f3548804a89b7fbe15fa92ea8686f08b990b083 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:36 +0200
|
||||
Subject: [PATCH] mlxsw: core_thermal: Add line card id prefix to line card
|
||||
thermal zone name
|
||||
|
||||
Add prefix "lc#n" to thermal zones associated with the thermal objects
|
||||
found on line cards.
|
||||
|
||||
For example thermal zone for module #9 located at line card #7 will
|
||||
have type:
|
||||
mlxsw-lc7-module9.
|
||||
And thermal zone for gearbox #3 located at line card #5 will have type:
|
||||
mlxsw-lc5-gearbox3.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_thermal.c | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
index 2efedd35b..421555d3f 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -730,8 +730,12 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)
|
||||
char tz_name[MLXSW_THERMAL_ZONE_MAX_NAME];
|
||||
int err;
|
||||
|
||||
- snprintf(tz_name, sizeof(tz_name), "mlxsw-module%d",
|
||||
- module_tz->module + 1);
|
||||
+ if (module_tz->slot_index)
|
||||
+ snprintf(tz_name, sizeof(tz_name), "mlxsw-lc%d-module%d",
|
||||
+ module_tz->slot_index, module_tz->module + 1);
|
||||
+ else
|
||||
+ snprintf(tz_name, sizeof(tz_name), "mlxsw-module%d",
|
||||
+ module_tz->module + 1);
|
||||
module_tz->tzdev = thermal_zone_device_register(tz_name,
|
||||
MLXSW_THERMAL_NUM_TRIPS,
|
||||
MLXSW_THERMAL_TRIP_MASK,
|
||||
@@ -865,8 +869,12 @@ mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
|
||||
char tz_name[MLXSW_THERMAL_ZONE_MAX_NAME];
|
||||
int ret;
|
||||
|
||||
- snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d",
|
||||
- gearbox_tz->module + 1);
|
||||
+ if (gearbox_tz->slot_index)
|
||||
+ snprintf(tz_name, sizeof(tz_name), "mlxsw-lc%d-gearbox%d",
|
||||
+ gearbox_tz->slot_index, gearbox_tz->module + 1);
|
||||
+ else
|
||||
+ snprintf(tz_name, sizeof(tz_name), "mlxsw-gearbox%d",
|
||||
+ gearbox_tz->module + 1);
|
||||
gearbox_tz->tzdev = thermal_zone_device_register(tz_name,
|
||||
MLXSW_THERMAL_NUM_TRIPS,
|
||||
MLXSW_THERMAL_TRIP_MASK,
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,35 @@
|
||||
From 34251eb77f3f50ac2d574876f33c65d8d2c70e9c Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:37 +0200
|
||||
Subject: [PATCH] mlxsw: core_thermal: Use exact name of cooling devices for
|
||||
binding
|
||||
|
||||
Modular system supports additional cooling devices "mlxreg_fan1",
|
||||
"mlxreg_fan2", etcetera. Thermal zones in "mlxsw" driver should be
|
||||
bound to the same device as before called "mlxreg_fan". Used exact
|
||||
match for cooling device name to avoid binding to new additional
|
||||
cooling devices.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
index 421555d3f..a20a91285 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -141,8 +141,7 @@ static int mlxsw_get_cooling_device_idx(struct mlxsw_thermal *thermal,
|
||||
|
||||
/* Allow mlxsw thermal zone binding to an external cooling device */
|
||||
for (i = 0; i < ARRAY_SIZE(mlxsw_thermal_external_allowed_cdev); i++) {
|
||||
- if (strnstr(cdev->type, mlxsw_thermal_external_allowed_cdev[i],
|
||||
- strlen(cdev->type)))
|
||||
+ if (!strcmp(cdev->type, mlxsw_thermal_external_allowed_cdev[i]))
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,48 @@
|
||||
From 56370efd25ad5b77b87645d779dd577674c12864 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Tue, 14 Dec 2021 10:57:38 +0200
|
||||
Subject: [PATCH] mlxsw: core_thermal: Use common define for thermal zone name
|
||||
length
|
||||
|
||||
Replace internal define 'MLXSW_THERMAL_ZONE_MAX_NAME' by common
|
||||
'THERMAL_NAME_LENGTH'.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
index a20a91285..e860cade5 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -21,7 +21,6 @@
|
||||
#define MLXSW_THERMAL_ASIC_TEMP_HOT 105000 /* 105C */
|
||||
#define MLXSW_THERMAL_HYSTERESIS_TEMP 5000 /* 5C */
|
||||
#define MLXSW_THERMAL_MODULE_TEMP_SHIFT (MLXSW_THERMAL_HYSTERESIS_TEMP * 2)
|
||||
-#define MLXSW_THERMAL_ZONE_MAX_NAME 16
|
||||
#define MLXSW_THERMAL_TEMP_SCORE_MAX GENMASK(31, 0)
|
||||
#define MLXSW_THERMAL_MAX_STATE 10
|
||||
#define MLXSW_THERMAL_MAX_DUTY 255
|
||||
@@ -726,7 +725,7 @@ static const struct thermal_cooling_device_ops mlxsw_cooling_ops = {
|
||||
static int
|
||||
mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)
|
||||
{
|
||||
- char tz_name[MLXSW_THERMAL_ZONE_MAX_NAME];
|
||||
+ char tz_name[THERMAL_NAME_LENGTH];
|
||||
int err;
|
||||
|
||||
if (module_tz->slot_index)
|
||||
@@ -865,7 +864,7 @@ mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal,
|
||||
static int
|
||||
mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
|
||||
{
|
||||
- char tz_name[MLXSW_THERMAL_ZONE_MAX_NAME];
|
||||
+ char tz_name[THERMAL_NAME_LENGTH];
|
||||
int ret;
|
||||
|
||||
if (gearbox_tz->slot_index)
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,531 @@
|
||||
From 242d6e2b00a25ec4184a63cec76c9f7f7c235594 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Wed, 22 Dec 2021 08:57:27 +0000
|
||||
Subject: [PATCH] devlink: add support to create line card and expose to user
|
||||
|
||||
Extend the devlink API so the driver is going to be able to create and
|
||||
destroy linecard instances. There can be multiple line cards per devlink
|
||||
device. Expose this new type of object over devlink netlink API to the
|
||||
userspace, with notifications.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
include/net/devlink.h | 15 ++
|
||||
include/uapi/linux/devlink.h | 22 +++
|
||||
net/core/devlink.c | 303 ++++++++++++++++++++++++++++++++++-
|
||||
3 files changed, 339 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/net/devlink.h b/include/net/devlink.h
|
||||
index b01bb9bca..e8f046590 100644
|
||||
--- a/include/net/devlink.h
|
||||
+++ b/include/net/devlink.h
|
||||
@@ -31,6 +31,7 @@ struct devlink_dev_stats {
|
||||
struct devlink_ops;
|
||||
|
||||
struct devlink {
|
||||
+ u32 index;
|
||||
struct list_head list;
|
||||
struct list_head port_list;
|
||||
struct list_head sb_list;
|
||||
@@ -44,6 +45,8 @@ struct devlink {
|
||||
struct list_head trap_list;
|
||||
struct list_head trap_group_list;
|
||||
struct list_head trap_policer_list;
|
||||
+ struct list_head linecard_list;
|
||||
+ struct mutex linecards_lock; /* protects linecard_list */
|
||||
const struct devlink_ops *ops;
|
||||
struct xarray snapshot_ids;
|
||||
struct devlink_dev_stats stats;
|
||||
@@ -55,6 +58,8 @@ struct devlink {
|
||||
u8 reload_failed:1,
|
||||
reload_enabled:1,
|
||||
registered:1;
|
||||
+ refcount_t refcount;
|
||||
+ struct completion comp;
|
||||
char priv[0] __aligned(NETDEV_ALIGN);
|
||||
};
|
||||
|
||||
@@ -137,6 +142,13 @@ struct devlink_port {
|
||||
struct mutex reporters_lock; /* Protects reporter_list */
|
||||
};
|
||||
|
||||
+struct devlink_linecard {
|
||||
+ struct list_head list;
|
||||
+ struct devlink *devlink;
|
||||
+ unsigned int index;
|
||||
+ refcount_t refcount;
|
||||
+};
|
||||
+
|
||||
struct devlink_sb_pool_info {
|
||||
enum devlink_sb_pool_type pool_type;
|
||||
u32 size;
|
||||
@@ -1401,6 +1413,9 @@ void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 contro
|
||||
u16 pf, bool external);
|
||||
void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
|
||||
u16 pf, u16 vf, bool external);
|
||||
+struct devlink_linecard *devlink_linecard_create(struct devlink *devlink,
|
||||
+ unsigned int linecard_index);
|
||||
+void devlink_linecard_destroy(struct devlink_linecard *linecard);
|
||||
int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
|
||||
u32 size, u16 ingress_pools_count,
|
||||
u16 egress_pools_count, u16 ingress_tc_count,
|
||||
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
|
||||
index cf89c318f..ff07ad596 100644
|
||||
--- a/include/uapi/linux/devlink.h
|
||||
+++ b/include/uapi/linux/devlink.h
|
||||
@@ -126,6 +126,16 @@ enum devlink_command {
|
||||
|
||||
DEVLINK_CMD_HEALTH_REPORTER_TEST,
|
||||
|
||||
+ DEVLINK_CMD_RATE_GET, /* can dump */
|
||||
+ DEVLINK_CMD_RATE_SET,
|
||||
+ DEVLINK_CMD_RATE_NEW,
|
||||
+ DEVLINK_CMD_RATE_DEL,
|
||||
+
|
||||
+ DEVLINK_CMD_LINECARD_GET, /* can dump */
|
||||
+ DEVLINK_CMD_LINECARD_SET,
|
||||
+ DEVLINK_CMD_LINECARD_NEW,
|
||||
+ DEVLINK_CMD_LINECARD_DEL,
|
||||
+
|
||||
/* add new commands above here */
|
||||
__DEVLINK_CMD_MAX,
|
||||
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
|
||||
@@ -529,6 +539,18 @@ enum devlink_attr {
|
||||
DEVLINK_ATTR_RELOAD_ACTION_INFO, /* nested */
|
||||
DEVLINK_ATTR_RELOAD_ACTION_STATS, /* nested */
|
||||
|
||||
+ DEVLINK_ATTR_PORT_PCI_SF_NUMBER, /* u32 */
|
||||
+
|
||||
+ DEVLINK_ATTR_RATE_TYPE, /* u16 */
|
||||
+ DEVLINK_ATTR_RATE_TX_SHARE, /* u64 */
|
||||
+ DEVLINK_ATTR_RATE_TX_MAX, /* u64 */
|
||||
+ DEVLINK_ATTR_RATE_NODE_NAME, /* string */
|
||||
+ DEVLINK_ATTR_RATE_PARENT_NODE_NAME, /* string */
|
||||
+
|
||||
+ DEVLINK_ATTR_REGION_MAX_SNAPSHOTS, /* u32 */
|
||||
+
|
||||
+ DEVLINK_ATTR_LINECARD_INDEX, /* u32 */
|
||||
+
|
||||
/* add new attributes above here, update the policy in devlink.c */
|
||||
|
||||
__DEVLINK_ATTR_MAX,
|
||||
diff --git a/net/core/devlink.c b/net/core/devlink.c
|
||||
index 72047750d..645fe0612 100644
|
||||
--- a/net/core/devlink.c
|
||||
+++ b/net/core/devlink.c
|
||||
@@ -91,6 +91,25 @@ static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_
|
||||
|
||||
static LIST_HEAD(devlink_list);
|
||||
|
||||
+static DEFINE_XARRAY_FLAGS(devlinks, XA_FLAGS_ALLOC);
|
||||
+#define DEVLINK_REGISTERED XA_MARK_1
|
||||
+
|
||||
+/* devlink instances are open to the access from the user space after
|
||||
+ * devlink_register() call. Such logical barrier allows us to have certain
|
||||
+ * expectations related to locking.
|
||||
+ *
|
||||
+ * Before *_register() - we are in initialization stage and no parallel
|
||||
+ * access possible to the devlink instance. All drivers perform that phase
|
||||
+ * by implicitly holding device_lock.
|
||||
+ *
|
||||
+ * After *_register() - users and driver can access devlink instance at
|
||||
+ * the same time.
|
||||
+ */
|
||||
+#define ASSERT_DEVLINK_REGISTERED(d) \
|
||||
+ WARN_ON_ONCE(!xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED))
|
||||
+#define ASSERT_DEVLINK_NOT_REGISTERED(d) \
|
||||
+ WARN_ON_ONCE(xa_get_mark(&devlinks, (d)->index, DEVLINK_REGISTERED))
|
||||
+
|
||||
/* devlink_mutex
|
||||
*
|
||||
* An overall lock guarding every operation coming from userspace.
|
||||
@@ -105,6 +124,19 @@ struct net *devlink_net(const struct devlink *devlink)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_net);
|
||||
|
||||
+void devlink_put(struct devlink *devlink)
|
||||
+{
|
||||
+ if (refcount_dec_and_test(&devlink->refcount))
|
||||
+ complete(&devlink->comp);
|
||||
+}
|
||||
+
|
||||
+struct devlink *__must_check devlink_try_get(struct devlink *devlink)
|
||||
+{
|
||||
+ if (refcount_inc_not_zero(&devlink->refcount))
|
||||
+ return devlink;
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void __devlink_net_set(struct devlink *devlink, struct net *net)
|
||||
{
|
||||
write_pnet(&devlink->_net, net);
|
||||
@@ -187,6 +219,56 @@ static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
|
||||
return devlink_port_get_from_attrs(devlink, info->attrs);
|
||||
}
|
||||
|
||||
+static struct devlink_linecard *
|
||||
+devlink_linecard_get_by_index(struct devlink *devlink,
|
||||
+ unsigned int linecard_index)
|
||||
+{
|
||||
+ struct devlink_linecard *devlink_linecard;
|
||||
+
|
||||
+ list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) {
|
||||
+ if (devlink_linecard->index == linecard_index)
|
||||
+ return devlink_linecard;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static bool devlink_linecard_index_exists(struct devlink *devlink,
|
||||
+ unsigned int linecard_index)
|
||||
+{
|
||||
+ return devlink_linecard_get_by_index(devlink, linecard_index);
|
||||
+}
|
||||
+
|
||||
+static struct devlink_linecard *
|
||||
+devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
|
||||
+{
|
||||
+ if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) {
|
||||
+ u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]);
|
||||
+ struct devlink_linecard *linecard;
|
||||
+
|
||||
+ mutex_lock(&devlink->linecards_lock);
|
||||
+ linecard = devlink_linecard_get_by_index(devlink, linecard_index);
|
||||
+ if (linecard)
|
||||
+ refcount_inc(&linecard->refcount);
|
||||
+ mutex_unlock(&devlink->linecards_lock);
|
||||
+ if (!linecard)
|
||||
+ return ERR_PTR(-ENODEV);
|
||||
+ return linecard;
|
||||
+ }
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
+}
|
||||
+
|
||||
+static struct devlink_linecard *
|
||||
+devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info)
|
||||
+{
|
||||
+ return devlink_linecard_get_from_attrs(devlink, info->attrs);
|
||||
+}
|
||||
+
|
||||
+static void devlink_linecard_put(struct devlink_linecard *linecard)
|
||||
+{
|
||||
+ if (refcount_dec_and_test(&linecard->refcount))
|
||||
+ kfree(linecard);
|
||||
+}
|
||||
+
|
||||
struct devlink_sb {
|
||||
struct list_head list;
|
||||
unsigned int index;
|
||||
@@ -405,16 +487,20 @@ devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
|
||||
|
||||
#define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
|
||||
#define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT BIT(1)
|
||||
+#define DEVLINK_NL_FLAG_NEED_RATE BIT(2)
|
||||
+#define DEVLINK_NL_FLAG_NEED_RATE_NODE BIT(3)
|
||||
+#define DEVLINK_NL_FLAG_NEED_LINECARD BIT(4)
|
||||
|
||||
/* The per devlink instance lock is taken by default in the pre-doit
|
||||
* operation, yet several commands do not require this. The global
|
||||
* devlink lock is taken and protects from disruption by user-calls.
|
||||
*/
|
||||
-#define DEVLINK_NL_FLAG_NO_LOCK BIT(2)
|
||||
+#define DEVLINK_NL_FLAG_NO_LOCK BIT(5)
|
||||
|
||||
static int devlink_nl_pre_doit(const struct genl_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
+ struct devlink_linecard *linecard;
|
||||
struct devlink_port *devlink_port;
|
||||
struct devlink *devlink;
|
||||
int err;
|
||||
@@ -439,6 +525,13 @@ static int devlink_nl_pre_doit(const struct genl_ops *ops,
|
||||
devlink_port = devlink_port_get_from_info(devlink, info);
|
||||
if (!IS_ERR(devlink_port))
|
||||
info->user_ptr[1] = devlink_port;
|
||||
+ } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) {
|
||||
+ linecard = devlink_linecard_get_from_info(devlink, info);
|
||||
+ if (IS_ERR(linecard)) {
|
||||
+ err = PTR_ERR(linecard);
|
||||
+ goto unlock;
|
||||
+ }
|
||||
+ info->user_ptr[1] = linecard;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -452,9 +545,14 @@ static int devlink_nl_pre_doit(const struct genl_ops *ops,
|
||||
static void devlink_nl_post_doit(const struct genl_ops *ops,
|
||||
struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
+ struct devlink_linecard *linecard;
|
||||
struct devlink *devlink;
|
||||
|
||||
devlink = info->user_ptr[0];
|
||||
+ if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_LINECARD) {
|
||||
+ linecard = info->user_ptr[1];
|
||||
+ devlink_linecard_put(linecard);
|
||||
+ }
|
||||
if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
|
||||
mutex_unlock(&devlink->lock);
|
||||
mutex_unlock(&devlink_mutex);
|
||||
@@ -1135,6 +1233,132 @@ static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
|
||||
return devlink_port_unsplit(devlink, port_index, info->extack);
|
||||
}
|
||||
|
||||
+static int devlink_nl_linecard_fill(struct sk_buff *msg,
|
||||
+ struct devlink *devlink,
|
||||
+ struct devlink_linecard *linecard,
|
||||
+ enum devlink_command cmd, u32 portid,
|
||||
+ u32 seq, int flags,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ void *hdr;
|
||||
+
|
||||
+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
|
||||
+ if (!hdr)
|
||||
+ return -EMSGSIZE;
|
||||
+
|
||||
+ if (devlink_nl_put_handle(msg, devlink))
|
||||
+ goto nla_put_failure;
|
||||
+ if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
+ genlmsg_end(msg, hdr);
|
||||
+ return 0;
|
||||
+
|
||||
+nla_put_failure:
|
||||
+ genlmsg_cancel(msg, hdr);
|
||||
+ return -EMSGSIZE;
|
||||
+}
|
||||
+
|
||||
+static void devlink_linecard_notify(struct devlink_linecard *linecard,
|
||||
+ enum devlink_command cmd)
|
||||
+{
|
||||
+ struct devlink *devlink = linecard->devlink;
|
||||
+ struct sk_buff *msg;
|
||||
+ int err;
|
||||
+
|
||||
+ WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW &&
|
||||
+ cmd != DEVLINK_CMD_LINECARD_DEL);
|
||||
+
|
||||
+ if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
|
||||
+ return;
|
||||
+
|
||||
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
+ if (!msg)
|
||||
+ return;
|
||||
+
|
||||
+ err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0,
|
||||
+ NULL);
|
||||
+ if (err) {
|
||||
+ nlmsg_free(msg);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
|
||||
+ msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
|
||||
+}
|
||||
+
|
||||
+static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb,
|
||||
+ struct genl_info *info)
|
||||
+{
|
||||
+ struct devlink_linecard *linecard = info->user_ptr[1];
|
||||
+ struct devlink *devlink = linecard->devlink;
|
||||
+ struct sk_buff *msg;
|
||||
+ int err;
|
||||
+
|
||||
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
+ if (!msg)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ err = devlink_nl_linecard_fill(msg, devlink, linecard,
|
||||
+ DEVLINK_CMD_LINECARD_NEW,
|
||||
+ info->snd_portid, info->snd_seq, 0,
|
||||
+ info->extack);
|
||||
+ if (err) {
|
||||
+ nlmsg_free(msg);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return genlmsg_reply(msg, info);
|
||||
+}
|
||||
+
|
||||
+static int devlink_nl_cmd_linecard_get_dumpit(struct sk_buff *msg,
|
||||
+ struct netlink_callback *cb)
|
||||
+{
|
||||
+ struct devlink_linecard *linecard;
|
||||
+ struct devlink *devlink;
|
||||
+ int start = cb->args[0];
|
||||
+ unsigned long index;
|
||||
+ int idx = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&devlink_mutex);
|
||||
+ xa_for_each_marked(&devlinks, index, devlink, DEVLINK_REGISTERED) {
|
||||
+ if (!devlink_try_get(devlink))
|
||||
+ continue;
|
||||
+
|
||||
+ if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
|
||||
+ goto retry;
|
||||
+
|
||||
+ mutex_lock(&devlink->linecards_lock);
|
||||
+ list_for_each_entry(linecard, &devlink->linecard_list, list) {
|
||||
+ if (idx < start) {
|
||||
+ idx++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ err = devlink_nl_linecard_fill(msg, devlink, linecard,
|
||||
+ DEVLINK_CMD_LINECARD_NEW,
|
||||
+ NETLINK_CB(cb->skb).portid,
|
||||
+ cb->nlh->nlmsg_seq,
|
||||
+ NLM_F_MULTI,
|
||||
+ cb->extack);
|
||||
+ if (err) {
|
||||
+ mutex_unlock(&devlink->linecards_lock);
|
||||
+ devlink_put(devlink);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ idx++;
|
||||
+ }
|
||||
+ mutex_unlock(&devlink->linecards_lock);
|
||||
+retry:
|
||||
+ devlink_put(devlink);
|
||||
+ }
|
||||
+out:
|
||||
+ mutex_unlock(&devlink_mutex);
|
||||
+
|
||||
+ cb->args[0] = idx;
|
||||
+ return msg->len;
|
||||
+}
|
||||
+
|
||||
static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
struct devlink_sb *devlink_sb,
|
||||
enum devlink_command cmd, u32 portid,
|
||||
@@ -7594,6 +7818,19 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
|
||||
[DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
|
||||
DEVLINK_RELOAD_ACTION_MAX),
|
||||
[DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK),
|
||||
+//<<<<<<< HEAD
|
||||
+//=======
|
||||
+ [DEVLINK_ATTR_PORT_FLAVOUR] = { .type = NLA_U16 },
|
||||
+ [DEVLINK_ATTR_PORT_PCI_PF_NUMBER] = { .type = NLA_U16 },
|
||||
+ [DEVLINK_ATTR_PORT_PCI_SF_NUMBER] = { .type = NLA_U32 },
|
||||
+ [DEVLINK_ATTR_PORT_CONTROLLER_NUMBER] = { .type = NLA_U32 },
|
||||
+ [DEVLINK_ATTR_RATE_TYPE] = { .type = NLA_U16 },
|
||||
+ [DEVLINK_ATTR_RATE_TX_SHARE] = { .type = NLA_U64 },
|
||||
+ [DEVLINK_ATTR_RATE_TX_MAX] = { .type = NLA_U64 },
|
||||
+ [DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING },
|
||||
+ [DEVLINK_ATTR_RATE_PARENT_NODE_NAME] = { .type = NLA_NUL_STRING },
|
||||
+ [DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32 },
|
||||
+//>>>>>>> 1180815a3831... devlink: add support to create line card and expose to user
|
||||
};
|
||||
|
||||
static const struct genl_small_ops devlink_nl_ops[] = {
|
||||
@@ -7633,6 +7870,14 @@ static const struct genl_small_ops devlink_nl_ops[] = {
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
.internal_flags = DEVLINK_NL_FLAG_NO_LOCK,
|
||||
},
|
||||
+ {
|
||||
+ .cmd = DEVLINK_CMD_LINECARD_GET,
|
||||
+ .doit = devlink_nl_cmd_linecard_get_doit,
|
||||
+ .dumpit = devlink_nl_cmd_linecard_get_dumpit,
|
||||
+ .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD |
|
||||
+ DEVLINK_NL_FLAG_NO_LOCK,
|
||||
+ /* can be retrieved by unprivileged users */
|
||||
+ },
|
||||
{
|
||||
.cmd = DEVLINK_CMD_SB_GET,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
@@ -7980,6 +8225,7 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
|
||||
xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
|
||||
__devlink_net_set(devlink, &init_net);
|
||||
INIT_LIST_HEAD(&devlink->port_list);
|
||||
+ INIT_LIST_HEAD(&devlink->linecard_list);
|
||||
INIT_LIST_HEAD(&devlink->sb_list);
|
||||
INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
|
||||
INIT_LIST_HEAD(&devlink->resource_list);
|
||||
@@ -7991,6 +8237,8 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
|
||||
INIT_LIST_HEAD(&devlink->trap_policer_list);
|
||||
mutex_init(&devlink->lock);
|
||||
mutex_init(&devlink->reporters_lock);
|
||||
+ mutex_init(&devlink->linecards_lock);
|
||||
+
|
||||
return devlink;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_alloc);
|
||||
@@ -8071,6 +8319,7 @@ EXPORT_SYMBOL_GPL(devlink_reload_disable);
|
||||
*/
|
||||
void devlink_free(struct devlink *devlink)
|
||||
{
|
||||
+ mutex_destroy(&devlink->linecards_lock);
|
||||
mutex_destroy(&devlink->reporters_lock);
|
||||
mutex_destroy(&devlink->lock);
|
||||
WARN_ON(!list_empty(&devlink->trap_policer_list));
|
||||
@@ -8082,6 +8331,7 @@ void devlink_free(struct devlink *devlink)
|
||||
WARN_ON(!list_empty(&devlink->resource_list));
|
||||
WARN_ON(!list_empty(&devlink->dpipe_table_list));
|
||||
WARN_ON(!list_empty(&devlink->sb_list));
|
||||
+ WARN_ON(!list_empty(&devlink->linecard_list));
|
||||
WARN_ON(!list_empty(&devlink->port_list));
|
||||
|
||||
xa_destroy(&devlink->snapshot_ids);
|
||||
@@ -8427,6 +8677,57 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * devlink_linecard_create - Create devlink linecard
|
||||
+ *
|
||||
+ * @devlink: devlink
|
||||
+ * @linecard_index: driver-specific numerical identifier of the linecard
|
||||
+ *
|
||||
+ * Create devlink linecard instance with provided linecard index.
|
||||
+ * Caller can use any indexing, even hw-related one.
|
||||
+ */
|
||||
+struct devlink_linecard *devlink_linecard_create(struct devlink *devlink,
|
||||
+ unsigned int linecard_index)
|
||||
+{
|
||||
+ struct devlink_linecard *linecard;
|
||||
+
|
||||
+ mutex_lock(&devlink->linecards_lock);
|
||||
+ if (devlink_linecard_index_exists(devlink, linecard_index)) {
|
||||
+ mutex_unlock(&devlink->linecards_lock);
|
||||
+ return ERR_PTR(-EEXIST);
|
||||
+ }
|
||||
+
|
||||
+ linecard = kzalloc(sizeof(*linecard), GFP_KERNEL);
|
||||
+ if (!linecard)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ linecard->devlink = devlink;
|
||||
+ linecard->index = linecard_index;
|
||||
+ list_add_tail(&linecard->list, &devlink->linecard_list);
|
||||
+ refcount_set(&linecard->refcount, 1);
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ mutex_unlock(&devlink->linecards_lock);
|
||||
+ return linecard;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devlink_linecard_create);
|
||||
+
|
||||
+/**
|
||||
+ * devlink_linecard_destroy - Destroy devlink linecard
|
||||
+ *
|
||||
+ * @linecard: devlink linecard
|
||||
+ */
|
||||
+void devlink_linecard_destroy(struct devlink_linecard *linecard)
|
||||
+{
|
||||
+ struct devlink *devlink = linecard->devlink;
|
||||
+
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
|
||||
+ mutex_lock(&devlink->linecards_lock);
|
||||
+ list_del(&linecard->list);
|
||||
+ mutex_unlock(&devlink->linecards_lock);
|
||||
+ devlink_linecard_put(linecard);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devlink_linecard_destroy);
|
||||
+
|
||||
int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
|
||||
u32 size, u16 ingress_pools_count,
|
||||
u16 egress_pools_count, u16 ingress_tc_count,
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,554 @@
|
||||
From b0a30f401ca5d69f3cd78a0bf6dd1471f7aea0be Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Thu, 31 Dec 2020 17:35:08 +0100
|
||||
Subject: [PATCH] devlink: implement line card provisioning
|
||||
|
||||
In order to be able to configure all needed stuff on a port/netdevice
|
||||
of a line card without the line card being present, introduce line card
|
||||
provisioning. Basically by setting a type, provisioning process will
|
||||
start and driver is supposed to create a placeholder for instances
|
||||
(ports/netdevices) for a line card type.
|
||||
|
||||
Allow the user to query the supported line card types over line card
|
||||
get command. Then implement two netlink command SET to allow user to
|
||||
set/unset the card type.
|
||||
|
||||
On the driver API side, add provision/unprovision ops and supported
|
||||
types array to be advertised. Upon provision op call, the driver should
|
||||
take care of creating the instances for the particular line card type.
|
||||
Introduce provision_set/clear() functions to be called by the driver
|
||||
once the provisioning/unprovisioning is done on its side. These helpers
|
||||
are not to be called directly due to the async nature of provisioning.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
include/net/devlink.h | 41 ++++-
|
||||
include/uapi/linux/devlink.h | 15 ++
|
||||
net/core/devlink.c | 311 ++++++++++++++++++++++++++++++++---
|
||||
3 files changed, 346 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/include/net/devlink.h b/include/net/devlink.h
|
||||
index e8f046590..44b60085e 100644
|
||||
--- a/include/net/devlink.h
|
||||
+++ b/include/net/devlink.h
|
||||
@@ -142,11 +142,43 @@ struct devlink_port {
|
||||
struct mutex reporters_lock; /* Protects reporter_list */
|
||||
};
|
||||
|
||||
+struct devlink_linecard_ops;
|
||||
+struct devlink_linecard_type;
|
||||
+
|
||||
struct devlink_linecard {
|
||||
struct list_head list;
|
||||
struct devlink *devlink;
|
||||
unsigned int index;
|
||||
refcount_t refcount;
|
||||
+ const struct devlink_linecard_ops *ops;
|
||||
+ void *priv;
|
||||
+ enum devlink_linecard_state state;
|
||||
+ struct mutex state_lock; /* Protects state */
|
||||
+ const char *type;
|
||||
+ struct devlink_linecard_type *types;
|
||||
+ unsigned int types_count;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct devlink_linecard_ops - Linecard operations
|
||||
+ * @provision: callback to provision the linecard slot with certain
|
||||
+ * type of linecard
|
||||
+ * @unprovision: callback to unprovision the linecard slot
|
||||
+ * @types_init: callback to initialize types list
|
||||
+ * @types_fini: callback to finalize types list
|
||||
+ * @types_get: callback to get next type in list
|
||||
+ */
|
||||
+struct devlink_linecard_ops {
|
||||
+ int (*provision)(struct devlink_linecard *linecard, void *priv,
|
||||
+ const char *type, const void *type_priv,
|
||||
+ struct netlink_ext_ack *extack);
|
||||
+ int (*unprovision)(struct devlink_linecard *linecard, void *priv,
|
||||
+ struct netlink_ext_ack *extack);
|
||||
+ unsigned int (*types_count)(struct devlink_linecard *linecard,
|
||||
+ void *priv);
|
||||
+ void (*types_get)(struct devlink_linecard *linecard,
|
||||
+ void *priv, unsigned int index, const char **type,
|
||||
+ const void **type_priv);
|
||||
};
|
||||
|
||||
struct devlink_sb_pool_info {
|
||||
@@ -1413,9 +1445,14 @@ void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 contro
|
||||
u16 pf, bool external);
|
||||
void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
|
||||
u16 pf, u16 vf, bool external);
|
||||
-struct devlink_linecard *devlink_linecard_create(struct devlink *devlink,
|
||||
- unsigned int linecard_index);
|
||||
+struct devlink_linecard *
|
||||
+devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
|
||||
+ const struct devlink_linecard_ops *ops, void *priv);
|
||||
void devlink_linecard_destroy(struct devlink_linecard *linecard);
|
||||
+void devlink_linecard_provision_set(struct devlink_linecard *linecard,
|
||||
+ const char *type);
|
||||
+void devlink_linecard_provision_clear(struct devlink_linecard *linecard);
|
||||
+void devlink_linecard_provision_fail(struct devlink_linecard *linecard);
|
||||
int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
|
||||
u32 size, u16 ingress_pools_count,
|
||||
u16 egress_pools_count, u16 ingress_tc_count,
|
||||
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
|
||||
index ff07ad596..d88336645 100644
|
||||
--- a/include/uapi/linux/devlink.h
|
||||
+++ b/include/uapi/linux/devlink.h
|
||||
@@ -334,6 +334,18 @@ enum devlink_reload_limit {
|
||||
|
||||
#define DEVLINK_RELOAD_LIMITS_VALID_MASK (_BITUL(__DEVLINK_RELOAD_LIMIT_MAX) - 1)
|
||||
|
||||
+enum devlink_linecard_state {
|
||||
+ DEVLINK_LINECARD_STATE_UNSPEC,
|
||||
+ DEVLINK_LINECARD_STATE_UNPROVISIONED,
|
||||
+ DEVLINK_LINECARD_STATE_UNPROVISIONING,
|
||||
+ DEVLINK_LINECARD_STATE_PROVISIONING,
|
||||
+ DEVLINK_LINECARD_STATE_PROVISIONING_FAILED,
|
||||
+ DEVLINK_LINECARD_STATE_PROVISIONED,
|
||||
+
|
||||
+ __DEVLINK_LINECARD_STATE_MAX,
|
||||
+ DEVLINK_LINECARD_STATE_MAX = __DEVLINK_LINECARD_STATE_MAX - 1
|
||||
+};
|
||||
+
|
||||
enum devlink_attr {
|
||||
/* don't change the order or add anything between, this is ABI! */
|
||||
DEVLINK_ATTR_UNSPEC,
|
||||
@@ -550,6 +562,9 @@ enum devlink_attr {
|
||||
DEVLINK_ATTR_REGION_MAX_SNAPSHOTS, /* u32 */
|
||||
|
||||
DEVLINK_ATTR_LINECARD_INDEX, /* u32 */
|
||||
+ DEVLINK_ATTR_LINECARD_STATE, /* u8 */
|
||||
+ DEVLINK_ATTR_LINECARD_TYPE, /* string */
|
||||
+ DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES, /* nested */
|
||||
|
||||
/* add new attributes above here, update the policy in devlink.c */
|
||||
|
||||
diff --git a/net/core/devlink.c b/net/core/devlink.c
|
||||
index 645fe0612..943973ffc 100644
|
||||
--- a/net/core/devlink.c
|
||||
+++ b/net/core/devlink.c
|
||||
@@ -265,8 +265,10 @@ devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info)
|
||||
|
||||
static void devlink_linecard_put(struct devlink_linecard *linecard)
|
||||
{
|
||||
- if (refcount_dec_and_test(&linecard->refcount))
|
||||
+ if (refcount_dec_and_test(&linecard->refcount)) {
|
||||
+ mutex_destroy(&linecard->state_lock);
|
||||
kfree(linecard);
|
||||
+ }
|
||||
}
|
||||
|
||||
struct devlink_sb {
|
||||
@@ -1233,6 +1235,12 @@ static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
|
||||
return devlink_port_unsplit(devlink, port_index, info->extack);
|
||||
}
|
||||
|
||||
+struct devlink_linecard_type {
|
||||
+ struct list_head list;
|
||||
+ const char *type;
|
||||
+ const void *priv;
|
||||
+};
|
||||
+
|
||||
static int devlink_nl_linecard_fill(struct sk_buff *msg,
|
||||
struct devlink *devlink,
|
||||
struct devlink_linecard *linecard,
|
||||
@@ -1240,7 +1248,10 @@ static int devlink_nl_linecard_fill(struct sk_buff *msg,
|
||||
u32 seq, int flags,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
+ struct devlink_linecard_type *linecard_type;
|
||||
+ struct nlattr *attr;
|
||||
void *hdr;
|
||||
+ int i;
|
||||
|
||||
hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
|
||||
if (!hdr)
|
||||
@@ -1250,6 +1261,25 @@ static int devlink_nl_linecard_fill(struct sk_buff *msg,
|
||||
goto nla_put_failure;
|
||||
if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
|
||||
goto nla_put_failure;
|
||||
+ if (nla_put_u8(msg, DEVLINK_ATTR_LINECARD_STATE, linecard->state))
|
||||
+ goto nla_put_failure;
|
||||
+ if (linecard->state >= DEVLINK_LINECARD_STATE_PROVISIONED &&
|
||||
+ nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, linecard->type))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
+ if (linecard->types_count) {
|
||||
+ attr = nla_nest_start(msg,
|
||||
+ DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES);
|
||||
+ if (!attr)
|
||||
+ goto nla_put_failure;
|
||||
+ for (i = 0; i < linecard->types_count; i++) {
|
||||
+ linecard_type = &linecard->types[i];
|
||||
+ if (nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE,
|
||||
+ linecard_type->type))
|
||||
+ goto nla_put_failure;
|
||||
+ }
|
||||
+ nla_nest_end(msg, attr);
|
||||
+ }
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
return 0;
|
||||
@@ -1335,12 +1365,14 @@ static int devlink_nl_cmd_linecard_get_dumpit(struct sk_buff *msg,
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
+ mutex_lock(&linecard->state_lock);
|
||||
err = devlink_nl_linecard_fill(msg, devlink, linecard,
|
||||
DEVLINK_CMD_LINECARD_NEW,
|
||||
NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq,
|
||||
NLM_F_MULTI,
|
||||
cb->extack);
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
if (err) {
|
||||
mutex_unlock(&devlink->linecards_lock);
|
||||
devlink_put(devlink);
|
||||
@@ -1359,6 +1391,153 @@ static int devlink_nl_cmd_linecard_get_dumpit(struct sk_buff *msg,
|
||||
return msg->len;
|
||||
}
|
||||
|
||||
+static struct devlink_linecard_type *
|
||||
+devlink_linecard_type_lookup(struct devlink_linecard *linecard,
|
||||
+ const char *type)
|
||||
+{
|
||||
+ struct devlink_linecard_type *linecard_type;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < linecard->types_count; i++) {
|
||||
+ linecard_type = &linecard->types[i];
|
||||
+ if (!strcmp(type, linecard_type->type))
|
||||
+ return linecard_type;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int devlink_linecard_type_set(struct devlink_linecard *linecard,
|
||||
+ const char *type,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct devlink_linecard_type *linecard_type;
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&linecard->state_lock);
|
||||
+ if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
|
||||
+ NL_SET_ERR_MSG_MOD(extack, "Linecard is currently being provisioned");
|
||||
+ err = -EBUSY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
|
||||
+ NL_SET_ERR_MSG_MOD(extack, "Linecard is currently being unprovisioned");
|
||||
+ err = -EBUSY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONED &&
|
||||
+ linecard->state != DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
|
||||
+ NL_SET_ERR_MSG_MOD(extack, "Linecard already provisioned");
|
||||
+ err = -EBUSY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ linecard_type = devlink_linecard_type_lookup(linecard, type);
|
||||
+ if (!linecard_type) {
|
||||
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported provision type provided");
|
||||
+ err = -EINVAL;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING;
|
||||
+ linecard->type = linecard_type->type;
|
||||
+ devlink_linecard_notify(linecard,
|
||||
+ DEVLINK_CMD_LINECARD_NEW);
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+ err = linecard->ops->provision(linecard, linecard->priv,
|
||||
+ linecard_type->type, linecard_type->priv,
|
||||
+ extack);
|
||||
+ if (err) {
|
||||
+ /* Provisioning failed. Assume the linecard is unprovisioned
|
||||
+ * for future operations.
|
||||
+ */
|
||||
+ mutex_lock(&linecard->state_lock);
|
||||
+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+ }
|
||||
+ return err;
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int devlink_linecard_type_unset(struct devlink_linecard *linecard,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ mutex_lock(&linecard->state_lock);
|
||||
+ if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
|
||||
+ NL_SET_ERR_MSG_MOD(extack, "Linecard is currently being provisioned");
|
||||
+ err = -EBUSY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
|
||||
+ NL_SET_ERR_MSG_MOD(extack, "Linecard is currently being unprovisioned");
|
||||
+ err = -EBUSY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
|
||||
+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
|
||||
+ linecard->type = NULL;
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ err = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED ||
|
||||
+ linecard->state == DEVLINK_LINECARD_STATE_UNSPEC) {
|
||||
+ NL_SET_ERR_MSG_MOD(extack, "Linecard is not provisioned");
|
||||
+ err = -EOPNOTSUPP;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONING;
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+ err = linecard->ops->unprovision(linecard, linecard->priv,
|
||||
+ extack);
|
||||
+ if (err) {
|
||||
+ /* Unprovisioning failed. Assume the linecard is unprovisioned
|
||||
+ * for future operations.
|
||||
+ */
|
||||
+ mutex_lock(&linecard->state_lock);
|
||||
+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+ }
|
||||
+ return err;
|
||||
+
|
||||
+out:
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
|
||||
+ struct genl_info *info)
|
||||
+{
|
||||
+ struct devlink_linecard *linecard = info->user_ptr[1];
|
||||
+ struct netlink_ext_ack *extack = info->extack;
|
||||
+ int err;
|
||||
+
|
||||
+ if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) {
|
||||
+ const char *type;
|
||||
+
|
||||
+ type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]);
|
||||
+ if (strcmp(type, "")) {
|
||||
+ err = devlink_linecard_type_set(linecard, type, extack);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ } else {
|
||||
+ err = devlink_linecard_type_unset(linecard, extack);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
struct devlink_sb *devlink_sb,
|
||||
enum devlink_command cmd, u32 portid,
|
||||
@@ -7818,19 +7997,8 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
|
||||
[DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
|
||||
DEVLINK_RELOAD_ACTION_MAX),
|
||||
[DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(DEVLINK_RELOAD_LIMITS_VALID_MASK),
|
||||
-//<<<<<<< HEAD
|
||||
-//=======
|
||||
- [DEVLINK_ATTR_PORT_FLAVOUR] = { .type = NLA_U16 },
|
||||
- [DEVLINK_ATTR_PORT_PCI_PF_NUMBER] = { .type = NLA_U16 },
|
||||
- [DEVLINK_ATTR_PORT_PCI_SF_NUMBER] = { .type = NLA_U32 },
|
||||
- [DEVLINK_ATTR_PORT_CONTROLLER_NUMBER] = { .type = NLA_U32 },
|
||||
- [DEVLINK_ATTR_RATE_TYPE] = { .type = NLA_U16 },
|
||||
- [DEVLINK_ATTR_RATE_TX_SHARE] = { .type = NLA_U64 },
|
||||
- [DEVLINK_ATTR_RATE_TX_MAX] = { .type = NLA_U64 },
|
||||
- [DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING },
|
||||
- [DEVLINK_ATTR_RATE_PARENT_NODE_NAME] = { .type = NLA_NUL_STRING },
|
||||
[DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32 },
|
||||
-//>>>>>>> 1180815a3831... devlink: add support to create line card and expose to user
|
||||
+ [DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING },
|
||||
};
|
||||
|
||||
static const struct genl_small_ops devlink_nl_ops[] = {
|
||||
@@ -7878,6 +8046,13 @@ static const struct genl_small_ops devlink_nl_ops[] = {
|
||||
DEVLINK_NL_FLAG_NO_LOCK,
|
||||
/* can be retrieved by unprivileged users */
|
||||
},
|
||||
+ {
|
||||
+ .cmd = DEVLINK_CMD_LINECARD_SET,
|
||||
+ .doit = devlink_nl_cmd_linecard_set_doit,
|
||||
+ .flags = GENL_ADMIN_PERM,
|
||||
+ .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD |
|
||||
+ DEVLINK_NL_FLAG_NO_LOCK,
|
||||
+ },
|
||||
{
|
||||
.cmd = DEVLINK_CMD_SB_GET,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
@@ -8677,35 +8852,85 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int devlink_linecard_types_init(struct devlink_linecard *linecard)
|
||||
+{
|
||||
+ struct devlink_linecard_type *linecard_type;
|
||||
+ unsigned int count;
|
||||
+ int i;
|
||||
+
|
||||
+ count = linecard->ops->types_count(linecard, linecard->priv);
|
||||
+ linecard->types = kmalloc_array(count, sizeof(*linecard_type),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!linecard->types)
|
||||
+ return -ENOMEM;
|
||||
+ linecard->types_count = count;
|
||||
+
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ linecard_type = &linecard->types[i];
|
||||
+ linecard->ops->types_get(linecard, linecard->priv, i,
|
||||
+ &linecard_type->type,
|
||||
+ &linecard_type->priv);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void devlink_linecard_types_fini(struct devlink_linecard *linecard)
|
||||
+{
|
||||
+ kfree(linecard->types);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* devlink_linecard_create - Create devlink linecard
|
||||
*
|
||||
* @devlink: devlink
|
||||
* @linecard_index: driver-specific numerical identifier of the linecard
|
||||
+ * @ops: linecards ops
|
||||
+ * @priv: user priv pointer
|
||||
*
|
||||
* Create devlink linecard instance with provided linecard index.
|
||||
* Caller can use any indexing, even hw-related one.
|
||||
*/
|
||||
-struct devlink_linecard *devlink_linecard_create(struct devlink *devlink,
|
||||
- unsigned int linecard_index)
|
||||
+struct devlink_linecard *
|
||||
+devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
|
||||
+ const struct devlink_linecard_ops *ops, void *priv)
|
||||
{
|
||||
struct devlink_linecard *linecard;
|
||||
+ int err;
|
||||
+
|
||||
+ if (WARN_ON(!ops || !ops->provision || !ops->unprovision ||
|
||||
+ !ops->types_count || !ops->types_get))
|
||||
+ return ERR_PTR(-EINVAL);
|
||||
|
||||
mutex_lock(&devlink->linecards_lock);
|
||||
if (devlink_linecard_index_exists(devlink, linecard_index)) {
|
||||
- mutex_unlock(&devlink->linecards_lock);
|
||||
- return ERR_PTR(-EEXIST);
|
||||
+ linecard = ERR_PTR(-EEXIST);
|
||||
+ goto unlock;
|
||||
}
|
||||
|
||||
linecard = kzalloc(sizeof(*linecard), GFP_KERNEL);
|
||||
- if (!linecard)
|
||||
- return ERR_PTR(-ENOMEM);
|
||||
+ if (!linecard) {
|
||||
+ linecard = ERR_PTR(-ENOMEM);
|
||||
+ goto unlock;
|
||||
+ }
|
||||
|
||||
linecard->devlink = devlink;
|
||||
linecard->index = linecard_index;
|
||||
+ linecard->ops = ops;
|
||||
+ linecard->priv = priv;
|
||||
+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
|
||||
+ mutex_init(&linecard->state_lock);
|
||||
+
|
||||
+ err = devlink_linecard_types_init(linecard);
|
||||
+ if (err) {
|
||||
+ kfree(linecard);
|
||||
+ linecard = ERR_PTR(err);
|
||||
+ goto unlock;
|
||||
+ }
|
||||
+
|
||||
list_add_tail(&linecard->list, &devlink->linecard_list);
|
||||
refcount_set(&linecard->refcount, 1);
|
||||
devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+unlock:
|
||||
mutex_unlock(&devlink->linecards_lock);
|
||||
return linecard;
|
||||
}
|
||||
@@ -8721,6 +8946,7 @@ void devlink_linecard_destroy(struct devlink_linecard *linecard)
|
||||
struct devlink *devlink = linecard->devlink;
|
||||
|
||||
devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
|
||||
+ devlink_linecard_types_fini(linecard);
|
||||
mutex_lock(&devlink->linecards_lock);
|
||||
list_del(&linecard->list);
|
||||
mutex_unlock(&devlink->linecards_lock);
|
||||
@@ -8728,6 +8954,53 @@ void devlink_linecard_destroy(struct devlink_linecard *linecard)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_linecard_destroy);
|
||||
|
||||
+/**
|
||||
+ * devlink_linecard_provision_set - Set provisioning on linecard
|
||||
+ *
|
||||
+ * @linecard: devlink linecard
|
||||
+ * @type: linecard type
|
||||
+ */
|
||||
+void devlink_linecard_provision_set(struct devlink_linecard *linecard,
|
||||
+ const char *type)
|
||||
+{
|
||||
+ mutex_lock(&linecard->state_lock);
|
||||
+ WARN_ON(linecard->type && linecard->type != type);
|
||||
+ linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
|
||||
+ linecard->type = type;
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
|
||||
+
|
||||
+/**
|
||||
+ * devlink_linecard_provision_clear - Clear provisioning on linecard
|
||||
+ *
|
||||
+ * @linecard: devlink linecard
|
||||
+ */
|
||||
+void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
|
||||
+{
|
||||
+ mutex_lock(&linecard->state_lock);
|
||||
+ linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
|
||||
+ linecard->type = NULL;
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear);
|
||||
+
|
||||
+/**
|
||||
+ * devlink_linecard_provision_fail - Fail provisioning on linecard
|
||||
+ *
|
||||
+ * @linecard: devlink linecard
|
||||
+ */
|
||||
+void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
|
||||
+{
|
||||
+ mutex_lock(&linecard->state_lock);
|
||||
+ linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail);
|
||||
+
|
||||
int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
|
||||
u32 size, u16 ingress_pools_count,
|
||||
u16 egress_pools_count, u16 ingress_tc_count,
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,98 @@
|
||||
From 999c148a0a19a6a6c96dbc5b6615285d80c28de9 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Wed, 6 Jan 2021 16:03:43 +0100
|
||||
Subject: [PATCH] devlink: implement line card active state
|
||||
|
||||
Allow driver to mark a linecard as active. Expose this state to the
|
||||
userspace over devlink netlink interface with proper notifications.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
include/net/devlink.h | 3 +++
|
||||
include/uapi/linux/devlink.h | 1 +
|
||||
net/core/devlink.c | 36 ++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 40 insertions(+)
|
||||
|
||||
diff --git a/include/net/devlink.h b/include/net/devlink.h
|
||||
index 44b60085e..d9b2b559c 100644
|
||||
--- a/include/net/devlink.h
|
||||
+++ b/include/net/devlink.h
|
||||
@@ -157,6 +157,7 @@ struct devlink_linecard {
|
||||
const char *type;
|
||||
struct devlink_linecard_type *types;
|
||||
unsigned int types_count;
|
||||
+ bool active;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1453,6 +1454,8 @@ void devlink_linecard_provision_set(struct devlink_linecard *linecard,
|
||||
const char *type);
|
||||
void devlink_linecard_provision_clear(struct devlink_linecard *linecard);
|
||||
void devlink_linecard_provision_fail(struct devlink_linecard *linecard);
|
||||
+void devlink_linecard_activate(struct devlink_linecard *linecard);
|
||||
+void devlink_linecard_deactivate(struct devlink_linecard *linecard);
|
||||
int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
|
||||
u32 size, u16 ingress_pools_count,
|
||||
u16 egress_pools_count, u16 ingress_tc_count,
|
||||
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
|
||||
index d88336645..5ace55666 100644
|
||||
--- a/include/uapi/linux/devlink.h
|
||||
+++ b/include/uapi/linux/devlink.h
|
||||
@@ -341,6 +341,7 @@ enum devlink_linecard_state {
|
||||
DEVLINK_LINECARD_STATE_PROVISIONING,
|
||||
DEVLINK_LINECARD_STATE_PROVISIONING_FAILED,
|
||||
DEVLINK_LINECARD_STATE_PROVISIONED,
|
||||
+ DEVLINK_LINECARD_STATE_ACTIVE,
|
||||
|
||||
__DEVLINK_LINECARD_STATE_MAX,
|
||||
DEVLINK_LINECARD_STATE_MAX = __DEVLINK_LINECARD_STATE_MAX - 1
|
||||
diff --git a/net/core/devlink.c b/net/core/devlink.c
|
||||
index 943973ffc..724633810 100644
|
||||
--- a/net/core/devlink.c
|
||||
+++ b/net/core/devlink.c
|
||||
@@ -9001,6 +9001,42 @@ void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail);
|
||||
|
||||
+/**
|
||||
+ * devlink_linecard_activate - Set linecard active
|
||||
+ *
|
||||
+ * @devlink_linecard: devlink linecard
|
||||
+ */
|
||||
+void devlink_linecard_activate(struct devlink_linecard *linecard)
|
||||
+{
|
||||
+ mutex_lock(&linecard->state_lock);
|
||||
+ WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED);
|
||||
+ linecard->state = DEVLINK_LINECARD_STATE_ACTIVE;
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devlink_linecard_activate);
|
||||
+
|
||||
+/**
|
||||
+ * devlink_linecard_deactivate - Set linecard inactive
|
||||
+ *
|
||||
+ * @devlink_linecard: devlink linecard
|
||||
+ */
|
||||
+void devlink_linecard_deactivate(struct devlink_linecard *linecard)
|
||||
+{
|
||||
+ bool should_notify = false;
|
||||
+
|
||||
+ mutex_lock(&linecard->state_lock);
|
||||
+ if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONING) {
|
||||
+ WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_ACTIVE);
|
||||
+ linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
|
||||
+ should_notify = true;
|
||||
+ }
|
||||
+ if (should_notify)
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
|
||||
+
|
||||
int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
|
||||
u32 size, u16 ingress_pools_count,
|
||||
u16 egress_pools_count, u16 ingress_tc_count,
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,101 @@
|
||||
From ce052dd9aec77733b55fe1285a9be5c4cbcc87b3 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Wed, 22 Dec 2021 14:10:14 +0000
|
||||
Subject: [PATCH] devlink: add port to line card relationship set
|
||||
|
||||
In order to properly inform user about relationship between port and
|
||||
line card, introduce a driver API to set line card for a port. Use this
|
||||
information to extend port devlink netlink message by line card index
|
||||
and also include the line card index into phys_port_name and by that
|
||||
into a netdevice name.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
include/net/devlink.h | 4 ++++
|
||||
net/core/devlink.c | 34 ++++++++++++++++++++++++++++------
|
||||
2 files changed, 32 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/include/net/devlink.h b/include/net/devlink.h
|
||||
index d9b2b559c..3d4ceb290 100644
|
||||
--- a/include/net/devlink.h
|
||||
+++ b/include/net/devlink.h
|
||||
@@ -140,6 +140,8 @@ struct devlink_port {
|
||||
struct delayed_work type_warn_dw;
|
||||
struct list_head reporter_list;
|
||||
struct mutex reporters_lock; /* Protects reporter_list */
|
||||
+
|
||||
+ struct devlink_linecard *linecard;
|
||||
};
|
||||
|
||||
struct devlink_linecard_ops;
|
||||
@@ -1446,6 +1448,8 @@ void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 contro
|
||||
u16 pf, bool external);
|
||||
void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
|
||||
u16 pf, u16 vf, bool external);
|
||||
+void devlink_port_linecard_set(struct devlink_port *devlink_port,
|
||||
+ struct devlink_linecard *linecard);
|
||||
struct devlink_linecard *
|
||||
devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
|
||||
const struct devlink_linecard_ops *ops, void *priv);
|
||||
diff --git a/net/core/devlink.c b/net/core/devlink.c
|
||||
index 724633810..b43e93ccc 100644
|
||||
--- a/net/core/devlink.c
|
||||
+++ b/net/core/devlink.c
|
||||
@@ -905,6 +905,10 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
goto nla_put_failure;
|
||||
if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
|
||||
goto nla_put_failure;
|
||||
+ if (devlink_port->linecard &&
|
||||
+ nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX,
|
||||
+ devlink_port->linecard->index))
|
||||
+ goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
return 0;
|
||||
@@ -8795,6 +8799,21 @@ void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 contro
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
|
||||
|
||||
+/**
|
||||
+ * devlink_port_linecard_set - Link port with a linecard
|
||||
+ *
|
||||
+ * @devlink_port: devlink port
|
||||
+ * @devlink_linecard: devlink linecard
|
||||
+ */
|
||||
+void devlink_port_linecard_set(struct devlink_port *devlink_port,
|
||||
+ struct devlink_linecard *linecard)
|
||||
+{
|
||||
+ if (WARN_ON(devlink_port->devlink))
|
||||
+ return;
|
||||
+ devlink_port->linecard = linecard;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devlink_port_linecard_set);
|
||||
+
|
||||
static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
|
||||
char *name, size_t len)
|
||||
{
|
||||
@@ -8806,12 +8825,15 @@ static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
|
||||
|
||||
switch (attrs->flavour) {
|
||||
case DEVLINK_PORT_FLAVOUR_PHYSICAL:
|
||||
- if (!attrs->split)
|
||||
- n = snprintf(name, len, "p%u", attrs->phys.port_number);
|
||||
- else
|
||||
- n = snprintf(name, len, "p%us%u",
|
||||
- attrs->phys.port_number,
|
||||
- attrs->phys.split_subport_number);
|
||||
+ if (devlink_port->linecard)
|
||||
+ n = snprintf(name, len, "l%u",
|
||||
+ devlink_port->linecard->index);
|
||||
+ if (n < len)
|
||||
+ n += snprintf(name + n, len - n, "p%u",
|
||||
+ attrs->phys.port_number);
|
||||
+ if (n < len && attrs->split)
|
||||
+ n += snprintf(name + n, len - n, "s%u",
|
||||
+ attrs->phys.split_subport_number);
|
||||
break;
|
||||
case DEVLINK_PORT_FLAVOUR_CPU:
|
||||
case DEVLINK_PORT_FLAVOUR_DSA:
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,245 @@
|
||||
From fdc91e1289c5e491e93f7d7a872d2d656d1d0e7f Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Fri, 19 Feb 2021 09:36:15 +0100
|
||||
Subject: [PATCH] devlink: introduce linecard info get message
|
||||
|
||||
Allow the driver to provide per line card info get op to fill-up info,
|
||||
similar to the "devlink dev info".
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
include/net/devlink.h | 7 +-
|
||||
include/uapi/linux/devlink.h | 3 +
|
||||
net/core/devlink.c | 135 +++++++++++++++++++++++++++++++++--
|
||||
3 files changed, 140 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/include/net/devlink.h b/include/net/devlink.h
|
||||
index 3d4ceb290..059bed6ae 100644
|
||||
--- a/include/net/devlink.h
|
||||
+++ b/include/net/devlink.h
|
||||
@@ -162,6 +162,8 @@ struct devlink_linecard {
|
||||
bool active;
|
||||
};
|
||||
|
||||
+struct devlink_info_req;
|
||||
+
|
||||
/**
|
||||
* struct devlink_linecard_ops - Linecard operations
|
||||
* @provision: callback to provision the linecard slot with certain
|
||||
@@ -170,6 +172,7 @@ struct devlink_linecard {
|
||||
* @types_init: callback to initialize types list
|
||||
* @types_fini: callback to finalize types list
|
||||
* @types_get: callback to get next type in list
|
||||
+ * @info_get: callback to get linecard info
|
||||
*/
|
||||
struct devlink_linecard_ops {
|
||||
int (*provision)(struct devlink_linecard *linecard, void *priv,
|
||||
@@ -182,6 +185,9 @@ struct devlink_linecard_ops {
|
||||
void (*types_get)(struct devlink_linecard *linecard,
|
||||
void *priv, unsigned int index, const char **type,
|
||||
const void **type_priv);
|
||||
+ int (*info_get)(struct devlink_linecard *linecard, void *priv,
|
||||
+ struct devlink_info_req *req,
|
||||
+ struct netlink_ext_ack *extack);
|
||||
};
|
||||
|
||||
struct devlink_sb_pool_info {
|
||||
@@ -630,7 +636,6 @@ struct devlink_flash_update_params {
|
||||
#define DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK BIT(1)
|
||||
|
||||
struct devlink_region;
|
||||
-struct devlink_info_req;
|
||||
|
||||
/**
|
||||
* struct devlink_region_ops - Region operations
|
||||
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
|
||||
index 5ace55666..2c9f7d584 100644
|
||||
--- a/include/uapi/linux/devlink.h
|
||||
+++ b/include/uapi/linux/devlink.h
|
||||
@@ -136,6 +136,8 @@ enum devlink_command {
|
||||
DEVLINK_CMD_LINECARD_NEW,
|
||||
DEVLINK_CMD_LINECARD_DEL,
|
||||
|
||||
+ DEVLINK_CMD_LINECARD_INFO_GET, /* can dump */
|
||||
+
|
||||
/* add new commands above here */
|
||||
__DEVLINK_CMD_MAX,
|
||||
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
|
||||
@@ -566,6 +568,7 @@ enum devlink_attr {
|
||||
DEVLINK_ATTR_LINECARD_STATE, /* u8 */
|
||||
DEVLINK_ATTR_LINECARD_TYPE, /* string */
|
||||
DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES, /* nested */
|
||||
+ DEVLINK_ATTR_LINECARD_INFO, /* nested */
|
||||
|
||||
/* add new attributes above here, update the policy in devlink.c */
|
||||
|
||||
diff --git a/net/core/devlink.c b/net/core/devlink.c
|
||||
index b43e93ccc..04f8038f8 100644
|
||||
--- a/net/core/devlink.c
|
||||
+++ b/net/core/devlink.c
|
||||
@@ -1245,6 +1245,10 @@ struct devlink_linecard_type {
|
||||
const void *priv;
|
||||
};
|
||||
|
||||
+struct devlink_info_req {
|
||||
+ struct sk_buff *msg;
|
||||
+};
|
||||
+
|
||||
static int devlink_nl_linecard_fill(struct sk_buff *msg,
|
||||
struct devlink *devlink,
|
||||
struct devlink_linecard *linecard,
|
||||
@@ -1542,6 +1546,125 @@ static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+devlink_nl_linecard_info_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
+ struct devlink_linecard *linecard,
|
||||
+ enum devlink_command cmd, u32 portid,
|
||||
+ u32 seq, int flags, struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct devlink_info_req req;
|
||||
+ struct nlattr *attr;
|
||||
+ void *hdr;
|
||||
+ int err;
|
||||
+
|
||||
+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
|
||||
+ if (!hdr)
|
||||
+ return -EMSGSIZE;
|
||||
+
|
||||
+ err = -EMSGSIZE;
|
||||
+ if (devlink_nl_put_handle(msg, devlink))
|
||||
+ goto nla_put_failure;
|
||||
+ if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_INFO);
|
||||
+ if (!attr)
|
||||
+ goto nla_put_failure;
|
||||
+ req.msg = msg;
|
||||
+ err = linecard->ops->info_get(linecard, linecard->priv, &req, extack);
|
||||
+ if (err)
|
||||
+ goto nla_put_failure;
|
||||
+ nla_nest_end(msg, attr);
|
||||
+
|
||||
+ genlmsg_end(msg, hdr);
|
||||
+ return 0;
|
||||
+
|
||||
+nla_put_failure:
|
||||
+ genlmsg_cancel(msg, hdr);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static int devlink_nl_cmd_linecard_info_get_doit(struct sk_buff *skb,
|
||||
+ struct genl_info *info)
|
||||
+{
|
||||
+ struct devlink_linecard *linecard = info->user_ptr[1];
|
||||
+ struct devlink *devlink = linecard->devlink;
|
||||
+ struct sk_buff *msg;
|
||||
+ int err;
|
||||
+
|
||||
+ if (!linecard->ops->info_get)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
+ if (!msg)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ err = devlink_nl_linecard_info_fill(msg, devlink, linecard,
|
||||
+ DEVLINK_CMD_LINECARD_INFO_GET,
|
||||
+ info->snd_portid, info->snd_seq, 0,
|
||||
+ info->extack);
|
||||
+ if (err) {
|
||||
+ nlmsg_free(msg);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ return genlmsg_reply(msg, info);
|
||||
+}
|
||||
+
|
||||
+static int devlink_nl_cmd_linecard_info_get_dumpit(struct sk_buff *msg,
|
||||
+ struct netlink_callback *cb)
|
||||
+{
|
||||
+ struct devlink_linecard *linecard;
|
||||
+ struct devlink *devlink;
|
||||
+ int start = cb->args[0];
|
||||
+ unsigned long index;
|
||||
+ int idx = 0;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ mutex_lock(&devlink_mutex);
|
||||
+ xa_for_each_marked(&devlinks, index, devlink, DEVLINK_REGISTERED) {
|
||||
+ if (!devlink_try_get(devlink))
|
||||
+ continue;
|
||||
+
|
||||
+ if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
|
||||
+ goto retry;
|
||||
+
|
||||
+ mutex_lock(&devlink->linecards_lock);
|
||||
+ list_for_each_entry(linecard, &devlink->linecard_list, list) {
|
||||
+ if (idx < start || !linecard->ops->info_get) {
|
||||
+ idx++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ mutex_lock(&linecard->state_lock);
|
||||
+ err = devlink_nl_linecard_info_fill(msg, devlink, linecard,
|
||||
+ DEVLINK_CMD_LINECARD_INFO_GET,
|
||||
+ NETLINK_CB(cb->skb).portid,
|
||||
+ cb->nlh->nlmsg_seq,
|
||||
+ NLM_F_MULTI,
|
||||
+ cb->extack);
|
||||
+ mutex_unlock(&linecard->state_lock);
|
||||
+ if (err) {
|
||||
+ mutex_unlock(&devlink->linecards_lock);
|
||||
+ devlink_put(devlink);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ idx++;
|
||||
+ }
|
||||
+ mutex_unlock(&devlink->linecards_lock);
|
||||
+retry:
|
||||
+ devlink_put(devlink);
|
||||
+ }
|
||||
+out:
|
||||
+ mutex_unlock(&devlink_mutex);
|
||||
+
|
||||
+ if (err != -EMSGSIZE)
|
||||
+ return err;
|
||||
+
|
||||
+ cb->args[0] = idx;
|
||||
+ return msg->len;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
struct devlink_sb *devlink_sb,
|
||||
enum devlink_command cmd, u32 portid,
|
||||
@@ -5455,10 +5578,6 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
|
||||
return err;
|
||||
}
|
||||
|
||||
-struct devlink_info_req {
|
||||
- struct sk_buff *msg;
|
||||
-};
|
||||
-
|
||||
int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
|
||||
{
|
||||
return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
|
||||
@@ -8057,6 +8176,14 @@ static const struct genl_small_ops devlink_nl_ops[] = {
|
||||
.internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD |
|
||||
DEVLINK_NL_FLAG_NO_LOCK,
|
||||
},
|
||||
+ {
|
||||
+ .cmd = DEVLINK_CMD_LINECARD_INFO_GET,
|
||||
+ .doit = devlink_nl_cmd_linecard_info_get_doit,
|
||||
+ .dumpit = devlink_nl_cmd_linecard_info_get_dumpit,
|
||||
+ .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD |
|
||||
+ DEVLINK_NL_FLAG_NO_LOCK,
|
||||
+ /* can be retrieved by unprivileged users */
|
||||
+ },
|
||||
{
|
||||
.cmd = DEVLINK_CMD_SB_GET,
|
||||
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,315 @@
|
||||
From 7a39de95203f7dc033bdc81703989d627f2ca0de Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Wed, 22 Dec 2021 15:11:36 +0000
|
||||
Subject: [PATCH] devlink: introduce linecard info get message
|
||||
|
||||
Allow the driver to provide per line card info get op to fill-up info,
|
||||
similar to the "devlink dev info".
|
||||
|
||||
devlink: introduce line card devices support
|
||||
|
||||
Line card can contain a device. For example, this can be a gearbox with
|
||||
flash. This flash could be updated. Provide the driver possibility to
|
||||
attach such devices to a line card and expose those to user. Leverage
|
||||
the existing devlink flash update mechanism and allow driver to pass a
|
||||
custom "component name" string identifying the line card device to
|
||||
flash.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
include/net/devlink.h | 12 +++
|
||||
include/uapi/linux/devlink.h | 4 +
|
||||
net/core/devlink.c | 166 +++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 182 insertions(+)
|
||||
|
||||
diff --git a/include/net/devlink.h b/include/net/devlink.h
|
||||
index 059bed6ae..06b61c1d7 100644
|
||||
--- a/include/net/devlink.h
|
||||
+++ b/include/net/devlink.h
|
||||
@@ -160,9 +160,11 @@ struct devlink_linecard {
|
||||
struct devlink_linecard_type *types;
|
||||
unsigned int types_count;
|
||||
bool active;
|
||||
+ struct list_head device_list;
|
||||
};
|
||||
|
||||
struct devlink_info_req;
|
||||
+struct devlink_linecard_device;
|
||||
|
||||
/**
|
||||
* struct devlink_linecard_ops - Linecard operations
|
||||
@@ -188,6 +190,9 @@ struct devlink_linecard_ops {
|
||||
int (*info_get)(struct devlink_linecard *linecard, void *priv,
|
||||
struct devlink_info_req *req,
|
||||
struct netlink_ext_ack *extack);
|
||||
+ int (*device_info_get)(struct devlink_linecard_device *device,
|
||||
+ void *priv, struct devlink_info_req *req,
|
||||
+ struct netlink_ext_ack *extack);
|
||||
};
|
||||
|
||||
struct devlink_sb_pool_info {
|
||||
@@ -1459,6 +1464,13 @@ struct devlink_linecard *
|
||||
devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
|
||||
const struct devlink_linecard_ops *ops, void *priv);
|
||||
void devlink_linecard_destroy(struct devlink_linecard *linecard);
|
||||
+struct devlink_linecard_device *
|
||||
+devlink_linecard_device_create(struct devlink_linecard *linecard,
|
||||
+ unsigned int device_index,
|
||||
+ const char *flash_component, void *priv);
|
||||
+void
|
||||
+devlink_linecard_device_destroy(struct devlink_linecard *linecard,
|
||||
+ struct devlink_linecard_device *linecard_device);
|
||||
void devlink_linecard_provision_set(struct devlink_linecard *linecard,
|
||||
const char *type);
|
||||
void devlink_linecard_provision_clear(struct devlink_linecard *linecard);
|
||||
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
|
||||
index 2c9f7d584..bac94c3c1 100644
|
||||
--- a/include/uapi/linux/devlink.h
|
||||
+++ b/include/uapi/linux/devlink.h
|
||||
@@ -569,6 +569,10 @@ enum devlink_attr {
|
||||
DEVLINK_ATTR_LINECARD_TYPE, /* string */
|
||||
DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES, /* nested */
|
||||
DEVLINK_ATTR_LINECARD_INFO, /* nested */
|
||||
+ DEVLINK_ATTR_LINECARD_DEVICE_LIST, /* nested */
|
||||
+ DEVLINK_ATTR_LINECARD_DEVICE, /* nested */
|
||||
+ DEVLINK_ATTR_LINECARD_DEVICE_INDEX, /* u32 */
|
||||
+ DEVLINK_ATTR_LINECARD_DEVICE_INFO, /* nested */
|
||||
|
||||
/* add new attributes above here, update the policy in devlink.c */
|
||||
|
||||
diff --git a/net/core/devlink.c b/net/core/devlink.c
|
||||
index 04f8038f8..ca014f40a 100644
|
||||
--- a/net/core/devlink.c
|
||||
+++ b/net/core/devlink.c
|
||||
@@ -1249,6 +1249,59 @@ struct devlink_info_req {
|
||||
struct sk_buff *msg;
|
||||
};
|
||||
|
||||
+struct devlink_linecard_device {
|
||||
+ struct list_head list;
|
||||
+ unsigned int index;
|
||||
+ const char *flash_component;
|
||||
+ void *priv;
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+devlink_nl_linecard_device_fill(struct sk_buff *msg,
|
||||
+ struct devlink_linecard *linecard,
|
||||
+ struct devlink_linecard_device *linecard_device)
|
||||
+{
|
||||
+ struct nlattr *attr;
|
||||
+
|
||||
+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE);
|
||||
+ if (!attr)
|
||||
+ return -EMSGSIZE;
|
||||
+ if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_DEVICE_INDEX,
|
||||
+ linecard_device->index))
|
||||
+ return -EMSGSIZE;
|
||||
+ if (linecard_device->flash_component &&
|
||||
+ nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
|
||||
+ linecard_device->flash_component))
|
||||
+ return -EMSGSIZE;
|
||||
+ nla_nest_end(msg, attr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int devlink_nl_linecard_devices_fill(struct sk_buff *msg,
|
||||
+ struct devlink_linecard *linecard)
|
||||
+{
|
||||
+ struct devlink_linecard_device *linecard_device;
|
||||
+ struct nlattr *attr;
|
||||
+ int err;
|
||||
+
|
||||
+ if (list_empty(&linecard->device_list))
|
||||
+ return 0;
|
||||
+
|
||||
+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE_LIST);
|
||||
+ if (!attr)
|
||||
+ return -EMSGSIZE;
|
||||
+ list_for_each_entry(linecard_device, &linecard->device_list, list) {
|
||||
+ err = devlink_nl_linecard_device_fill(msg, linecard,
|
||||
+ linecard_device);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+ nla_nest_end(msg, attr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int devlink_nl_linecard_fill(struct sk_buff *msg,
|
||||
struct devlink *devlink,
|
||||
struct devlink_linecard *linecard,
|
||||
@@ -1259,6 +1312,7 @@ static int devlink_nl_linecard_fill(struct sk_buff *msg,
|
||||
struct devlink_linecard_type *linecard_type;
|
||||
struct nlattr *attr;
|
||||
void *hdr;
|
||||
+ int err;
|
||||
int i;
|
||||
|
||||
hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
|
||||
@@ -1289,6 +1343,10 @@ static int devlink_nl_linecard_fill(struct sk_buff *msg,
|
||||
nla_nest_end(msg, attr);
|
||||
}
|
||||
|
||||
+ err = devlink_nl_linecard_devices_fill(msg, linecard);
|
||||
+ if (err)
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
genlmsg_end(msg, hdr);
|
||||
return 0;
|
||||
|
||||
@@ -1546,6 +1604,66 @@ static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+devlink_nl_linecard_device_info_fill(struct sk_buff *msg,
|
||||
+ struct devlink_linecard *linecard,
|
||||
+ struct devlink_linecard_device *linecard_device,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct nlattr *attr, *attr2;
|
||||
+
|
||||
+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE);
|
||||
+ if (!attr)
|
||||
+ return -EMSGSIZE;
|
||||
+ if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_DEVICE_INDEX,
|
||||
+ linecard_device->index))
|
||||
+ return -EMSGSIZE;
|
||||
+ if (linecard->ops->device_info_get) {
|
||||
+ struct devlink_info_req req;
|
||||
+ int err;
|
||||
+
|
||||
+ attr2 = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE_INFO);
|
||||
+ if (!attr2)
|
||||
+ return -EMSGSIZE;
|
||||
+ req.msg = msg;
|
||||
+ err = linecard->ops->device_info_get(linecard_device,
|
||||
+ linecard_device->priv,
|
||||
+ &req, extack);
|
||||
+ if (err)
|
||||
+ return -EMSGSIZE;
|
||||
+ nla_nest_end(msg, attr2);
|
||||
+ }
|
||||
+ nla_nest_end(msg, attr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int devlink_nl_linecard_devices_info_fill(struct sk_buff *msg,
|
||||
+ struct devlink_linecard *linecard,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct devlink_linecard_device *linecard_device;
|
||||
+ struct nlattr *attr;
|
||||
+ int err;
|
||||
+
|
||||
+ if (list_empty(&linecard->device_list))
|
||||
+ return 0;
|
||||
+
|
||||
+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE_LIST);
|
||||
+ if (!attr)
|
||||
+ return -EMSGSIZE;
|
||||
+ list_for_each_entry(linecard_device, &linecard->device_list, list) {
|
||||
+ err = devlink_nl_linecard_device_info_fill(msg, linecard,
|
||||
+ linecard_device,
|
||||
+ extack);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ }
|
||||
+ nla_nest_end(msg, attr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
devlink_nl_linecard_info_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
struct devlink_linecard *linecard,
|
||||
@@ -1576,6 +1694,10 @@ devlink_nl_linecard_info_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
goto nla_put_failure;
|
||||
nla_nest_end(msg, attr);
|
||||
|
||||
+ err = devlink_nl_linecard_devices_info_fill(msg, linecard, extack);
|
||||
+ if (err)
|
||||
+ goto nla_put_failure;
|
||||
+
|
||||
genlmsg_end(msg, hdr);
|
||||
return 0;
|
||||
|
||||
@@ -9068,6 +9190,7 @@ devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
|
||||
linecard->priv = priv;
|
||||
linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
|
||||
mutex_init(&linecard->state_lock);
|
||||
+ INIT_LIST_HEAD(&linecard->device_list);
|
||||
|
||||
err = devlink_linecard_types_init(linecard);
|
||||
if (err) {
|
||||
@@ -9096,6 +9219,7 @@ void devlink_linecard_destroy(struct devlink_linecard *linecard)
|
||||
|
||||
devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
|
||||
devlink_linecard_types_fini(linecard);
|
||||
+ WARN_ON(!list_empty(&linecard->device_list));
|
||||
mutex_lock(&devlink->linecards_lock);
|
||||
list_del(&linecard->list);
|
||||
mutex_unlock(&devlink->linecards_lock);
|
||||
@@ -9103,6 +9227,47 @@ void devlink_linecard_destroy(struct devlink_linecard *linecard)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devlink_linecard_destroy);
|
||||
|
||||
+/**
|
||||
+ * devlink_linecard_device_create - Create a device on linecard
|
||||
+ *
|
||||
+ * @devlink_linecard: devlink linecard
|
||||
+ * @device_index: index of the linecard device
|
||||
+ * @flash_component: name of flash update component,
|
||||
+ * NULL if unable to flash
|
||||
+ */
|
||||
+struct devlink_linecard_device *
|
||||
+devlink_linecard_device_create(struct devlink_linecard *linecard,
|
||||
+ unsigned int device_index,
|
||||
+ const char *flash_component, void *priv)
|
||||
+{
|
||||
+ struct devlink_linecard_device *linecard_device;
|
||||
+
|
||||
+ linecard_device = kzalloc(sizeof(*linecard_device), GFP_KERNEL);
|
||||
+ if (!linecard_device)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+ linecard_device->index = device_index;
|
||||
+ linecard_device->flash_component = flash_component;
|
||||
+ linecard_device->priv = priv;
|
||||
+ mutex_lock(&linecard->devlink->lock);
|
||||
+ list_add_tail(&linecard_device->list, &linecard->device_list);
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ mutex_unlock(&linecard->devlink->lock);
|
||||
+ return linecard_device;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devlink_linecard_device_create);
|
||||
+
|
||||
+void
|
||||
+devlink_linecard_device_destroy(struct devlink_linecard *linecard,
|
||||
+ struct devlink_linecard_device *linecard_device)
|
||||
+{
|
||||
+ mutex_lock(&linecard->devlink->lock);
|
||||
+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
+ list_del(&linecard_device->list);
|
||||
+ mutex_unlock(&linecard->devlink->lock);
|
||||
+ kfree(linecard_device);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(devlink_linecard_device_destroy);
|
||||
+
|
||||
/**
|
||||
* devlink_linecard_provision_set - Set provisioning on linecard
|
||||
*
|
||||
@@ -9129,6 +9294,7 @@ EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
|
||||
void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
|
||||
{
|
||||
mutex_lock(&linecard->state_lock);
|
||||
+ WARN_ON(!list_empty(&linecard->device_list));
|
||||
linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
|
||||
linecard->type = NULL;
|
||||
devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,98 @@
|
||||
From ec8e91d320c8cccb8ad59663d2d59810ea5aecb9 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Fri, 29 Jan 2021 08:45:09 +0100
|
||||
Subject: [PATCH] mlxsw: reg: Add Ports Mapping event Configuration Register
|
||||
|
||||
The PMECR register use to enable/disable event trigger in case of
|
||||
local port mapping change.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 64 +++++++++++++++++++++++
|
||||
1 file changed, 64 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index 9de037b9a..42169957c 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -5524,6 +5524,69 @@ static inline void mlxsw_reg_pplr_pack(char *payload, u8 local_port,
|
||||
MLXSW_REG_PPLR_LB_TYPE_BIT_PHY_LOCAL : 0);
|
||||
}
|
||||
|
||||
+/* PMECR - Ports Mapping event Configuration Register
|
||||
+ * --------------------------------------------------
|
||||
+ * The PMECR register use to enable/disable event trigger in case of
|
||||
+ * local port mapping change.
|
||||
+ */
|
||||
+#define MLXSW_REG_PMECR_ID 0x501B
|
||||
+#define MLXSW_REG_PMECR_LEN 0x20
|
||||
+
|
||||
+MLXSW_REG_DEFINE(pmecr, MLXSW_REG_PMECR_ID, MLXSW_REG_PMECR_LEN);
|
||||
+
|
||||
+/* reg_pmecr_local_port
|
||||
+ * Local port number.
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, pmecr, local_port, 0x00, 16, 8);
|
||||
+
|
||||
+/* reg_pmecr_ee
|
||||
+ * Event update enable. If this bit is set, event generation will be updated
|
||||
+ * based on the e field. Only relevant on Set operations.
|
||||
+ * Access: WO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, pmecr, ee, 0x04, 30, 1);
|
||||
+
|
||||
+/* reg_pmecr_eswi
|
||||
+ * Software ignore enable bit. If this bit is set, the value if swi is used.
|
||||
+ * If this bit is clear, the value of swi is ignored.
|
||||
+ * Only relevant on Set operations.
|
||||
+ * Access: WO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, pmecr, eswi, 0x04, 24, 1);
|
||||
+
|
||||
+/* reg_pmecr_swi
|
||||
+ * Software ignore. If this bit is set, the device shouldn't generate events
|
||||
+ * in case of PMLP SET operation but only upon self local port mapping change
|
||||
+ * (if applicable according to e configuration). This is supplementary
|
||||
+ * configuration on top of e value.
|
||||
+ * Access: RW
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, pmecr, swi, 0x04, 8, 1);
|
||||
+
|
||||
+enum mlxsw_reg_pmecr_e {
|
||||
+ MLXSW_REG_PMECR_E_DO_NOT_GENERATE_EVENT,
|
||||
+ MLXSW_REG_PMECR_E_GENERATE_EVENT,
|
||||
+ MLXSW_REG_PMECR_E_GENERATE_SINGLE_EVENT,
|
||||
+};
|
||||
+
|
||||
+/* reg_pmecr_e
|
||||
+ * Event generation on local port mapping change.
|
||||
+ * Access: RW
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, pmecr, e, 0x04, 0, 2);
|
||||
+
|
||||
+static inline void mlxsw_reg_pmecr_pack(char *payload, u8 local_port,
|
||||
+ enum mlxsw_reg_pmecr_e e)
|
||||
+{
|
||||
+ MLXSW_REG_ZERO(pmecr, payload);
|
||||
+ mlxsw_reg_pmecr_local_port_set(payload, local_port);
|
||||
+ mlxsw_reg_pmecr_e_set(payload, e);
|
||||
+ mlxsw_reg_pmecr_ee_set(payload, true);
|
||||
+ mlxsw_reg_pmecr_swi_set(payload, true);
|
||||
+ mlxsw_reg_pmecr_eswi_set(payload, true);
|
||||
+}
|
||||
+
|
||||
/* PMPE - Port Module Plug/Unplug Event Register
|
||||
* ---------------------------------------------
|
||||
* This register reports any operational status change of a module.
|
||||
@@ -11376,6 +11439,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
|
||||
MLXSW_REG(pspa),
|
||||
MLXSW_REG(pmaos),
|
||||
MLXSW_REG(pplr),
|
||||
+ MLXSW_REG(pmecr),
|
||||
MLXSW_REG(pmpe),
|
||||
MLXSW_REG(pddr),
|
||||
MLXSW_REG(pmtm),
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,267 @@
|
||||
From e46f9bfa89b8b9caced49a74db695e86e963b35d Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Mon, 3 Jan 2022 10:20:49 +0000
|
||||
Subject: [PATCH] mlxsw: reg: Add Management DownStream Device Query Register
|
||||
|
||||
The MDDQ register allows to query the DownStream device properties.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 234 ++++++++++++++++++++++
|
||||
1 file changed, 234 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index 42169957c..d5301bd6f 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -10297,6 +10297,239 @@ mlxsw_reg_mgpir_unpack(char *payload, u8 *num_of_devices,
|
||||
*num_of_slots = mlxsw_reg_mgpir_num_of_slots_get(payload);
|
||||
}
|
||||
|
||||
+/* MDDQ - Management DownStream Device Query Register
|
||||
+ * --------------------------------------------------
|
||||
+ * This register allows to query the DownStream device properties. The desired
|
||||
+ * information is chosen upon the query_type field and is delivered by 32B
|
||||
+ * of data blocks.
|
||||
+ */
|
||||
+#define MLXSW_REG_MDDQ_ID 0x9161
|
||||
+#define MLXSW_REG_MDDQ_LEN 0x30
|
||||
+
|
||||
+MLXSW_REG_DEFINE(mddq, MLXSW_REG_MDDQ_ID, MLXSW_REG_MDDQ_LEN);
|
||||
+
|
||||
+/* reg_mddq_sie
|
||||
+ * Slot info event enable.
|
||||
+ * When set to '1', each change in the slot_info.provisioned / sr_valid /
|
||||
+ * active / ready will generate an event.
|
||||
+ * Access: RW
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, sie, 0x00, 31, 1);
|
||||
+
|
||||
+enum mlxsw_reg_mddq_query_type {
|
||||
+ MLXSW_REG_MDDQ_QUERY_TYPE_SLOT_INFO = 1,
|
||||
+ MLXSW_REG_MDDQ_QUERY_TYPE_DEVICE_INFO, /* If there are no devices
|
||||
+ * on the slot, data_valid
|
||||
+ * will be '0'.
|
||||
+ */
|
||||
+ MLXSW_REG_MDDQ_QUERY_TYPE_SLOT_NAME,
|
||||
+};
|
||||
+
|
||||
+/* reg_mddq_query_type
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, query_type, 0x00, 16, 8);
|
||||
+
|
||||
+/* reg_mddq_slot_index
|
||||
+ * Slot index. 0 is reserved.
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, slot_index, 0x00, 0, 4);
|
||||
+
|
||||
+/* reg_mddq_response_msg_seq
|
||||
+ * Response message sequential number. For a specific request, the response
|
||||
+ * message sequential number is the following one. In addition, the last
|
||||
+ * message should be 0.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, response_msg_seq, 0x04, 16, 8);
|
||||
+
|
||||
+/* reg_mddq_request_msg_seq
|
||||
+ * Request message sequential number.
|
||||
+ * The first message number should be 0.
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, request_msg_seq, 0x04, 0, 8);
|
||||
+
|
||||
+/* reg_mddq_data_valid
|
||||
+ * If set, the data in the data field is valid and contain the information
|
||||
+ * for the queried index.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, data_valid, 0x08, 31, 1);
|
||||
+
|
||||
+/* reg_mddq_provisioned
|
||||
+ * If set, the INI file is applied and the card is provisioned.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, provisioned, 0x10, 31, 1);
|
||||
+
|
||||
+/* reg_mddq_sr_valid
|
||||
+ * If set, Shift Register is valid (after being provisioned).
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, sr_valid, 0x10, 30, 1);
|
||||
+
|
||||
+enum mlxsw_reg_mddq_ready {
|
||||
+ MLXSW_REG_MDDQ_READY_NOT_READY,
|
||||
+ MLXSW_REG_MDDQ_READY_READY,
|
||||
+ MLXSW_REG_MDDQ_READY_ERROR,
|
||||
+};
|
||||
+
|
||||
+/* reg_mddq_lc_ready
|
||||
+ * If set, the LC is powered on, matching the INI version and a new FW
|
||||
+ * version can be burnt (if necessary).
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, lc_ready, 0x10, 28, 2);
|
||||
+
|
||||
+/* reg_mddq_active
|
||||
+ * If set, the FW has completed the MDDC.device_enable command.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, active, 0x10, 27, 1);
|
||||
+
|
||||
+/* reg_mddq_hw_revision
|
||||
+ * Major user-configured version number of the current INI file.
|
||||
+ * Valid only when active or ready are '1'.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, hw_revision, 0x14, 16, 16);
|
||||
+
|
||||
+/* reg_mddq_ini_file_version
|
||||
+ * User-configured version number of the current INI file.
|
||||
+ * Valid only when active or lc_ready are '1'.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, ini_file_version, 0x14, 0, 16);
|
||||
+
|
||||
+enum mlxsw_reg_mddq_card_type {
|
||||
+ MLXSW_REG_MDDQ_CARD_TYPE_BUFFALO_4X400G,
|
||||
+ MLXSW_REG_MDDQ_CARD_TYPE_BUFFALO_8X200G,
|
||||
+ MLXSW_REG_MDDQ_CARD_TYPE_BUFFALO_16X100G,
|
||||
+};
|
||||
+
|
||||
+/* reg_mddq_card_type
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, card_type, 0x18, 0, 8);
|
||||
+
|
||||
+static inline void
|
||||
+__mlxsw_reg_mddq_pack(char *payload, u8 slot_index,
|
||||
+ enum mlxsw_reg_mddq_query_type query_type)
|
||||
+{
|
||||
+ MLXSW_REG_ZERO(mddq, payload);
|
||||
+ mlxsw_reg_mddq_slot_index_set(payload, slot_index);
|
||||
+ mlxsw_reg_mddq_query_type_set(payload, query_type);
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+mlxsw_reg_mddq_slot_info_pack(char *payload, u8 slot_index, bool sie)
|
||||
+{
|
||||
+ __mlxsw_reg_mddq_pack(payload, slot_index,
|
||||
+ MLXSW_REG_MDDQ_QUERY_TYPE_SLOT_INFO);
|
||||
+ mlxsw_reg_mddq_sie_set(payload, sie);
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+mlxsw_reg_mddq_slot_info_unpack(const char *payload, u8 *p_slot_index,
|
||||
+ bool *p_provisioned, bool *p_sr_valid,
|
||||
+ enum mlxsw_reg_mddq_ready *p_lc_ready,
|
||||
+ bool *p_active, u16 *p_hw_revision,
|
||||
+ u16 *p_ini_file_version,
|
||||
+ enum mlxsw_reg_mddq_card_type *p_card_type)
|
||||
+{
|
||||
+ *p_slot_index = mlxsw_reg_mddq_slot_index_get(payload);
|
||||
+ *p_provisioned = mlxsw_reg_mddq_provisioned_get(payload);
|
||||
+ *p_sr_valid = mlxsw_reg_mddq_sr_valid_get(payload);
|
||||
+ *p_lc_ready = mlxsw_reg_mddq_lc_ready_get(payload);
|
||||
+ *p_active = mlxsw_reg_mddq_active_get(payload);
|
||||
+ *p_hw_revision = mlxsw_reg_mddq_hw_revision_get(payload);
|
||||
+ *p_ini_file_version = mlxsw_reg_mddq_ini_file_version_get(payload);
|
||||
+ *p_card_type = mlxsw_reg_mddq_card_type_get(payload);
|
||||
+}
|
||||
+
|
||||
+/* reg_mddq_flash_owner
|
||||
+ * If set, the device is the flash owner. Otherwise, a shared flash
|
||||
+ * is used by this device (another device is the flash owner).
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, flash_owner, 0x10, 30, 1);
|
||||
+
|
||||
+/* reg_mddq_device_index
|
||||
+ * Device index. The first device should number 0.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, device_index, 0x10, 0, 8);
|
||||
+
|
||||
+/* reg_mddq_fw_major
|
||||
+ * Major FW version number.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, fw_major, 0x14, 16, 16);
|
||||
+
|
||||
+/* reg_mddq_fw_minor
|
||||
+ * Minor FW version number.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, fw_minor, 0x18, 16, 16);
|
||||
+
|
||||
+/* reg_mddq_fw_sub_minor
|
||||
+ * Sub-minor FW version number.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddq, fw_sub_minor, 0x18, 0, 16);
|
||||
+
|
||||
+static inline void
|
||||
+mlxsw_reg_mddq_device_info_pack(char *payload, u8 slot_index,
|
||||
+ u8 request_msg_seq)
|
||||
+{
|
||||
+ __mlxsw_reg_mddq_pack(payload, slot_index,
|
||||
+ MLXSW_REG_MDDQ_QUERY_TYPE_DEVICE_INFO);
|
||||
+ mlxsw_reg_mddq_request_msg_seq_set(payload, request_msg_seq);
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+mlxsw_reg_mddq_device_info_unpack(const char *payload, u8 *p_response_msg_seq,
|
||||
+ bool *p_data_valid, bool *p_flash_owner,
|
||||
+ u8 *p_device_index, u16 *p_fw_major,
|
||||
+ u16 *p_fw_minor, u16 *p_fw_sub_minor)
|
||||
+{
|
||||
+ *p_response_msg_seq = mlxsw_reg_mddq_response_msg_seq_get(payload);
|
||||
+ *p_data_valid = mlxsw_reg_mddq_data_valid_get(payload);
|
||||
+ if (p_flash_owner)
|
||||
+ *p_flash_owner = mlxsw_reg_mddq_flash_owner_get(payload);
|
||||
+ *p_device_index = mlxsw_reg_mddq_device_index_get(payload);
|
||||
+ if (p_fw_major)
|
||||
+ *p_fw_major = mlxsw_reg_mddq_fw_major_get(payload);
|
||||
+ if (p_fw_minor)
|
||||
+ *p_fw_minor = mlxsw_reg_mddq_fw_minor_get(payload);
|
||||
+ if (p_fw_sub_minor)
|
||||
+ *p_fw_sub_minor = mlxsw_reg_mddq_fw_sub_minor_get(payload);
|
||||
+}
|
||||
+
|
||||
+#define MLXSW_REG_MDDQ_SLOT_ACII_NAME_LEN 20
|
||||
+
|
||||
+/* reg_mddq_slot_ascii_name
|
||||
+ * Slot's ASCII name.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM_BUF(reg, mddq, slot_ascii_name, 0x10,
|
||||
+ MLXSW_REG_MDDQ_SLOT_ACII_NAME_LEN);
|
||||
+
|
||||
+static inline void
|
||||
+mlxsw_reg_mddq_slot_name_pack(char *payload, u8 slot_index)
|
||||
+{
|
||||
+ __mlxsw_reg_mddq_pack(payload, slot_index,
|
||||
+ MLXSW_REG_MDDQ_QUERY_TYPE_SLOT_NAME);
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+mlxsw_reg_mddq_slot_name_unpack(const char *payload, char *slot_ascii_name)
|
||||
+{
|
||||
+ mlxsw_reg_mddq_slot_ascii_name_memcpy_from(payload, slot_ascii_name);
|
||||
+}
|
||||
+
|
||||
/* MFDE - Monitoring FW Debug Register
|
||||
* -----------------------------------
|
||||
*/
|
||||
@@ -11496,6 +11729,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
|
||||
MLXSW_REG(mtptpt),
|
||||
MLXSW_REG(mfgd),
|
||||
MLXSW_REG(mgpir),
|
||||
+ MLXSW_REG(mddq),
|
||||
MLXSW_REG(mfde),
|
||||
MLXSW_REG(tngcr),
|
||||
MLXSW_REG(tnumt),
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,70 @@
|
||||
From ab25c37ca20274cbf51ab603aa44f682cf5b51b5 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Tue, 19 Jan 2021 12:16:58 +0100
|
||||
Subject: [PATCH] mlxsw: reg: Add Management DownStream Device Control Register
|
||||
|
||||
The MDDC register allows control downstream devices and line cards.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 37 +++++++++++++++++++++++
|
||||
1 file changed, 37 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index d5301bd6f..9cbdf407f 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -10530,6 +10530,42 @@ mlxsw_reg_mddq_slot_name_unpack(const char *payload, char *slot_ascii_name)
|
||||
mlxsw_reg_mddq_slot_ascii_name_memcpy_from(payload, slot_ascii_name);
|
||||
}
|
||||
|
||||
+/* MDDC - Management DownStream Device Control Register
|
||||
+ * ----------------------------------------------------
|
||||
+ * This register allows control downstream devices and line cards.
|
||||
+ */
|
||||
+#define MLXSW_REG_MDDC_ID 0x9163
|
||||
+#define MLXSW_REG_MDDC_LEN 0x30
|
||||
+
|
||||
+MLXSW_REG_DEFINE(mddc, MLXSW_REG_MDDC_ID, MLXSW_REG_MDDC_LEN);
|
||||
+
|
||||
+/* reg_mddc_slot_index
|
||||
+ * Slot index. 0 is reserved.
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddc, slot_index, 0x00, 0, 4);
|
||||
+
|
||||
+/* reg_mddc_rst
|
||||
+ * Reset request.
|
||||
+ * Access: RW
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddc, rst, 0x04, 29, 1);
|
||||
+
|
||||
+/* reg_mddc_device_enable
|
||||
+ * When set, FW is the manager and allowed to program the Downstream Device.
|
||||
+ * Access: RW
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddc, device_enable, 0x04, 28, 1);
|
||||
+
|
||||
+static inline void mlxsw_reg_mddc_pack(char *payload, u8 slot_index, bool rst,
|
||||
+ bool device_enable)
|
||||
+{
|
||||
+ MLXSW_REG_ZERO(mddc, payload);
|
||||
+ mlxsw_reg_mddc_slot_index_set(payload, slot_index);
|
||||
+ mlxsw_reg_mddc_rst_set(payload, rst);
|
||||
+ mlxsw_reg_mddc_device_enable_set(payload, device_enable);
|
||||
+}
|
||||
+
|
||||
/* MFDE - Monitoring FW Debug Register
|
||||
* -----------------------------------
|
||||
*/
|
||||
@@ -11730,6 +11766,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
|
||||
MLXSW_REG(mfgd),
|
||||
MLXSW_REG(mgpir),
|
||||
MLXSW_REG(mddq),
|
||||
+ MLXSW_REG(mddc),
|
||||
MLXSW_REG(mfde),
|
||||
MLXSW_REG(tngcr),
|
||||
MLXSW_REG(tnumt),
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,154 @@
|
||||
From 618665ccbf600c2838fb2e181246aef0fa90bac2 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Thu, 10 Dec 2020 18:27:38 +0100
|
||||
Subject: [PATCH] mlxsw: reg: Add Management Binary Code Transfer Register
|
||||
|
||||
The MBCT register allows to transfer binary codes from the Host to
|
||||
the management FW by transferring it by chunks of maximum 1KB.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 120 ++++++++++++++++++++++
|
||||
1 file changed, 120 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index 9cbdf407f..89b21910f 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -10297,6 +10297,125 @@ mlxsw_reg_mgpir_unpack(char *payload, u8 *num_of_devices,
|
||||
*num_of_slots = mlxsw_reg_mgpir_num_of_slots_get(payload);
|
||||
}
|
||||
|
||||
+/* MBCT - Management Binary Code Transfer Register
|
||||
+ * -----------------------------------------------
|
||||
+ * This register allows to transfer binary codes from the Host to
|
||||
+ * the management FW by transferring it by chunks of maximum 1KB.
|
||||
+ */
|
||||
+#define MLXSW_REG_MBCT_ID 0x9120
|
||||
+#define MLXSW_REG_MBCT_LEN 0x420
|
||||
+
|
||||
+MLXSW_REG_DEFINE(mbct, MLXSW_REG_MBCT_ID, MLXSW_REG_MBCT_LEN);
|
||||
+
|
||||
+/* reg_mbct_slot_index
|
||||
+ * Slot index. 0 is reserved.
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mbct, slot_index, 0x00, 0, 4);
|
||||
+
|
||||
+/* reg_mbct_data_size
|
||||
+ * Actual data field size in bytes for the current data transfer.
|
||||
+ * Access: WO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mbct, data_size, 0x04, 0, 11);
|
||||
+
|
||||
+enum mlxsw_reg_mbct_op {
|
||||
+ MLXSW_REG_MBCT_OP_ERASE_INI_IMAGE = 1,
|
||||
+ MLXSW_REG_MBCT_OP_DATA_TRANSFER, /* Download */
|
||||
+ MLXSW_REG_MBCT_OP_ACTIVATE,
|
||||
+ MLXSW_REG_MBCT_OP_CLEAR_ERRORS = 6,
|
||||
+ MLXSW_REG_MBCT_OP_QUERY_STATUS,
|
||||
+};
|
||||
+
|
||||
+/* reg_mbct_op
|
||||
+ * Access: OP
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mbct, op, 0x08, 28, 4);
|
||||
+
|
||||
+/* reg_mbct_last
|
||||
+ * Indicates that the current data field is the last chunk of the INI.
|
||||
+ * Access: WO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mbct, last, 0x08, 26, 1);
|
||||
+
|
||||
+/* reg_mbct_oee
|
||||
+ * Opcode Event Enable. When set an event will be sent once the opcode
|
||||
+ * was executed and the fsm_state has changed.
|
||||
+ * Access: WO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mbct, oee, 0x08, 25, 1);
|
||||
+
|
||||
+enum mlxsw_reg_mbct_status {
|
||||
+ /* Partial data transfer completed successfully and ready for next
|
||||
+ * data transfer.
|
||||
+ */
|
||||
+ MLXSW_REG_MBCT_STATUS_PART_DATA = 2,
|
||||
+ MLXSW_REG_MBCT_STATUS_LAST_DATA,
|
||||
+ MLXSW_REG_MBCT_STATUS_ERASE_COMPLETE,
|
||||
+ /* Error - trying to erase INI while it being used. */
|
||||
+ MLXSW_REG_MBCT_STATUS_ERROR_INI_IN_USE,
|
||||
+ /* Last data transfer completed, applying magic pattern. */
|
||||
+ MLXSW_REG_MBCT_STATUS_ERASE_FAILED = 7,
|
||||
+ MLXSW_REG_MBCT_STATUS_INI_ERROR,
|
||||
+ MLXSW_REG_MBCT_STATUS_ACTIVATION_FAILED,
|
||||
+ MLXSW_REG_MBCT_STATUS_ILLEGAL_OPERATION = 11,
|
||||
+};
|
||||
+
|
||||
+/* reg_mbct_status
|
||||
+ * Status.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mbct, status, 0x0C, 24, 5);
|
||||
+
|
||||
+enum mlxsw_reg_mbct_fsm_state {
|
||||
+ MLXSW_REG_MBCT_FSM_STATE_INI_IN_USE = 5,
|
||||
+ MLXSW_REG_MBCT_FSM_STATE_ERROR = 6,
|
||||
+};
|
||||
+
|
||||
+/* reg_mbct_fsm_state
|
||||
+ * FSM state.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mbct, fsm_state, 0x0C, 16, 4);
|
||||
+
|
||||
+#define MLXSW_REG_MBCT_DATA_LEN 1024
|
||||
+
|
||||
+/* reg_mbct_data
|
||||
+ * Up to 1KB of data.
|
||||
+ * Access: WO
|
||||
+ */
|
||||
+MLXSW_ITEM_BUF(reg, mbct, data, 0x20, MLXSW_REG_MBCT_DATA_LEN);
|
||||
+
|
||||
+static inline void mlxsw_reg_mbct_pack(char *payload, u8 slot_index,
|
||||
+ enum mlxsw_reg_mbct_op op,
|
||||
+ u16 data_size, bool last, bool oee,
|
||||
+ const char *data)
|
||||
+{
|
||||
+ MLXSW_REG_ZERO(mbct, payload);
|
||||
+ mlxsw_reg_mbct_slot_index_set(payload, slot_index);
|
||||
+ mlxsw_reg_mbct_op_set(payload, op);
|
||||
+ mlxsw_reg_mbct_oee_set(payload, oee);
|
||||
+ if (op == MLXSW_REG_MBCT_OP_DATA_TRANSFER) {
|
||||
+ if (WARN_ON(data_size > MLXSW_REG_MBCT_DATA_LEN))
|
||||
+ return;
|
||||
+ mlxsw_reg_mbct_data_size_set(payload, data_size);
|
||||
+ mlxsw_reg_mbct_last_set(payload, last);
|
||||
+ mlxsw_reg_mbct_data_memcpy_to(payload, data);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline void
|
||||
+mlxsw_reg_mbct_unpack(const char *payload, u8 *p_slot_index,
|
||||
+ enum mlxsw_reg_mbct_status *p_status,
|
||||
+ enum mlxsw_reg_mbct_fsm_state *p_fsm_state)
|
||||
+{
|
||||
+ if (p_slot_index)
|
||||
+ *p_slot_index = mlxsw_reg_mbct_slot_index_get(payload);
|
||||
+ *p_status = mlxsw_reg_mbct_status_get(payload);
|
||||
+ if (p_fsm_state)
|
||||
+ *p_fsm_state = mlxsw_reg_mbct_fsm_state_get(payload);
|
||||
+}
|
||||
+
|
||||
/* MDDQ - Management DownStream Device Query Register
|
||||
* --------------------------------------------------
|
||||
* This register allows to query the DownStream device properties. The desired
|
||||
@@ -11765,6 +11884,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
|
||||
MLXSW_REG(mtptpt),
|
||||
MLXSW_REG(mfgd),
|
||||
MLXSW_REG(mgpir),
|
||||
+ MLXSW_REG(mbct),
|
||||
MLXSW_REG(mddq),
|
||||
MLXSW_REG(mddc),
|
||||
MLXSW_REG(mfde),
|
||||
--
|
||||
2.30.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,205 @@
|
||||
From f2ecea65348e527345e9e7a59766162eb2297a53 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Fri, 22 Jan 2021 14:45:06 +0100
|
||||
Subject: [PATCH] mlxsw: core_linecards: Implement line card activation process
|
||||
|
||||
Allow to process events generated upon line card getting "ready" and
|
||||
"active".
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.h | 3 +
|
||||
.../ethernet/mellanox/mlxsw/core_linecards.c | 85 +++++++++++++++++--
|
||||
2 files changed, 80 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
index d3c5d8289..ecd91bb8c 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
@@ -521,6 +521,9 @@ struct mlxsw_linecard {
|
||||
char read_name[MLXSW_REG_MDDQ_SLOT_ACII_NAME_LEN];
|
||||
char mbct_pl[MLXSW_REG_MBCT_LEN]; /* too big for stack */
|
||||
bool provisioned;
|
||||
+ bool ready;
|
||||
+ bool active;
|
||||
+ bool unprovision_done;
|
||||
};
|
||||
|
||||
struct mlxsw_linecard_types_info;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
index a324ce243..134437f49 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
@@ -67,6 +67,8 @@ static const char *mlxsw_linecard_type_name(struct mlxsw_linecard *linecard)
|
||||
static void mlxsw_linecard_provision_fail(struct mlxsw_linecard *linecard)
|
||||
{
|
||||
linecard->provisioned = false;
|
||||
+ linecard->ready = false;
|
||||
+ linecard->active = false;
|
||||
devlink_linecard_provision_fail(linecard->devlink_linecard);
|
||||
}
|
||||
|
||||
@@ -94,10 +96,51 @@ static void mlxsw_linecard_provision_clear(struct mlxsw_linecard *linecard)
|
||||
devlink_linecard_provision_clear(linecard->devlink_linecard);
|
||||
}
|
||||
|
||||
+static int mlxsw_linecard_ready_set(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecard *linecard)
|
||||
+{
|
||||
+ char mddc_pl[MLXSW_REG_MDDC_LEN];
|
||||
+ int err;
|
||||
+
|
||||
+ mlxsw_reg_mddc_pack(mddc_pl, linecard->slot_index, false, true);
|
||||
+ err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(mddc), mddc_pl);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ linecard->ready = true;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mlxsw_linecard_ready_clear(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecard *linecard)
|
||||
+{
|
||||
+ char mddc_pl[MLXSW_REG_MDDC_LEN];
|
||||
+ int err;
|
||||
+
|
||||
+ mlxsw_reg_mddc_pack(mddc_pl, linecard->slot_index, false, false);
|
||||
+ err = mlxsw_reg_write(mlxsw_core, MLXSW_REG(mddc), mddc_pl);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ linecard->ready = false;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_linecard_active_set(struct mlxsw_linecard *linecard)
|
||||
+{
|
||||
+ linecard->active = true;
|
||||
+ devlink_linecard_activate(linecard->devlink_linecard);
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_linecard_active_clear(struct mlxsw_linecard *linecard)
|
||||
+{
|
||||
+ linecard->active = false;
|
||||
+ devlink_linecard_deactivate(linecard->devlink_linecard);
|
||||
+}
|
||||
+
|
||||
static int __mlxsw_linecard_status_process(struct mlxsw_core *mlxsw_core,
|
||||
struct mlxsw_linecards *linecards,
|
||||
struct mlxsw_linecard *linecard,
|
||||
- const char *mddq_pl)
|
||||
+ const char *mddq_pl,
|
||||
+ bool process_provision_only)
|
||||
{
|
||||
enum mlxsw_reg_mddq_card_type card_type;
|
||||
enum mlxsw_reg_mddq_ready ready;
|
||||
@@ -132,6 +175,27 @@ static int __mlxsw_linecard_status_process(struct mlxsw_core *mlxsw_core,
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if (!process_provision_only && !linecard->unprovision_done &&
|
||||
+ ready == MLXSW_REG_MDDQ_READY_READY && !linecard->ready) {
|
||||
+ err = mlxsw_linecard_ready_set(mlxsw_core, linecard);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (!process_provision_only && !linecard->unprovision_done && active &&
|
||||
+ linecard->active != active && linecard->ready)
|
||||
+ mlxsw_linecard_active_set(linecard);
|
||||
+
|
||||
+ if (!process_provision_only && !active && linecard->active != active)
|
||||
+ mlxsw_linecard_active_clear(linecard);
|
||||
+
|
||||
+ if (!process_provision_only && ready != MLXSW_REG_MDDQ_READY_READY &&
|
||||
+ linecard->ready) {
|
||||
+ err = mlxsw_linecard_ready_clear(mlxsw_core, linecard);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (!provisioned && linecard->provisioned != provisioned)
|
||||
mlxsw_linecard_provision_clear(linecard);
|
||||
|
||||
@@ -146,13 +210,14 @@ int mlxsw_linecard_status_process(struct mlxsw_core *mlxsw_core,
|
||||
struct mlxsw_linecards *linecards = mlxsw_core_linecards(mlxsw_core);
|
||||
|
||||
return __mlxsw_linecard_status_process(mlxsw_core, linecards, NULL,
|
||||
- mddq_pl);
|
||||
+ mddq_pl, false);
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_linecard_status_process);
|
||||
|
||||
static int mlxsw_linecard_status_get_and_process(struct mlxsw_core *mlxsw_core,
|
||||
struct mlxsw_linecards *linecards,
|
||||
- struct mlxsw_linecard *linecard)
|
||||
+ struct mlxsw_linecard *linecard,
|
||||
+ bool process_provision_only)
|
||||
{
|
||||
char mddq_pl[MLXSW_REG_MDDQ_LEN];
|
||||
int err;
|
||||
@@ -163,7 +228,7 @@ static int mlxsw_linecard_status_get_and_process(struct mlxsw_core *mlxsw_core,
|
||||
return err;
|
||||
|
||||
return __mlxsw_linecard_status_process(mlxsw_core, linecards, linecard,
|
||||
- mddq_pl);
|
||||
+ mddq_pl, process_provision_only);
|
||||
}
|
||||
|
||||
static int __mlxsw_linecard_fix_fsm_state(struct mlxsw_linecard *linecard)
|
||||
@@ -308,6 +373,7 @@ static int mlxsw_linecard_provision(struct devlink_linecard *devlink_linecard,
|
||||
|
||||
mutex_lock(&linecard->lock);
|
||||
|
||||
+ linecard->unprovision_done = false;
|
||||
linecards = linecard->linecards;
|
||||
mlxsw_core = linecards->mlxsw_core;
|
||||
mlxsw_reg_mbct_pack(linecard->mbct_pl, linecard->slot_index,
|
||||
@@ -416,6 +482,7 @@ static int mlxsw_linecard_unprovision(struct devlink_linecard *devlink_linecard,
|
||||
NL_SET_ERR_MSG_MOD(extack, "Failed to erase linecard INI while being used");
|
||||
goto fix_fsm_err_out;
|
||||
}
|
||||
+ linecard->unprovision_done = true;
|
||||
goto out;
|
||||
|
||||
fix_fsm_err_out:
|
||||
@@ -478,7 +545,7 @@ static int mlxsw_linecard_init(struct mlxsw_core *mlxsw_core,
|
||||
linecard->devlink_linecard = devlink_linecard;
|
||||
|
||||
err = mlxsw_linecard_status_get_and_process(mlxsw_core, linecards,
|
||||
- linecard);
|
||||
+ linecard, true);
|
||||
if (err)
|
||||
goto err_status_get_and_process;
|
||||
|
||||
@@ -514,7 +581,7 @@ static int mlxsw_linecard_post_init(struct mlxsw_core *mlxsw_core,
|
||||
return err;
|
||||
|
||||
err = mlxsw_linecard_status_get_and_process(mlxsw_core, linecards,
|
||||
- linecard);
|
||||
+ linecard, false);
|
||||
if (err)
|
||||
goto err_status_get_and_process;
|
||||
|
||||
@@ -533,6 +600,10 @@ static void mlxsw_linecard_pre_fini(struct mlxsw_core *mlxsw_core,
|
||||
|
||||
linecard = mlxsw_linecard_get(linecards, slot_index);
|
||||
mlxsw_linecard_event_delivery_set(mlxsw_core, linecard, false);
|
||||
+ /* Make sure all scheduled events are processed */
|
||||
+ mlxsw_core_flush_owq();
|
||||
+ if (linecard->active)
|
||||
+ mlxsw_linecard_active_clear(linecard);
|
||||
}
|
||||
|
||||
static void mlxsw_linecard_fini(struct mlxsw_core *mlxsw_core,
|
||||
@@ -754,8 +825,6 @@ void mlxsw_linecards_pre_fini(struct mlxsw_core *mlxsw_core,
|
||||
return;
|
||||
for (i = 0; i < linecards->count; i++)
|
||||
mlxsw_linecard_pre_fini(mlxsw_core, linecards, i + 1);
|
||||
- /* Make sure all scheduled events are processed */
|
||||
- mlxsw_core_flush_owq();
|
||||
}
|
||||
|
||||
void mlxsw_linecards_fini(struct mlxsw_core *mlxsw_core,
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,98 @@
|
||||
From 063ca0577ceb2355884555d96a24a740a2c03bdb Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Wed, 22 Dec 2021 16:26:43 +0000
|
||||
Subject: [PATCH] mlxsw: core: Extend driver ops by remove selected ports op
|
||||
|
||||
In case of line card implementation, the core has to have a way to
|
||||
remove relevant ports manually. Extend the Spectrum driver ops by an op
|
||||
that implements port removal of selected ports upon request.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.c | 9 +++++++++
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.h | 8 ++++++++
|
||||
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 15 +++++++++++++++
|
||||
3 files changed, 32 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
index 246db548f..2b4f9844b 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
@@ -2870,6 +2870,15 @@ mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_core_port_devlink_port_get);
|
||||
|
||||
+void mlxsw_core_ports_remove_selected(struct mlxsw_core *mlxsw_core,
|
||||
+ bool (*selector)(void *priv, u16 local_port),
|
||||
+ void *priv)
|
||||
+{
|
||||
+ if (WARN_ON(!mlxsw_core->driver->ports_remove_selected))
|
||||
+ return;
|
||||
+ mlxsw_core->driver->ports_remove_selected(mlxsw_core, selector, priv);
|
||||
+}
|
||||
+
|
||||
struct mlxsw_env *mlxsw_core_env(const struct mlxsw_core *mlxsw_core)
|
||||
{
|
||||
return mlxsw_core->env;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
index ecd91bb8c..70f97ef74 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
@@ -223,6 +223,10 @@ enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
|
||||
struct devlink_port *
|
||||
mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
|
||||
u8 local_port);
|
||||
+void mlxsw_core_ports_remove_selected(struct mlxsw_core *mlxsw_core,
|
||||
+ bool (*selector)(void *priv,
|
||||
+ u16 local_port),
|
||||
+ void *priv);
|
||||
struct mlxsw_env *mlxsw_core_env(const struct mlxsw_core *mlxsw_core);
|
||||
int mlxsw_core_module_max_width(struct mlxsw_core *mlxsw_core, u8 module);
|
||||
|
||||
@@ -296,6 +300,10 @@ struct mlxsw_driver {
|
||||
unsigned int count, struct netlink_ext_ack *extack);
|
||||
int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u8 local_port,
|
||||
struct netlink_ext_ack *extack);
|
||||
+ void (*ports_remove_selected)(struct mlxsw_core *mlxsw_core,
|
||||
+ bool (*selector)(void *priv,
|
||||
+ u16 local_port),
|
||||
+ void *priv);
|
||||
int (*sb_pool_get)(struct mlxsw_core *mlxsw_core,
|
||||
unsigned int sb_index, u16 pool_index,
|
||||
struct devlink_sb_pool_info *pool_info);
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
|
||||
index d7a230828..75b418fbe 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
|
||||
@@ -1736,6 +1736,20 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
|
||||
mlxsw_sp->ports = NULL;
|
||||
}
|
||||
|
||||
+static void
|
||||
+mlxsw_sp_ports_remove_selected(struct mlxsw_core *mlxsw_core,
|
||||
+ bool (*selector)(void *priv, u16 local_port),
|
||||
+ void *priv)
|
||||
+{
|
||||
+ struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
|
||||
+ unsigned int max_ports = mlxsw_core_max_ports(mlxsw_core);
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 1; i < max_ports; i++)
|
||||
+ if (mlxsw_sp_port_created(mlxsw_sp, i) && selector(priv, i))
|
||||
+ mlxsw_sp_port_remove(mlxsw_sp, i);
|
||||
+}
|
||||
+
|
||||
static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
|
||||
{
|
||||
unsigned int max_ports = mlxsw_core_max_ports(mlxsw_sp->core);
|
||||
@@ -3370,6 +3384,7 @@ static struct mlxsw_driver mlxsw_sp3_driver = {
|
||||
.basic_trap_groups_set = mlxsw_sp_basic_trap_groups_set,
|
||||
.port_split = mlxsw_sp_port_split,
|
||||
.port_unsplit = mlxsw_sp_port_unsplit,
|
||||
+ .ports_remove_selected = mlxsw_sp_ports_remove_selected,
|
||||
.sb_pool_get = mlxsw_sp_sb_pool_get,
|
||||
.sb_pool_set = mlxsw_sp_sb_pool_set,
|
||||
.sb_port_pool_get = mlxsw_sp_sb_port_pool_get,
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,152 @@
|
||||
From fd68af1d7a7c58c3f7db6ec95aba528137ec4c2d Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Mon, 3 Jan 2022 11:22:42 +0000
|
||||
Subject: [PATCH] mlxsw: spectrum: Add port to linecard mapping
|
||||
|
||||
For each port get slot_index using PMLP register. For ports residing
|
||||
on a linecard, identify it with the linecard by setting mapping
|
||||
using devlink_port_linecard_set() helper. Use linecard slot index for
|
||||
PMTDB register queries.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.c | 18 ++++++++++++++----
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.h | 3 ++-
|
||||
drivers/net/ethernet/mellanox/mlxsw/minimal.c | 2 +-
|
||||
drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 2 +-
|
||||
drivers/net/ethernet/mellanox/mlxsw/switchib.c | 2 +-
|
||||
drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 2 +-
|
||||
6 files changed, 20 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
index 2b4f9844b..68ef007ac 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
@@ -48,6 +48,7 @@ struct mlxsw_core_port {
|
||||
struct devlink_port devlink_port;
|
||||
void *port_driver_priv;
|
||||
u8 local_port;
|
||||
+ struct mlxsw_linecard *linecard;
|
||||
};
|
||||
|
||||
void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port)
|
||||
@@ -2723,7 +2724,7 @@ EXPORT_SYMBOL(mlxsw_core_res_get);
|
||||
|
||||
static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
|
||||
enum devlink_port_flavour flavour,
|
||||
- u32 port_number, bool split,
|
||||
+ u8 slot_index, u32 port_number, bool split,
|
||||
u32 split_port_subnumber,
|
||||
bool splittable, u32 lanes,
|
||||
const unsigned char *switch_id,
|
||||
@@ -2746,6 +2747,15 @@ static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
|
||||
attrs.switch_id.id_len = switch_id_len;
|
||||
mlxsw_core_port->local_port = local_port;
|
||||
devlink_port_attrs_set(devlink_port, &attrs);
|
||||
+ if (slot_index) {
|
||||
+ struct mlxsw_linecard *linecard;
|
||||
+
|
||||
+ linecard = mlxsw_linecard_get(mlxsw_core->linecards,
|
||||
+ slot_index);
|
||||
+ mlxsw_core_port->linecard = linecard;
|
||||
+ devlink_port_linecard_set(devlink_port,
|
||||
+ linecard->devlink_linecard);
|
||||
+ }
|
||||
err = devlink_port_register(devlink, devlink_port, local_port);
|
||||
if (err)
|
||||
memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
|
||||
@@ -2763,14 +2773,14 @@ static void __mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
|
||||
}
|
||||
|
||||
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
|
||||
- u32 port_number, bool split,
|
||||
+ u8 slot_index, u32 port_number, bool split,
|
||||
u32 split_port_subnumber,
|
||||
bool splittable, u32 lanes,
|
||||
const unsigned char *switch_id,
|
||||
unsigned char switch_id_len)
|
||||
{
|
||||
return __mlxsw_core_port_init(mlxsw_core, local_port,
|
||||
- DEVLINK_PORT_FLAVOUR_PHYSICAL,
|
||||
+ DEVLINK_PORT_FLAVOUR_PHYSICAL, slot_index,
|
||||
port_number, split, split_port_subnumber,
|
||||
splittable, lanes,
|
||||
switch_id, switch_id_len);
|
||||
@@ -2794,7 +2804,7 @@ int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
|
||||
|
||||
err = __mlxsw_core_port_init(mlxsw_core, MLXSW_PORT_CPU_PORT,
|
||||
DEVLINK_PORT_FLAVOUR_CPU,
|
||||
- 0, false, 0, false, 0,
|
||||
+ 0, 0, false, 0, false, 0,
|
||||
switch_id, switch_id_len);
|
||||
if (err)
|
||||
return err;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
index 70f97ef74..8e738ddb3 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
@@ -202,7 +202,8 @@ void mlxsw_core_lag_mapping_clear(struct mlxsw_core *mlxsw_core,
|
||||
|
||||
void *mlxsw_core_port_driver_priv(struct mlxsw_core_port *mlxsw_core_port);
|
||||
int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
|
||||
- u32 port_number, bool split, u32 split_port_subnumber,
|
||||
+ u8 slot_index, u32 port_number, bool split,
|
||||
+ u32 split_port_subnumber,
|
||||
bool splittable, u32 lanes,
|
||||
const unsigned char *switch_id,
|
||||
unsigned char switch_id_len);
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
index 104f1ba02..30925f573 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
@@ -210,7 +210,7 @@ mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u8 local_port, u8 module)
|
||||
struct net_device *dev;
|
||||
int err;
|
||||
|
||||
- err = mlxsw_core_port_init(mlxsw_m->core, local_port,
|
||||
+ err = mlxsw_core_port_init(mlxsw_m->core, local_port, 0,
|
||||
module + 1, false, 0, false,
|
||||
0, mlxsw_m->base_mac,
|
||||
sizeof(mlxsw_m->base_mac));
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
|
||||
index 75b418fbe..31eec40a3 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
|
||||
@@ -1399,7 +1399,7 @@ static int mlxsw_sp_port_create(struct mlxsw_sp *mlxsw_sp, u8 local_port,
|
||||
int err;
|
||||
|
||||
splittable = lanes > 1 && !split;
|
||||
- err = mlxsw_core_port_init(mlxsw_sp->core, local_port,
|
||||
+ err = mlxsw_core_port_init(mlxsw_sp->core, local_port, 0,
|
||||
port_mapping->module + 1, split,
|
||||
port_mapping->lane / lanes,
|
||||
splittable, lanes,
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchib.c b/drivers/net/ethernet/mellanox/mlxsw/switchib.c
|
||||
index 1e561132e..090b9a103 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/switchib.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchib.c
|
||||
@@ -280,7 +280,7 @@ static int mlxsw_sib_port_create(struct mlxsw_sib *mlxsw_sib, u8 local_port,
|
||||
{
|
||||
int err;
|
||||
|
||||
- err = mlxsw_core_port_init(mlxsw_sib->core, local_port,
|
||||
+ err = mlxsw_core_port_init(mlxsw_sib->core, local_port, 0,
|
||||
module + 1, false, 0, false, 0,
|
||||
mlxsw_sib->hw_id, sizeof(mlxsw_sib->hw_id));
|
||||
if (err) {
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
|
||||
index 131b2a53d..bf8a54776 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c
|
||||
@@ -1085,7 +1085,7 @@ static int mlxsw_sx_port_eth_create(struct mlxsw_sx *mlxsw_sx, u8 local_port,
|
||||
{
|
||||
int err;
|
||||
|
||||
- err = mlxsw_core_port_init(mlxsw_sx->core, local_port,
|
||||
+ err = mlxsw_core_port_init(mlxsw_sx->core, local_port, 0,
|
||||
module + 1, false, 0, false, 0,
|
||||
mlxsw_sx->hw_id, sizeof(mlxsw_sx->hw_id));
|
||||
if (err) {
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,105 @@
|
||||
From a719653b2a7f0943e757c04dab73df324e469436 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Wed, 12 May 2021 22:57:37 +0300
|
||||
Subject: [PATCH] mlxsw: reg: Introduce Management Temperature Extended
|
||||
Capabilities Register
|
||||
|
||||
Introduce new register MTECR (Management Temperature Extended
|
||||
Capabilities Register). This register exposes the capabilities of the
|
||||
device and system temperature sensing. It provides information for
|
||||
all possible temperature sensors that are on the system.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 67 +++++++++++++++++++++++
|
||||
1 file changed, 67 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index 89b21910f..c1ce0b42e 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -10297,6 +10297,72 @@ mlxsw_reg_mgpir_unpack(char *payload, u8 *num_of_devices,
|
||||
*num_of_slots = mlxsw_reg_mgpir_num_of_slots_get(payload);
|
||||
}
|
||||
|
||||
+/* MTECR - Management Temperature Extended Capabilities Register
|
||||
+ * -------------------------------------------------------------
|
||||
+ * MTECR register exposes the capabilities of the device and system
|
||||
+ * temperature sensing.
|
||||
+ */
|
||||
+#define MLXSW_REG_MTECR_ID 0x9109
|
||||
+#define MLXSW_REG_MTECR_LEN 0x60
|
||||
+#define MLXSW_REG_MTECR_SENSOR_MAP_LEN 0x58
|
||||
+
|
||||
+MLXSW_REG_DEFINE(mtecr, MLXSW_REG_MTECR_ID, MLXSW_REG_MTECR_LEN);
|
||||
+
|
||||
+/* reg_mtecr_last_sensor.
|
||||
+ * Last sensor index that is available in the system to read from.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mtecr, last_sensor, 0x00, 16, 12);
|
||||
+
|
||||
+/* reg_mtecr_sensor_count.
|
||||
+ * Number of sensors supported by the device.
|
||||
+ * This includes the ASIC, ambient sensors, Gearboxes etc.
|
||||
+ * QSFP module sensors are not included.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mtecr, sensor_count, 0x00, 0, 12);
|
||||
+
|
||||
+/* reg_mtecr_slot_index.
|
||||
+ * Slot index (0: Main board).
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mtecr, slot_index, 0x04, 28, 4);
|
||||
+
|
||||
+/* reg_mtecr_internal_sensor_count.
|
||||
+ * Number of sensors supported by the device that are in the ASIC.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mtecr, internal_sensor_count, 0x04, 0, 7);
|
||||
+
|
||||
+/* reg_mtecr_sensor_map.
|
||||
+ * Mapping of system sensors supported by the device. Each bit represents a
|
||||
+ * sensor. This field is size variable based on the last_sensor field and in
|
||||
+ * granularity of 32 bits.
|
||||
+ * 0: Not connected or not supported
|
||||
+ * 1: Supports temperature measurements
|
||||
+ *
|
||||
+ */
|
||||
+MLXSW_ITEM_BIT_ARRAY(reg, mtecr, sensor_map, 0x08, MLXSW_REG_MTECR_SENSOR_MAP_LEN, 1);
|
||||
+
|
||||
+static inline void mlxsw_reg_mtecr_pack(char *payload, u8 slot_index)
|
||||
+{
|
||||
+ MLXSW_REG_ZERO(mtecr, payload);
|
||||
+ mlxsw_reg_mtecr_slot_index_set(payload, slot_index);
|
||||
+}
|
||||
+
|
||||
+static inline void mlxsw_reg_mtecr_unpack(char *payload, u16 *sensor_count,
|
||||
+ u16 *last_sensor,
|
||||
+ u8 *internal_sensor_count)
|
||||
+{
|
||||
+ if (sensor_count)
|
||||
+ *sensor_count = mlxsw_reg_mtecr_sensor_count_get(payload);
|
||||
+ if (last_sensor)
|
||||
+ *last_sensor = mlxsw_reg_mtecr_last_sensor_get(payload);
|
||||
+ if (internal_sensor_count)
|
||||
+ *internal_sensor_count =
|
||||
+ mlxsw_reg_mtecr_internal_sensor_count_get(payload);
|
||||
+}
|
||||
+
|
||||
/* MBCT - Management Binary Code Transfer Register
|
||||
* -----------------------------------------------
|
||||
* This register allows to transfer binary codes from the Host to
|
||||
@@ -11884,6 +11950,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
|
||||
MLXSW_REG(mtptpt),
|
||||
MLXSW_REG(mfgd),
|
||||
MLXSW_REG(mgpir),
|
||||
+ MLXSW_REG(mtecr),
|
||||
MLXSW_REG(mbct),
|
||||
MLXSW_REG(mddq),
|
||||
MLXSW_REG(mddc),
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,113 @@
|
||||
From 1ea36b4966e21d9d599da7e4e3195364841d9318 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Mon, 13 Dec 2021 12:29:10 +0000
|
||||
Subject: [PATCH] mlxsw: core: Add APIs for thermal sensor mapping
|
||||
|
||||
Add APIs mlxsw_env_sensor_map_init() and mlxsw_env_sensor_map_fini(().
|
||||
The purpose of the first one is to allocate and create thermal sensors
|
||||
mapping for temperature sensors, presented within the main board or
|
||||
line card. It obtains mapping information from the Management
|
||||
Temperature Extended Capabilities Register, by specifying the relevant
|
||||
device by the number of a slot at which this device is located. Slot
|
||||
zero is used for the main board. The second API just free allocated
|
||||
memory.
|
||||
The motivation is to create dynamic mapping for gearbox thermal sensors
|
||||
access.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_env.c | 47 +++++++++++++++++++
|
||||
.../net/ethernet/mellanox/mlxsw/core_env.h | 12 +++++
|
||||
2 files changed, 59 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index 94d44db1a..c27cd424b 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -626,6 +626,53 @@ mlxsw_env_set_module_power_mode(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_env_set_module_power_mode);
|
||||
|
||||
+int mlxsw_env_sensor_map_create(struct mlxsw_core *core,
|
||||
+ const struct mlxsw_bus_info *bus_info,
|
||||
+ u8 slot_index,
|
||||
+ struct mlxsw_env_gearbox_sensors_map *map)
|
||||
+{
|
||||
+ char mtecr_pl[MLXSW_REG_MTECR_LEN];
|
||||
+ u16 last_sensor, offset;
|
||||
+ int i, bit, err;
|
||||
+
|
||||
+ mlxsw_reg_mtecr_pack(mtecr_pl, slot_index);
|
||||
+ err = mlxsw_reg_query(core, MLXSW_REG(mtecr), mtecr_pl);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ mlxsw_reg_mtecr_unpack(mtecr_pl, &map->sensor_count, &last_sensor, NULL);
|
||||
+ if (!map->sensor_count) {
|
||||
+ map->sensor_bit_map = NULL;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Fill out sensor mapping array. */
|
||||
+ map->sensor_bit_map = kcalloc(map->sensor_count, sizeof(u16), GFP_KERNEL);
|
||||
+ if (!map->sensor_bit_map)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ /* Sensors bitmap is size variable based on the last_sensor field and
|
||||
+ * in granularity of 32 bits. Calculate an offset in payload buffer to
|
||||
+ * start from.
|
||||
+ */
|
||||
+ offset = MLXSW_REG_MTECR_SENSOR_MAP_LEN * 8 - last_sensor - 1;
|
||||
+ offset -= offset % 32;
|
||||
+ for (bit = 0, i = 0; bit <= last_sensor && i < map->sensor_count; bit++) {
|
||||
+ if (mlxsw_reg_mtecr_sensor_map_get(mtecr_pl, bit + offset))
|
||||
+ map->sensor_bit_map[i++] = bit;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(mlxsw_env_sensor_map_create);
|
||||
+
|
||||
+void mlxsw_env_sensor_map_destroy(const struct mlxsw_bus_info *bus_info,
|
||||
+ u16 *sensor_bit_map)
|
||||
+{
|
||||
+ kfree(sensor_bit_map);
|
||||
+}
|
||||
+EXPORT_SYMBOL(mlxsw_env_sensor_map_destroy);
|
||||
+
|
||||
static int mlxsw_env_module_has_temp_sensor(struct mlxsw_core *mlxsw_core,
|
||||
u8 slot_index, u8 module,
|
||||
bool *p_has_temp_sensor)
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.h b/drivers/net/ethernet/mellanox/mlxsw/core_env.h
|
||||
index 03d027870..336c9ee57 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.h
|
||||
@@ -9,6 +9,11 @@
|
||||
struct ethtool_modinfo;
|
||||
struct ethtool_eeprom;
|
||||
|
||||
+struct mlxsw_env_gearbox_sensors_map {
|
||||
+ u16 sensor_count;
|
||||
+ u16 *sensor_bit_map;
|
||||
+};
|
||||
+
|
||||
int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core,
|
||||
u8 slot_index, int module, int off,
|
||||
int *temp);
|
||||
@@ -21,6 +26,13 @@ int mlxsw_env_get_module_eeprom(struct net_device *netdev,
|
||||
int module, struct ethtool_eeprom *ee,
|
||||
u8 *data);
|
||||
|
||||
+int mlxsw_env_sensor_map_create(struct mlxsw_core *core,
|
||||
+ const struct mlxsw_bus_info *bus_info,
|
||||
+ u8 slot_index,
|
||||
+ struct mlxsw_env_gearbox_sensors_map *map);
|
||||
+void mlxsw_env_sensor_map_destroy(const struct mlxsw_bus_info *bus_info,
|
||||
+ u16 *sensor_bit_map);
|
||||
+
|
||||
int
|
||||
mlxsw_env_get_module_eeprom_by_page(struct mlxsw_core *mlxsw_core,
|
||||
u8 slot_index, u8 module,
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,126 @@
|
||||
From 46563dcd511270f67a9e771497ccfc73907aa4d3 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Thu, 25 Feb 2021 10:17:53 +0100
|
||||
Subject: [PATCH] mlxsw: reg: Add Management DownStream Device Tunneling
|
||||
Register
|
||||
|
||||
The MDDT register allows deliver query and request messages
|
||||
(PRM registers, commands) to a DownStream device.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/reg.h | 91 +++++++++++++++++++++++
|
||||
1 file changed, 91 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
index c1ce0b42e..f8c828e05 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
|
||||
@@ -10482,6 +10482,96 @@ mlxsw_reg_mbct_unpack(const char *payload, u8 *p_slot_index,
|
||||
*p_fsm_state = mlxsw_reg_mbct_fsm_state_get(payload);
|
||||
}
|
||||
|
||||
+/* MDDT - Management DownStream Device Tunneling Register
|
||||
+ * ------------------------------------------------------
|
||||
+ * This register allows deliver query and request messages (PRM registers,
|
||||
+ * commands) to a DownStream device.
|
||||
+ */
|
||||
+#define MLXSW_REG_MDDT_ID 0x9160
|
||||
+#define MLXSW_REG_MDDT_LEN 0x110
|
||||
+
|
||||
+MLXSW_REG_DEFINE(mddt, MLXSW_REG_MDDT_ID, MLXSW_REG_MDDT_LEN);
|
||||
+
|
||||
+/* reg_mddt_slot_index
|
||||
+ * Slot index.
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+
|
||||
+MLXSW_ITEM32(reg, mddt, slot_index, 0x00, 8, 4);
|
||||
+
|
||||
+/* reg_mddt_device_index
|
||||
+ * Device index.
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddt, device_index, 0x00, 0, 8);
|
||||
+
|
||||
+/* reg_mddt_read_size
|
||||
+ * Read size in D-Words.
|
||||
+ * Access: OP
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddt, read_size, 0x04, 24, 8);
|
||||
+
|
||||
+/* reg_mddt_write_size
|
||||
+ * Write size in D-Words.
|
||||
+ * Access: OP
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddt, write_size, 0x04, 16, 8);
|
||||
+
|
||||
+enum mlxsw_reg_mddt_status {
|
||||
+ MLXSW_REG_MDDT_STATUS_OK,
|
||||
+};
|
||||
+
|
||||
+/* reg_mddt_status
|
||||
+ * Return code of the Downstream Device to the register that was sent.
|
||||
+ * Access: RO
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddt, status, 0x0C, 24, 8);
|
||||
+
|
||||
+enum mlxsw_reg_mddt_method {
|
||||
+ MLXSW_REG_MDDT_METHOD_QUERY,
|
||||
+ MLXSW_REG_MDDT_METHOD_WRITE,
|
||||
+};
|
||||
+
|
||||
+/* reg_mddt_method
|
||||
+ * Access: OP
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddt, method, 0x0C, 22, 2);
|
||||
+
|
||||
+/* reg_mddt_register_id
|
||||
+ * Access: Index
|
||||
+ */
|
||||
+MLXSW_ITEM32(reg, mddt, register_id, 0x0C, 0, 16);
|
||||
+
|
||||
+#define MLXSW_REG_MDDT_PAYLOAD_OFFSET 0x0C
|
||||
+#define MLXSW_REG_MDDT_PRM_REGISTER_HEADER_LEN 4
|
||||
+
|
||||
+static inline char *mlxsw_reg_mddt_inner_payload(char *payload)
|
||||
+{
|
||||
+ return payload + MLXSW_REG_MDDT_PAYLOAD_OFFSET +
|
||||
+ MLXSW_REG_MDDT_PRM_REGISTER_HEADER_LEN;
|
||||
+}
|
||||
+
|
||||
+static inline void mlxsw_reg_mddt_pack(char *payload, u8 slot_index,
|
||||
+ u8 device_index,
|
||||
+ enum mlxsw_reg_mddt_method method,
|
||||
+ const struct mlxsw_reg_info *reg,
|
||||
+ char **inner_payload)
|
||||
+{
|
||||
+ int len = reg->len + MLXSW_REG_MDDT_PRM_REGISTER_HEADER_LEN;
|
||||
+
|
||||
+ if (WARN_ON(len + MLXSW_REG_MDDT_PAYLOAD_OFFSET > MLXSW_REG_MDDT_LEN))
|
||||
+ len = MLXSW_REG_MDDT_LEN - MLXSW_REG_MDDT_PAYLOAD_OFFSET;
|
||||
+
|
||||
+ MLXSW_REG_ZERO(mddt, payload);
|
||||
+ mlxsw_reg_mddt_slot_index_set(payload, slot_index);
|
||||
+ mlxsw_reg_mddt_device_index_set(payload, device_index);
|
||||
+ mlxsw_reg_mddt_method_set(payload, method);
|
||||
+ mlxsw_reg_mddt_register_id_set(payload, reg->id);
|
||||
+ mlxsw_reg_mddt_read_size_set(payload, len / 4);
|
||||
+ mlxsw_reg_mddt_write_size_set(payload, len / 4);
|
||||
+ *inner_payload = mlxsw_reg_mddt_inner_payload(payload);
|
||||
+}
|
||||
+
|
||||
/* MDDQ - Management DownStream Device Query Register
|
||||
* --------------------------------------------------
|
||||
* This register allows to query the DownStream device properties. The desired
|
||||
@@ -11952,6 +12042,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
|
||||
MLXSW_REG(mgpir),
|
||||
MLXSW_REG(mtecr),
|
||||
MLXSW_REG(mbct),
|
||||
+ MLXSW_REG(mddt),
|
||||
MLXSW_REG(mddq),
|
||||
MLXSW_REG(mddc),
|
||||
MLXSW_REG(mfde),
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,224 @@
|
||||
From 70bc337251ccbfe095a89457ded233c3ad5b9bbc Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Fri, 26 Feb 2021 13:15:09 +0100
|
||||
Subject: [PATCH] mlxsw: core_linecards: Probe devices for provisioned line
|
||||
card and attach them
|
||||
|
||||
In case the line card is provisioned, go over all possible existing
|
||||
devices (gearboxes) on it and attach them, so devlink core is aware of
|
||||
them. In case the device can be flashed, register mlxsw flash component.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.h | 3 +
|
||||
.../ethernet/mellanox/mlxsw/core_linecards.c | 113 ++++++++++++++++--
|
||||
2 files changed, 108 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
index 8e738ddb3..593470d14 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
@@ -533,6 +533,9 @@ struct mlxsw_linecard {
|
||||
bool ready;
|
||||
bool active;
|
||||
bool unprovision_done;
|
||||
+ u16 hw_revision;
|
||||
+ u16 ini_version;
|
||||
+ struct list_head device_list;
|
||||
};
|
||||
|
||||
struct mlxsw_linecard_types_info;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
index 134437f49..720ad6d82 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
@@ -64,27 +64,120 @@ static const char *mlxsw_linecard_type_name(struct mlxsw_linecard *linecard)
|
||||
return linecard->read_name;
|
||||
}
|
||||
|
||||
-static void mlxsw_linecard_provision_fail(struct mlxsw_linecard *linecard)
|
||||
+struct mlxsw_linecard_device {
|
||||
+ struct list_head list;
|
||||
+ u8 index;
|
||||
+ struct mlxsw_linecard *linecard;
|
||||
+ struct devlink_linecard_device *devlink_device;
|
||||
+};
|
||||
+
|
||||
+static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecard *linecard,
|
||||
+ u8 device_index, bool flash_owner)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device *device;
|
||||
+ int err;
|
||||
+
|
||||
+ device = kzalloc(sizeof(*device), GFP_KERNEL);
|
||||
+ if (!device)
|
||||
+ return -ENOMEM;
|
||||
+ device->index = device_index;
|
||||
+ device->linecard = linecard;
|
||||
+
|
||||
+ device->devlink_device = devlink_linecard_device_create(linecard->devlink_linecard,
|
||||
+ device_index,
|
||||
+ NULL, NULL);
|
||||
+ if (IS_ERR(device->devlink_device)) {
|
||||
+ err = PTR_ERR(device->devlink_device);
|
||||
+ goto err_devlink_linecard_device_attach;
|
||||
+ }
|
||||
+
|
||||
+ list_add_tail(&device->list, &linecard->device_list);
|
||||
+ return 0;
|
||||
+
|
||||
+err_devlink_linecard_device_attach:
|
||||
+ kfree(device);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_linecard_device_detach(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecard *linecard,
|
||||
+ struct mlxsw_linecard_device *device)
|
||||
+{
|
||||
+ list_del(&device->list);
|
||||
+ devlink_linecard_device_destroy(linecard->devlink_linecard,
|
||||
+ device->devlink_device);
|
||||
+ kfree(device);
|
||||
+}
|
||||
+
|
||||
+static int mlxsw_linecard_devices_attach(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecard *linecard)
|
||||
+{
|
||||
+ char mddq_pl[MLXSW_REG_MDDQ_LEN];
|
||||
+ bool flash_owner;
|
||||
+ bool data_valid;
|
||||
+ u8 device_index;
|
||||
+ u8 msg_seq = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ do {
|
||||
+ mlxsw_reg_mddq_device_info_pack(mddq_pl, linecard->slot_index,
|
||||
+ msg_seq);
|
||||
+ err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mddq), mddq_pl);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ mlxsw_reg_mddq_device_info_unpack(mddq_pl, &msg_seq,
|
||||
+ &data_valid, &flash_owner,
|
||||
+ &device_index, NULL,
|
||||
+ NULL, NULL);
|
||||
+ if (!data_valid)
|
||||
+ break;
|
||||
+ err = mlxsw_linecard_device_attach(mlxsw_core, linecard,
|
||||
+ device_index, flash_owner);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ } while (msg_seq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_linecard_devices_detach(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecard *linecard)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device *device, *tmp;
|
||||
+
|
||||
+ list_for_each_entry_safe(device, tmp, &linecard->device_list, list)
|
||||
+ mlxsw_linecard_device_detach(mlxsw_core, linecard, device);
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_linecard_provision_fail(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecard *linecard)
|
||||
{
|
||||
linecard->provisioned = false;
|
||||
linecard->ready = false;
|
||||
linecard->active = false;
|
||||
+ mlxsw_linecard_devices_detach(mlxsw_core, linecard);
|
||||
devlink_linecard_provision_fail(linecard->devlink_linecard);
|
||||
}
|
||||
|
||||
static int
|
||||
-mlxsw_linecard_provision_set(struct mlxsw_linecards *linecards,
|
||||
+mlxsw_linecard_provision_set(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecards *linecards,
|
||||
struct mlxsw_linecard *linecard,
|
||||
enum mlxsw_reg_mddq_card_type card_type)
|
||||
{
|
||||
const char *type = mlxsw_linecard_types_lookup(linecards, card_type);
|
||||
+ int err;
|
||||
|
||||
if (!type)
|
||||
type = mlxsw_linecard_type_name(linecard);
|
||||
if (!type) {
|
||||
- mlxsw_linecard_provision_fail(linecard);
|
||||
+ mlxsw_linecard_provision_fail(mlxsw_core, linecard);
|
||||
return -EINVAL;
|
||||
}
|
||||
+ err = mlxsw_linecard_devices_attach(mlxsw_core, linecard);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
linecard->provisioned = true;
|
||||
devlink_linecard_provision_set(linecard->devlink_linecard, type);
|
||||
return 0;
|
||||
@@ -93,6 +186,8 @@ mlxsw_linecard_provision_set(struct mlxsw_linecards *linecards,
|
||||
static void mlxsw_linecard_provision_clear(struct mlxsw_linecard *linecard)
|
||||
{
|
||||
linecard->provisioned = false;
|
||||
+ mlxsw_linecard_devices_detach(linecard->linecards->mlxsw_core,
|
||||
+ linecard);
|
||||
devlink_linecard_provision_clear(linecard->devlink_linecard);
|
||||
}
|
||||
|
||||
@@ -169,8 +264,8 @@ static int __mlxsw_linecard_status_process(struct mlxsw_core *mlxsw_core,
|
||||
mutex_lock(&linecard->lock);
|
||||
|
||||
if (provisioned && linecard->provisioned != provisioned) {
|
||||
- err = mlxsw_linecard_provision_set(linecards, linecard,
|
||||
- card_type);
|
||||
+ err = mlxsw_linecard_provision_set(mlxsw_core, linecards,
|
||||
+ linecard, card_type);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
@@ -353,7 +448,7 @@ int mlxsw_linecard_bct_process(struct mlxsw_core *mlxsw_core,
|
||||
|
||||
fix_fsm_err_out:
|
||||
mlxsw_linecard_fix_fsm_state(linecard, fsm_state);
|
||||
- mlxsw_linecard_provision_fail(linecard);
|
||||
+ mlxsw_linecard_provision_fail(mlxsw_core, linecard);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(mlxsw_linecard_bct_process);
|
||||
@@ -415,7 +510,7 @@ static int mlxsw_linecard_provision(struct devlink_linecard *devlink_linecard,
|
||||
fix_fsm_err_out:
|
||||
mlxsw_linecard_fix_fsm_state(linecard, fsm_state);
|
||||
err_out:
|
||||
- mlxsw_linecard_provision_fail(linecard);
|
||||
+ mlxsw_linecard_provision_fail(mlxsw_core, linecard);
|
||||
out:
|
||||
mutex_unlock(&linecard->lock);
|
||||
return err;
|
||||
@@ -488,7 +583,7 @@ static int mlxsw_linecard_unprovision(struct devlink_linecard *devlink_linecard,
|
||||
fix_fsm_err_out:
|
||||
mlxsw_linecard_fix_fsm_state(linecard, fsm_state);
|
||||
err_out:
|
||||
- mlxsw_linecard_provision_fail(linecard);
|
||||
+ mlxsw_linecard_provision_fail(mlxsw_core, linecard);
|
||||
out:
|
||||
mutex_unlock(&linecard->lock);
|
||||
return err;
|
||||
@@ -536,6 +631,7 @@ static int mlxsw_linecard_init(struct mlxsw_core *mlxsw_core,
|
||||
linecard->slot_index = slot_index;
|
||||
linecard->linecards = linecards;
|
||||
mutex_init(&linecard->lock);
|
||||
+ INIT_LIST_HEAD(&linecard->device_list);
|
||||
|
||||
devlink_linecard = devlink_linecard_create(priv_to_devlink(mlxsw_core),
|
||||
slot_index, &mlxsw_linecard_ops,
|
||||
@@ -613,6 +709,7 @@ static void mlxsw_linecard_fini(struct mlxsw_core *mlxsw_core,
|
||||
struct mlxsw_linecard *linecard;
|
||||
|
||||
linecard = mlxsw_linecard_get(linecards, slot_index);
|
||||
+ mlxsw_linecard_devices_detach(mlxsw_core, linecard);
|
||||
devlink_linecard_destroy(linecard->devlink_linecard);
|
||||
mutex_destroy(&linecard->lock);
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,177 @@
|
||||
From 8279b3c273fac860394fb922c70c336993e6f087 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Thu, 10 Jun 2021 15:32:00 +0200
|
||||
Subject: [PATCH] mlxsw: core_linecards: Expose device FW version over device
|
||||
info
|
||||
|
||||
Extend MDDQ to obtain FW version of line card device and implement
|
||||
device_info_get() op to fill up the info with that.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
.../ethernet/mellanox/mlxsw/core_linecards.c | 104 +++++++++++++++++-
|
||||
1 file changed, 100 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
index 720ad6d82..cb872f918 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
@@ -64,13 +64,31 @@ static const char *mlxsw_linecard_type_name(struct mlxsw_linecard *linecard)
|
||||
return linecard->read_name;
|
||||
}
|
||||
|
||||
+struct mlxsw_linecard_device_info {
|
||||
+ u16 fw_major;
|
||||
+ u16 fw_minor;
|
||||
+ u16 fw_sub_minor;
|
||||
+};
|
||||
+
|
||||
struct mlxsw_linecard_device {
|
||||
struct list_head list;
|
||||
u8 index;
|
||||
struct mlxsw_linecard *linecard;
|
||||
struct devlink_linecard_device *devlink_device;
|
||||
+ struct mlxsw_linecard_device_info info;
|
||||
};
|
||||
|
||||
+static struct mlxsw_linecard_device *
|
||||
+mlxsw_linecard_device_lookup(struct mlxsw_linecard *linecard, u8 index)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device *device;
|
||||
+
|
||||
+ list_for_each_entry(device, &linecard->device_list, list)
|
||||
+ if (device->index == index)
|
||||
+ return device;
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
|
||||
struct mlxsw_linecard *linecard,
|
||||
u8 device_index, bool flash_owner)
|
||||
@@ -86,7 +104,7 @@ static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
|
||||
|
||||
device->devlink_device = devlink_linecard_device_create(linecard->devlink_linecard,
|
||||
device_index,
|
||||
- NULL, NULL);
|
||||
+ NULL, device);
|
||||
if (IS_ERR(device->devlink_device)) {
|
||||
err = PTR_ERR(device->devlink_device);
|
||||
goto err_devlink_linecard_device_attach;
|
||||
@@ -150,6 +168,71 @@ static void mlxsw_linecard_devices_detach(struct mlxsw_core *mlxsw_core,
|
||||
mlxsw_linecard_device_detach(mlxsw_core, linecard, device);
|
||||
}
|
||||
|
||||
+static void mlxsw_linecard_device_update(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecard *linecard,
|
||||
+ u8 device_index,
|
||||
+ struct mlxsw_linecard_device_info *info)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device *device;
|
||||
+
|
||||
+ device = mlxsw_linecard_device_lookup(linecard, device_index);
|
||||
+ if (!device)
|
||||
+ return;
|
||||
+ device->info = *info;
|
||||
+}
|
||||
+
|
||||
+static int mlxsw_linecard_devices_update(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecard *linecard)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_info info;
|
||||
+ char mddq_pl[MLXSW_REG_MDDQ_LEN];
|
||||
+ bool data_valid;
|
||||
+ u8 device_index;
|
||||
+ u8 msg_seq = 0;
|
||||
+ int err;
|
||||
+
|
||||
+ do {
|
||||
+ mlxsw_reg_mddq_device_info_pack(mddq_pl, linecard->slot_index,
|
||||
+ msg_seq);
|
||||
+ err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mddq), mddq_pl);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ mlxsw_reg_mddq_device_info_unpack(mddq_pl, &msg_seq,
|
||||
+ &data_valid, NULL,
|
||||
+ &device_index,
|
||||
+ &info.fw_major,
|
||||
+ &info.fw_minor,
|
||||
+ &info.fw_sub_minor);
|
||||
+ if (!data_valid)
|
||||
+ break;
|
||||
+ mlxsw_linecard_device_update(mlxsw_core, linecard,
|
||||
+ device_index, &info);
|
||||
+ } while (msg_seq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mlxsw_linecard_device_info_get(struct devlink_linecard_device *devlink_linecard_device,
|
||||
+ void *priv, struct devlink_info_req *req,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device *device = priv;
|
||||
+ struct mlxsw_linecard_device_info *info;
|
||||
+ char buf[32];
|
||||
+
|
||||
+ if (!device->linecard->active)
|
||||
+ return 0;
|
||||
+
|
||||
+ info = &device->info;
|
||||
+
|
||||
+ sprintf(buf, "%u.%u.%u", info->fw_major, info->fw_minor,
|
||||
+ info->fw_sub_minor);
|
||||
+ return devlink_info_version_running_put(req,
|
||||
+ DEVLINK_INFO_VERSION_GENERIC_FW,
|
||||
+ buf);
|
||||
+}
|
||||
+
|
||||
static void mlxsw_linecard_provision_fail(struct mlxsw_core *mlxsw_core,
|
||||
struct mlxsw_linecard *linecard)
|
||||
{
|
||||
@@ -219,10 +302,18 @@ static int mlxsw_linecard_ready_clear(struct mlxsw_core *mlxsw_core,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void mlxsw_linecard_active_set(struct mlxsw_linecard *linecard)
|
||||
+static int mlxsw_linecard_active_set(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecard *linecard,
|
||||
+ u16 hw_revision, u16 ini_version)
|
||||
{
|
||||
+ int err;
|
||||
+
|
||||
+ err = mlxsw_linecard_devices_update(mlxsw_core, linecard);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
linecard->active = true;
|
||||
devlink_linecard_activate(linecard->devlink_linecard);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void mlxsw_linecard_active_clear(struct mlxsw_linecard *linecard)
|
||||
@@ -278,8 +369,12 @@ static int __mlxsw_linecard_status_process(struct mlxsw_core *mlxsw_core,
|
||||
}
|
||||
|
||||
if (!process_provision_only && !linecard->unprovision_done && active &&
|
||||
- linecard->active != active && linecard->ready)
|
||||
- mlxsw_linecard_active_set(linecard);
|
||||
+ linecard->active != active && linecard->ready) {
|
||||
+ err = mlxsw_linecard_active_set(mlxsw_core, linecard,
|
||||
+ hw_revision, ini_version);
|
||||
+ if (err)
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
if (!process_provision_only && !active && linecard->active != active)
|
||||
mlxsw_linecard_active_clear(linecard);
|
||||
@@ -617,6 +712,7 @@ static const struct devlink_linecard_ops mlxsw_linecard_ops = {
|
||||
.unprovision = mlxsw_linecard_unprovision,
|
||||
.types_count = mlxsw_linecard_types_count,
|
||||
.types_get = mlxsw_linecard_types_get,
|
||||
+ .device_info_get = mlxsw_linecard_device_info_get,
|
||||
};
|
||||
|
||||
static int mlxsw_linecard_init(struct mlxsw_core *mlxsw_core,
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,243 @@
|
||||
From a1421cadee435540d09a5526525f692821a271cd Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Fri, 26 Feb 2021 18:40:28 +0100
|
||||
Subject: [PATCH] mlxsw: core: Introduce flash update components
|
||||
|
||||
Introduce an infrastructure allowing to have multiple components for
|
||||
flashing purposes that can be registered from inside the driver. Convert
|
||||
the existing "no component" flash update to use the new infra.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.c | 117 +++++++++++++++++++--
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.h | 12 +++
|
||||
include/net/devlink.h | 3 +
|
||||
3 files changed, 125 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
index 68ef007ac..f55071982 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
@@ -91,6 +91,10 @@ struct mlxsw_core {
|
||||
struct devlink_health_reporter *fw_fatal;
|
||||
} health;
|
||||
struct mlxsw_env *env;
|
||||
+ struct list_head flash_component_list;
|
||||
+ struct mutex flash_update_lock; /* Protects component list and component
|
||||
+ * callbacks.
|
||||
+ */
|
||||
unsigned long driver_priv[];
|
||||
/* driver_priv has to be always the last item */
|
||||
};
|
||||
@@ -1113,21 +1117,101 @@ static int mlxsw_core_fw_rev_validate(struct mlxsw_core *mlxsw_core,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int mlxsw_core_fw_flash_cb(struct mlxsw_core *mlxsw_core,
|
||||
+ const struct firmware *firmware,
|
||||
+ struct netlink_ext_ack *extack, void *priv)
|
||||
+{
|
||||
+ return mlxsw_core_fw_flash(mlxsw_core, firmware, extack);
|
||||
+}
|
||||
+
|
||||
+struct mlxsw_core_flash_component {
|
||||
+ struct list_head list;
|
||||
+ const char *name;
|
||||
+ mlxsw_core_flash_update_cb cb;
|
||||
+ void *priv;
|
||||
+};
|
||||
+
|
||||
+static struct mlxsw_core_flash_component *
|
||||
+mlxsw_core_flash_component_lookup(struct mlxsw_core *mlxsw_core,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ struct mlxsw_core_flash_component *component;
|
||||
+
|
||||
+ list_for_each_entry(component, &mlxsw_core->flash_component_list,
|
||||
+ list) {
|
||||
+ if ((name && component->name &&
|
||||
+ !strcmp(name, component->name)) ||
|
||||
+ (!name && !component->name))
|
||||
+ return component;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static int mlxsw_core_fw_flash_update(struct mlxsw_core *mlxsw_core,
|
||||
struct devlink_flash_update_params *params,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
- const struct firmware *firmware;
|
||||
+ struct mlxsw_core_flash_component *component;
|
||||
int err;
|
||||
|
||||
- err = request_firmware_direct(&firmware, params->file_name, mlxsw_core->bus_info->dev);
|
||||
- if (err)
|
||||
- return err;
|
||||
- err = mlxsw_core_fw_flash(mlxsw_core, firmware, extack);
|
||||
- release_firmware(firmware);
|
||||
+ mutex_lock(&mlxsw_core->flash_update_lock);
|
||||
+ component = mlxsw_core_flash_component_lookup(mlxsw_core,
|
||||
+ params->component);
|
||||
+ if (!component) {
|
||||
+ NL_SET_ERR_MSG_MOD(extack, "Component does not exist");
|
||||
+ err = -ENOENT;
|
||||
+ goto unlock;
|
||||
+ }
|
||||
+ err = component->cb(mlxsw_core, params->fw, extack, component->priv);
|
||||
+unlock:
|
||||
+ mutex_unlock(&mlxsw_core->flash_update_lock);
|
||||
+ return err;
|
||||
+}
|
||||
|
||||
+int mlxsw_core_flash_component_register(struct mlxsw_core *mlxsw_core,
|
||||
+ const char *name,
|
||||
+ mlxsw_core_flash_update_cb cb,
|
||||
+ void *priv)
|
||||
+{
|
||||
+ struct mlxsw_core_flash_component *component;
|
||||
+ int err = 0;
|
||||
+
|
||||
+ mutex_lock(&mlxsw_core->flash_update_lock);
|
||||
+ component = mlxsw_core_flash_component_lookup(mlxsw_core, name);
|
||||
+ if (WARN_ON(component)) {
|
||||
+ err = -EEXIST;
|
||||
+ goto unlock;
|
||||
+ }
|
||||
+ component = kzalloc(sizeof(*component), GFP_KERNEL);
|
||||
+ if (!component) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto unlock;
|
||||
+ }
|
||||
+ component->name = name;
|
||||
+ component->cb = cb;
|
||||
+ component->priv = priv;
|
||||
+ list_add_tail(&component->list, &mlxsw_core->flash_component_list);
|
||||
+unlock:
|
||||
+ mutex_unlock(&mlxsw_core->flash_update_lock);
|
||||
return err;
|
||||
}
|
||||
+EXPORT_SYMBOL(mlxsw_core_flash_component_register);
|
||||
+
|
||||
+void mlxsw_core_flash_component_unregister(struct mlxsw_core *mlxsw_core,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ struct mlxsw_core_flash_component *component;
|
||||
+
|
||||
+ mutex_lock(&mlxsw_core->flash_update_lock);
|
||||
+ component = mlxsw_core_flash_component_lookup(mlxsw_core, name);
|
||||
+ if (WARN_ON(!component))
|
||||
+ goto unlock;
|
||||
+ list_del(&component->list);
|
||||
+unlock:
|
||||
+ mutex_unlock(&mlxsw_core->flash_update_lock);
|
||||
+ kfree(component);
|
||||
+}
|
||||
+EXPORT_SYMBOL(mlxsw_core_flash_component_unregister);
|
||||
|
||||
static int mlxsw_core_devlink_param_fw_load_policy_validate(struct devlink *devlink, u32 id,
|
||||
union devlink_param_value val,
|
||||
@@ -1572,6 +1656,7 @@ mlxsw_devlink_trap_policer_counter_get(struct devlink *devlink,
|
||||
}
|
||||
|
||||
static const struct devlink_ops mlxsw_devlink_ops = {
|
||||
+ .supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT,
|
||||
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
|
||||
BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
|
||||
.reload_down = mlxsw_devlink_core_bus_device_reload_down,
|
||||
@@ -1894,6 +1979,16 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||
mlxsw_core->bus_priv = bus_priv;
|
||||
mlxsw_core->bus_info = mlxsw_bus_info;
|
||||
|
||||
+ if (!reload) {
|
||||
+ INIT_LIST_HEAD(&mlxsw_core->flash_component_list);
|
||||
+ mutex_init(&mlxsw_core->flash_update_lock);
|
||||
+ err = mlxsw_core_flash_component_register(mlxsw_core, NULL,
|
||||
+ mlxsw_core_fw_flash_cb,
|
||||
+ NULL);
|
||||
+ if (err)
|
||||
+ goto err_flash_component_register;
|
||||
+ }
|
||||
+
|
||||
res = mlxsw_driver->res_query_enabled ? &mlxsw_core->res : NULL;
|
||||
err = mlxsw_bus->init(bus_priv, mlxsw_core, mlxsw_driver->profile, res);
|
||||
if (err)
|
||||
@@ -2013,6 +2108,11 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||
err_register_resources:
|
||||
mlxsw_bus->fini(bus_priv);
|
||||
err_bus_init:
|
||||
+ if (!reload) {
|
||||
+ mlxsw_core_flash_component_unregister(mlxsw_core, NULL);
|
||||
+ mutex_destroy(&mlxsw_core->flash_update_lock);
|
||||
+ }
|
||||
+err_flash_component_register:
|
||||
if (!reload)
|
||||
devlink_free(devlink);
|
||||
err_devlink_alloc:
|
||||
@@ -2081,8 +2181,11 @@ void mlxsw_core_bus_device_unregister(struct mlxsw_core *mlxsw_core,
|
||||
if (!reload)
|
||||
devlink_resources_unregister(devlink, NULL);
|
||||
mlxsw_core->bus->fini(mlxsw_core->bus_priv);
|
||||
- if (!reload)
|
||||
+ if (!reload) {
|
||||
+ mlxsw_core_flash_component_unregister(mlxsw_core, NULL);
|
||||
+ mutex_destroy(&mlxsw_core->flash_update_lock);
|
||||
devlink_free(devlink);
|
||||
+ }
|
||||
|
||||
return;
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
index 593470d14..30f00da0a 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
@@ -41,6 +41,18 @@ mlxsw_core_fw_rev_minor_subminor_validate(const struct mlxsw_fw_rev *rev,
|
||||
int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
|
||||
void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);
|
||||
|
||||
+typedef int (*mlxsw_core_flash_update_cb)(struct mlxsw_core *mlxsw_core,
|
||||
+ const struct firmware *firmware,
|
||||
+ struct netlink_ext_ack *extack,
|
||||
+ void *priv);
|
||||
+
|
||||
+int mlxsw_core_flash_component_register(struct mlxsw_core *mlxsw_core,
|
||||
+ const char *name,
|
||||
+ mlxsw_core_flash_update_cb cb,
|
||||
+ void *priv);
|
||||
+void mlxsw_core_flash_component_unregister(struct mlxsw_core *mlxsw_core,
|
||||
+ const char *name);
|
||||
+
|
||||
int mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||
const struct mlxsw_bus *mlxsw_bus,
|
||||
void *bus_priv, bool reload,
|
||||
diff --git a/include/net/devlink.h b/include/net/devlink.h
|
||||
index 06b61c1d7..fafbec26d 100644
|
||||
--- a/include/net/devlink.h
|
||||
+++ b/include/net/devlink.h
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <net/flow_offload.h>
|
||||
#include <uapi/linux/devlink.h>
|
||||
#include <linux/xarray.h>
|
||||
+#include <linux/firmware.h>
|
||||
|
||||
#define DEVLINK_RELOAD_STATS_ARRAY_SIZE \
|
||||
(__DEVLINK_RELOAD_LIMIT_MAX * __DEVLINK_RELOAD_ACTION_MAX)
|
||||
@@ -624,6 +625,7 @@ enum devlink_param_generic_id {
|
||||
|
||||
/**
|
||||
* struct devlink_flash_update_params - Flash Update parameters
|
||||
+ * @fw: pointer to the firmware data to update from
|
||||
* @file_name: the name of the flash firmware file to update from
|
||||
* @component: the flash component to update
|
||||
*
|
||||
@@ -632,6 +634,7 @@ enum devlink_param_generic_id {
|
||||
* their devlink_ops structure.
|
||||
*/
|
||||
struct devlink_flash_update_params {
|
||||
+ const struct firmware *fw;
|
||||
const char *file_name;
|
||||
const char *component;
|
||||
u32 overwrite_mask;
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,200 @@
|
||||
From ecf655b1e2329f2376f014c2cad0f81ec2ac5deb Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Fri, 4 Jun 2021 10:25:35 +0200
|
||||
Subject: [PATCH] mlxfw: Get the PSID value using op instead of passing it in
|
||||
struct
|
||||
|
||||
In preparation for line card device flashing, where the PSID is going to
|
||||
be obtained dynamically using MGIR register for each individual line
|
||||
card device. So convert the PSID value get to an extra op.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlx5/core/fw.c | 18 +++++++++++++--
|
||||
drivers/net/ethernet/mellanox/mlxfw/mlxfw.h | 4 ++--
|
||||
.../net/ethernet/mellanox/mlxfw/mlxfw_fsm.c | 23 ++++++++++++++-----
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.c | 19 +++++++++++++--
|
||||
4 files changed, 52 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw.c b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
|
||||
index 02558ac2a..06edfd5b1 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlx5/core/fw.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlx5/core/fw.c
|
||||
@@ -494,6 +494,20 @@ struct mlx5_mlxfw_dev {
|
||||
struct mlx5_core_dev *mlx5_core_dev;
|
||||
};
|
||||
|
||||
+static const char *mlx5_psid_get(struct mlxfw_dev *mlxfw_dev, u16 *psid_size)
|
||||
+{
|
||||
+ struct mlx5_mlxfw_dev *mlx5_mlxfw_dev =
|
||||
+ container_of(mlxfw_dev, struct mlx5_mlxfw_dev, mlxfw_dev);
|
||||
+ struct mlx5_core_dev *dev = mlx5_mlxfw_dev->mlx5_core_dev;
|
||||
+
|
||||
+ *psid_size = MLX5_BOARD_ID_LEN;
|
||||
+ return dev->board_id;
|
||||
+}
|
||||
+
|
||||
+static void mlx5_psid_put(const char *psid)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
static int mlx5_component_query(struct mlxfw_dev *mlxfw_dev,
|
||||
u16 component_index, u32 *p_max_size,
|
||||
u8 *p_align_bits, u16 *p_max_write_size)
|
||||
@@ -651,6 +665,8 @@ static int mlx5_fsm_reactivate(struct mlxfw_dev *mlxfw_dev, u8 *status)
|
||||
}
|
||||
|
||||
static const struct mlxfw_dev_ops mlx5_mlxfw_dev_ops = {
|
||||
+ .psid_get = mlx5_psid_get,
|
||||
+ .psid_put = mlx5_psid_put,
|
||||
.component_query = mlx5_component_query,
|
||||
.fsm_lock = mlx5_fsm_lock,
|
||||
.fsm_component_update = mlx5_fsm_component_update,
|
||||
@@ -670,8 +686,6 @@ int mlx5_firmware_flash(struct mlx5_core_dev *dev,
|
||||
struct mlx5_mlxfw_dev mlx5_mlxfw_dev = {
|
||||
.mlxfw_dev = {
|
||||
.ops = &mlx5_mlxfw_dev_ops,
|
||||
- .psid = dev->board_id,
|
||||
- .psid_size = strlen(dev->board_id),
|
||||
.devlink = priv_to_devlink(dev),
|
||||
},
|
||||
.mlx5_core_dev = dev
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h b/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h
|
||||
index 7654841a0..b83651246 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxfw/mlxfw.h
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
struct mlxfw_dev {
|
||||
const struct mlxfw_dev_ops *ops;
|
||||
- const char *psid;
|
||||
- u16 psid_size;
|
||||
struct devlink *devlink;
|
||||
};
|
||||
|
||||
@@ -70,6 +68,8 @@ enum mlxfw_fsm_reactivate_status {
|
||||
};
|
||||
|
||||
struct mlxfw_dev_ops {
|
||||
+ const char * (*psid_get)(struct mlxfw_dev *mlxfw_dev, u16 *psid_size);
|
||||
+ void (*psid_put)(const char *psid);
|
||||
int (*component_query)(struct mlxfw_dev *mlxfw_dev, u16 component_index,
|
||||
u32 *p_max_size, u8 *p_align_bits,
|
||||
u16 *p_max_write_size);
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
|
||||
index bcd166911..329ddf1b3 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_fsm.c
|
||||
@@ -303,7 +303,8 @@ static int mlxfw_flash_component(struct mlxfw_dev *mlxfw_dev,
|
||||
return err;
|
||||
}
|
||||
|
||||
-static int mlxfw_flash_components(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
|
||||
+static int mlxfw_flash_components(struct mlxfw_dev *mlxfw_dev, const char *psid,
|
||||
+ u16 psid_size, u32 fwhandle,
|
||||
struct mlxfw_mfa2_file *mfa2_file,
|
||||
bool reactivate_supp,
|
||||
struct netlink_ext_ack *extack)
|
||||
@@ -312,8 +313,7 @@ static int mlxfw_flash_components(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
|
||||
int err;
|
||||
int i;
|
||||
|
||||
- err = mlxfw_mfa2_file_component_count(mfa2_file, mlxfw_dev->psid,
|
||||
- mlxfw_dev->psid_size,
|
||||
+ err = mlxfw_mfa2_file_component_count(mfa2_file, psid, psid_size,
|
||||
&component_count);
|
||||
if (err) {
|
||||
MLXFW_ERR_MSG(mlxfw_dev, extack,
|
||||
@@ -324,8 +324,8 @@ static int mlxfw_flash_components(struct mlxfw_dev *mlxfw_dev, u32 fwhandle,
|
||||
for (i = 0; i < component_count; i++) {
|
||||
struct mlxfw_mfa2_component *comp;
|
||||
|
||||
- comp = mlxfw_mfa2_file_component_get(mfa2_file, mlxfw_dev->psid,
|
||||
- mlxfw_dev->psid_size, i);
|
||||
+ comp = mlxfw_mfa2_file_component_get(mfa2_file, psid,
|
||||
+ psid_size, i);
|
||||
if (IS_ERR(comp)) {
|
||||
err = PTR_ERR(comp);
|
||||
MLXFW_ERR_MSG(mlxfw_dev, extack,
|
||||
@@ -350,6 +350,8 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
|
||||
{
|
||||
struct mlxfw_mfa2_file *mfa2_file;
|
||||
bool reactivate_supp = true;
|
||||
+ const char *psid;
|
||||
+ u16 psid_size;
|
||||
u32 fwhandle;
|
||||
int err;
|
||||
|
||||
@@ -392,8 +394,16 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
|
||||
if (err)
|
||||
goto err_state_wait_reactivate_to_locked;
|
||||
|
||||
- err = mlxfw_flash_components(mlxfw_dev, fwhandle, mfa2_file,
|
||||
+ psid = mlxfw_dev->ops->psid_get(mlxfw_dev, &psid_size);
|
||||
+ if (IS_ERR(psid)) {
|
||||
+ err = PTR_ERR(psid);
|
||||
+ goto err_psid_get;
|
||||
+ }
|
||||
+
|
||||
+ err = mlxfw_flash_components(mlxfw_dev, psid, psid_size,
|
||||
+ fwhandle, mfa2_file,
|
||||
reactivate_supp, extack);
|
||||
+ mlxfw_dev->ops->psid_put(psid);
|
||||
if (err)
|
||||
goto err_flash_components;
|
||||
|
||||
@@ -423,6 +433,7 @@ int mlxfw_firmware_flash(struct mlxfw_dev *mlxfw_dev,
|
||||
err_state_wait_activate_to_locked:
|
||||
err_fsm_activate:
|
||||
err_flash_components:
|
||||
+err_psid_get:
|
||||
err_state_wait_reactivate_to_locked:
|
||||
err_fsm_reactivate:
|
||||
err_state_wait_idle_to_locked:
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
index f55071982..8c1280781 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
@@ -890,6 +890,21 @@ struct mlxsw_core_fw_info {
|
||||
struct mlxsw_core *mlxsw_core;
|
||||
};
|
||||
|
||||
+static const char *mlxsw_core_fw_psid_get(struct mlxfw_dev *mlxfw_dev,
|
||||
+ u16 *psid_size)
|
||||
+{
|
||||
+ struct mlxsw_core_fw_info *mlxsw_core_fw_info =
|
||||
+ container_of(mlxfw_dev, struct mlxsw_core_fw_info, mlxfw_dev);
|
||||
+ struct mlxsw_core *mlxsw_core = mlxsw_core_fw_info->mlxsw_core;
|
||||
+
|
||||
+ *psid_size = strlen(mlxsw_core->bus_info->psid);
|
||||
+ return mlxsw_core->bus_info->psid;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_core_fw_psid_put(const char *psid)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
static int mlxsw_core_fw_component_query(struct mlxfw_dev *mlxfw_dev,
|
||||
u16 component_index, u32 *p_max_size,
|
||||
u8 *p_align_bits, u16 *p_max_write_size)
|
||||
@@ -1028,6 +1043,8 @@ static void mlxsw_core_fw_fsm_release(struct mlxfw_dev *mlxfw_dev, u32 fwhandle)
|
||||
}
|
||||
|
||||
static const struct mlxfw_dev_ops mlxsw_core_fw_mlxsw_dev_ops = {
|
||||
+ .psid_get = mlxsw_core_fw_psid_get,
|
||||
+ .psid_put = mlxsw_core_fw_psid_put,
|
||||
.component_query = mlxsw_core_fw_component_query,
|
||||
.fsm_lock = mlxsw_core_fw_fsm_lock,
|
||||
.fsm_component_update = mlxsw_core_fw_fsm_component_update,
|
||||
@@ -1045,8 +1062,6 @@ static int mlxsw_core_fw_flash(struct mlxsw_core *mlxsw_core, const struct firmw
|
||||
struct mlxsw_core_fw_info mlxsw_core_fw_info = {
|
||||
.mlxfw_dev = {
|
||||
.ops = &mlxsw_core_fw_mlxsw_dev_ops,
|
||||
- .psid = mlxsw_core->bus_info->psid,
|
||||
- .psid_size = strlen(mlxsw_core->bus_info->psid),
|
||||
.devlink = priv_to_devlink(mlxsw_core),
|
||||
},
|
||||
.mlxsw_core = mlxsw_core
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,400 @@
|
||||
From b721c11b90bb0ef2fcd0bfccd6334948153edea2 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Fri, 5 Mar 2021 09:33:21 +0100
|
||||
Subject: [PATCH] mlxsw: core_linecards: Implement line card device flashing
|
||||
|
||||
Generate flash component name and register it internally within mlxsw
|
||||
for flashing. Also, propagate the component name to devlink core which
|
||||
exposes the information about device being flashable and the component
|
||||
name to use to the user. Implement flashing using MDDT register and
|
||||
mlxfw.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
.../ethernet/mellanox/mlxsw/core_linecards.c | 335 +++++++++++++++++-
|
||||
1 file changed, 334 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
index cb872f918..9f9ee582f 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
@@ -73,6 +73,7 @@ struct mlxsw_linecard_device_info {
|
||||
struct mlxsw_linecard_device {
|
||||
struct list_head list;
|
||||
u8 index;
|
||||
+ char component_name[16];
|
||||
struct mlxsw_linecard *linecard;
|
||||
struct devlink_linecard_device *devlink_device;
|
||||
struct mlxsw_linecard_device_info info;
|
||||
@@ -89,11 +90,322 @@ mlxsw_linecard_device_lookup(struct mlxsw_linecard *linecard, u8 index)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+struct mlxsw_linecard_device_fw_info {
|
||||
+ struct mlxfw_dev mlxfw_dev;
|
||||
+ struct mlxsw_core *mlxsw_core;
|
||||
+ struct mlxsw_linecard_device *device;
|
||||
+};
|
||||
+
|
||||
+static const char *
|
||||
+mlxsw_linecard_device_fw_psid_get(struct mlxfw_dev *mlxfw_dev, u16 *psid_size)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_fw_info *info =
|
||||
+ container_of(mlxfw_dev, struct mlxsw_linecard_device_fw_info,
|
||||
+ mlxfw_dev);
|
||||
+ struct mlxsw_linecard_device *device = info->device;
|
||||
+ struct mlxsw_core *mlxsw_core = info->mlxsw_core;
|
||||
+ char mddt_pl[MLXSW_REG_MDDT_LEN];
|
||||
+ char *mgir_pl;
|
||||
+ char *psid;
|
||||
+ int err;
|
||||
+
|
||||
+ mlxsw_reg_mddt_pack(mddt_pl, device->linecard->slot_index,
|
||||
+ device->index,
|
||||
+ MLXSW_REG_MDDT_METHOD_QUERY,
|
||||
+ MLXSW_REG(mgir), &mgir_pl);
|
||||
+
|
||||
+ mlxsw_reg_mgir_pack(mgir_pl);
|
||||
+ err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mddt), mddt_pl);
|
||||
+ if (err)
|
||||
+ return ERR_PTR(err);
|
||||
+ psid = kzalloc(MLXSW_REG_MGIR_FW_INFO_PSID_SIZE, GFP_KERNEL);
|
||||
+ if (!psid)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ mlxsw_reg_mgir_fw_info_psid_memcpy_from(mgir_pl, psid);
|
||||
+ *psid_size = strlen(psid);
|
||||
+ return psid;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_linecard_device_fw_psid_put(const char *psid)
|
||||
+{
|
||||
+ kfree(psid);
|
||||
+}
|
||||
+
|
||||
+static int mlxsw_linecard_device_fw_component_query(struct mlxfw_dev *mlxfw_dev,
|
||||
+ u16 component_index,
|
||||
+ u32 *p_max_size,
|
||||
+ u8 *p_align_bits,
|
||||
+ u16 *p_max_write_size)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_fw_info *info =
|
||||
+ container_of(mlxfw_dev, struct mlxsw_linecard_device_fw_info,
|
||||
+ mlxfw_dev);
|
||||
+ struct mlxsw_linecard_device *device = info->device;
|
||||
+ struct mlxsw_core *mlxsw_core = info->mlxsw_core;
|
||||
+ char mddt_pl[MLXSW_REG_MDDT_LEN];
|
||||
+ char *mcqi_pl;
|
||||
+ int err;
|
||||
+
|
||||
+ mlxsw_reg_mddt_pack(mddt_pl, device->linecard->slot_index,
|
||||
+ device->index,
|
||||
+ MLXSW_REG_MDDT_METHOD_QUERY,
|
||||
+ MLXSW_REG(mcqi), &mcqi_pl);
|
||||
+
|
||||
+ mlxsw_reg_mcqi_pack(mcqi_pl, component_index);
|
||||
+ err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mddt), mddt_pl);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+ mlxsw_reg_mcqi_unpack(mcqi_pl, p_max_size, p_align_bits,
|
||||
+ p_max_write_size);
|
||||
+
|
||||
+ *p_align_bits = max_t(u8, *p_align_bits, 2);
|
||||
+ *p_max_write_size = min_t(u16, *p_max_write_size,
|
||||
+ MLXSW_REG_MCDA_MAX_DATA_LEN);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mlxsw_linecard_device_fw_fsm_lock(struct mlxfw_dev *mlxfw_dev,
|
||||
+ u32 *fwhandle)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_fw_info *info =
|
||||
+ container_of(mlxfw_dev, struct mlxsw_linecard_device_fw_info,
|
||||
+ mlxfw_dev);
|
||||
+ struct mlxsw_linecard_device *device = info->device;
|
||||
+ struct mlxsw_core *mlxsw_core = info->mlxsw_core;
|
||||
+ char mddt_pl[MLXSW_REG_MDDT_LEN];
|
||||
+ u8 control_state;
|
||||
+ char *mcc_pl;
|
||||
+ int err;
|
||||
+
|
||||
+ mlxsw_reg_mddt_pack(mddt_pl, device->linecard->slot_index,
|
||||
+ device->index,
|
||||
+ MLXSW_REG_MDDT_METHOD_QUERY,
|
||||
+ MLXSW_REG(mcc), &mcc_pl);
|
||||
+ mlxsw_reg_mcc_pack(mcc_pl, 0, 0, 0, 0);
|
||||
+ err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mddt), mddt_pl);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ mlxsw_reg_mcc_unpack(mcc_pl, fwhandle, NULL, &control_state);
|
||||
+ if (control_state != MLXFW_FSM_STATE_IDLE)
|
||||
+ return -EBUSY;
|
||||
+
|
||||
+ mlxsw_reg_mddt_pack(mddt_pl, device->linecard->slot_index,
|
||||
+ device->index,
|
||||
+ MLXSW_REG_MDDT_METHOD_QUERY,
|
||||
+ MLXSW_REG(mcc), &mcc_pl);
|
||||
+ mlxsw_reg_mcc_pack(mcc_pl, MLXSW_REG_MCC_INSTRUCTION_LOCK_UPDATE_HANDLE,
|
||||
+ 0, *fwhandle, 0);
|
||||
+ return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mddt), mddt_pl);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mlxsw_linecard_device_fw_fsm_component_update(struct mlxfw_dev *mlxfw_dev,
|
||||
+ u32 fwhandle,
|
||||
+ u16 component_index,
|
||||
+ u32 component_size)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_fw_info *info =
|
||||
+ container_of(mlxfw_dev, struct mlxsw_linecard_device_fw_info,
|
||||
+ mlxfw_dev);
|
||||
+ struct mlxsw_linecard_device *device = info->device;
|
||||
+ struct mlxsw_core *mlxsw_core = info->mlxsw_core;
|
||||
+ char mddt_pl[MLXSW_REG_MDDT_LEN];
|
||||
+ char *mcc_pl;
|
||||
+
|
||||
+ mlxsw_reg_mddt_pack(mddt_pl, device->linecard->slot_index,
|
||||
+ device->index,
|
||||
+ MLXSW_REG_MDDT_METHOD_WRITE,
|
||||
+ MLXSW_REG(mcc), &mcc_pl);
|
||||
+ mlxsw_reg_mcc_pack(mcc_pl, MLXSW_REG_MCC_INSTRUCTION_UPDATE_COMPONENT,
|
||||
+ component_index, fwhandle, component_size);
|
||||
+ return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mddt), mddt_pl);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mlxsw_linecard_device_fw_fsm_block_download(struct mlxfw_dev *mlxfw_dev,
|
||||
+ u32 fwhandle, u8 *data,
|
||||
+ u16 size, u32 offset)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_fw_info *info =
|
||||
+ container_of(mlxfw_dev, struct mlxsw_linecard_device_fw_info,
|
||||
+ mlxfw_dev);
|
||||
+ struct mlxsw_linecard_device *device = info->device;
|
||||
+ struct mlxsw_core *mlxsw_core = info->mlxsw_core;
|
||||
+ char mddt_pl[MLXSW_REG_MDDT_LEN];
|
||||
+ char *mcda_pl;
|
||||
+
|
||||
+ mlxsw_reg_mddt_pack(mddt_pl, device->linecard->slot_index,
|
||||
+ device->index,
|
||||
+ MLXSW_REG_MDDT_METHOD_WRITE,
|
||||
+ MLXSW_REG(mcda), &mcda_pl);
|
||||
+ mlxsw_reg_mcda_pack(mcda_pl, fwhandle, offset, size, data);
|
||||
+ return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mddt), mddt_pl);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mlxsw_linecard_device_fw_fsm_component_verify(struct mlxfw_dev *mlxfw_dev,
|
||||
+ u32 fwhandle, u16 component_index)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_fw_info *info =
|
||||
+ container_of(mlxfw_dev, struct mlxsw_linecard_device_fw_info,
|
||||
+ mlxfw_dev);
|
||||
+ struct mlxsw_linecard_device *device = info->device;
|
||||
+ struct mlxsw_core *mlxsw_core = info->mlxsw_core;
|
||||
+ char mddt_pl[MLXSW_REG_MDDT_LEN];
|
||||
+ char *mcc_pl;
|
||||
+
|
||||
+ mlxsw_reg_mddt_pack(mddt_pl, device->linecard->slot_index,
|
||||
+ device->index,
|
||||
+ MLXSW_REG_MDDT_METHOD_WRITE,
|
||||
+ MLXSW_REG(mcc), &mcc_pl);
|
||||
+ mlxsw_reg_mcc_pack(mcc_pl, MLXSW_REG_MCC_INSTRUCTION_VERIFY_COMPONENT,
|
||||
+ component_index, fwhandle, 0);
|
||||
+ return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mddt), mddt_pl);
|
||||
+}
|
||||
+
|
||||
+static int mlxsw_linecard_device_fw_fsm_activate(struct mlxfw_dev *mlxfw_dev,
|
||||
+ u32 fwhandle)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_fw_info *info =
|
||||
+ container_of(mlxfw_dev, struct mlxsw_linecard_device_fw_info,
|
||||
+ mlxfw_dev);
|
||||
+ struct mlxsw_linecard_device *device = info->device;
|
||||
+ struct mlxsw_core *mlxsw_core = info->mlxsw_core;
|
||||
+ char mddt_pl[MLXSW_REG_MDDT_LEN];
|
||||
+ char *mcc_pl;
|
||||
+
|
||||
+ mlxsw_reg_mddt_pack(mddt_pl, device->linecard->slot_index,
|
||||
+ device->index,
|
||||
+ MLXSW_REG_MDDT_METHOD_WRITE,
|
||||
+ MLXSW_REG(mcc), &mcc_pl);
|
||||
+ mlxsw_reg_mcc_pack(mcc_pl, MLXSW_REG_MCC_INSTRUCTION_ACTIVATE,
|
||||
+ 0, fwhandle, 0);
|
||||
+ return mlxsw_reg_write(mlxsw_core, MLXSW_REG(mddt), mddt_pl);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mlxsw_linecard_device_fw_fsm_query_state(struct mlxfw_dev *mlxfw_dev,
|
||||
+ u32 fwhandle,
|
||||
+ enum mlxfw_fsm_state *fsm_state,
|
||||
+ enum mlxfw_fsm_state_err *fsm_state_err)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_fw_info *info =
|
||||
+ container_of(mlxfw_dev, struct mlxsw_linecard_device_fw_info,
|
||||
+ mlxfw_dev);
|
||||
+ struct mlxsw_linecard_device *device = info->device;
|
||||
+ struct mlxsw_core *mlxsw_core = info->mlxsw_core;
|
||||
+ char mddt_pl[MLXSW_REG_MDDT_LEN];
|
||||
+ u8 control_state;
|
||||
+ u8 error_code;
|
||||
+ char *mcc_pl;
|
||||
+ int err;
|
||||
+
|
||||
+ mlxsw_reg_mddt_pack(mddt_pl, device->linecard->slot_index,
|
||||
+ device->index,
|
||||
+ MLXSW_REG_MDDT_METHOD_QUERY,
|
||||
+ MLXSW_REG(mcc), &mcc_pl);
|
||||
+ mlxsw_reg_mcc_pack(mcc_pl, 0, 0, fwhandle, 0);
|
||||
+ err = mlxsw_reg_query(mlxsw_core, MLXSW_REG(mddt), mddt_pl);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ mlxsw_reg_mcc_unpack(mcc_pl, NULL, &error_code, &control_state);
|
||||
+ *fsm_state = control_state;
|
||||
+ *fsm_state_err = min_t(enum mlxfw_fsm_state_err, error_code,
|
||||
+ MLXFW_FSM_STATE_ERR_MAX);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_linecard_device_fw_fsm_cancel(struct mlxfw_dev *mlxfw_dev,
|
||||
+ u32 fwhandle)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_fw_info *info =
|
||||
+ container_of(mlxfw_dev, struct mlxsw_linecard_device_fw_info,
|
||||
+ mlxfw_dev);
|
||||
+ struct mlxsw_linecard_device *device = info->device;
|
||||
+ struct mlxsw_core *mlxsw_core = info->mlxsw_core;
|
||||
+ char mddt_pl[MLXSW_REG_MDDT_LEN];
|
||||
+ char *mcc_pl;
|
||||
+
|
||||
+ mlxsw_reg_mddt_pack(mddt_pl, device->linecard->slot_index,
|
||||
+ device->index,
|
||||
+ MLXSW_REG_MDDT_METHOD_WRITE,
|
||||
+ MLXSW_REG(mcc), &mcc_pl);
|
||||
+ mlxsw_reg_mcc_pack(mcc_pl, MLXSW_REG_MCC_INSTRUCTION_CANCEL,
|
||||
+ 0, fwhandle, 0);
|
||||
+ mlxsw_reg_write(mlxsw_core, MLXSW_REG(mddt), mddt_pl);
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_linecard_device_fw_fsm_release(struct mlxfw_dev *mlxfw_dev,
|
||||
+ u32 fwhandle)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_fw_info *info =
|
||||
+ container_of(mlxfw_dev, struct mlxsw_linecard_device_fw_info,
|
||||
+ mlxfw_dev);
|
||||
+ struct mlxsw_linecard_device *device = info->device;
|
||||
+ struct mlxsw_core *mlxsw_core = info->mlxsw_core;
|
||||
+ char mddt_pl[MLXSW_REG_MDDT_LEN];
|
||||
+ char *mcc_pl;
|
||||
+
|
||||
+ mlxsw_reg_mddt_pack(mddt_pl, device->linecard->slot_index,
|
||||
+ device->index,
|
||||
+ MLXSW_REG_MDDT_METHOD_WRITE,
|
||||
+ MLXSW_REG(mcc), &mcc_pl);
|
||||
+ mlxsw_reg_mcc_pack(mcc_pl,
|
||||
+ MLXSW_REG_MCC_INSTRUCTION_RELEASE_UPDATE_HANDLE,
|
||||
+ 0, fwhandle, 0);
|
||||
+ mlxsw_reg_write(mlxsw_core, MLXSW_REG(mddt), mddt_pl);
|
||||
+}
|
||||
+
|
||||
+static const struct mlxfw_dev_ops mlxsw_linecard_device_dev_ops = {
|
||||
+ .psid_get = mlxsw_linecard_device_fw_psid_get,
|
||||
+ .psid_put = mlxsw_linecard_device_fw_psid_put,
|
||||
+ .component_query = mlxsw_linecard_device_fw_component_query,
|
||||
+ .fsm_lock = mlxsw_linecard_device_fw_fsm_lock,
|
||||
+ .fsm_component_update = mlxsw_linecard_device_fw_fsm_component_update,
|
||||
+ .fsm_block_download = mlxsw_linecard_device_fw_fsm_block_download,
|
||||
+ .fsm_component_verify = mlxsw_linecard_device_fw_fsm_component_verify,
|
||||
+ .fsm_activate = mlxsw_linecard_device_fw_fsm_activate,
|
||||
+ .fsm_query_state = mlxsw_linecard_device_fw_fsm_query_state,
|
||||
+ .fsm_cancel = mlxsw_linecard_device_fw_fsm_cancel,
|
||||
+ .fsm_release = mlxsw_linecard_device_fw_fsm_release,
|
||||
+};
|
||||
+
|
||||
+static int mlxsw_linecard_device_fw_flash(struct mlxsw_core *mlxsw_core,
|
||||
+ const struct firmware *firmware,
|
||||
+ struct mlxsw_linecard_device *device,
|
||||
+ struct netlink_ext_ack *extack)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device_fw_info info = {
|
||||
+ .mlxfw_dev = {
|
||||
+ .ops = &mlxsw_linecard_device_dev_ops,
|
||||
+ .devlink = priv_to_devlink(mlxsw_core),
|
||||
+ },
|
||||
+ .mlxsw_core = mlxsw_core,
|
||||
+ .device = device,
|
||||
+ };
|
||||
+
|
||||
+ return mlxfw_firmware_flash(&info.mlxfw_dev, firmware, extack);
|
||||
+}
|
||||
+
|
||||
+static int mlxsw_linecard_device_flash_cb(struct mlxsw_core *mlxsw_core,
|
||||
+ const struct firmware *firmware,
|
||||
+ struct netlink_ext_ack *extack, void *priv)
|
||||
+{
|
||||
+ struct mlxsw_linecard_device *device = priv;
|
||||
+
|
||||
+ return mlxsw_linecard_device_fw_flash(mlxsw_core, firmware,
|
||||
+ device, extack);
|
||||
+}
|
||||
+
|
||||
static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
|
||||
struct mlxsw_linecard *linecard,
|
||||
u8 device_index, bool flash_owner)
|
||||
{
|
||||
struct mlxsw_linecard_device *device;
|
||||
+ char *component_name = NULL;
|
||||
int err;
|
||||
|
||||
device = kzalloc(sizeof(*device), GFP_KERNEL);
|
||||
@@ -102,9 +414,23 @@ static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
|
||||
device->index = device_index;
|
||||
device->linecard = linecard;
|
||||
|
||||
+ if (flash_owner) {
|
||||
+ snprintf(device->component_name,
|
||||
+ sizeof(device->component_name), "lc%u_dev%u",
|
||||
+ linecard->slot_index, device->index);
|
||||
+ component_name = device->component_name;
|
||||
+ err = mlxsw_core_flash_component_register(mlxsw_core,
|
||||
+ component_name,
|
||||
+ mlxsw_linecard_device_flash_cb,
|
||||
+ device);
|
||||
+ if (err)
|
||||
+ goto err_flash_component_register;
|
||||
+ }
|
||||
+
|
||||
device->devlink_device = devlink_linecard_device_create(linecard->devlink_linecard,
|
||||
device_index,
|
||||
- NULL, device);
|
||||
+ component_name,
|
||||
+ device);
|
||||
if (IS_ERR(device->devlink_device)) {
|
||||
err = PTR_ERR(device->devlink_device);
|
||||
goto err_devlink_linecard_device_attach;
|
||||
@@ -114,6 +440,10 @@ static int mlxsw_linecard_device_attach(struct mlxsw_core *mlxsw_core,
|
||||
return 0;
|
||||
|
||||
err_devlink_linecard_device_attach:
|
||||
+ if (flash_owner)
|
||||
+ mlxsw_core_flash_component_unregister(mlxsw_core,
|
||||
+ device->component_name);
|
||||
+err_flash_component_register:
|
||||
kfree(device);
|
||||
return err;
|
||||
}
|
||||
@@ -125,6 +455,9 @@ static void mlxsw_linecard_device_detach(struct mlxsw_core *mlxsw_core,
|
||||
list_del(&device->list);
|
||||
devlink_linecard_device_destroy(linecard->devlink_linecard,
|
||||
device->devlink_device);
|
||||
+ if (strlen(device->component_name))
|
||||
+ mlxsw_core_flash_component_unregister(mlxsw_core,
|
||||
+ device->component_name);
|
||||
kfree(device);
|
||||
}
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,277 @@
|
||||
From 19bae5f5978a43a22258843cc999b592d0e4b414 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Pirko <jiri@nvidia.com>
|
||||
Date: Fri, 22 Jan 2021 15:01:06 +0100
|
||||
Subject: [PATCH] mlxsw: core_linecards: Introduce ops for linecards status
|
||||
change tracking
|
||||
|
||||
Introduce an infrastructure allowing the core to register set of ops
|
||||
which are called whenever line card gets provisione/unprovisioned
|
||||
and active/inactive.
|
||||
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.h | 22 +++
|
||||
.../ethernet/mellanox/mlxsw/core_linecards.c | 134 +++++++++++++++++-
|
||||
2 files changed, 150 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
index 30f00da0a..10ea541bb 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
@@ -582,4 +582,26 @@ int mlxsw_linecard_status_process(struct mlxsw_core *mlxsw_core,
|
||||
int mlxsw_linecard_bct_process(struct mlxsw_core *mlxsw_core,
|
||||
const char *mbct_pl);
|
||||
|
||||
+struct mlxsw_linecards_event_ops {
|
||||
+ int (*got_provisioned)(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard,
|
||||
+ void *priv);
|
||||
+ void (*got_unprovisioned)(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard,
|
||||
+ void *priv);
|
||||
+ void (*got_active)(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard,
|
||||
+ void *priv);
|
||||
+ void (*got_inactive)(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard,
|
||||
+ void *priv);
|
||||
+};
|
||||
+
|
||||
+int mlxsw_linecards_event_ops_register(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecards_event_ops *ops,
|
||||
+ void *priv);
|
||||
+void mlxsw_linecards_event_ops_unregister(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecards_event_ops *ops,
|
||||
+ void *priv);
|
||||
+
|
||||
#endif
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
index 9f9ee582f..3a2fdd22d 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c
|
||||
@@ -576,6 +576,59 @@ static void mlxsw_linecard_provision_fail(struct mlxsw_core *mlxsw_core,
|
||||
devlink_linecard_provision_fail(linecard->devlink_linecard);
|
||||
}
|
||||
|
||||
+struct mlxsw_linecards_event_ops_item {
|
||||
+ struct list_head list;
|
||||
+ struct mlxsw_linecards_event_ops *event_ops;
|
||||
+ void *priv;
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+mlxsw_linecard_provision_cbs_call(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecards *linecards,
|
||||
+ struct mlxsw_linecard *linecard)
|
||||
+{
|
||||
+ struct mlxsw_linecards_event_ops_item *item;
|
||||
+ int err;
|
||||
+
|
||||
+ list_for_each_entry(item, &linecards->event_ops_list, list) {
|
||||
+ if (!item->event_ops->got_provisioned)
|
||||
+ continue;
|
||||
+ err = item->event_ops->got_provisioned(mlxsw_core,
|
||||
+ linecard->slot_index,
|
||||
+ linecard, item->priv);
|
||||
+ if (err)
|
||||
+ goto rollback;
|
||||
+ }
|
||||
+ return 0;
|
||||
+
|
||||
+rollback:
|
||||
+ list_for_each_entry_continue_reverse(item, &linecards->event_ops_list,
|
||||
+ list) {
|
||||
+ if (!item->event_ops->got_unprovisioned)
|
||||
+ continue;
|
||||
+ item->event_ops->got_unprovisioned(mlxsw_core,
|
||||
+ linecard->slot_index,
|
||||
+ linecard, item->priv);
|
||||
+ }
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mlxsw_linecard_unprovision_cbs_call(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecards *linecards,
|
||||
+ struct mlxsw_linecard *linecard)
|
||||
+{
|
||||
+ struct mlxsw_linecards_event_ops_item *item;
|
||||
+
|
||||
+ list_for_each_entry(item, &linecards->event_ops_list, list) {
|
||||
+ if (!item->event_ops->got_unprovisioned)
|
||||
+ continue;
|
||||
+ item->event_ops->got_unprovisioned(mlxsw_core,
|
||||
+ linecard->slot_index,
|
||||
+ linecard, item->priv);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int
|
||||
mlxsw_linecard_provision_set(struct mlxsw_core *mlxsw_core,
|
||||
struct mlxsw_linecards *linecards,
|
||||
@@ -594,14 +647,27 @@ mlxsw_linecard_provision_set(struct mlxsw_core *mlxsw_core,
|
||||
err = mlxsw_linecard_devices_attach(mlxsw_core, linecard);
|
||||
if (err)
|
||||
return err;
|
||||
+ err = mlxsw_linecard_provision_cbs_call(mlxsw_core, linecards,
|
||||
+ linecard);
|
||||
+ if (err)
|
||||
+ goto err_cbs_call;
|
||||
linecard->provisioned = true;
|
||||
devlink_linecard_provision_set(linecard->devlink_linecard, type);
|
||||
return 0;
|
||||
+
|
||||
+err_cbs_call:
|
||||
+ mlxsw_linecard_devices_detach(linecard->linecards->mlxsw_core,
|
||||
+ linecard);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
-static void mlxsw_linecard_provision_clear(struct mlxsw_linecard *linecard)
|
||||
+static void mlxsw_linecard_provision_clear(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecards *linecards,
|
||||
+ struct mlxsw_linecard *linecard)
|
||||
{
|
||||
linecard->provisioned = false;
|
||||
+ mlxsw_linecard_unprovision_cbs_call(mlxsw_core, linecards,
|
||||
+ linecard);
|
||||
mlxsw_linecard_devices_detach(linecard->linecards->mlxsw_core,
|
||||
linecard);
|
||||
devlink_linecard_provision_clear(linecard->devlink_linecard);
|
||||
@@ -636,22 +702,43 @@ static int mlxsw_linecard_ready_clear(struct mlxsw_core *mlxsw_core,
|
||||
}
|
||||
|
||||
static int mlxsw_linecard_active_set(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecards *linecards,
|
||||
struct mlxsw_linecard *linecard,
|
||||
u16 hw_revision, u16 ini_version)
|
||||
{
|
||||
+ struct mlxsw_linecards_event_ops_item *item;
|
||||
int err;
|
||||
|
||||
err = mlxsw_linecard_devices_update(mlxsw_core, linecard);
|
||||
if (err)
|
||||
return err;
|
||||
+
|
||||
linecard->active = true;
|
||||
+ linecard->hw_revision = hw_revision;
|
||||
+ linecard->ini_version = ini_version;
|
||||
+ list_for_each_entry(item, &linecards->event_ops_list, list) {
|
||||
+ if (!item->event_ops->got_active)
|
||||
+ continue;
|
||||
+ item->event_ops->got_active(mlxsw_core, linecard->slot_index,
|
||||
+ linecard, item->priv);
|
||||
+ }
|
||||
devlink_linecard_activate(linecard->devlink_linecard);
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static void mlxsw_linecard_active_clear(struct mlxsw_linecard *linecard)
|
||||
+static void mlxsw_linecard_active_clear(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecards *linecards,
|
||||
+ struct mlxsw_linecard *linecard)
|
||||
{
|
||||
+ struct mlxsw_linecards_event_ops_item *item;
|
||||
+
|
||||
linecard->active = false;
|
||||
+ list_for_each_entry(item, &linecards->event_ops_list, list) {
|
||||
+ if (!item->event_ops->got_inactive)
|
||||
+ continue;
|
||||
+ item->event_ops->got_inactive(mlxsw_core, linecard->slot_index,
|
||||
+ linecard, item->priv);
|
||||
+ }
|
||||
devlink_linecard_deactivate(linecard->devlink_linecard);
|
||||
}
|
||||
|
||||
@@ -703,14 +790,14 @@ static int __mlxsw_linecard_status_process(struct mlxsw_core *mlxsw_core,
|
||||
|
||||
if (!process_provision_only && !linecard->unprovision_done && active &&
|
||||
linecard->active != active && linecard->ready) {
|
||||
- err = mlxsw_linecard_active_set(mlxsw_core, linecard,
|
||||
+ err = mlxsw_linecard_active_set(mlxsw_core, linecards, linecard,
|
||||
hw_revision, ini_version);
|
||||
if (err)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!process_provision_only && !active && linecard->active != active)
|
||||
- mlxsw_linecard_active_clear(linecard);
|
||||
+ mlxsw_linecard_active_clear(mlxsw_core, linecards, linecard);
|
||||
|
||||
if (!process_provision_only && ready != MLXSW_REG_MDDQ_READY_READY &&
|
||||
linecard->ready) {
|
||||
@@ -720,7 +807,7 @@ static int __mlxsw_linecard_status_process(struct mlxsw_core *mlxsw_core,
|
||||
}
|
||||
|
||||
if (!provisioned && linecard->provisioned != provisioned)
|
||||
- mlxsw_linecard_provision_clear(linecard);
|
||||
+ mlxsw_linecard_provision_clear(mlxsw_core, linecards, linecard);
|
||||
|
||||
out:
|
||||
mutex_unlock(&linecard->lock);
|
||||
@@ -1128,7 +1215,7 @@ static void mlxsw_linecard_pre_fini(struct mlxsw_core *mlxsw_core,
|
||||
/* Make sure all scheduled events are processed */
|
||||
mlxsw_core_flush_owq();
|
||||
if (linecard->active)
|
||||
- mlxsw_linecard_active_clear(linecard);
|
||||
+ mlxsw_linecard_active_clear(mlxsw_core, linecards, linecard);
|
||||
}
|
||||
|
||||
static void mlxsw_linecard_fini(struct mlxsw_core *mlxsw_core,
|
||||
@@ -1287,6 +1374,7 @@ int mlxsw_linecards_init(struct mlxsw_core *mlxsw_core,
|
||||
linecards->count = slot_count;
|
||||
linecards->mlxsw_core = mlxsw_core;
|
||||
linecards->bus_info = bus_info;
|
||||
+ INIT_LIST_HEAD(&linecards->event_ops_list);
|
||||
|
||||
linecards->wq = alloc_workqueue("mlxsw_linecards", 0, 0);
|
||||
if (!linecards->wq) {
|
||||
@@ -1360,6 +1448,7 @@ void mlxsw_linecards_fini(struct mlxsw_core *mlxsw_core,
|
||||
|
||||
if (!linecards)
|
||||
return;
|
||||
+ WARN_ON(!list_empty(&linecards->event_ops_list));
|
||||
for (i = 0; i < linecards->count; i++)
|
||||
mlxsw_linecard_fini(mlxsw_core, linecards, i + 1);
|
||||
mlxsw_linecard_types_fini(linecards);
|
||||
@@ -1367,4 +1456,37 @@ void mlxsw_linecards_fini(struct mlxsw_core *mlxsw_core,
|
||||
kfree(linecards);
|
||||
}
|
||||
|
||||
+int mlxsw_linecards_event_ops_register(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecards_event_ops *ops,
|
||||
+ void *priv)
|
||||
+{
|
||||
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(mlxsw_core);
|
||||
+ struct mlxsw_linecards_event_ops_item *item;
|
||||
+
|
||||
+ item = kzalloc(sizeof(*item), GFP_KERNEL);
|
||||
+ if (!item)
|
||||
+ return -ENOMEM;
|
||||
+ item->event_ops = ops;
|
||||
+ item->priv = priv;
|
||||
+ list_add_tail(&item->list, &linecards->event_ops_list);
|
||||
+ return 0;
|
||||
+}
|
||||
+EXPORT_SYMBOL(mlxsw_linecards_event_ops_register);
|
||||
+
|
||||
+void mlxsw_linecards_event_ops_unregister(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_linecards_event_ops *ops,
|
||||
+ void *priv)
|
||||
+{
|
||||
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(mlxsw_core);
|
||||
+ struct mlxsw_linecards_event_ops_item *item, *tmp;
|
||||
+
|
||||
+ list_for_each_entry_safe(item, tmp, &linecards->event_ops_list, list) {
|
||||
+ if (item->event_ops == ops && item->priv == priv) {
|
||||
+ list_del(&item->list);
|
||||
+ kfree(item);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+EXPORT_SYMBOL(mlxsw_linecards_event_ops_unregister);
|
||||
+
|
||||
MODULE_FIRMWARE(MLXSW_LINECARDS_INI_BUNDLE_FILE);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,133 @@
|
||||
From 8d6f7da411b62b4450db1ebb8b687dbc5a386300 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Mon, 13 Dec 2021 12:54:36 +0000
|
||||
Subject: [PATCH] mlxsw: core: Add interfaces for line card initialization and
|
||||
de-initialization
|
||||
|
||||
Add callback functions for line card cables info initialization and
|
||||
de-initialization.
|
||||
|
||||
The line card initialization / de-initialization APIs are to be called
|
||||
when line card is set to active / inactive state by got_active() /
|
||||
got_inactive() callbacks from line card state machine.
|
||||
Access to cable info and real number of modules is available only after
|
||||
line card is activated.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_env.c | 78 +++++++++++++++++++
|
||||
1 file changed, 78 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
index c27cd424b..f9c770eec 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
|
||||
@@ -1162,6 +1162,77 @@ mlxsw_env_module_event_disable(struct mlxsw_env *mlxsw_env, u8 slot_index)
|
||||
{
|
||||
}
|
||||
|
||||
+static void
|
||||
+mlxsw_env_got_active(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard, void *priv)
|
||||
+{
|
||||
+ struct mlxsw_env *mlxsw_env = priv;
|
||||
+ char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
+ int err;
|
||||
+
|
||||
+ mlxsw_reg_mgpir_pack(mgpir_pl, slot_index);
|
||||
+ err = mlxsw_reg_query(mlxsw_env->core, MLXSW_REG(mgpir), mgpir_pl);
|
||||
+ if (err)
|
||||
+ return;
|
||||
+
|
||||
+ mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL,
|
||||
+ &mlxsw_env->line_cards[slot_index]->module_count,
|
||||
+ NULL);
|
||||
+ mlxsw_env_module_event_enable(mlxsw_env, slot_index);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mlxsw_env_got_inactive(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard, void *priv)
|
||||
+{
|
||||
+ struct mlxsw_env *mlxsw_env = priv;
|
||||
+
|
||||
+ mlxsw_env_module_event_disable(mlxsw_env, slot_index);
|
||||
+}
|
||||
+
|
||||
+static struct mlxsw_linecards_event_ops mlxsw_env_event_ops = {
|
||||
+ .got_active = mlxsw_env_got_active,
|
||||
+ .got_inactive = mlxsw_env_got_inactive,
|
||||
+};
|
||||
+
|
||||
+static int mlxsw_env_linecards_register(struct mlxsw_env *mlxsw_env)
|
||||
+{
|
||||
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(mlxsw_env->core);
|
||||
+ int err;
|
||||
+
|
||||
+ if (!linecards || !linecards->count)
|
||||
+ return 0;
|
||||
+
|
||||
+ err = mlxsw_linecards_event_ops_register(mlxsw_env->core,
|
||||
+ &mlxsw_env_event_ops,
|
||||
+ mlxsw_env);
|
||||
+ if (err)
|
||||
+ goto err_linecards_event_ops_register;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_linecards_event_ops_register:
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_env_linecards_unregister(struct mlxsw_env *mlxsw_env)
|
||||
+{
|
||||
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(mlxsw_env->core);
|
||||
+ int i;
|
||||
+
|
||||
+ if (!linecards || !linecards->count)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 1; i <= linecards->count; i++) {
|
||||
+ if (mlxsw_env->line_cards[i]->module_count)
|
||||
+ mlxsw_env_got_inactive(mlxsw_env->core, i, NULL,
|
||||
+ mlxsw_env);
|
||||
+ }
|
||||
+
|
||||
+ mlxsw_linecards_event_ops_unregister(mlxsw_env->core,
|
||||
+ &mlxsw_env_event_ops, mlxsw_env);
|
||||
+}
|
||||
+
|
||||
int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
|
||||
{
|
||||
u8 module_count, num_of_slots, max_module_count;
|
||||
@@ -1198,6 +1269,10 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
|
||||
mutex_init(&env->line_cards_lock);
|
||||
*p_env = env;
|
||||
|
||||
+ err = mlxsw_env_linecards_register(env);
|
||||
+ if (err)
|
||||
+ goto err_linecards_register;
|
||||
+
|
||||
err = mlxsw_env_temp_warn_event_register(mlxsw_core);
|
||||
if (err)
|
||||
goto err_temp_warn_event_register;
|
||||
@@ -1225,6 +1300,8 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, struct mlxsw_env **p_env)
|
||||
err_module_plug_event_register:
|
||||
mlxsw_env_temp_warn_event_unregister(env);
|
||||
err_temp_warn_event_register:
|
||||
+ mlxsw_env_linecards_unregister(env);
|
||||
+err_linecards_register:
|
||||
mutex_destroy(&env->line_cards_lock);
|
||||
mlxsw_env_line_cards_free(env);
|
||||
err_mlxsw_env_line_cards_alloc:
|
||||
@@ -1239,6 +1316,7 @@ void mlxsw_env_fini(struct mlxsw_env *env)
|
||||
/* Make sure there is no more event work scheduled. */
|
||||
mlxsw_core_flush_owq();
|
||||
mlxsw_env_temp_warn_event_unregister(env);
|
||||
+ mlxsw_env_linecards_unregister(env);
|
||||
mutex_destroy(&env->line_cards_lock);
|
||||
mlxsw_env_line_cards_free(env);
|
||||
kfree(env);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,213 @@
|
||||
From 62b2da593b9ee1042b0d65c7b84e9f463497ecd8 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Wed, 12 May 2021 22:57:39 +0300
|
||||
Subject: [PATCH] mlxsw: core_thermal: Add interfaces for line card
|
||||
initialization and de-initialization
|
||||
|
||||
Add callback functions for line card thermal area initialization and
|
||||
de-initialization. Each line card is associated with the relevant
|
||||
thermal area, which may contain thermal zones for cages and gearboxes
|
||||
found on this line card.
|
||||
|
||||
The line card thermal initialization / de-initialization APIs are to be
|
||||
called when line card is set to active / inactive state by
|
||||
got_active() / got_inactive() callbacks from line card state machine.
|
||||
|
||||
For example thermal zone for module #9 located at line card #7 will
|
||||
have type:
|
||||
mlxsw-lc7-module9.
|
||||
And thermal zone for gearbox #2 located at line card #5 will have type:
|
||||
mlxsw-lc5-gearbox2.
|
||||
|
||||
For now the slot index is always 0 and field 'name' of the structure
|
||||
'mlxsw_hwmon_dev' is empty. For line card this field is supposed to
|
||||
be initialized to 'lc#n', when line card in slot #n is enabled.
|
||||
|
||||
Add validation of modules number found on main board in function
|
||||
mlxsw_thermal_modules_init(). On modular system this counter might be
|
||||
zero.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
.../ethernet/mellanox/mlxsw/core_thermal.c | 129 ++++++++++++++++++
|
||||
1 file changed, 129 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
index e860cade5..88a2f63c8 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
|
||||
@@ -96,6 +96,7 @@ struct mlxsw_thermal_module {
|
||||
};
|
||||
|
||||
struct mlxsw_thermal_area {
|
||||
+ struct mlxsw_thermal *parent;
|
||||
struct mlxsw_thermal_module *tz_module_arr;
|
||||
u8 tz_module_num;
|
||||
struct mlxsw_thermal_module *tz_gearbox_arr;
|
||||
@@ -113,6 +114,7 @@ struct mlxsw_thermal {
|
||||
u8 cooling_levels[MLXSW_THERMAL_MAX_STATE + 1];
|
||||
struct mlxsw_thermal_trip trips[MLXSW_THERMAL_NUM_TRIPS];
|
||||
struct mlxsw_thermal_area *main;
|
||||
+ struct mlxsw_thermal_area **linecards;
|
||||
unsigned int tz_highest_score;
|
||||
struct thermal_zone_device *tz_highest_dev;
|
||||
};
|
||||
@@ -989,6 +991,126 @@ mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal,
|
||||
mlxsw_thermal_gearbox_tz_fini(&area->tz_gearbox_arr[i]);
|
||||
}
|
||||
|
||||
+static void
|
||||
+mlxsw_thermal_got_active(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard, void *priv)
|
||||
+{
|
||||
+ struct mlxsw_env_gearbox_sensors_map map;
|
||||
+ struct mlxsw_thermal *thermal = priv;
|
||||
+ struct mlxsw_thermal_area *lc;
|
||||
+ int err;
|
||||
+
|
||||
+ lc = kzalloc(sizeof(*lc), GFP_KERNEL);
|
||||
+ if (!lc)
|
||||
+ return;
|
||||
+
|
||||
+ lc->slot_index = slot_index;
|
||||
+ lc->parent = thermal;
|
||||
+ thermal->linecards[slot_index - 1] = lc;
|
||||
+ err = mlxsw_thermal_modules_init(thermal->bus_info->dev, thermal->core,
|
||||
+ thermal, lc);
|
||||
+ if (err)
|
||||
+ goto err_thermal_linecard_modules_init;
|
||||
+
|
||||
+ err = mlxsw_env_sensor_map_create(thermal->core, thermal->bus_info,
|
||||
+ linecard->slot_index, &map);
|
||||
+ if (err)
|
||||
+ goto err_thermal_linecard_env_sensor_map_create;
|
||||
+
|
||||
+ lc->gearbox_sensor_map = map.sensor_bit_map;
|
||||
+ lc->tz_gearbox_num = map.sensor_count;
|
||||
+ lc->tz_gearbox_arr = kcalloc(lc->tz_gearbox_num, sizeof(*lc->tz_gearbox_arr),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!lc->tz_gearbox_arr) {
|
||||
+ err = -ENOMEM;
|
||||
+ goto err_tz_gearbox_arr_alloc;
|
||||
+ }
|
||||
+
|
||||
+ err = mlxsw_thermal_gearboxes_init(thermal->bus_info->dev, thermal->core,
|
||||
+ thermal, lc);
|
||||
+ if (err)
|
||||
+ goto err_thermal_linecard_gearboxes_init;
|
||||
+
|
||||
+ return;
|
||||
+
|
||||
+err_thermal_linecard_gearboxes_init:
|
||||
+ kfree(lc->tz_gearbox_arr);
|
||||
+err_tz_gearbox_arr_alloc:
|
||||
+ mlxsw_env_sensor_map_destroy(thermal->bus_info,
|
||||
+ lc->gearbox_sensor_map);
|
||||
+err_thermal_linecard_env_sensor_map_create:
|
||||
+ mlxsw_thermal_modules_fini(thermal, lc);
|
||||
+err_thermal_linecard_modules_init:
|
||||
+ kfree(lc);
|
||||
+ thermal->linecards[slot_index - 1] = NULL;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_thermal_got_inactive(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard, void *priv)
|
||||
+{
|
||||
+ struct mlxsw_thermal *thermal = priv;
|
||||
+ struct mlxsw_thermal_area *lc = thermal->linecards[slot_index - 1];
|
||||
+
|
||||
+ mlxsw_thermal_gearboxes_fini(thermal, lc);
|
||||
+ kfree(lc->tz_gearbox_arr);
|
||||
+ mlxsw_env_sensor_map_destroy(thermal->bus_info,
|
||||
+ lc->gearbox_sensor_map);
|
||||
+ mlxsw_thermal_modules_fini(thermal, lc);
|
||||
+ kfree(lc);
|
||||
+ thermal->linecards[slot_index - 1] = NULL;
|
||||
+}
|
||||
+
|
||||
+static struct mlxsw_linecards_event_ops mlxsw_thermal_event_ops = {
|
||||
+ .got_active = mlxsw_thermal_got_active,
|
||||
+ .got_inactive = mlxsw_thermal_got_inactive,
|
||||
+};
|
||||
+
|
||||
+static int mlxsw_thermal_linecards_register(struct mlxsw_core *mlxsw_core,
|
||||
+ struct mlxsw_thermal *thermal)
|
||||
+{
|
||||
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(mlxsw_core);
|
||||
+ int err;
|
||||
+
|
||||
+ if (!linecards || !linecards->count)
|
||||
+ return 0;
|
||||
+
|
||||
+ thermal->linecards = kcalloc(linecards->count, sizeof(*thermal->linecards),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!thermal->linecards)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ err = mlxsw_linecards_event_ops_register(mlxsw_core,
|
||||
+ &mlxsw_thermal_event_ops,
|
||||
+ thermal);
|
||||
+ if (err)
|
||||
+ goto err_linecards_event_ops_register;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_linecards_event_ops_register:
|
||||
+ kfree(thermal->linecards);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_thermal_linecards_unregister(struct mlxsw_thermal *thermal)
|
||||
+{
|
||||
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(thermal->core);
|
||||
+ int i;
|
||||
+
|
||||
+ if (!linecards || !linecards->count)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 1; i <= linecards->count; i++) {
|
||||
+ if (thermal->linecards[i - 1])
|
||||
+ mlxsw_thermal_got_inactive(thermal->core, i, NULL,
|
||||
+ thermal);
|
||||
+ }
|
||||
+
|
||||
+ mlxsw_linecards_event_ops_unregister(thermal->core,
|
||||
+ &mlxsw_thermal_event_ops, thermal);
|
||||
+ kfree(thermal->linecards);
|
||||
+}
|
||||
+
|
||||
int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
const struct mlxsw_bus_info *bus_info,
|
||||
struct mlxsw_thermal **p_thermal)
|
||||
@@ -1094,6 +1216,10 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
if (err)
|
||||
goto err_thermal_gearboxes_init;
|
||||
|
||||
+ err = mlxsw_thermal_linecards_register(core, thermal);
|
||||
+ if (err)
|
||||
+ goto err_linecards_register;
|
||||
+
|
||||
err = thermal_zone_device_enable(thermal->tzdev);
|
||||
if (err)
|
||||
goto err_thermal_zone_device_enable;
|
||||
@@ -1102,6 +1228,8 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
|
||||
return 0;
|
||||
|
||||
err_thermal_zone_device_enable:
|
||||
+ mlxsw_thermal_linecards_unregister(thermal);
|
||||
+err_linecards_register:
|
||||
mlxsw_thermal_gearboxes_fini(thermal, thermal->main);
|
||||
err_thermal_gearboxes_init:
|
||||
mlxsw_thermal_gearboxes_main_fini(thermal->main);
|
||||
@@ -1129,6 +1257,7 @@ void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
|
||||
{
|
||||
int i;
|
||||
|
||||
+ mlxsw_thermal_linecards_unregister(thermal);
|
||||
mlxsw_thermal_gearboxes_fini(thermal, thermal->main);
|
||||
mlxsw_thermal_gearboxes_main_fini(thermal->main);
|
||||
mlxsw_thermal_modules_fini(thermal, thermal->main);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,235 @@
|
||||
From 97f2a14ec9543588b37be8fc54aad9ed13cceec9 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Wed, 12 May 2021 22:57:42 +0300
|
||||
Subject: [PATCH] mlxsw: core_hwmon: Add interfaces for line card
|
||||
initialization and de-initialization
|
||||
|
||||
Add callback functions for line card 'hwmon' initialization and
|
||||
de-initialization. Each line card is associated with the relevant
|
||||
'hwmon' device, which may contain thermal attributes for the cages
|
||||
and gearboxes found on this line card.
|
||||
|
||||
The line card 'hwmon' initialization / de-initialization APIs are to be
|
||||
called when line card is set to active / inactive state by
|
||||
got_active() / got_inactive() callbacks from line card state machine.
|
||||
|
||||
For example cage temperature for module #9 located at line card #7 will
|
||||
be exposed by utility 'sensors' like:
|
||||
linecard#07
|
||||
front panel 009: +32.0C (crit = +70.0C, emerg = +80.0C)
|
||||
And temperature for gearbox #3 located at line card #5 will be exposed
|
||||
like:
|
||||
linecard#05
|
||||
gearbox 003: +41.0C (highest = +41.0C)
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
|
||||
---
|
||||
.../net/ethernet/mellanox/mlxsw/core_hwmon.c | 137 +++++++++++++++++-
|
||||
1 file changed, 134 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
index 6af23f472..a27146cca 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#define MLXSW_HWMON_ATTR_PER_SENSOR 3
|
||||
#define MLXSW_HWMON_ATTR_PER_MODULE 7
|
||||
#define MLXSW_HWMON_ATTR_PER_GEARBOX 4
|
||||
+#define MLXSW_HWMON_DEV_NAME_LEN_MAX 16
|
||||
|
||||
#define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_SENSORS_MAX_COUNT * MLXSW_HWMON_ATTR_PER_SENSOR + \
|
||||
MLXSW_HWMON_MODULES_MAX_COUNT * MLXSW_HWMON_ATTR_PER_MODULE + \
|
||||
@@ -42,6 +43,7 @@ mlxsw_hwmon_get_attr_index(int index, int count, u16 *gearbox_sensor_map)
|
||||
}
|
||||
|
||||
struct mlxsw_hwmon_dev {
|
||||
+ char name[MLXSW_HWMON_DEV_NAME_LEN_MAX];
|
||||
struct mlxsw_hwmon *hwmon;
|
||||
struct device *hwmon_dev;
|
||||
struct attribute_group group;
|
||||
@@ -59,6 +61,7 @@ struct mlxsw_hwmon {
|
||||
struct mlxsw_core *core;
|
||||
const struct mlxsw_bus_info *bus_info;
|
||||
struct mlxsw_hwmon_dev *main;
|
||||
+ struct mlxsw_hwmon_dev **linecards;
|
||||
};
|
||||
|
||||
static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
|
||||
@@ -405,9 +408,14 @@ mlxsw_hwmon_module_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_dev *mlxsw_hwmon_dev;
|
||||
+ int index = mlxsw_hwmon_attr->type_index;
|
||||
+
|
||||
+ mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
|
||||
+ if (strlen(mlxsw_hwmon_dev->name))
|
||||
+ index += 1;
|
||||
|
||||
- return sprintf(buf, "front panel %03u\n",
|
||||
- mlxsw_hwmon_attr->type_index);
|
||||
+ return sprintf(buf, "front panel %03u\n", index);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
@@ -691,7 +699,7 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev)
|
||||
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;
|
||||
@@ -819,6 +827,122 @@ mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon_dev *mlxsw_hwmon_dev, u8 gbox_num)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void
|
||||
+mlxsw_hwmon_got_active(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard, void *priv)
|
||||
+{
|
||||
+ struct mlxsw_hwmon *hwmon = priv;
|
||||
+ struct device *dev = hwmon->bus_info->dev;
|
||||
+ struct mlxsw_env_gearbox_sensors_map map;
|
||||
+ struct mlxsw_hwmon_dev *lc;
|
||||
+ int err;
|
||||
+
|
||||
+ lc = kzalloc(sizeof(*lc), GFP_KERNEL);
|
||||
+ if (!lc)
|
||||
+ return;
|
||||
+ lc->slot_index = slot_index;
|
||||
+ lc->hwmon = hwmon;
|
||||
+ err = mlxsw_hwmon_module_init(lc);
|
||||
+ if (err)
|
||||
+ goto err_hwmon_linecard_module_init;
|
||||
+
|
||||
+ err = mlxsw_env_sensor_map_create(hwmon->core,
|
||||
+ hwmon->bus_info, slot_index,
|
||||
+ &map);
|
||||
+ if (err)
|
||||
+ goto err_hwmon_linecard_env_sensor_map_create;
|
||||
+
|
||||
+ lc->gearbox_sensor_map = map.sensor_bit_map;
|
||||
+ err = mlxsw_hwmon_gearbox_init(lc, map.sensor_count);
|
||||
+ if (err)
|
||||
+ goto err_hwmon_linecard_gearbox_init;
|
||||
+
|
||||
+ lc->groups[0] = &lc->group;
|
||||
+ lc->group.attrs = lc->attrs;
|
||||
+ sprintf(lc->name, "%s#%02u", "linecard", slot_index);
|
||||
+ lc->hwmon_dev = hwmon_device_register_with_groups(dev, (const char *) lc->name,
|
||||
+ lc, lc->groups);
|
||||
+ if (IS_ERR(lc->hwmon_dev)) {
|
||||
+ err = PTR_ERR(lc->hwmon_dev);
|
||||
+ goto err_hwmon_linecard_register;
|
||||
+ }
|
||||
+ hwmon->linecards[slot_index - 1] = lc;
|
||||
+
|
||||
+ return;
|
||||
+
|
||||
+err_hwmon_linecard_register:
|
||||
+err_hwmon_linecard_gearbox_init:
|
||||
+ mlxsw_env_sensor_map_destroy(hwmon->bus_info,
|
||||
+ lc->gearbox_sensor_map);
|
||||
+err_hwmon_linecard_env_sensor_map_create:
|
||||
+err_hwmon_linecard_module_init:
|
||||
+ kfree(lc);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mlxsw_hwmon_got_inactive(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard, void *priv)
|
||||
+{
|
||||
+ struct mlxsw_hwmon *hwmon = priv;
|
||||
+ struct mlxsw_hwmon_dev *lc = hwmon->linecards[slot_index - 1];
|
||||
+
|
||||
+ if (lc->hwmon_dev)
|
||||
+ hwmon_device_unregister(lc->hwmon_dev);
|
||||
+ mlxsw_env_sensor_map_destroy(hwmon->bus_info,
|
||||
+ lc->gearbox_sensor_map);
|
||||
+ kfree(lc);
|
||||
+ hwmon->linecards[slot_index - 1] = NULL;
|
||||
+}
|
||||
+
|
||||
+static struct mlxsw_linecards_event_ops mlxsw_hwmon_event_ops = {
|
||||
+ .got_active = mlxsw_hwmon_got_active,
|
||||
+ .got_inactive = mlxsw_hwmon_got_inactive,
|
||||
+};
|
||||
+
|
||||
+static int mlxsw_hwmon_linecards_register(struct mlxsw_hwmon *hwmon)
|
||||
+{
|
||||
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(hwmon->core);
|
||||
+ int err;
|
||||
+
|
||||
+ if (!linecards || !linecards->count)
|
||||
+ return 0;
|
||||
+
|
||||
+ hwmon->linecards = kcalloc(linecards->count, sizeof(*hwmon->linecards),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!hwmon->linecards)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ err = mlxsw_linecards_event_ops_register(hwmon->core,
|
||||
+ &mlxsw_hwmon_event_ops,
|
||||
+ hwmon);
|
||||
+ if (err)
|
||||
+ goto err_linecards_event_ops_register;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+err_linecards_event_ops_register:
|
||||
+ kfree(hwmon->linecards);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_hwmon_linecards_unregister(struct mlxsw_hwmon *hwmon)
|
||||
+{
|
||||
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(hwmon->core);
|
||||
+ int i;
|
||||
+
|
||||
+ if (!linecards || !linecards->count)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 1; i <= linecards->count; i++) {
|
||||
+ if (hwmon->linecards[i - 1])
|
||||
+ mlxsw_hwmon_got_inactive(hwmon->core, i, NULL, hwmon);
|
||||
+ }
|
||||
+
|
||||
+ mlxsw_linecards_event_ops_unregister(hwmon->core,
|
||||
+ &mlxsw_hwmon_event_ops, hwmon);
|
||||
+ kfree(hwmon->linecards);
|
||||
+}
|
||||
+
|
||||
int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
|
||||
const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||
struct mlxsw_hwmon **p_hwmon)
|
||||
@@ -872,10 +996,16 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
|
||||
goto err_hwmon_register;
|
||||
}
|
||||
|
||||
+ err = mlxsw_hwmon_linecards_register(mlxsw_hwmon);
|
||||
+ if (err)
|
||||
+ goto err_linecards_register;
|
||||
+
|
||||
mlxsw_hwmon->main->hwmon_dev = hwmon_dev;
|
||||
*p_hwmon = mlxsw_hwmon;
|
||||
return 0;
|
||||
|
||||
+err_linecards_register:
|
||||
+ hwmon_device_unregister(mlxsw_hwmon->main->hwmon_dev);
|
||||
err_hwmon_register:
|
||||
err_gearbox_init:
|
||||
mlxsw_hwmon_gearbox_main_fini(mlxsw_hwmon->main);
|
||||
@@ -891,6 +1021,7 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
|
||||
|
||||
void mlxsw_hwmon_fini(struct mlxsw_hwmon *mlxsw_hwmon)
|
||||
{
|
||||
+ mlxsw_hwmon_linecards_unregister(mlxsw_hwmon);
|
||||
hwmon_device_unregister(mlxsw_hwmon->main->hwmon_dev);
|
||||
mlxsw_hwmon_gearbox_main_fini(mlxsw_hwmon->main);
|
||||
kfree(mlxsw_hwmon->main);
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,495 @@
|
||||
From 37eabf5ec0121c1a5092f48360b3d1208a22e655 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Thu, 30 Dec 2021 16:02:59 +0000
|
||||
Subject: [PATCH] mlxsw: minimal: Prepare driver for modular system support
|
||||
|
||||
As a preparation for line cards support:
|
||||
- Allocate per line card array according to the queried number of slots
|
||||
in the system. For each line card, allocate a port mapping array
|
||||
according to the queried maximum number of ports available in system.
|
||||
Port mapping array includes port object handle, local port number and
|
||||
module number.
|
||||
- Extend port creation APIs with 'slot_index' argument.
|
||||
- Extend port structure with slot index and module offset for this slot
|
||||
index.
|
||||
|
||||
For main board, slot will always be set to zero and these APIs will work
|
||||
as before. For the ports located on line cards, slot should be set to the
|
||||
physical slot number, where line card is located in modular systems.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/minimal.c | 293 +++++++++++++++---
|
||||
1 file changed, 242 insertions(+), 51 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
index 30925f573..59c5053dc 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
@@ -24,22 +24,40 @@ static const struct mlxsw_fw_rev mlxsw_m_fw_rev = {
|
||||
.subminor = MLXSW_M_FWREV_SUBMINOR,
|
||||
};
|
||||
|
||||
+struct mlxsw_m_line_card;
|
||||
struct mlxsw_m_port;
|
||||
|
||||
struct mlxsw_m {
|
||||
- struct mlxsw_m_port **ports;
|
||||
- int *module_to_port;
|
||||
struct mlxsw_core *core;
|
||||
const struct mlxsw_bus_info *bus_info;
|
||||
u8 base_mac[ETH_ALEN];
|
||||
u8 max_ports;
|
||||
+ u8 max_module_count; /* Maximum number of modules per-slot. */
|
||||
+ u8 num_of_slots; /* Including the main board. */
|
||||
+ struct mlxsw_m_line_card **line_cards;
|
||||
+};
|
||||
+
|
||||
+struct mlxsw_m_port_mapping {
|
||||
+ struct mlxsw_m_port *port;
|
||||
+ int module_to_port;
|
||||
+ u8 module;
|
||||
+};
|
||||
+
|
||||
+struct mlxsw_m_line_card {
|
||||
+ struct mlxsw_m *mlxsw_m;
|
||||
+ u8 max_ports;
|
||||
+ u8 module_offset;
|
||||
+ bool active;
|
||||
+ struct mlxsw_m_port_mapping port_mapping[];
|
||||
};
|
||||
|
||||
struct mlxsw_m_port {
|
||||
struct net_device *dev;
|
||||
struct mlxsw_m *mlxsw_m;
|
||||
- u8 local_port;
|
||||
+ u16 local_port;
|
||||
u8 module;
|
||||
+ u8 slot_index;
|
||||
+ u8 module_offset;
|
||||
};
|
||||
|
||||
static int mlxsw_m_base_mac_get(struct mlxsw_m *mlxsw_m)
|
||||
@@ -111,8 +129,8 @@ 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(core, 0, mlxsw_m_port->module,
|
||||
- modinfo);
|
||||
+ return mlxsw_env_get_module_info(core, mlxsw_m_port->slot_index,
|
||||
+ mlxsw_m_port->module, modinfo);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -122,7 +140,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, 0,
|
||||
+ return mlxsw_env_get_module_eeprom(netdev, core,
|
||||
+ mlxsw_m_port->slot_index,
|
||||
mlxsw_m_port->module, ee, data);
|
||||
}
|
||||
|
||||
@@ -134,7 +153,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, 0,
|
||||
+ return mlxsw_env_get_module_eeprom_by_page(core,
|
||||
+ mlxsw_m_port->slot_index,
|
||||
mlxsw_m_port->module,
|
||||
page, extack);
|
||||
}
|
||||
@@ -144,7 +164,8 @@ 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, 0, mlxsw_m_port->module,
|
||||
+ return mlxsw_env_reset_module(netdev, core, mlxsw_m_port->slot_index,
|
||||
+ mlxsw_m_port->module,
|
||||
flags);
|
||||
}
|
||||
|
||||
@@ -156,7 +177,8 @@ 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, 0, mlxsw_m_port->module,
|
||||
+ return mlxsw_env_get_module_power_mode(core, mlxsw_m_port->slot_index,
|
||||
+ mlxsw_m_port->module,
|
||||
params, extack);
|
||||
}
|
||||
|
||||
@@ -168,7 +190,8 @@ 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, 0, mlxsw_m_port->module,
|
||||
+ return mlxsw_env_set_module_power_mode(core, mlxsw_m_port->slot_index,
|
||||
+ mlxsw_m_port->module,
|
||||
params->policy, extack);
|
||||
}
|
||||
|
||||
@@ -199,19 +222,31 @@ mlxsw_m_port_dev_addr_get(struct mlxsw_m_port *mlxsw_m_port)
|
||||
* to be such it does not overflow when adding local_port
|
||||
* value.
|
||||
*/
|
||||
- dev->dev_addr[ETH_ALEN - 1] = mlxsw_m_port->module + 1;
|
||||
+ dev->dev_addr[ETH_ALEN - 1] = mlxsw_m_port->module + 1 +
|
||||
+ mlxsw_m_port->module_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static struct
|
||||
+mlxsw_m_port_mapping *mlxsw_m_port_mapping_get(struct mlxsw_m *mlxsw_m,
|
||||
+ u8 slot_index, u8 local_port)
|
||||
+{
|
||||
+ return &mlxsw_m->line_cards[slot_index]->port_mapping[local_port];
|
||||
+}
|
||||
+
|
||||
static int
|
||||
-mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u8 local_port, u8 module)
|
||||
+mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u8 slot_index, u16 local_port,
|
||||
+ u8 module)
|
||||
{
|
||||
+ struct mlxsw_m_port_mapping *port_mapping;
|
||||
struct mlxsw_m_port *mlxsw_m_port;
|
||||
struct net_device *dev;
|
||||
+ u8 module_offset;
|
||||
int err;
|
||||
|
||||
- err = mlxsw_core_port_init(mlxsw_m->core, local_port, 0,
|
||||
- module + 1, false, 0, false,
|
||||
+ module_offset = mlxsw_m->line_cards[slot_index]->module_offset;
|
||||
+ err = mlxsw_core_port_init(mlxsw_m->core, local_port, slot_index,
|
||||
+ module + 1 + module_offset, false, 0, false,
|
||||
0, mlxsw_m->base_mac,
|
||||
sizeof(mlxsw_m->base_mac));
|
||||
if (err) {
|
||||
@@ -233,6 +268,13 @@ mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u8 local_port, u8 module)
|
||||
mlxsw_m_port->mlxsw_m = mlxsw_m;
|
||||
mlxsw_m_port->local_port = local_port;
|
||||
mlxsw_m_port->module = module;
|
||||
+ mlxsw_m_port->slot_index = slot_index;
|
||||
+ /* Add module offset for line card. Offset for main board iz zero.
|
||||
+ * For line card in slot #n offset is calculated as (#n - 1)
|
||||
+ * multiplied by maximum modules number, which could be found on a line
|
||||
+ * card.
|
||||
+ */
|
||||
+ mlxsw_m_port->module_offset = module_offset;
|
||||
|
||||
dev->netdev_ops = &mlxsw_m_port_netdev_ops;
|
||||
dev->ethtool_ops = &mlxsw_m_port_ethtool_ops;
|
||||
@@ -245,7 +287,9 @@ mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u8 local_port, u8 module)
|
||||
}
|
||||
|
||||
netif_carrier_off(dev);
|
||||
- mlxsw_m->ports[local_port] = mlxsw_m_port;
|
||||
+ port_mapping = mlxsw_m_port_mapping_get(mlxsw_m, slot_index,
|
||||
+ local_port);
|
||||
+ port_mapping->port = mlxsw_m_port;
|
||||
err = register_netdev(dev);
|
||||
if (err) {
|
||||
dev_err(mlxsw_m->bus_info->dev, "Port %d: Failed to register netdev\n",
|
||||
@@ -259,7 +303,7 @@ mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u8 local_port, u8 module)
|
||||
return 0;
|
||||
|
||||
err_register_netdev:
|
||||
- mlxsw_m->ports[local_port] = NULL;
|
||||
+ port_mapping->port = NULL;
|
||||
err_dev_addr_get:
|
||||
free_netdev(dev);
|
||||
err_alloc_etherdev:
|
||||
@@ -267,72 +311,130 @@ mlxsw_m_port_create(struct mlxsw_m *mlxsw_m, u8 local_port, u8 module)
|
||||
return err;
|
||||
}
|
||||
|
||||
-static void mlxsw_m_port_remove(struct mlxsw_m *mlxsw_m, u8 local_port)
|
||||
+static void mlxsw_m_port_remove(struct mlxsw_m *mlxsw_m, u8 slot_index,
|
||||
+ u16 local_port)
|
||||
{
|
||||
- struct mlxsw_m_port *mlxsw_m_port = mlxsw_m->ports[local_port];
|
||||
+ struct mlxsw_m_port_mapping *port_mapping;
|
||||
+ struct mlxsw_m_port *mlxsw_m_port;
|
||||
|
||||
+ port_mapping = mlxsw_m_port_mapping_get(mlxsw_m, slot_index,
|
||||
+ local_port);
|
||||
+ mlxsw_m_port = port_mapping->port;
|
||||
mlxsw_core_port_clear(mlxsw_m->core, local_port, mlxsw_m);
|
||||
unregister_netdev(mlxsw_m_port->dev); /* This calls ndo_stop */
|
||||
- mlxsw_m->ports[local_port] = NULL;
|
||||
+ port_mapping->port = NULL;
|
||||
free_netdev(mlxsw_m_port->dev);
|
||||
mlxsw_core_port_fini(mlxsw_m->core, local_port);
|
||||
}
|
||||
|
||||
-static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)
|
||||
+static int mlxsw_m_port_module_map(struct mlxsw_m *mlxsw_m, u8 slot_index,
|
||||
+ u16 local_port, u8 module)
|
||||
+{
|
||||
+ struct mlxsw_m_port_mapping *port_mapping;
|
||||
+
|
||||
+ port_mapping = mlxsw_m_port_mapping_get(mlxsw_m, slot_index,
|
||||
+ local_port);
|
||||
+
|
||||
+ if (WARN_ON_ONCE(port_mapping->module_to_port >= mlxsw_m->max_ports))
|
||||
+ return -EINVAL;
|
||||
+ mlxsw_env_module_port_map(mlxsw_m->core, slot_index, module);
|
||||
+ port_mapping->module_to_port = local_port;
|
||||
+ port_mapping->module = module;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mlxsw_m_port_module_unmap(struct mlxsw_m *mlxsw_m, u8 slot_index,
|
||||
+ struct mlxsw_m_port_mapping *port_mapping)
|
||||
{
|
||||
+ port_mapping->module_to_port = -1;
|
||||
+ mlxsw_env_module_port_unmap(mlxsw_m->core, slot_index,
|
||||
+ port_mapping->module);
|
||||
+}
|
||||
+
|
||||
+static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m, u8 slot_index)
|
||||
+{
|
||||
+ struct mlxsw_m_port_mapping *port_mapping;
|
||||
+ struct mlxsw_m_line_card *line_card;
|
||||
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
int i, err;
|
||||
|
||||
- mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
+ mlxsw_reg_mgpir_pack(mgpir_pl, slot_index);
|
||||
err = mlxsw_reg_query(mlxsw_m->core, MLXSW_REG(mgpir), mgpir_pl);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+ line_card = mlxsw_m->line_cards[slot_index];
|
||||
mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL,
|
||||
- &mlxsw_m->max_ports, NULL);
|
||||
- if (!mlxsw_m->max_ports)
|
||||
+ &line_card->max_ports, NULL);
|
||||
+ if (!line_card->max_ports)
|
||||
return 0;
|
||||
|
||||
- mlxsw_m->ports = kcalloc(mlxsw_m->max_ports, sizeof(*mlxsw_m->ports),
|
||||
- GFP_KERNEL);
|
||||
- if (!mlxsw_m->ports)
|
||||
- return -ENOMEM;
|
||||
+ line_card->max_ports += 1;
|
||||
+ line_card->module_offset = slot_index ? (slot_index - 1) *
|
||||
+ mlxsw_m->max_module_count : 0;
|
||||
|
||||
- mlxsw_m->module_to_port = kmalloc_array(mlxsw_m->max_ports, sizeof(int),
|
||||
- GFP_KERNEL);
|
||||
- if (!mlxsw_m->module_to_port) {
|
||||
- err = -ENOMEM;
|
||||
- goto err_module_to_port_alloc;
|
||||
+ /* Fill out module to local port mapping array */
|
||||
+ for (i = 1; i < mlxsw_m->line_cards[slot_index]->max_ports; i++) {
|
||||
+ err = mlxsw_m_port_module_map(mlxsw_m, slot_index, i +
|
||||
+ line_card->module_offset, i - 1);
|
||||
+ if (err)
|
||||
+ goto err_module_to_port_map;
|
||||
}
|
||||
|
||||
- /* Create port objects for each entry. */
|
||||
+ /* Create port objects for each valid entry */
|
||||
for (i = 0; i < mlxsw_m->max_ports; i++) {
|
||||
- mlxsw_m->module_to_port[i] = i;
|
||||
- err = mlxsw_m_port_create(mlxsw_m, mlxsw_m->module_to_port[i], i);
|
||||
- if (err)
|
||||
- goto err_module_to_port_create;
|
||||
+ port_mapping = mlxsw_m_port_mapping_get(mlxsw_m, slot_index,
|
||||
+ i);
|
||||
+ if (port_mapping->module_to_port > 0) {
|
||||
+ err = mlxsw_m_port_create(mlxsw_m, slot_index,
|
||||
+ port_mapping->module_to_port,
|
||||
+ port_mapping->module);
|
||||
+ if (err)
|
||||
+ goto err_module_to_port_create;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_module_to_port_create:
|
||||
- for (i--; i >= 0; i--)
|
||||
- mlxsw_m_port_remove(mlxsw_m, mlxsw_m->module_to_port[i]);
|
||||
- kfree(mlxsw_m->module_to_port);
|
||||
-err_module_to_port_alloc:
|
||||
- kfree(mlxsw_m->ports);
|
||||
+ for (i--; i >= 0; i--) {
|
||||
+ port_mapping = mlxsw_m_port_mapping_get(mlxsw_m, slot_index,
|
||||
+ i);
|
||||
+ if (port_mapping->module_to_port > 0)
|
||||
+ mlxsw_m_port_remove(mlxsw_m, slot_index,
|
||||
+ port_mapping->module_to_port);
|
||||
+ }
|
||||
+ i = mlxsw_m->max_ports;
|
||||
+err_module_to_port_map:
|
||||
+ for (i--; i > 0; i--) {
|
||||
+ port_mapping = mlxsw_m_port_mapping_get(mlxsw_m, slot_index,
|
||||
+ i);
|
||||
+ if (port_mapping->module_to_port > 0)
|
||||
+ mlxsw_m_port_module_unmap(mlxsw_m, slot_index,
|
||||
+ port_mapping);
|
||||
+ }
|
||||
return err;
|
||||
}
|
||||
|
||||
-static void mlxsw_m_ports_remove(struct mlxsw_m *mlxsw_m)
|
||||
+static void mlxsw_m_ports_remove(struct mlxsw_m *mlxsw_m, u8 slot_index)
|
||||
{
|
||||
+ struct mlxsw_m_port_mapping *port_mapping;
|
||||
+ u8 module;
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < mlxsw_m->max_ports; i++)
|
||||
- mlxsw_m_port_remove(mlxsw_m, mlxsw_m->module_to_port[i]);
|
||||
-
|
||||
- kfree(mlxsw_m->module_to_port);
|
||||
- kfree(mlxsw_m->ports);
|
||||
+ for (i = 0; i < mlxsw_m->max_ports; i++) {
|
||||
+ port_mapping = mlxsw_m_port_mapping_get(mlxsw_m, slot_index,
|
||||
+ i);
|
||||
+ if (port_mapping->module_to_port > 0) {
|
||||
+ module = port_mapping->port->module;
|
||||
+ mlxsw_m_port_remove(mlxsw_m, slot_index,
|
||||
+ port_mapping->module_to_port);
|
||||
+ mlxsw_m_port_module_unmap(mlxsw_m, slot_index,
|
||||
+ port_mapping);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
static int mlxsw_m_fw_rev_validate(struct mlxsw_m *mlxsw_m)
|
||||
@@ -353,6 +455,78 @@ static int mlxsw_m_fw_rev_validate(struct mlxsw_m *mlxsw_m)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+static int mlxsw_m_get_peripheral_info(struct mlxsw_m *mlxsw_m)
|
||||
+{
|
||||
+ char mgpir_pl[MLXSW_REG_MGPIR_LEN];
|
||||
+ u8 module_count;
|
||||
+ int err;
|
||||
+
|
||||
+ mlxsw_reg_mgpir_pack(mgpir_pl, 0);
|
||||
+ err = mlxsw_reg_query(mlxsw_m->core, MLXSW_REG(mgpir), mgpir_pl);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, &module_count,
|
||||
+ &mlxsw_m->num_of_slots);
|
||||
+ /* If the system is modular, get the maximum number of modules per-slot.
|
||||
+ * Otherwise, get the maximum number of modules on the main board.
|
||||
+ */
|
||||
+ mlxsw_m->max_module_count = mlxsw_m->num_of_slots ?
|
||||
+ mlxsw_reg_mgpir_max_modules_per_slot_get(mgpir_pl) :
|
||||
+ module_count;
|
||||
+ /* Add slot for main board. */
|
||||
+ mlxsw_m->num_of_slots += 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mlxsw_env_line_cards_alloc(struct mlxsw_m *mlxsw_m)
|
||||
+{
|
||||
+ unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
|
||||
+ struct mlxsw_m_port_mapping *port_mapping;
|
||||
+ int i, j;
|
||||
+
|
||||
+ mlxsw_m->line_cards = kcalloc(mlxsw_m->num_of_slots,
|
||||
+ sizeof(*mlxsw_m->line_cards),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!mlxsw_m->line_cards)
|
||||
+ goto err_kcalloc;
|
||||
+
|
||||
+ for (i = 0; i < mlxsw_m->num_of_slots; i++) {
|
||||
+ mlxsw_m->line_cards[i] = kzalloc(struct_size(mlxsw_m->line_cards[i],
|
||||
+ port_mapping, max_ports),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!mlxsw_m->line_cards[i])
|
||||
+ goto kzalloc_err;
|
||||
+
|
||||
+ /* Invalidate the entries of module to local port mapping array */
|
||||
+ for (j = 0; j < mlxsw_m->max_ports; j++) {
|
||||
+ port_mapping = mlxsw_m_port_mapping_get(mlxsw_m, i, j);
|
||||
+ port_mapping->module_to_port = -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ mlxsw_m->max_ports = max_ports;
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+kzalloc_err:
|
||||
+ for (i--; i >= 0; i--)
|
||||
+ kfree(mlxsw_m->line_cards[i]);
|
||||
+err_kcalloc:
|
||||
+ kfree(mlxsw_m->line_cards);
|
||||
+ return -ENOMEM;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_m_line_cards_free(struct mlxsw_m *mlxsw_m)
|
||||
+{
|
||||
+ int i = mlxsw_m->num_of_slots;
|
||||
+
|
||||
+ for (i--; i >= 0; i--)
|
||||
+ kfree(mlxsw_m->line_cards[i]);
|
||||
+ kfree(mlxsw_m->line_cards);
|
||||
+}
|
||||
+
|
||||
static int mlxsw_m_init(struct mlxsw_core *mlxsw_core,
|
||||
const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||
struct netlink_ext_ack *extack)
|
||||
@@ -367,26 +541,43 @@ static int mlxsw_m_init(struct mlxsw_core *mlxsw_core,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
+ err = mlxsw_m_get_peripheral_info(mlxsw_m);
|
||||
+ if (err) {
|
||||
+ dev_err(mlxsw_m->bus_info->dev, "Failed to get peripheral info\n");
|
||||
+ 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");
|
||||
return err;
|
||||
}
|
||||
|
||||
- err = mlxsw_m_ports_create(mlxsw_m);
|
||||
+ err = mlxsw_env_line_cards_alloc(mlxsw_m);
|
||||
if (err) {
|
||||
- dev_err(mlxsw_m->bus_info->dev, "Failed to create ports\n");
|
||||
+ dev_err(mlxsw_m->bus_info->dev, "Failed to allocate memory\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
+ err = mlxsw_m_ports_create(mlxsw_m, 0);
|
||||
+ if (err) {
|
||||
+ dev_err(mlxsw_m->bus_info->dev, "Failed to create ports\n");
|
||||
+ goto err_mlxsw_m_ports_create;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
+
|
||||
+err_mlxsw_m_ports_create:
|
||||
+ mlxsw_m_line_cards_free(mlxsw_m);
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static void mlxsw_m_fini(struct mlxsw_core *mlxsw_core)
|
||||
{
|
||||
struct mlxsw_m *mlxsw_m = mlxsw_core_driver_priv(mlxsw_core);
|
||||
|
||||
- mlxsw_m_ports_remove(mlxsw_m);
|
||||
+ mlxsw_m_ports_remove(mlxsw_m, 0);
|
||||
+ mlxsw_m_line_cards_free(mlxsw_m);
|
||||
}
|
||||
|
||||
static const struct mlxsw_config_profile mlxsw_m_config_profile;
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,90 @@
|
||||
From bf88a40c8d0379e1ce8a6cc0a2bf4f935f90307c Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Wed, 15 Dec 2021 08:59:14 +0000
|
||||
Subject: [PATCH] mlxsw: core: Extend bus init function with event handler
|
||||
argument
|
||||
|
||||
The purpose of new argument - is to introduce system event handler for
|
||||
treating line card activation / deactivation signals on modular system.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.c | 3 ++-
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.h | 4 +++-
|
||||
drivers/net/ethernet/mellanox/mlxsw/i2c.c | 3 ++-
|
||||
drivers/net/ethernet/mellanox/mlxsw/pci.c | 9 ++++++---
|
||||
4 files changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
index 8c1280781..a9bb43837 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
@@ -2005,7 +2005,8 @@ __mlxsw_core_bus_device_register(const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||
}
|
||||
|
||||
res = mlxsw_driver->res_query_enabled ? &mlxsw_core->res : NULL;
|
||||
- err = mlxsw_bus->init(bus_priv, mlxsw_core, mlxsw_driver->profile, res);
|
||||
+ err = mlxsw_bus->init(bus_priv, mlxsw_core, mlxsw_driver->profile, res,
|
||||
+ mlxsw_driver->sys_event_handler);
|
||||
if (err)
|
||||
goto err_bus_init;
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
index 10ea541bb..b09f9013d 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
|
||||
@@ -390,6 +390,7 @@ struct mlxsw_driver {
|
||||
*/
|
||||
void (*ptp_transmitted)(struct mlxsw_core *mlxsw_core,
|
||||
struct sk_buff *skb, u8 local_port);
|
||||
+ void (*sys_event_handler)(struct mlxsw_core *mlxsw_core);
|
||||
|
||||
u8 txhdr_len;
|
||||
const struct mlxsw_config_profile *profile;
|
||||
@@ -432,7 +433,8 @@ struct mlxsw_bus {
|
||||
const char *kind;
|
||||
int (*init)(void *bus_priv, struct mlxsw_core *mlxsw_core,
|
||||
const struct mlxsw_config_profile *profile,
|
||||
- struct mlxsw_res *res);
|
||||
+ struct mlxsw_res *res,
|
||||
+ void (*sys_event_handler)(struct mlxsw_core *mlxsw_core));
|
||||
void (*fini)(void *bus_priv);
|
||||
bool (*skb_transmit_busy)(void *bus_priv,
|
||||
const struct mlxsw_tx_info *tx_info);
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
|
||||
index b8a5c0cbb..b75416561 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
|
||||
@@ -530,7 +530,8 @@ static int mlxsw_i2c_skb_transmit(void *bus_priv, struct sk_buff *skb,
|
||||
static int
|
||||
mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
|
||||
const struct mlxsw_config_profile *profile,
|
||||
- struct mlxsw_res *res)
|
||||
+ struct mlxsw_res *res,
|
||||
+ void (*sys_event_handler)(struct mlxsw_core *mlxsw_core))
|
||||
{
|
||||
struct mlxsw_i2c *mlxsw_i2c = bus_priv;
|
||||
char *mbox;
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c
|
||||
index dbb16ce25..e8e91130c 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c
|
||||
@@ -1411,9 +1411,12 @@ static void mlxsw_pci_free_irq_vectors(struct mlxsw_pci *mlxsw_pci)
|
||||
pci_free_irq_vectors(mlxsw_pci->pdev);
|
||||
}
|
||||
|
||||
-static int mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
|
||||
- const struct mlxsw_config_profile *profile,
|
||||
- struct mlxsw_res *res)
|
||||
+static int
|
||||
+mlxsw_pci_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
|
||||
+ const struct mlxsw_config_profile *profile,
|
||||
+ struct mlxsw_res *res,
|
||||
+ void (*sys_event_handler)(struct mlxsw_core *mlxsw_core))
|
||||
+
|
||||
{
|
||||
struct mlxsw_pci *mlxsw_pci = bus_priv;
|
||||
struct pci_dev *pdev = mlxsw_pci->pdev;
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,198 @@
|
||||
From c5235b3c4a8ab2b758140d75a7422117e917478c Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Sun, 19 Dec 2021 09:12:58 +0000
|
||||
Subject: [PATCH] mlxsw: i2c: Add support for system events handling
|
||||
|
||||
Extend i2c bus driver with interrupt handler to support system specific
|
||||
hotplug events, related to line card state change.
|
||||
Provide system IRQ line for interrupt handler. Line Id could be
|
||||
provided through the platform data if available, or could be set to the
|
||||
default value.
|
||||
Handler is supposed to be set by "mlxsw" driver through bus driver init()
|
||||
call.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/i2c.c | 110 ++++++++++++++++++++++
|
||||
1 file changed, 110 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
|
||||
index b75416561..e5883b4e8 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
+#include <linux/platform_data/mlxreg.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "cmd.h"
|
||||
@@ -51,6 +52,12 @@
|
||||
#define MLXSW_I2C_TIMEOUT_MSECS 5000
|
||||
#define MLXSW_I2C_MAX_DATA_SIZE 256
|
||||
|
||||
+#define MLXSW_I2C_WORK_ARMED 1
|
||||
+#define MLXSW_I2C_WORK_CLOSED GENMASK(31, 0)
|
||||
+#define MLXSW_I2C_WORK_DELAY (usecs_to_jiffies(100))
|
||||
+#define MLXSW_I2C_DEFAULT_IRQ 17
|
||||
+#define MLXSW_I2C_VIRT_SLAVE 0x37
|
||||
+
|
||||
/**
|
||||
* struct mlxsw_i2c - device private data:
|
||||
* @cmd: command attributes;
|
||||
@@ -64,6 +71,12 @@
|
||||
* @bus_info: bus info block;
|
||||
* @block_size: maximum block size allowed to pass to under layer;
|
||||
* @status: status to indicate chip reset or in-service update;
|
||||
+ * @pdata: device platform data;
|
||||
+ * @dwork_irq: interrupts delayed work queue;
|
||||
+ * @lock - lock for interrupts sync;
|
||||
+ * @sys_event_handler: system events handler callback;
|
||||
+ * @irq: IRQ line number;
|
||||
+ * @irq_unhandled_count: number of unhandled interrupts;
|
||||
*/
|
||||
struct mlxsw_i2c {
|
||||
struct {
|
||||
@@ -78,6 +91,12 @@ struct mlxsw_i2c {
|
||||
struct mlxsw_bus_info bus_info;
|
||||
u16 block_size;
|
||||
u8 status;
|
||||
+ struct mlxreg_core_hotplug_platform_data *pdata;
|
||||
+ struct delayed_work dwork_irq;
|
||||
+ spinlock_t lock; /* sync with interrupt */
|
||||
+ void (*sys_event_handler)(struct mlxsw_core *mlxsw_core);
|
||||
+ int irq;
|
||||
+ atomic_t irq_unhandled_count;
|
||||
};
|
||||
|
||||
#define MLXSW_I2C_READ_MSG(_client, _addr_buf, _buf, _len) { \
|
||||
@@ -538,6 +557,7 @@ mlxsw_i2c_init(void *bus_priv, struct mlxsw_core *mlxsw_core,
|
||||
int err;
|
||||
|
||||
mlxsw_i2c->core = mlxsw_core;
|
||||
+ mlxsw_i2c->sys_event_handler = sys_event_handler;
|
||||
|
||||
mbox = mlxsw_cmd_mbox_alloc();
|
||||
if (!mbox)
|
||||
@@ -568,6 +588,87 @@ static void mlxsw_i2c_fini(void *bus_priv)
|
||||
mlxsw_i2c->core = NULL;
|
||||
}
|
||||
|
||||
+static void mlxsw_i2c_work_handler(struct work_struct *work)
|
||||
+{
|
||||
+ struct mlxsw_i2c *mlxsw_i2c;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ mlxsw_i2c = container_of(work, struct mlxsw_i2c, dwork_irq.work);
|
||||
+
|
||||
+ if (atomic_read(&mlxsw_i2c->irq_unhandled_count)) {
|
||||
+ if (atomic_dec_and_test(&mlxsw_i2c->irq_unhandled_count))
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ mlxsw_i2c->sys_event_handler(mlxsw_i2c->core);
|
||||
+
|
||||
+ spin_lock_irqsave(&mlxsw_i2c->lock, flags);
|
||||
+
|
||||
+ /* It is possible, that some signals have been inserted, while
|
||||
+ * interrupts has been masked. In this case such signals could be missed.
|
||||
+ * In order to handle these signals delayed work is canceled and work task
|
||||
+ * re-scheduled for immediate execution. It allows to handle missed
|
||||
+ * signals, if any. In other case work handler just validates that no new
|
||||
+ * signals have been received during masking.
|
||||
+ */
|
||||
+ cancel_delayed_work(&mlxsw_i2c->dwork_irq);
|
||||
+ schedule_delayed_work(&mlxsw_i2c->dwork_irq, MLXSW_I2C_WORK_DELAY);
|
||||
+
|
||||
+ spin_unlock_irqrestore(&mlxsw_i2c->lock, flags);
|
||||
+
|
||||
+ if (!atomic_read(&mlxsw_i2c->irq_unhandled_count))
|
||||
+ atomic_set(&mlxsw_i2c->irq_unhandled_count, MLXSW_I2C_WORK_ARMED);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t mlxsw_i2c_irq_handler(int irq, void *dev)
|
||||
+{
|
||||
+ struct mlxsw_i2c *mlxsw_i2c = (struct mlxsw_i2c *)dev;
|
||||
+
|
||||
+ /* Schedule work task for immediate execution.*/
|
||||
+ schedule_delayed_work(&mlxsw_i2c->dwork_irq, 0);
|
||||
+
|
||||
+ return IRQ_NONE;
|
||||
+}
|
||||
+
|
||||
+static int mlxsw_i2c_event_handler_register(struct mlxsw_i2c *mlxsw_i2c)
|
||||
+{
|
||||
+ int err;
|
||||
+
|
||||
+ /* Initialize interrupt handler if system hotplug driver is reachable
|
||||
+ * and platform data is available.
|
||||
+ */
|
||||
+ if (!IS_REACHABLE(CONFIG_MLXREG_HOTPLUG))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (mlxsw_i2c->pdata && mlxsw_i2c->pdata->irq)
|
||||
+ mlxsw_i2c->irq = mlxsw_i2c->pdata->irq;
|
||||
+
|
||||
+ if (!mlxsw_i2c->irq)
|
||||
+ return 0;
|
||||
+
|
||||
+ err = request_irq(mlxsw_i2c->irq, mlxsw_i2c_irq_handler,
|
||||
+ IRQF_TRIGGER_FALLING | IRQF_SHARED, "mlxsw-i2c",
|
||||
+ mlxsw_i2c);
|
||||
+ if (err) {
|
||||
+ dev_err(mlxsw_i2c->bus_info.dev, "Failed to request irq: %d\n",
|
||||
+ err);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ spin_lock_init(&mlxsw_i2c->lock);
|
||||
+ INIT_DELAYED_WORK(&mlxsw_i2c->dwork_irq, mlxsw_i2c_work_handler);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_i2c_event_handler_unregister(struct mlxsw_i2c *mlxsw_i2c)
|
||||
+{
|
||||
+ if (!IS_REACHABLE(CONFIG_MLXREG_HOTPLUG) || !mlxsw_i2c->irq)
|
||||
+ return;
|
||||
+ cancel_delayed_work_sync(&mlxsw_i2c->dwork_irq);
|
||||
+ free_irq(mlxsw_i2c->irq, mlxsw_i2c);
|
||||
+}
|
||||
+
|
||||
static const struct mlxsw_bus mlxsw_i2c_bus = {
|
||||
.kind = "i2c",
|
||||
.init = mlxsw_i2c_init,
|
||||
@@ -662,6 +763,7 @@ static int mlxsw_i2c_probe(struct i2c_client *client,
|
||||
mlxsw_i2c->bus_info.dev = &client->dev;
|
||||
mlxsw_i2c->bus_info.low_frequency = true;
|
||||
mlxsw_i2c->dev = &client->dev;
|
||||
+ mlxsw_i2c->pdata = client->dev.platform_data;
|
||||
|
||||
err = mlxsw_core_bus_device_register(&mlxsw_i2c->bus_info,
|
||||
&mlxsw_i2c_bus, mlxsw_i2c, false,
|
||||
@@ -671,6 +773,12 @@ static int mlxsw_i2c_probe(struct i2c_client *client,
|
||||
return err;
|
||||
}
|
||||
|
||||
+ if (client->addr == MLXSW_I2C_VIRT_SLAVE)
|
||||
+ mlxsw_i2c->irq = MLXSW_I2C_DEFAULT_IRQ;
|
||||
+ err = mlxsw_i2c_event_handler_register(mlxsw_i2c);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
return 0;
|
||||
|
||||
errout:
|
||||
@@ -684,6 +792,8 @@ static int mlxsw_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
|
||||
|
||||
+ atomic_set(&mlxsw_i2c->irq_unhandled_count, MLXSW_I2C_WORK_CLOSED);
|
||||
+ mlxsw_i2c_event_handler_unregister(mlxsw_i2c);
|
||||
mlxsw_core_bus_device_unregister(mlxsw_i2c->core, false);
|
||||
mutex_destroy(&mlxsw_i2c->cmd.lock);
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,27 @@
|
||||
From 8099c3baf5f819fdf187b67cc3ed0ce25360cf88 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Sun, 19 Dec 2021 09:31:32 +0000
|
||||
Subject: [PATCH] mlxsw: core: Export line card API
|
||||
|
||||
Export API mlxsw_core_linecards() for being used by 'minimal' driver.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/core.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
index a9bb43837..a26c6d880 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
|
||||
@@ -103,6 +103,7 @@ struct mlxsw_linecards *mlxsw_core_linecards(struct mlxsw_core *mlxsw_core)
|
||||
{
|
||||
return mlxsw_core->linecards;
|
||||
}
|
||||
+EXPORT_SYMBOL(mlxsw_core_linecards);
|
||||
|
||||
#define MLXSW_PORT_MAX_PORTS_DEFAULT 0x40
|
||||
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,61 @@
|
||||
From b526413a86afcd1d6bd3f4e05f25631c8103f617 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Sun, 19 Dec 2021 09:25:35 +0000
|
||||
Subject: [PATCH] mlxsw: minimal: Add system event handler
|
||||
|
||||
Add system event handler for treating line card specific signals on
|
||||
modular system. These signals indicate line card state changes, like
|
||||
line card activation or de-activation.
|
||||
When such signals are received, driver should create or destroy "hwmon"
|
||||
"thermal" and module info objects, associated with line card in a slot,
|
||||
for which signal has been received.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/minimal.c | 23 +++++++++++++++++++
|
||||
1 file changed, 23 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
index 59c5053dc..27afb28e4 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
@@ -527,6 +527,28 @@ static void mlxsw_m_line_cards_free(struct mlxsw_m *mlxsw_m)
|
||||
kfree(mlxsw_m->line_cards);
|
||||
}
|
||||
|
||||
+static void mlxsw_m_sys_event_handler(struct mlxsw_core *mlxsw_core)
|
||||
+{
|
||||
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(mlxsw_core);
|
||||
+ struct mlxsw_m *mlxsw_m = mlxsw_core_driver_priv(mlxsw_core);
|
||||
+ char mddq_pl[MLXSW_REG_MDDQ_LEN];
|
||||
+ int i, err;
|
||||
+
|
||||
+ if (!linecards)
|
||||
+ return;
|
||||
+
|
||||
+ /* Handle line cards, for which active status has been changed. */
|
||||
+ for (i = 1; i <= linecards->count; i++) {
|
||||
+ mlxsw_reg_mddq_slot_info_pack(mddq_pl, i, false);
|
||||
+ err = mlxsw_reg_query(mlxsw_m->core, MLXSW_REG(mddq), mddq_pl);
|
||||
+ if (err)
|
||||
+ dev_err(mlxsw_m->bus_info->dev, "Fail to query MDDQ register for slot %d\n",
|
||||
+ i);
|
||||
+
|
||||
+ mlxsw_linecard_status_process(mlxsw_m->core, mddq_pl);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int mlxsw_m_init(struct mlxsw_core *mlxsw_core,
|
||||
const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||
struct netlink_ext_ack *extack)
|
||||
@@ -587,6 +609,7 @@ static struct mlxsw_driver mlxsw_m_driver = {
|
||||
.priv_size = sizeof(struct mlxsw_m),
|
||||
.init = mlxsw_m_init,
|
||||
.fini = mlxsw_m_fini,
|
||||
+ .sys_event_handler = mlxsw_m_sys_event_handler,
|
||||
.profile = &mlxsw_m_config_profile,
|
||||
.res_query_enabled = true,
|
||||
};
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,119 @@
|
||||
From 20b2dd627f42e79a8fce30d29d4cea64f6636521 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Sun, 19 Dec 2021 09:40:34 +0000
|
||||
Subject: [PATCH] mlxsw: minimal: Add interfaces for line card initialization
|
||||
and de-initialization
|
||||
|
||||
Add callback functions for line card 'netdevice' objects initialization
|
||||
and de-initialization. Each line card is associated with the set of
|
||||
'netdevices', which are created/destroyed dynamically, when line card
|
||||
is getting to active / inactive states.
|
||||
|
||||
Add APIs for line card registration and de-registration during init and
|
||||
de-init.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
drivers/net/ethernet/mellanox/mlxsw/minimal.c | 70 +++++++++++++++++++
|
||||
1 file changed, 70 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
index 27afb28e4..0b605c6aa 100644
|
||||
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
|
||||
@@ -549,6 +549,69 @@ static void mlxsw_m_sys_event_handler(struct mlxsw_core *mlxsw_core)
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+mlxsw_m_got_active(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard, void *priv)
|
||||
+{
|
||||
+ struct mlxsw_m *mlxsw_m = priv;
|
||||
+ int err;
|
||||
+
|
||||
+ err = mlxsw_m_ports_create(mlxsw_m, slot_index);
|
||||
+ if (err) {
|
||||
+ dev_err(mlxsw_m->bus_info->dev, "Failed to set line card at slot %d\n",
|
||||
+ slot_index);
|
||||
+ goto mlxsw_m_ports_create_fail;
|
||||
+ }
|
||||
+ mlxsw_m->line_cards[slot_index]->active = true;
|
||||
+
|
||||
+mlxsw_m_ports_create_fail:
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mlxsw_m_got_inactive(struct mlxsw_core *mlxsw_core, u8 slot_index,
|
||||
+ const struct mlxsw_linecard *linecard, void *priv)
|
||||
+{
|
||||
+ struct mlxsw_m *mlxsw_m = priv;
|
||||
+
|
||||
+ mlxsw_m_ports_remove(mlxsw_m, slot_index);
|
||||
+ mlxsw_m->line_cards[slot_index]->active = false;
|
||||
+}
|
||||
+
|
||||
+static struct mlxsw_linecards_event_ops mlxsw_m_event_ops = {
|
||||
+ .got_active = mlxsw_m_got_active,
|
||||
+ .got_inactive = mlxsw_m_got_inactive,
|
||||
+};
|
||||
+
|
||||
+static int mlxsw_m_linecards_register(struct mlxsw_m *mlxsw_m)
|
||||
+{
|
||||
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(mlxsw_m->core);
|
||||
+
|
||||
+ if (!linecards || !linecards->count)
|
||||
+ return 0;
|
||||
+
|
||||
+ return mlxsw_linecards_event_ops_register(mlxsw_m->core,
|
||||
+ &mlxsw_m_event_ops,
|
||||
+ mlxsw_m);
|
||||
+}
|
||||
+
|
||||
+static void mlxsw_m_linecards_unregister(struct mlxsw_m *mlxsw_m)
|
||||
+{
|
||||
+ struct mlxsw_linecards *linecards = mlxsw_core_linecards(mlxsw_m->core);
|
||||
+ int i;
|
||||
+
|
||||
+ if (!linecards || !linecards->count)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 1; i <= linecards->count; i++) {
|
||||
+ if (mlxsw_m->line_cards[i]->active)
|
||||
+ mlxsw_m_got_inactive(mlxsw_m->core, i, NULL, mlxsw_m);
|
||||
+ }
|
||||
+
|
||||
+ mlxsw_linecards_event_ops_unregister(mlxsw_m->core,
|
||||
+ &mlxsw_m_event_ops, mlxsw_m);
|
||||
+}
|
||||
+
|
||||
static int mlxsw_m_init(struct mlxsw_core *mlxsw_core,
|
||||
const struct mlxsw_bus_info *mlxsw_bus_info,
|
||||
struct netlink_ext_ack *extack)
|
||||
@@ -587,8 +650,14 @@ static int mlxsw_m_init(struct mlxsw_core *mlxsw_core,
|
||||
goto err_mlxsw_m_ports_create;
|
||||
}
|
||||
|
||||
+ err = mlxsw_m_linecards_register(mlxsw_m);
|
||||
+ if (err)
|
||||
+ goto err_linecards_register;
|
||||
+
|
||||
return 0;
|
||||
|
||||
+err_linecards_register:
|
||||
+ mlxsw_m_ports_remove(mlxsw_m, 0);
|
||||
err_mlxsw_m_ports_create:
|
||||
mlxsw_m_line_cards_free(mlxsw_m);
|
||||
return err;
|
||||
@@ -598,6 +667,7 @@ static void mlxsw_m_fini(struct mlxsw_core *mlxsw_core)
|
||||
{
|
||||
struct mlxsw_m *mlxsw_m = mlxsw_core_driver_priv(mlxsw_core);
|
||||
|
||||
+ mlxsw_m_linecards_unregister(mlxsw_m);
|
||||
mlxsw_m_ports_remove(mlxsw_m, 0);
|
||||
mlxsw_m_line_cards_free(mlxsw_m);
|
||||
}
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,420 @@
|
||||
From bb18ddc163092447e40f8aba96140280e2201409 Mon Sep 17 00:00:00 2001
|
||||
From: Vadim Pasternak <vadimp@nvidia.com>
|
||||
Date: Mon, 14 Feb 2022 13:24:44 +0200
|
||||
Subject: [PATCH] platform: mellanox: Introduce support for rack manager switch
|
||||
|
||||
The rack switch is designed to provide high bandwidth, low latency
|
||||
connectivity using optical fiber as the primary interconnect.
|
||||
|
||||
System supports 32 OSFP ports, non-blocking switching capacity of
|
||||
25.6Tbps.
|
||||
System equipped with:
|
||||
- 2 replaceable power supplies (AC) with 1+1 redundancy model.
|
||||
- 7 replaceable fan drawers with 6+1 redundancy model.
|
||||
- 2 External Root of Trust or EROT (Glacier) devices for securing
|
||||
ASICs firmware.
|
||||
|
||||
Signed-off-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
drivers/platform/x86/mlx-platform.c | 259 ++++++++++++++++++++++++++++
|
||||
1 file changed, 259 insertions(+)
|
||||
|
||||
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
|
||||
index d0bb2becf..f1d0cc1aa 100644
|
||||
--- a/drivers/platform/x86/mlx-platform.c
|
||||
+++ b/drivers/platform/x86/mlx-platform.c
|
||||
@@ -90,6 +90,12 @@
|
||||
#define MLXPLAT_CPLD_LPC_REG_FAN_OFFSET 0x88
|
||||
#define MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET 0x89
|
||||
#define MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET 0x8a
|
||||
+#define MLXPLAT_CPLD_LPC_REG_EROT_OFFSET 0x91
|
||||
+#define MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET 0x92
|
||||
+#define MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET 0x93
|
||||
+#define MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET 0x94
|
||||
+#define MLXPLAT_CPLD_LPC_REG_EROTE_EVENT_OFFSET 0x95
|
||||
+#define MLXPLAT_CPLD_LPC_REG_EROTE_MASK_OFFSET 0x96
|
||||
#define MLXPLAT_CPLD_LPC_REG_LC_VR_OFFSET 0x9a
|
||||
#define MLXPLAT_CPLD_LPC_REG_LC_VR_EVENT_OFFSET 0x9b
|
||||
#define MLXPLAT_CPLD_LPC_REG_LC_VR_MASK_OFFSET 0x9c
|
||||
@@ -109,6 +115,8 @@
|
||||
#define MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET 0xaa
|
||||
#define MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET 0xab
|
||||
#define MLXPLAT_CPLD_LPC_REG_LC_PWR_ON 0xb2
|
||||
+#define MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET 0xc2
|
||||
+#define MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT 0xc3
|
||||
#define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET 0xc7
|
||||
#define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET 0xc8
|
||||
#define MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET 0xc9
|
||||
@@ -214,6 +222,7 @@
|
||||
#define MLXPLAT_CPLD_LED_HI_NIBBLE_MASK GENMASK(3, 0)
|
||||
#define MLXPLAT_CPLD_VOLTREG_UPD_MASK GENMASK(5, 4)
|
||||
#define MLXPLAT_CPLD_GWP_MASK GENMASK(0, 0)
|
||||
+#define MLXPLAT_CPLD_EROT_MASK GENMASK(1, 0)
|
||||
#define MLXPLAT_CPLD_I2C_CAP_BIT 0x04
|
||||
#define MLXPLAT_CPLD_I2C_CAP_MASK GENMASK(5, MLXPLAT_CPLD_I2C_CAP_BIT)
|
||||
|
||||
@@ -243,6 +252,7 @@
|
||||
#define MLXPLAT_CPLD_CH2_ETH_MODULAR 3
|
||||
#define MLXPLAT_CPLD_CH3_ETH_MODULAR 43
|
||||
#define MLXPLAT_CPLD_CH4_ETH_MODULAR 51
|
||||
+#define MLXPLAT_CPLD_CH2_RACK_SWITCH 18
|
||||
|
||||
/* Number of LPC attached MUX platform devices */
|
||||
#define MLXPLAT_CPLD_LPC_MUX_DEVS 4
|
||||
@@ -280,6 +290,9 @@
|
||||
/* Minimum power required for turning on Ethernet modular system (WATT) */
|
||||
#define MLXPLAT_CPLD_ETH_MODULAR_PWR_MIN 50
|
||||
|
||||
+/* Default value for PWM control register for rack switch system */
|
||||
+#define MLXPLAT_REGMAP_NVSWITCH_PWM_DEFAULT 0xf4
|
||||
+
|
||||
/* mlxplat_priv - platform private data
|
||||
* @pdev_i2c - i2c controller platform device
|
||||
* @pdev_mux - array of mux platform devices
|
||||
@@ -460,6 +473,36 @@ static struct i2c_mux_reg_platform_data mlxplat_modular_mux_data[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+/* Platform channels for rack swicth system family */
|
||||
+static const int mlxplat_rack_switch_channels[] = {
|
||||
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
+};
|
||||
+
|
||||
+/* Platform rack switch mux data */
|
||||
+static struct i2c_mux_reg_platform_data mlxplat_rack_switch_mux_data[] = {
|
||||
+ {
|
||||
+ .parent = 1,
|
||||
+ .base_nr = MLXPLAT_CPLD_CH1,
|
||||
+ .write_only = 1,
|
||||
+ .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
|
||||
+ .reg_size = 1,
|
||||
+ .idle_in_use = 1,
|
||||
+ .values = mlxplat_rack_switch_channels,
|
||||
+ .n_values = ARRAY_SIZE(mlxplat_rack_switch_channels),
|
||||
+ },
|
||||
+ {
|
||||
+ .parent = 1,
|
||||
+ .base_nr = MLXPLAT_CPLD_CH2_RACK_SWITCH,
|
||||
+ .write_only = 1,
|
||||
+ .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
|
||||
+ .reg_size = 1,
|
||||
+ .idle_in_use = 1,
|
||||
+ .values = mlxplat_msn21xx_channels,
|
||||
+ .n_values = ARRAY_SIZE(mlxplat_msn21xx_channels),
|
||||
+ },
|
||||
+
|
||||
+};
|
||||
+
|
||||
/* Platform hotplug devices */
|
||||
static struct i2c_board_info mlxplat_mlxcpld_pwr[] = {
|
||||
{
|
||||
@@ -2064,6 +2107,97 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_chassis_blade_data = {
|
||||
.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
|
||||
};
|
||||
|
||||
+/* Platform hotplug for switch systems family data */
|
||||
+static struct mlxreg_core_data mlxplat_mlxcpld_erot_ap_items_data[] = {
|
||||
+ {
|
||||
+ .label = "erot1_ap",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_EROT_OFFSET,
|
||||
+ .mask = BIT(0),
|
||||
+ .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "erot2_ap",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_EROT_OFFSET,
|
||||
+ .mask = BIT(1),
|
||||
+ .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct mlxreg_core_data mlxplat_mlxcpld_erot_error_items_data[] = {
|
||||
+ {
|
||||
+ .label = "erot1_error",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET,
|
||||
+ .mask = BIT(0),
|
||||
+ .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "erot2_error",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET,
|
||||
+ .mask = BIT(1),
|
||||
+ .hpdev.nr = MLXPLAT_CPLD_NR_NONE,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static struct mlxreg_core_item mlxplat_mlxcpld_rack_switch_items[] = {
|
||||
+ {
|
||||
+ .data = mlxplat_mlxcpld_ext_psu_items_data,
|
||||
+ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
|
||||
+ .mask = MLXPLAT_CPLD_PSU_EXT_MASK,
|
||||
+ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
|
||||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_ext_psu_items_data),
|
||||
+ .inversed = 1,
|
||||
+ .health = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .data = mlxplat_mlxcpld_ext_pwr_items_data,
|
||||
+ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
|
||||
+ .mask = MLXPLAT_CPLD_PWR_EXT_MASK,
|
||||
+ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
|
||||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_ext_pwr_items_data),
|
||||
+ .inversed = 0,
|
||||
+ .health = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .data = mlxplat_mlxcpld_default_ng_fan_items_data,
|
||||
+ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
|
||||
+ .mask = MLXPLAT_CPLD_FAN_NG_MASK,
|
||||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
|
||||
+ .inversed = 1,
|
||||
+ .health = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .data = mlxplat_mlxcpld_erot_ap_items_data,
|
||||
+ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_EROT_OFFSET,
|
||||
+ .mask = MLXPLAT_CPLD_EROT_MASK,
|
||||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_erot_ap_items_data),
|
||||
+ .inversed = 1,
|
||||
+ .health = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .data = mlxplat_mlxcpld_erot_error_items_data,
|
||||
+ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET,
|
||||
+ .mask = MLXPLAT_CPLD_EROT_MASK,
|
||||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_erot_error_items_data),
|
||||
+ .inversed = 1,
|
||||
+ .health = false,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static
|
||||
+struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_rack_switch_data = {
|
||||
+ .items = mlxplat_mlxcpld_rack_switch_items,
|
||||
+ .counter = ARRAY_SIZE(mlxplat_mlxcpld_rack_switch_items),
|
||||
+ .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
|
||||
+ .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
|
||||
+ .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
|
||||
+ .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW,
|
||||
+};
|
||||
+
|
||||
/* Platform led default data */
|
||||
static struct mlxreg_core_data mlxplat_mlxcpld_default_led_data[] = {
|
||||
{
|
||||
@@ -2947,6 +3081,42 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
|
||||
.mask = GENMASK(7, 0) & ~BIT(2),
|
||||
.mode = 0444,
|
||||
},
|
||||
+ {
|
||||
+ .label = "erot1_reset",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(6),
|
||||
+ .mode = 0644,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "erot2_reset",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_RESET_GP2_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(7),
|
||||
+ .mode = 0644,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "erot1_recovery",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(6),
|
||||
+ .mode = 0644,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "erot2_recovery",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(7),
|
||||
+ .mode = 0644,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "erot1_wp",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(4),
|
||||
+ .mode = 0644,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "erot2_wp",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(5),
|
||||
+ .mode = 0644,
|
||||
+ },
|
||||
{
|
||||
.label = "reset_long_pb",
|
||||
.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
|
||||
@@ -3142,6 +3312,25 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
|
||||
.mask = GENMASK(7, 0) & ~BIT(4),
|
||||
.mode = 0644,
|
||||
},
|
||||
+ {
|
||||
+ .label = "erot1_ap_reset",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(0),
|
||||
+ .mode = 0444,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "erot2_ap_reset",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(1),
|
||||
+ .mode = 0444,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "spi_chnl_select",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT,
|
||||
+ .mask = GENMASK(7, 0),
|
||||
+ .bit = 1,
|
||||
+ .mode = 0644,
|
||||
+ },
|
||||
{
|
||||
.label = "config1",
|
||||
.reg = MLXPLAT_CPLD_LPC_REG_CONFIG1_OFFSET,
|
||||
@@ -4257,6 +4446,10 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
|
||||
case MLXPLAT_CPLD_LPC_REG_PWR_MASK_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROTE_EVENT_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROTE_MASK_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_AGGRLC_MASK_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_IN_EVENT_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_IN_MASK_OFFSET:
|
||||
@@ -4274,6 +4467,8 @@ static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_PWR_ON:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT:
|
||||
case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
|
||||
@@ -4358,6 +4553,12 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
|
||||
case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROT_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROTE_EVENT_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROTE_MASK_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_AGGRLC_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_AGGRLC_MASK_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET:
|
||||
@@ -4382,6 +4583,7 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_PWR_ON:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT:
|
||||
case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
|
||||
@@ -4492,6 +4694,12 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
|
||||
case MLXPLAT_CPLD_LPC_REG_FAN_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROT_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROT_EVENT_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROT_MASK_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROTE_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROTE_EVENT_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_EROTE_MASK_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_AGGRLC_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_AGGRLC_MASK_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_IN_OFFSET:
|
||||
@@ -4516,6 +4724,8 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_SD_EVENT_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_SD_MASK_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_LC_PWR_ON:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET:
|
||||
+ case MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT:
|
||||
case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
|
||||
case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
|
||||
@@ -4583,6 +4793,13 @@ static const struct reg_default mlxplat_mlxcpld_regmap_ng400[] = {
|
||||
{ MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET, 0x00 },
|
||||
};
|
||||
|
||||
+static const struct reg_default mlxplat_mlxcpld_regmap_rack_switch[] = {
|
||||
+ { MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, MLXPLAT_REGMAP_NVSWITCH_PWM_DEFAULT },
|
||||
+ { MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET, 0x00 },
|
||||
+ { MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET, 0x00 },
|
||||
+ { MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET, 0x00 },
|
||||
+};
|
||||
+
|
||||
static const struct reg_default mlxplat_mlxcpld_regmap_eth_modular[] = {
|
||||
{ MLXPLAT_CPLD_LPC_REG_GP2_OFFSET, 0x61 },
|
||||
{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
|
||||
@@ -4676,6 +4893,20 @@ static const struct regmap_config mlxplat_mlxcpld_regmap_config_ng400 = {
|
||||
.reg_write = mlxplat_mlxcpld_reg_write,
|
||||
};
|
||||
|
||||
+static const struct regmap_config mlxplat_mlxcpld_regmap_config_rack_switch = {
|
||||
+ .reg_bits = 8,
|
||||
+ .val_bits = 8,
|
||||
+ .max_register = 255,
|
||||
+ .cache_type = REGCACHE_FLAT,
|
||||
+ .writeable_reg = mlxplat_mlxcpld_writeable_reg,
|
||||
+ .readable_reg = mlxplat_mlxcpld_readable_reg,
|
||||
+ .volatile_reg = mlxplat_mlxcpld_volatile_reg,
|
||||
+ .reg_defaults = mlxplat_mlxcpld_regmap_rack_switch,
|
||||
+ .num_reg_defaults = ARRAY_SIZE(mlxplat_mlxcpld_regmap_rack_switch),
|
||||
+ .reg_read = mlxplat_mlxcpld_reg_read,
|
||||
+ .reg_write = mlxplat_mlxcpld_reg_write,
|
||||
+};
|
||||
+
|
||||
static const struct regmap_config mlxplat_mlxcpld_regmap_config_eth_modular = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@@ -4957,6 +5188,27 @@ static int __init mlxplat_dmi_modular_matched(const struct dmi_system_id *dmi)
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static int __init mlxplat_dmi_rack_switch_matched(const struct dmi_system_id *dmi)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
|
||||
+ mlxplat_mux_num = ARRAY_SIZE(mlxplat_rack_switch_mux_data);
|
||||
+ mlxplat_mux_data = mlxplat_rack_switch_mux_data;
|
||||
+ mlxplat_hotplug = &mlxplat_mlxcpld_rack_switch_data;
|
||||
+ mlxplat_hotplug->deferred_nr =
|
||||
+ mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
|
||||
+ mlxplat_led = &mlxplat_default_ng_led_data;
|
||||
+ mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
|
||||
+ mlxplat_fan = &mlxplat_default_fan_data;
|
||||
+ for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
|
||||
+ mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
|
||||
+ mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
|
||||
+ mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_rack_switch;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
|
||||
{
|
||||
.callback = mlxplat_dmi_default_wc_matched,
|
||||
@@ -5007,6 +5259,13 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "VMOD0009"),
|
||||
},
|
||||
},
|
||||
+ {
|
||||
+ .callback = mlxplat_dmi_rack_switch_matched,
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "VMOD0010"),
|
||||
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "HI142"),
|
||||
+ },
|
||||
+ },
|
||||
{
|
||||
.callback = mlxplat_dmi_ng400_matched,
|
||||
.matches = {
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,30 @@
|
||||
From d3b1142ce6c3fbb02c39fc8d2e9f24ecbf466973 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Shych <michaelsh@nvidia.com>
|
||||
Date: Sun, 4 Sep 2022 10:41:45 +0300
|
||||
Subject: [PATCH] platform: mellanox: fix reset_pwr_converter_fail attribute.
|
||||
|
||||
Change incorrect reset_voltmon_upgrade_fail atitribute name to
|
||||
reset_pwr_converter_fail.
|
||||
|
||||
Signed-off-by: Michael Shych <michaelsh@nvidia.com>
|
||||
Reviewed-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
drivers/platform/x86/mlx-platform.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
|
||||
index f1d0cc1aa..31c5cc10f 100644
|
||||
--- a/drivers/platform/x86/mlx-platform.c
|
||||
+++ b/drivers/platform/x86/mlx-platform.c
|
||||
@@ -3904,7 +3904,7 @@ static struct mlxreg_core_data mlxplat_mlxcpld_chassis_blade_regs_io_data[] = {
|
||||
.mode = 0444,
|
||||
},
|
||||
{
|
||||
- .label = "reset_voltmon_upgrade_fail",
|
||||
+ .label = "reset_pwr_converter_fail",
|
||||
.reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
|
||||
.mask = GENMASK(7, 0) & ~BIT(0),
|
||||
.mode = 0444,
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,38 @@
|
||||
From 85ac7ddf15f380460b9e17f0e2c99aa8e476ef3f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Shych <michaelsh@nvidia.com>
|
||||
Date: Sun, 4 Sep 2022 10:46:01 +0300
|
||||
Subject: [PATCH] Documentation/ABI: fix description of fix
|
||||
reset_pwr_converter_fail attribute.
|
||||
|
||||
Change description of incorrect reset_voltmon_upgrade_fail atitribute
|
||||
name to reset_pwr_converter_fail.
|
||||
|
||||
Signed-off-by: Michael Shych <michaelsh@nvidia.com>
|
||||
Reviewed-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
Documentation/ABI/stable/sysfs-driver-mlxreg-io | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Documentation/ABI/stable/sysfs-driver-mlxreg-io b/Documentation/ABI/stable/sysfs-driver-mlxreg-io
|
||||
index 0913a8daf..ac503e84e 100644
|
||||
--- a/Documentation/ABI/stable/sysfs-driver-mlxreg-io
|
||||
+++ b/Documentation/ABI/stable/sysfs-driver-mlxreg-io
|
||||
@@ -103,13 +103,13 @@ Description: These files show the system reset cause, as following: power
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_comex_pwr_fail
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_from_comex
|
||||
What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_system
|
||||
-What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_voltmon_upgrade_fail
|
||||
+What: /sys/devices/platform/mlxplat/mlxreg-io/hwmon/hwmon*/reset_pwr_converter_fail
|
||||
Date: November 2018
|
||||
KernelVersion: 5.0
|
||||
Contact: Vadim Pasternak <vadimpmellanox.com>
|
||||
Description: These files show the system reset cause, as following: ComEx
|
||||
power fail, reset from ComEx, system platform reset, reset
|
||||
- due to voltage monitor devices upgrade failure,
|
||||
+ due to power converter devices failure,
|
||||
Value 1 in file means this is reset cause, 0 - otherwise.
|
||||
Only one bit could be 1 at the same time, representing only
|
||||
the last reset cause.
|
||||
--
|
||||
2.30.2
|
||||
|
@ -0,0 +1,295 @@
|
||||
From 4c485e6f50001f0ea691b0ce5c0d90a118e8d360 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Shych <michaelsh@nvidia.com>
|
||||
Date: Sun, 4 Sep 2022 14:03:58 +0300
|
||||
Subject: [PATCH] platform: mellanox: Introduce support for next-generation
|
||||
800GB/s ethernet switch.
|
||||
|
||||
Introduce support for Nvidia next-generation 800GB/s ethernet switch - SN5600.
|
||||
SN5600 is 51.2 Tbps Ethernet switch based on Nvidia Spectrum-4 ASIC.
|
||||
It can provide up to 64x800Gb/s (ETH) full bidirectional bandwidth per port
|
||||
using PAM-4 modulations. The system supports 64 Belly to Belly 2x4 OSFP cages.
|
||||
The switch was designed to fit standard 2U racks.
|
||||
|
||||
Features:
|
||||
- 64 OSFP ports support 800GbE - 10GbE speed.
|
||||
- Additional 25GbE - 1GbE service port on the front panel.
|
||||
- Air-cooled with 3 + 1 redundant fan units.
|
||||
- 1 + 1 redundant 3000W or 3600W PSUs.
|
||||
- System management board is based on Intel Coffee-lake CPU E-2276
|
||||
with secure-boot support.
|
||||
|
||||
Signed-off-by: Michael Shych <michaelsh@nvidia.com>
|
||||
Reviewed-by: Vadim Pasternak <vadimp@nvidia.com>
|
||||
---
|
||||
drivers/platform/x86/mlx-platform.c | 178 ++++++++++++++++++++++++++++
|
||||
1 file changed, 178 insertions(+)
|
||||
|
||||
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
|
||||
index 31c5cc10f..7e9f2a5ab 100644
|
||||
--- a/drivers/platform/x86/mlx-platform.c
|
||||
+++ b/drivers/platform/x86/mlx-platform.c
|
||||
@@ -253,6 +253,7 @@
|
||||
#define MLXPLAT_CPLD_CH3_ETH_MODULAR 43
|
||||
#define MLXPLAT_CPLD_CH4_ETH_MODULAR 51
|
||||
#define MLXPLAT_CPLD_CH2_RACK_SWITCH 18
|
||||
+#define MLXPLAT_CPLD_CH2_NG800 34
|
||||
|
||||
/* Number of LPC attached MUX platform devices */
|
||||
#define MLXPLAT_CPLD_LPC_MUX_DEVS 4
|
||||
@@ -503,6 +504,37 @@ static struct i2c_mux_reg_platform_data mlxplat_rack_switch_mux_data[] = {
|
||||
|
||||
};
|
||||
|
||||
+/* Platform channels for ng800 system family */
|
||||
+static const int mlxplat_ng800_channels[] = {
|
||||
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
|
||||
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
|
||||
+};
|
||||
+
|
||||
+/* Platform ng800 mux data */
|
||||
+static struct i2c_mux_reg_platform_data mlxplat_ng800_mux_data[] = {
|
||||
+ {
|
||||
+ .parent = 1,
|
||||
+ .base_nr = MLXPLAT_CPLD_CH1,
|
||||
+ .write_only = 1,
|
||||
+ .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG1,
|
||||
+ .reg_size = 1,
|
||||
+ .idle_in_use = 1,
|
||||
+ .values = mlxplat_ng800_channels,
|
||||
+ .n_values = ARRAY_SIZE(mlxplat_ng800_channels),
|
||||
+ },
|
||||
+ {
|
||||
+ .parent = 1,
|
||||
+ .base_nr = MLXPLAT_CPLD_CH2_NG800,
|
||||
+ .write_only = 1,
|
||||
+ .reg = (void __iomem *)MLXPLAT_CPLD_LPC_REG2,
|
||||
+ .reg_size = 1,
|
||||
+ .idle_in_use = 1,
|
||||
+ .values = mlxplat_msn21xx_channels,
|
||||
+ .n_values = ARRAY_SIZE(mlxplat_msn21xx_channels),
|
||||
+ },
|
||||
+
|
||||
+};
|
||||
+
|
||||
/* Platform hotplug devices */
|
||||
static struct i2c_board_info mlxplat_mlxcpld_pwr[] = {
|
||||
{
|
||||
@@ -522,6 +554,15 @@ static struct i2c_board_info mlxplat_mlxcpld_ext_pwr[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+static struct i2c_board_info mlxplat_mlxcpld_pwr_ng800[] = {
|
||||
+ {
|
||||
+ I2C_BOARD_INFO("dps460", 0x59),
|
||||
+ },
|
||||
+ {
|
||||
+ I2C_BOARD_INFO("dps460", 0x5a),
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static struct i2c_board_info mlxplat_mlxcpld_fan[] = {
|
||||
{
|
||||
I2C_BOARD_INFO("24c32", 0x50),
|
||||
@@ -601,6 +642,23 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_wc_items_data[] = {
|
||||
},
|
||||
};
|
||||
|
||||
+static struct mlxreg_core_data mlxplat_mlxcpld_default_pwr_ng800_items_data[] = {
|
||||
+ {
|
||||
+ .label = "pwr1",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
|
||||
+ .mask = BIT(0),
|
||||
+ .hpdev.brdinfo = &mlxplat_mlxcpld_pwr_ng800[0],
|
||||
+ .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "pwr2",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
|
||||
+ .mask = BIT(1),
|
||||
+ .hpdev.brdinfo = &mlxplat_mlxcpld_pwr_ng800[1],
|
||||
+ .hpdev.nr = MLXPLAT_CPLD_PSU_MSNXXXX_NR,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_items_data[] = {
|
||||
{
|
||||
.label = "fan1",
|
||||
@@ -1224,6 +1282,47 @@ static struct mlxreg_core_item mlxplat_mlxcpld_ext_items[] = {
|
||||
}
|
||||
};
|
||||
|
||||
+static struct mlxreg_core_item mlxplat_mlxcpld_ng800_items[] = {
|
||||
+ {
|
||||
+ .data = mlxplat_mlxcpld_default_ng_psu_items_data,
|
||||
+ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_PSU_OFFSET,
|
||||
+ .mask = MLXPLAT_CPLD_PSU_EXT_MASK,
|
||||
+ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
|
||||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_psu_items_data),
|
||||
+ .inversed = 1,
|
||||
+ .health = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .data = mlxplat_mlxcpld_default_pwr_ng800_items_data,
|
||||
+ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_PWR_OFFSET,
|
||||
+ .mask = MLXPLAT_CPLD_PWR_EXT_MASK,
|
||||
+ .capability = MLXPLAT_CPLD_LPC_REG_PSU_I2C_CAP_OFFSET,
|
||||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_default_pwr_ng800_items_data),
|
||||
+ .inversed = 0,
|
||||
+ .health = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .data = mlxplat_mlxcpld_default_ng_fan_items_data,
|
||||
+ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_FAN_OFFSET,
|
||||
+ .mask = MLXPLAT_CPLD_FAN_NG_MASK,
|
||||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_default_ng_fan_items_data),
|
||||
+ .inversed = 1,
|
||||
+ .health = false,
|
||||
+ },
|
||||
+ {
|
||||
+ .data = mlxplat_mlxcpld_default_asic_items_data,
|
||||
+ .aggr_mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF,
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_ASIC_HEALTH_OFFSET,
|
||||
+ .mask = MLXPLAT_CPLD_ASIC_MASK,
|
||||
+ .count = ARRAY_SIZE(mlxplat_mlxcpld_default_asic_items_data),
|
||||
+ .inversed = 0,
|
||||
+ .health = true,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
static
|
||||
struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ext_data = {
|
||||
.items = mlxplat_mlxcpld_ext_items,
|
||||
@@ -1234,6 +1333,16 @@ struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ext_data = {
|
||||
.mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW | MLXPLAT_CPLD_LOW_AGGR_MASK_ASIC2,
|
||||
};
|
||||
|
||||
+static
|
||||
+struct mlxreg_core_hotplug_platform_data mlxplat_mlxcpld_ng800_data = {
|
||||
+ .items = mlxplat_mlxcpld_ng800_items,
|
||||
+ .counter = ARRAY_SIZE(mlxplat_mlxcpld_ng800_items),
|
||||
+ .cell = MLXPLAT_CPLD_LPC_REG_AGGR_OFFSET,
|
||||
+ .mask = MLXPLAT_CPLD_AGGR_MASK_NG_DEF | MLXPLAT_CPLD_AGGR_MASK_COMEX,
|
||||
+ .cell_low = MLXPLAT_CPLD_LPC_REG_AGGRLO_OFFSET,
|
||||
+ .mask_low = MLXPLAT_CPLD_LOW_AGGR_MASK_LOW | MLXPLAT_CPLD_LOW_AGGR_MASK_ASIC2,
|
||||
+};
|
||||
+
|
||||
static struct mlxreg_core_data mlxplat_mlxcpld_modular_pwr_items_data[] = {
|
||||
{
|
||||
.label = "pwr1",
|
||||
@@ -3093,6 +3202,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
|
||||
.mask = GENMASK(7, 0) & ~BIT(7),
|
||||
.mode = 0644,
|
||||
},
|
||||
+ {
|
||||
+ .label = "clk_brd_prog_en",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(1),
|
||||
+ .mode = 0644,
|
||||
+ },
|
||||
{
|
||||
.label = "erot1_recovery",
|
||||
.reg = MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET,
|
||||
@@ -3219,6 +3334,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
|
||||
.mask = GENMASK(7, 0) & ~BIT(6),
|
||||
.mode = 0444,
|
||||
},
|
||||
+ {
|
||||
+ .label = "reset_ac_ok_fail",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(7),
|
||||
+ .mode = 0444,
|
||||
+ },
|
||||
{
|
||||
.label = "psu1_on",
|
||||
.reg = MLXPLAT_CPLD_LPC_REG_GP1_OFFSET,
|
||||
@@ -3324,6 +3445,30 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
|
||||
.mask = GENMASK(7, 0) & ~BIT(1),
|
||||
.mode = 0444,
|
||||
},
|
||||
+ {
|
||||
+ .label = "clk_brd1_boot_fail",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(4),
|
||||
+ .mode = 0444,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "clk_brd2_boot_fail",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(5),
|
||||
+ .mode = 0444,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "clk_brd_fail",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(6),
|
||||
+ .mode = 0444,
|
||||
+ },
|
||||
+ {
|
||||
+ .label = "asic_pg_fail",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_GP4_RO_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(7),
|
||||
+ .mode = 0444,
|
||||
+ },
|
||||
{
|
||||
.label = "spi_chnl_select",
|
||||
.reg = MLXPLAT_CPLD_LPC_REG_SPI_CHNL_SELECT,
|
||||
@@ -3621,6 +3766,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_modular_regs_io_data[] = {
|
||||
.bit = 5,
|
||||
.mode = 0444,
|
||||
},
|
||||
+ {
|
||||
+ .label = "pwr_converter_prog_en",
|
||||
+ .reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
|
||||
+ .mask = GENMASK(7, 0) & ~BIT(0),
|
||||
+ .mode = 0644,
|
||||
+ },
|
||||
{
|
||||
.label = "vpd_wp",
|
||||
.reg = MLXPLAT_CPLD_LPC_REG_GP0_OFFSET,
|
||||
@@ -5209,6 +5360,27 @@ static int __init mlxplat_dmi_rack_switch_matched(const struct dmi_system_id *dm
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static int __init mlxplat_dmi_ng800_matched(const struct dmi_system_id *dmi)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ mlxplat_max_adap_num = MLXPLAT_CPLD_MAX_PHYS_ADAPTER_NUM;
|
||||
+ mlxplat_mux_num = ARRAY_SIZE(mlxplat_ng800_mux_data);
|
||||
+ mlxplat_mux_data = mlxplat_ng800_mux_data;
|
||||
+ mlxplat_hotplug = &mlxplat_mlxcpld_ng800_data;
|
||||
+ mlxplat_hotplug->deferred_nr =
|
||||
+ mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
|
||||
+ mlxplat_led = &mlxplat_default_ng_led_data;
|
||||
+ mlxplat_regs_io = &mlxplat_default_ng_regs_io_data;
|
||||
+ mlxplat_fan = &mlxplat_default_fan_data;
|
||||
+ for (i = 0; i < ARRAY_SIZE(mlxplat_mlxcpld_wd_set_type2); i++)
|
||||
+ mlxplat_wd_data[i] = &mlxplat_mlxcpld_wd_set_type2[i];
|
||||
+ mlxplat_i2c = &mlxplat_mlxcpld_i2c_ng_data;
|
||||
+ mlxplat_regmap_config = &mlxplat_mlxcpld_regmap_config_ng400;
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
|
||||
{
|
||||
.callback = mlxplat_dmi_default_wc_matched,
|
||||
@@ -5278,6 +5450,12 @@ static const struct dmi_system_id mlxplat_dmi_table[] __initconst = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "VMOD0011"),
|
||||
},
|
||||
},
|
||||
+ {
|
||||
+ .callback = mlxplat_dmi_ng800_matched,
|
||||
+ .matches = {
|
||||
+ DMI_MATCH(DMI_BOARD_NAME, "VMOD0013"),
|
||||
+ },
|
||||
+ },
|
||||
{
|
||||
.callback = mlxplat_dmi_chassis_blade_matched,
|
||||
.matches = {
|
||||
--
|
||||
2.30.2
|
||||
|
86
platform/mellanox/non-upstream-patches/series.patch
Normal file
86
platform/mellanox/non-upstream-patches/series.patch
Normal file
@ -0,0 +1,86 @@
|
||||
diff --git a/patch/series b/patch/series
|
||||
index 95f6679..c8174a6 100755
|
||||
--- a/patch/series
|
||||
+++ b/patch/series
|
||||
@@ -146,12 +146,71 @@ kernel-compat-always-include-linux-compat.h-from-net-compat.patch
|
||||
0097-hwmon-mlxreg-fan-Support-distinctive-names-per-.patch
|
||||
0999-Revert-mlxsw-thermal-Fix-out-of-bounds-memory-a.patch
|
||||
0098-mlxsw-i2c-Prevent-transaction-execution-for.patch
|
||||
+0099-mlxsw-core_hwmon-Fix-variable-names-for-hwmon-attrib.patch
|
||||
+0100-mlxsw-core_thermal-Rename-labels-according-to-naming.patch
|
||||
+0101-mlxsw-core_thermal-Remove-obsolete-API-for-query-res.patch
|
||||
+0102-mlxsw-reg-Add-mgpir_-prefix-to-MGPIR-fields-comments.patch
|
||||
+0103-mlxsw-core-Remove-unnecessary-asserts.patch
|
||||
+0104-mlxsw-reg-Extend-MTMP-register-with-new-slot-number-.patch
|
||||
+0105-mlxsw-reg-Extend-MTBR-register-with-new-slot-number-.patch
|
||||
+0106-mlxsw-reg-Extend-MCIA-register-with-new-slot-number-.patch
|
||||
+0107-mlxsw-reg-Extend-MCION-register-with-new-slot-number.patch
|
||||
+0108-mlxsw-reg-Extend-PMMP-register-with-new-slot-number-.patch
|
||||
+0109-mlxsw-reg-Extend-MGPIR-register-with-new-slot-fields.patch
|
||||
+0110-mlxsw-core_env-Pass-slot-index-during-PMAOS-register.patch
|
||||
+0111-mlxsw-reg-Add-new-field-to-Management-General-Periph.patch
|
||||
+0112-mlxsw-core-Extend-interfaces-for-cable-info-access-w.patch
|
||||
+0113-mlxsw-core-Extend-port-module-data-structures-for-li.patch
|
||||
+0114-mlxsw-core-Move-port-module-events-enablement-to-a-s.patch
|
||||
+0115-mlxsw-core_hwmon-Split-gearbox-initialization.patch
|
||||
+0116-mlxsw-core_hwmon-Extend-internal-structures-to-suppo.patch
|
||||
+0117-mlxsw-core_hwmon-Introduce-slot-parameter-in-hwmon-i.patch
|
||||
+0118-mlxsw-core_hwmon-Extend-hwmon-device-with-gearbox-ma.patch
|
||||
+0119-mlxsw-core_thermal-Extend-internal-structures-to-sup.patch
|
||||
+0120-mlxsw-core_thermal-Split-gearbox-initialization.patch
|
||||
+0121-mlxsw-core_thermal-Extend-thermal-area-with-gearbox-.patch
|
||||
+0122-mlxsw-core_thermal-Add-line-card-id-prefix-to-line-c.patch
|
||||
+0123-mlxsw-core_thermal-Use-exact-name-of-cooling-devices.patch
|
||||
+0124-mlxsw-core_thermal-Use-common-define-for-thermal-zon.patch
|
||||
+0125-devlink-add-support-to-create-line-card-and-expose-t.patch
|
||||
+0126-devlink-implement-line-card-provisioning.patch
|
||||
+0127-devlink-implement-line-card-active-state.patch
|
||||
+0128-devlink-add-port-to-line-card-relationship-set.patch
|
||||
+0129-devlink-introduce-linecard-info-get-message.patch
|
||||
+0130-devlink-introduce-linecard-info-get-message.patch
|
||||
+0131-mlxsw-reg-Add-Ports-Mapping-event-Configuration-Regi.patch
|
||||
+0132-mlxsw-reg-Add-Management-DownStream-Device-Query-Reg.patch
|
||||
+0133-mlxsw-reg-Add-Management-DownStream-Device-Control-R.patch
|
||||
+0134-mlxsw-reg-Add-Management-Binary-Code-Transfer-Regist.patch
|
||||
+0135-mlxsw-core_linecards-Add-line-card-objects-and-imple.patch
|
||||
+0136-mlxsw-core_linecards-Implement-line-card-activation-.patch
|
||||
+0137-mlxsw-core-Extend-driver-ops-by-remove-selected-port.patch
|
||||
+0138-mlxsw-spectrum-Add-port-to-linecard-mapping.patch
|
||||
+0139-mlxsw-reg-Introduce-Management-Temperature-Extended-.patch
|
||||
+0140-mlxsw-core-Add-APIs-for-thermal-sensor-mapping.patch
|
||||
+0141-mlxsw-reg-Add-Management-DownStream-Device-Tunneling.patch
|
||||
+0142-mlxsw-core_linecards-Probe-devices-for-provisioned-l.patch
|
||||
+0143-mlxsw-core_linecards-Expose-device-FW-version-over-d.patch
|
||||
+0144-mlxsw-core-Introduce-flash-update-components.patch
|
||||
+0145-mlxfw-Get-the-PSID-value-using-op-instead-of-passing.patch
|
||||
+0146-mlxsw-core_linecards-Implement-line-card-device-flas.patch
|
||||
+0147-mlxsw-core_linecards-Introduce-ops-for-linecards-sta.patch
|
||||
+0148-mlxsw-core-Add-interfaces-for-line-card-initializati.patch
|
||||
+0149-mlxsw-core_thermal-Add-interfaces-for-line-card-init.patch
|
||||
+0150-mlxsw-core_hwmon-Add-interfaces-for-line-card-initia.patch
|
||||
+0151-mlxsw-minimal-Prepare-driver-for-modular-system-supp.patch
|
||||
+0152-mlxsw-core-Extend-bus-init-function-with-event-handl.patch
|
||||
+0153-mlxsw-i2c-Add-support-for-system-events-handling.patch
|
||||
+0154-mlxsw-core-Export-line-card-API.patch
|
||||
+0155-mlxsw-minimal-Add-system-event-handler.patch
|
||||
+0156-mlxsw-minimal-Add-interfaces-for-line-card-initializ.patch
|
||||
0157-platform-x86-mlx-platform-Make-activation-of-some-dr.patch
|
||||
0158-platform-x86-mlx-platform-Add-cosmetic-changes-for-a.patch
|
||||
0159-mlx-platform-Add-support-for-systems-equipped-with-t.patch
|
||||
0160-platform-mellanox-Introduce-support-for-COMe-NVSwitc.patch
|
||||
0161-platform-x86-mlx-platform-Add-support-for-new-system.patch
|
||||
0162-platform-mellanox-Add-COME-board-revision-register.patch
|
||||
+0163-platform-mellanox-Introduce-support-for-rack-manager.patch
|
||||
0164-hwmon-jc42-Add-support-for-Seiko-Instruments-S-34TS0.patch
|
||||
0165-platform-mellanox-mlxreg-io-Add-locking-for-io-opera.patch
|
||||
0167-leds-mlxreg-Send-udev-change-event.patch
|
||||
@@ -159,6 +218,9 @@ kernel-compat-always-include-linux-compat.h-from-net-compat.patch
|
||||
0171-platform-mellanox-mlxreg-lc-Fix-cleanup-on-failure-a.patch
|
||||
0173-core-Add-support-for-OSFP-transceiver-modules.patch
|
||||
0175-hwmon-pmbus-Add-support-for-Infineon-Digital-Multi-p.patch
|
||||
+0176-platform-mellanox-fix-reset_pwr_converter_fail-attri.patch
|
||||
+0177-Documentation-ABI-fix-description-of-fix-reset_pwr_c.patch
|
||||
+0178-platform-mellanox-Introduce-support-for-next-generat.patch
|
||||
0180-hwmon-pmbus-Fix-sensors-readouts-for-MPS-Multi-phase.patch
|
||||
|
||||
# Cisco patches for 5.10 kernel
|
@ -51,7 +51,7 @@ $(DOCKER_PLATFORM_MONITOR)_DEPENDS += $(APPLIBS) $(SX_COMPLIB) $(SXD_LIBS) $(SX_
|
||||
# Force the target bootloader for mellanox platforms to grub regardless of arch
|
||||
TARGET_BOOTLOADER = grub
|
||||
|
||||
# location for the platform specific external kernel patches tarball
|
||||
override EXTERNAL_KERNEL_PATCH_TAR := $(BUILD_WORKDIR)/$(PLATFORM_PATH)/non-upstream-patches/patches.tar.gz
|
||||
# location for the platform specific external kernel patches
|
||||
override EXTERNAL_KERNEL_PATCH_LOC := $(BUILD_WORKDIR)/$(PLATFORM_PATH)/non-upstream-patches/
|
||||
|
||||
export SONIC_BUFFER_MODEL=dynamic
|
||||
|
@ -12,14 +12,14 @@ endif
|
||||
# Place an URL here to .tar.gz file if you want to include those patches
|
||||
EXTERNAL_KERNEL_PATCH_URL =
|
||||
# Set y to include non upstream patches tarball provided by the corresponding platform
|
||||
INCLUDE_EXTERNAL_PATCH_TAR = n
|
||||
# platforms should override this and provide an absolute path to the tarball
|
||||
EXTERNAL_KERNEL_PATCH_TAR =
|
||||
INCLUDE_EXTERNAL_PATCHES = n
|
||||
# platforms should override this and provide an absolute location to the patches
|
||||
EXTERNAL_KERNEL_PATCH_LOC =
|
||||
|
||||
export KVERSION_SHORT KVERSION KERNEL_VERSION KERNEL_SUBVERSION
|
||||
export EXTERNAL_KERNEL_PATCH_URL
|
||||
export INCLUDE_EXTERNAL_PATCH_TAR
|
||||
export EXTERNAL_KERNEL_PATCH_TAR
|
||||
export INCLUDE_EXTERNAL_PATCHES
|
||||
export EXTERNAL_KERNEL_PATCH_LOC
|
||||
|
||||
LINUX_HEADERS_COMMON = linux-headers-$(KVERSION_SHORT)-common_$(KERNEL_VERSION)-$(KERNEL_SUBVERSION)_all.deb
|
||||
$(LINUX_HEADERS_COMMON)_SRC_PATH = $(SRC_PATH)/sonic-linux-kernel
|
||||
|
Reference in New Issue
Block a user