Merge pull request #564 from MellanoxBSP/onl-tigris-upstream_merge

Add Mellanox MSN3800 (Tigris) system support
This commit is contained in:
Jeffrey Townsend
2019-06-12 10:35:56 -07:00
committed by GitHub
68 changed files with 4941 additions and 94 deletions

View File

@@ -0,0 +1,839 @@
From a648f2856518f8884a7798469faf755d0f5dcd50 Mon Sep 17 00:00:00 2001
From: Michael Shych <michaelsh@mellanox.com>
Date: Mon, 17 Dec 2018 12:32:45 +0000
Subject: [PATCH v1 mlx-wdt 1/1] watchdog: mlx-wdt: introduce watchdog driver
for Mellanox systems
Watchdog driver for Mellanox watchdog devices, implemented in
programmable logic device.
Main and auxiliary watchdog devices can exist on the same system.
There are several actions that can be defined in the watchdog:
system reset, start fans on full speed and increase counter.
The last 2 actions are performed without system reset.
Actions without reset are provided for auxiliary watchdog devices,
which is optional.
Access to CPLD registers is performed through generic
regmap interface.
There are 2 types of HW CPLD watchdog implementations.
Type 1: actual HW timeout can be defined as power of 2 msec.
e.g. timeout 20 sec will be rounded up to 32768 msec.;
maximum timeout period is 32 sec (32768 msec.);
get time-left isn't supported
Type 2: actual HW timeout is defined in sec. and it's a same as
user defined timeout;
maximum timeout is 255 sec;
get time-left is supported;
Watchdog driver is probed from common mlx_platform driver.
Signed-off-by: Michael Shych <michaelsh@mellanox.com>
---
drivers/platform/x86/mlx-platform.c | 202 +++++++++++++++++-
drivers/watchdog/Kconfig | 15 ++
drivers/watchdog/Makefile | 1 +
drivers/watchdog/mlx_wdt.c | 391 +++++++++++++++++++++++++++++++++++
include/linux/platform_data/mlxreg.h | 6 +
5 files changed, 612 insertions(+), 3 deletions(-)
create mode 100644 drivers/watchdog/mlx_wdt.c
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
index 6e150b4..fc8d655 100644
--- a/drivers/platform/x86/mlx-platform.c
+++ b/drivers/platform/x86/mlx-platform.c
@@ -55,6 +55,14 @@
#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_WD_CLEAR_OFFSET 0xc7
+#define MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET 0xc8
+#define MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET 0xc9
+#define MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET 0xcb
+#define MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET 0xcd
+#define MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET 0xcf
+#define MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET 0xd1
+#define MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET 0xd2
#define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET 0xe3
#define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET 0xe4
#define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET 0xe5
@@ -128,6 +136,18 @@
#define MLXPLAT_CPLD_FAN3_DEFAULT_NR 13
#define MLXPLAT_CPLD_FAN4_DEFAULT_NR 14
+/* Masks and default values for watchdogs */
+#define MLXPLAT_CPLD_WD1_CLEAR_MASK GENMASK(7, 1)
+#define MLXPLAT_CPLD_WD2_CLEAR_MASK (GENMASK(7, 0) & ~BIT(1))
+
+#define MLXPLAT_CPLD_WD_TYPE1_TO_MASK GENMASK(7, 4)
+#define MLXPLAT_CPLD_WD_TYPE2_TO_MASK 0
+#define MLXPLAT_CPLD_WD_RESET_ACT_MASK GENMASK(7, 1)
+#define MLXPLAT_CPLD_WD_FAN_ACT_MASK (GENMASK(7, 0) & ~BIT(4))
+#define MLXPLAT_CPLD_WD_COUNT_ACT_MASK (GENMASK(7, 0) & ~BIT(7))
+#define MLXPLAT_CPLD_WD_DFLT_TIMEOUT 30
+#define MLXPLAT_CPLD_WD_MAX_DEVS 2
+
/* mlxplat_priv - platform private data
* @pdev_i2c - i2c controller platform device
* @pdev_mux - array of mux platform devices
@@ -135,6 +155,7 @@
* @pdev_led - led platform devices
* @pdev_io_regs - register access platform devices
* @pdev_fan - FAN platform devices
+ * @pdev_wd - array of watchdog platform devices
*/
struct mlxplat_priv {
struct platform_device *pdev_i2c;
@@ -143,6 +164,7 @@ struct mlxplat_priv {
struct platform_device *pdev_led;
struct platform_device *pdev_io_regs;
struct platform_device *pdev_fan;
+ struct platform_device *pdev_wd[MLXPLAT_CPLD_WD_MAX_DEVS];
};
/* Regions for LPC I2C controller and LPC base register space */
@@ -1340,6 +1362,132 @@ static struct mlxreg_core_platform_data mlxplat_default_fan_data = {
.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_data),
};
+/* Type1 watchdog implementation on MSN2700, MSN2100 and MSN2140 systems */
+static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type1[] = {
+ {
+ .label = "action",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
+ .bit = 0,
+ },
+ {
+ .label = "timeout",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK,
+ .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
+ },
+ {
+ .label = "ping",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET,
+ .mask = MLXPLAT_CPLD_WD1_CLEAR_MASK,
+ .bit = 0,
+ },
+ {
+ .label = "reset",
+ .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+ .mask = GENMASK(7, 0) & ~BIT(6),
+ .bit = 6,
+ },
+};
+
+static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type1[] = {
+ {
+ .label = "action",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
+ .bit = 4,
+ },
+ {
+ .label = "timeout",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_TYPE1_TO_MASK,
+ .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
+ },
+ {
+ .label = "ping",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD_CLEAR_OFFSET,
+ .mask = MLXPLAT_CPLD_WD1_CLEAR_MASK,
+ .bit = 1,
+ },
+};
+
+static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type1[] = {
+ {
+ .data = mlxplat_mlxcpld_wd_main_regs_type1,
+ .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type1),
+ .identity = "mlx-wdt-main",
+ },
+ {
+ .data = mlxplat_mlxcpld_wd_aux_regs_type1,
+ .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type1),
+ .identity = "mlx-wdt-aux",
+ },
+};
+
+/* Type2 watchdog implementation on MSB8700 and up systems
+ * To differentiate: ping reg == action reg
+ */
+static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type2[] = {
+ {
+ .label = "action",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
+ .bit = 0,
+ },
+ {
+ .label = "timeout",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
+ .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
+ },
+ {
+ .label = "ping",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
+ .bit = 0,
+ },
+ {
+ .label = "reset",
+ .reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
+ .mask = GENMASK(7, 0) & ~BIT(6),
+ .bit = 6,
+ },
+};
+
+static struct mlxreg_core_data mlxplat_mlxcpld_wd_aux_regs_type2[] = {
+ {
+ .label = "action",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
+ .bit = 4,
+ },
+ {
+ .label = "timeout",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
+ .health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
+ },
+ {
+ .label = "ping",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
+ .bit = 4,
+ },
+};
+
+static struct mlxreg_core_platform_data mlxplat_mlxcpld_wd_set_type2[] = {
+ {
+ .data = mlxplat_mlxcpld_wd_main_regs_type2,
+ .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type2),
+ .identity = "mlx-wdt-main",
+ },
+ {
+ .data = mlxplat_mlxcpld_wd_aux_regs_type2,
+ .counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type2),
+ .identity = "mlx-wdt-aux",
+ },
+};
+
static bool mlxplat_mlxcpld_writeable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
@@ -1362,6 +1510,14 @@ 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_WD_CLEAR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET:
case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET:
return true;
@@ -1404,6 +1560,14 @@ 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_WD_CLEAR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET:
case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
@@ -1460,6 +1624,8 @@ 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_WD2_TMR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
@@ -1487,6 +1653,7 @@ static const struct reg_default mlxplat_mlxcpld_regmap_default[] = {
{ MLXPLAT_CPLD_LPC_REG_WP1_OFFSET, 0x00 },
{ MLXPLAT_CPLD_LPC_REG_WP2_OFFSET, 0x00 },
{ MLXPLAT_CPLD_LPC_REG_PWM_CONTROL_OFFSET, 0x00 },
+ { MLXPLAT_CPLD_LPC_REG_WD_CLEAR_WP_OFFSET, 0x00 },
};
struct mlxplat_mlxcpld_regmap_context {
@@ -1536,6 +1703,8 @@ static struct mlxreg_core_hotplug_platform_data *mlxplat_hotplug;
static struct mlxreg_core_platform_data *mlxplat_led;
static struct mlxreg_core_platform_data *mlxplat_regs_io;
static struct mlxreg_core_platform_data *mlxplat_fan;
+static struct mlxreg_core_platform_data
+ *mlxplat_wd_data[MLXPLAT_CPLD_WD_MAX_DEVS];
static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
{
@@ -1551,6 +1720,7 @@ static int __init mlxplat_dmi_default_matched(const struct dmi_system_id *dmi)
mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
mlxplat_led = &mlxplat_default_led_data;
mlxplat_regs_io = &mlxplat_default_regs_io_data;
+ mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
return 1;
};
@@ -1569,6 +1739,7 @@ static int __init mlxplat_dmi_msn21xx_matched(const struct dmi_system_id *dmi)
mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
mlxplat_led = &mlxplat_msn21xx_led_data;
mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
+ mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
return 1;
};
@@ -1587,6 +1758,7 @@ static int __init mlxplat_dmi_msn274x_matched(const struct dmi_system_id *dmi)
mlxplat_msn21xx_channels[MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
mlxplat_led = &mlxplat_default_led_data;
mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
+ mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
return 1;
};
@@ -1605,6 +1777,7 @@ static int __init mlxplat_dmi_msn201x_matched(const struct dmi_system_id *dmi)
mlxplat_default_channels[i - 1][MLXPLAT_CPLD_GRP_CHNL_NUM - 1];
mlxplat_led = &mlxplat_msn21xx_led_data;
mlxplat_regs_io = &mlxplat_msn21xx_regs_io_data;
+ mlxplat_wd_data[0] = &mlxplat_mlxcpld_wd_set_type1[0];
return 1;
};
@@ -1624,6 +1797,8 @@ static int __init mlxplat_dmi_qmb7xx_matched(const struct dmi_system_id *dmi)
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];
return 1;
};
@@ -1906,15 +2081,33 @@ static int __init mlxplat_init(void)
}
}
+ /* Add WD drivers. */
+ for (j = 0; j < MLXPLAT_CPLD_WD_MAX_DEVS; j++) {
+ if (mlxplat_wd_data[j]) {
+ mlxplat_wd_data[j]->regmap = mlxplat_hotplug->regmap;
+ priv->pdev_wd[j] = platform_device_register_resndata(
+ &mlxplat_dev->dev,
+ "mlx-wdt", j, NULL, 0,
+ mlxplat_wd_data[j],
+ sizeof(*mlxplat_wd_data[j]));
+ if (IS_ERR(priv->pdev_wd[j])) {
+ err = PTR_ERR(priv->pdev_wd[j]);
+ goto fail_platform_wd_register;
+ }
+ }
+ }
+
/* Sync registers with hardware. */
regcache_mark_dirty(mlxplat_hotplug->regmap);
err = regcache_sync(mlxplat_hotplug->regmap);
if (err)
- goto fail_platform_fan_register;
+ goto fail_platform_wd_register;
return 0;
-fail_platform_fan_register:
+fail_platform_wd_register:
+ while (--j >= 0)
+ platform_device_unregister(priv->pdev_wd[j]);
if (mlxplat_fan)
platform_device_unregister(priv->pdev_fan);
fail_platform_io_regs_register:
@@ -1946,7 +2139,10 @@ static void __exit mlxplat_exit(void)
platform_device_unregister(priv->pdev_io_regs);
platform_device_unregister(priv->pdev_led);
platform_device_unregister(priv->pdev_hotplug);
-
+ for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--) {
+ if (mlxplat_wd_data[i])
+ platform_device_unregister(priv->pdev_wd[i]);
+ }
for (i = ARRAY_SIZE(mlxplat_mux_data) - 1; i >= 0 ; i--)
platform_device_unregister(priv->pdev_mux[i]);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 3eb58cb..ada5a33 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -141,6 +141,21 @@ config MENF21BMC_WATCHDOG
This driver can also be built as a module. If so the module
will be called menf21bmc_wdt.
+config MLX_WDT
+ tristate "Mellanox Watchdog"
+ select WATCHDOG_CORE
+ select REGMAP
+ ---help---
+ This is the driver for the hardware watchdog on Mellanox systems.
+ If you are going to use it, say Y here, otherwise N.
+ This driver can be used together with the watchdog daemon.
+ It can also watch your kernel to make sure it doesn't freeze,
+ and if it does, it reboots your system after a certain amount of
+ time.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mlx-wdt.
+
config TANGOX_WATCHDOG
tristate "Sigma Designs SMP86xx/SMP87xx watchdog"
select WATCHDOG_CORE
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index caa9f4a..50494df 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -139,6 +139,7 @@ obj-$(CONFIG_INTEL_SCU_WATCHDOG) += intel_scu_watchdog.o
obj-$(CONFIG_INTEL_MID_WATCHDOG) += intel-mid_wdt.o
obj-$(CONFIG_INTEL_MEI_WDT) += mei_wdt.o
obj-$(CONFIG_NI903X_WDT) += ni903x_wdt.o
+obj-$(CONFIG_MLX_WDT) += mlx_wdt.o
# M32R Architecture
diff --git a/drivers/watchdog/mlx_wdt.c b/drivers/watchdog/mlx_wdt.c
new file mode 100644
index 0000000..7effe8c
--- /dev/null
+++ b/drivers/watchdog/mlx_wdt.c
@@ -0,0 +1,391 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Mellanox watchdog driver
+ *
+ * Copyright (C) 2018 Mellanox Technologies
+ * Copyright (C) 2018 Michael Shych <mshych@mellanox.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/log2.h>
+#include <linux/module.h>
+#include <linux/platform_data/mlxreg.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+
+#define MLXREG_WDT_CLOCK_SCALE 1000
+#define MLXREG_WDT_MAX_TIMEOUT_TYPE1 32
+#define MLXREG_WDT_MAX_TIMEOUT_TYPE2 255
+#define MLXREG_WDT_MIN_TIMEOUT 1
+#define MLXREG_WDT_HW_TIMEOUT_CONVERT(hw_timeout) ((1 << (hw_timeout)) \
+ / MLXREG_WDT_CLOCK_SCALE)
+
+/**
+ * enum mlxreg_wdt_type - type of HW watchdog
+ *
+ * TYPE1 can be differentiated by different register/mask
+ * for WD action set and ping.
+ */
+enum mlxreg_wdt_type {
+ MLX_WDT_TYPE1,
+ MLX_WDT_TYPE2,
+};
+
+/**
+ * struct mlxreg_wdt - wd private data:
+ *
+ * @wdd: watchdog device;
+ * @device: basic device;
+ * @pdata: data received from platform driver;
+ * @regmap: register map of parent device;
+ * @timeout: defined timeout in sec.;
+ * @hw_timeout: real timeout set in hw;
+ * It will be roundup base of 2 in WD type 1,
+ * in WD type 2 it will be same number of sec as timeout;
+ * @action_idx: index for direct access to action register;
+ * @timeout_idx:index for direct access to TO register;
+ * @ping_idx: index for direct access to ping register;
+ * @reset_idx: index for direct access to reset cause register;
+ * @wd_type: watchdog HW type;
+ * @hw_timeout: actual HW timeout;
+ * @io_lock: spinlock for io access;
+ */
+struct mlxreg_wdt {
+ struct watchdog_device wdd;
+ struct mlxreg_core_platform_data *pdata;
+ void *regmap;
+ int action_idx;
+ int timeout_idx;
+ int ping_idx;
+ int reset_idx;
+ enum mlxreg_wdt_type wdt_type;
+ u8 hw_timeout;
+ spinlock_t io_lock; /* the lock for io operations */
+};
+
+static int mlxreg_wdt_roundup_to_base_2(struct mlxreg_wdt *wdt, int timeout)
+{
+ timeout *= MLXREG_WDT_CLOCK_SCALE;
+
+ wdt->hw_timeout = order_base_2(timeout);
+ dev_info(wdt->wdd.parent,
+ "watchdog %s timeout %d was rounded up to %lu (msec)\n",
+ wdt->wdd.info->identity, timeout, roundup_pow_of_two(timeout));
+
+ return 0;
+}
+
+static enum mlxreg_wdt_type
+mlxreg_wdt_check_watchdog_type(struct mlxreg_wdt *wdt,
+ struct mlxreg_core_platform_data *pdata)
+{
+ if ((pdata->data[wdt->action_idx].reg ==
+ pdata->data[wdt->ping_idx].reg) &&
+ (pdata->data[wdt->action_idx].mask ==
+ pdata->data[wdt->ping_idx].mask))
+ return MLX_WDT_TYPE2;
+ else
+ return MLX_WDT_TYPE1;
+}
+
+static int mlxreg_wdt_check_card_reset(struct mlxreg_wdt *wdt)
+{
+ struct mlxreg_core_data *reg_data;
+ u32 regval;
+ int rc;
+
+ if (wdt->reset_idx == -EINVAL)
+ return -EINVAL;
+
+ if (!(wdt->wdd.info->options & WDIOF_CARDRESET))
+ return 0;
+
+ spin_lock(&wdt->io_lock);
+ reg_data = &wdt->pdata->data[wdt->reset_idx];
+ rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
+ spin_unlock(&wdt->io_lock);
+ if (rc)
+ goto read_error;
+
+ if (regval & ~reg_data->mask) {
+ wdt->wdd.bootstatus = WDIOF_CARDRESET;
+ dev_info(wdt->wdd.parent,
+ "watchdog previously reset the CPU\n");
+ }
+
+read_error:
+ return rc;
+}
+
+static int mlxreg_wdt_start(struct watchdog_device *wdd)
+{
+ struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
+ struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->action_idx];
+ u32 regval;
+ int rc;
+
+ spin_lock(&wdt->io_lock);
+ rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
+ if (rc) {
+ spin_unlock(&wdt->io_lock);
+ goto read_error;
+ }
+
+ regval = (regval & reg_data->mask) | BIT(reg_data->bit);
+ rc = regmap_write(wdt->regmap, reg_data->reg, regval);
+ spin_unlock(&wdt->io_lock);
+ if (!rc) {
+ set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
+ dev_info(wdt->wdd.parent, "watchdog %s started\n",
+ wdd->info->identity);
+ }
+
+read_error:
+ return rc;
+}
+
+static int mlxreg_wdt_stop(struct watchdog_device *wdd)
+{
+ struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
+ struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->action_idx];
+ u32 regval;
+ int rc;
+
+ spin_lock(&wdt->io_lock);
+ rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
+ if (rc) {
+ spin_unlock(&wdt->io_lock);
+ goto read_error;
+ }
+
+ regval = (regval & reg_data->mask) & ~BIT(reg_data->bit);
+ rc = regmap_write(wdt->regmap, reg_data->reg, regval);
+ spin_unlock(&wdt->io_lock);
+ if (!rc)
+ dev_info(wdt->wdd.parent, "watchdog %s stopped\n",
+ wdd->info->identity);
+
+read_error:
+ return rc;
+}
+
+static int mlxreg_wdt_ping(struct watchdog_device *wdd)
+{
+ struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
+ struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->ping_idx];
+ u32 regval;
+ int rc;
+
+ spin_lock(&wdt->io_lock);
+ rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
+ if (rc)
+ goto read_error;
+
+ regval = (regval & reg_data->mask) | BIT(reg_data->bit);
+ rc = regmap_write(wdt->regmap, reg_data->reg, regval);
+
+read_error:
+ spin_unlock(&wdt->io_lock);
+
+ return rc;
+}
+
+static int mlxreg_wdt_set_timeout(struct watchdog_device *wdd,
+ unsigned int timeout)
+{
+ struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
+ struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->timeout_idx];
+ u32 regval;
+ int rc;
+
+ spin_lock(&wdt->io_lock);
+
+ if (wdt->wdt_type == MLX_WDT_TYPE1) {
+ rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
+ if (rc)
+ goto read_error;
+ regval = (regval & reg_data->mask) | wdt->hw_timeout;
+ } else {
+ wdt->hw_timeout = timeout;
+ regval = timeout;
+ }
+
+ rc = regmap_write(wdt->regmap, reg_data->reg, regval);
+
+read_error:
+ spin_unlock(&wdt->io_lock);
+
+ return rc;
+}
+
+static unsigned int mlxreg_wdt_get_timeleft(struct watchdog_device *wdd)
+{
+ struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
+ struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->timeout_idx];
+ u32 regval;
+ int rc;
+
+ if (wdt->wdt_type == MLX_WDT_TYPE1)
+ return 0;
+
+ spin_lock(&wdt->io_lock);
+ rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
+ if (rc)
+ rc = 0;
+ else
+ rc = regval;
+
+ spin_unlock(&wdt->io_lock);
+
+ return rc;
+}
+
+static const struct watchdog_ops mlxreg_wdt_ops_type1 = {
+ .start = mlxreg_wdt_start,
+ .stop = mlxreg_wdt_stop,
+ .ping = mlxreg_wdt_ping,
+ .set_timeout = mlxreg_wdt_set_timeout,
+ .owner = THIS_MODULE,
+};
+
+static const struct watchdog_ops mlxreg_wdt_ops_type2 = {
+ .start = mlxreg_wdt_start,
+ .stop = mlxreg_wdt_stop,
+ .ping = mlxreg_wdt_ping,
+ .set_timeout = mlxreg_wdt_set_timeout,
+ .get_timeleft = mlxreg_wdt_get_timeleft,
+ .owner = THIS_MODULE,
+};
+
+static const struct watchdog_info mlxreg_wdt_main_info = {
+ .options = WDIOF_KEEPALIVEPING
+ | WDIOF_MAGICCLOSE
+ | WDIOF_SETTIMEOUT
+ | WDIOF_CARDRESET,
+ .identity = "mlx-wdt-main",
+};
+
+static const struct watchdog_info mlxreg_wdt_aux_info = {
+ .options = WDIOF_KEEPALIVEPING
+ | WDIOF_MAGICCLOSE
+ | WDIOF_SETTIMEOUT
+ | WDIOF_ALARMONLY,
+ .identity = "mlx-wdt-aux",
+};
+
+static int mlxreg_wdt_config(struct mlxreg_wdt *wdt,
+ struct mlxreg_core_platform_data *pdata)
+{
+ struct mlxreg_core_data *data = pdata->data;
+ int i, timeout;
+
+ wdt->reset_idx = -EINVAL;
+ for (i = 0; i < pdata->counter; i++, data++) {
+ if (strnstr(data->label, "action", sizeof(data->label)))
+ wdt->action_idx = i;
+ else if (strnstr(data->label, "timeout", sizeof(data->label)))
+ wdt->timeout_idx = i;
+ else if (strnstr(data->label, "ping", sizeof(data->label)))
+ wdt->ping_idx = i;
+ else if (strnstr(data->label, "reset", sizeof(data->label)))
+ wdt->reset_idx = i;
+ }
+
+ wdt->pdata = pdata;
+ if (strnstr(pdata->identity, mlxreg_wdt_main_info.identity,
+ sizeof(mlxreg_wdt_main_info.identity)))
+ wdt->wdd.info = &mlxreg_wdt_main_info;
+ else
+ wdt->wdd.info = &mlxreg_wdt_aux_info;
+
+ timeout = pdata->data[wdt->timeout_idx].health_cntr;
+ wdt->wdt_type = mlxreg_wdt_check_watchdog_type(wdt, pdata);
+ if (wdt->wdt_type == MLX_WDT_TYPE2) {
+ wdt->hw_timeout = timeout;
+ wdt->wdd.ops = &mlxreg_wdt_ops_type2;
+ wdt->wdd.timeout = wdt->hw_timeout;
+ wdt->wdd.max_timeout = MLXREG_WDT_MAX_TIMEOUT_TYPE2;
+ } else {
+ mlxreg_wdt_roundup_to_base_2(wdt, timeout);
+ wdt->wdd.ops = &mlxreg_wdt_ops_type1;
+ /* Rowndown to actual closest number of sec. */
+ wdt->wdd.timeout =
+ MLXREG_WDT_HW_TIMEOUT_CONVERT(wdt->hw_timeout);
+ wdt->wdd.max_timeout = MLXREG_WDT_MAX_TIMEOUT_TYPE1;
+ }
+ wdt->wdd.min_timeout = MLXREG_WDT_MIN_TIMEOUT;
+
+ return -EINVAL;
+}
+
+static int mlxreg_wdt_probe(struct platform_device *pdev)
+{
+ struct mlxreg_core_platform_data *pdata;
+ struct mlxreg_wdt *wdt;
+ int rc;
+
+ pdata = dev_get_platdata(&pdev->dev);
+ if (!pdata) {
+ dev_err(&pdev->dev, "Failed to get platform data.\n");
+ return -EINVAL;
+ }
+ wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL);
+ if (!wdt)
+ return -ENOMEM;
+
+ spin_lock_init(&wdt->io_lock);
+
+ wdt->wdd.parent = &pdev->dev;
+ wdt->regmap = pdata->regmap;
+ mlxreg_wdt_config(wdt, pdata);
+
+ if ((pdata->features & MLXREG_CORE_WD_FEATURE_NOSTOP_AFTER_START))
+ watchdog_set_nowayout(&wdt->wdd, WATCHDOG_NOWAYOUT);
+ watchdog_stop_on_reboot(&wdt->wdd);
+ watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
+ watchdog_set_drvdata(&wdt->wdd, wdt);
+
+ mlxreg_wdt_check_card_reset(wdt);
+ rc = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
+ if (rc) {
+ dev_err(&pdev->dev,
+ "Cannot register watchdog device (err=%d)\n", rc);
+ return rc;
+ }
+
+ mlxreg_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout);
+ if ((pdata->features & MLXREG_CORE_WD_FEATURE_START_AT_BOOT))
+ mlxreg_wdt_start(&wdt->wdd);
+
+ return rc;
+}
+
+static int mlxreg_wdt_remove(struct platform_device *pdev)
+{
+ struct mlxreg_wdt *wdt = dev_get_platdata(&pdev->dev);
+
+ mlxreg_wdt_stop(&wdt->wdd);
+ watchdog_unregister_device(&wdt->wdd);
+
+ return 0;
+}
+
+static struct platform_driver mlxreg_wdt_driver = {
+ .probe = mlxreg_wdt_probe,
+ .remove = mlxreg_wdt_remove,
+ .driver = {
+ .name = "mlx-wdt",
+ },
+};
+
+module_platform_driver(mlxreg_wdt_driver);
+
+MODULE_AUTHOR("Michael Shych <michaelsh@mellanox.com>");
+MODULE_DESCRIPTION("Mellanox watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mlx-wdt");
diff --git a/include/linux/platform_data/mlxreg.h b/include/linux/platform_data/mlxreg.h
index 1b2f86f..4d70c00 100644
--- a/include/linux/platform_data/mlxreg.h
+++ b/include/linux/platform_data/mlxreg.h
@@ -35,6 +35,8 @@
#define __LINUX_PLATFORM_DATA_MLXREG_H
#define MLXREG_CORE_LABEL_MAX_SIZE 32
+#define MLXREG_CORE_WD_FEATURE_NOSTOP_AFTER_START BIT(0)
+#define MLXREG_CORE_WD_FEATURE_START_AT_BOOT BIT(1)
/**
* struct mlxreg_hotplug_device - I2C device data:
@@ -112,11 +114,15 @@ struct mlxreg_core_item {
* @data: instance private data;
* @regmap: register map of parent device;
* @counter: number of instances;
+ * @features: supported features of device;
+ * @identity: device identity name;
*/
struct mlxreg_core_platform_data {
struct mlxreg_core_data *data;
void *regmap;
int counter;
+ u32 features;
+ char identity[MLXREG_CORE_LABEL_MAX_SIZE];
};
/**
--
2.1.4

View File

@@ -0,0 +1,42 @@
From 81443e4927ec84223f8305e0e4cec647521856e4 Mon Sep 17 00:00:00 2001
From: Vadim Pasternak <vadimp@mellanox.com>
Date: Mon, 21 Jan 2019 14:54:58 +0000
Subject: [PATCH hwmon] hwmon: (pmbus) Fix driver info initialization in probe
routine
Fix tps53679_probe() by using dynamically allocated ?pmbus_driver_info?
structure instead of static. Usage of static structures causes
overwritten of the field ?vrm_version? - when the number of tps53679
devices with the different ?vrm_version? are used within the same
system, the last probed device overwrites this field for all others.
Fixes: 610526527a13e4c9 ("hwmon: (pmbus) Add support for Texas Instruments tps53679 device")
Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
---
drivers/hwmon/pmbus/tps53679.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/pmbus/tps53679.c b/drivers/hwmon/pmbus/tps53679.c
index 85b515c..45eacc5 100644
--- a/drivers/hwmon/pmbus/tps53679.c
+++ b/drivers/hwmon/pmbus/tps53679.c
@@ -80,7 +80,15 @@ static struct pmbus_driver_info tps53679_info = {
static int tps53679_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- return pmbus_do_probe(client, id, &tps53679_info);
+ struct pmbus_driver_info *info;
+
+ info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ memcpy(info, &tps53679_info, sizeof(*info));
+
+ return pmbus_do_probe(client, id, info);
}
static const struct i2c_device_id tps53679_id[] = {
--
2.1.4

View File

@@ -0,0 +1,35 @@
From 5da6a599af1072f278b5f41ed648bed2142d42f0 Mon Sep 17 00:00:00 2001
From: Vadim Pasternak <vadimp@mellanox.com>
Date: Mon, 21 Jan 2019 19:13:29 +0000
Subject: [PATCH mlxsw] mlxsw thermal: disable highest zone calculation
Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
index 444455c..0a2e7a2 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -433,7 +433,7 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
return err;
}
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
-
+#if 0
if (thermal->tz_module_arr) {
err = mlxsw_thermal_highest_tz_notify(dev, tzdev, thermal,
thermal->tz_module_num,
@@ -441,7 +441,7 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
if (err)
dev_err(dev, "Failed to query module temp sensor\n");
}
-
+#endif
*p_temp = (int) temp;
return 0;
}
--
2.1.4

View File

@@ -0,0 +1,63 @@
From 87859cbda6affc45fc8d513c12eb4318e2c81073 Mon Sep 17 00:00:00 2001
From: Vadim Pasternak <vadimp@mellanox.com>
Date: Thu, 24 Jan 2019 09:58:23 +0000
Subject: [PATCH platform] platform/x86: mlx-platform: Add CPLD4 register
Signed-off-by: <Vadim Pasternal vadimp@mellanox.com>
---
drivers/platform/x86/mlx-platform.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
index fc8d655..a80b968 100644
--- a/drivers/platform/x86/mlx-platform.c
+++ b/drivers/platform/x86/mlx-platform.c
@@ -25,6 +25,7 @@
#define MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET 0x00
#define MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET 0x01
#define MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET 0x02
+#define MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET 0x03
#define MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET 0x1d
#define MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET 0x1e
#define MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET 0x1f
@@ -1163,6 +1164,12 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
.mode = 0444,
},
{
+ .label = "cpld4_version",
+ .reg = MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET,
+ .bit = GENMASK(7, 0),
+ .mode = 0444,
+ },
+ {
.label = "reset_long_pb",
.reg = MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET,
.mask = GENMASK(7, 0) & ~BIT(0),
@@ -1251,7 +1258,7 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_regs_io_data[] = {
.label = "fan_dir",
.reg = MLXPLAT_CPLD_LPC_REG_FAN_DIRECTION,
.bit = GENMASK(7, 0),
- .mode = 0200,
+ .mode = 0444,
},
};
@@ -1531,6 +1538,7 @@ static bool mlxplat_mlxcpld_readable_reg(struct device *dev, unsigned int reg)
case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
@@ -1597,6 +1605,7 @@ static bool mlxplat_mlxcpld_volatile_reg(struct device *dev, unsigned int reg)
case MLXPLAT_CPLD_LPC_REG_CPLD1_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_CPLD2_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_CPLD3_VER_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_CPLD4_VER_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RESET_CAUSE_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RST_CAUSE1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_RST_CAUSE2_OFFSET:
--
2.1.4

View File

@@ -0,0 +1,564 @@
From 4df1b8e3a873293a8ad59afe276bb4a48dd2f613 Mon Sep 17 00:00:00 2001
From: Vadim Pasternak <vadimp@mellanox.com>
Date: Mon, 25 Feb 2019 07:18:14 +0000
Subject: [PATCH backport 5.1] mlxsw-Align-code-with-kernel-v-5.1.patch
Add latest hwmon and thermal ASIC modules amendments.
Fix LED driver.
Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
---
drivers/leds/leds-mlxreg.c | 21 ++-
drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 8 +-
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 168 +--------------------
drivers/net/ethernet/mellanox/mlxsw/i2c.c | 10 +-
drivers/net/ethernet/mellanox/mlxsw/minimal.c | 85 ++++++-----
5 files changed, 77 insertions(+), 215 deletions(-)
diff --git a/drivers/leds/leds-mlxreg.c b/drivers/leds/leds-mlxreg.c
index 2db200075cfc..0c14a7406c6e 100644
--- a/drivers/leds/leds-mlxreg.c
+++ b/drivers/leds/leds-mlxreg.c
@@ -22,6 +22,7 @@
#define MLXREG_LED_AMBER_SOLID 0x09 /* Solid amber */
#define MLXREG_LED_BLINK_3HZ 167 /* ~167 msec off/on - HW support */
#define MLXREG_LED_BLINK_6HZ 83 /* ~83 msec off/on - HW support */
+#define MLXREG_LED_CAPABILITY_CLEAR GENMASK(31, 8) /* Clear mask */
/**
* struct mlxreg_led_data - led control data:
@@ -100,7 +101,7 @@ mlxreg_led_get_hw(struct mlxreg_led_data *led_data)
struct mlxreg_core_platform_data *led_pdata = priv->pdata;
struct mlxreg_core_data *data = led_data->data;
u32 regval;
- int ret;
+ int err;
/*
* Each LED is controlled through low or high nibble of the relevant
@@ -112,10 +113,10 @@ mlxreg_led_get_hw(struct mlxreg_led_data *led_data)
* 0xf0 - lower nibble is to be used (bits from 0 to 3), mask 0x0f -
* higher nibble (bits from 4 to 7).
*/
- ret = regmap_read(led_pdata->regmap, data->reg, &regval);
- if (ret < 0) {
+ err = regmap_read(led_pdata->regmap, data->reg, &regval);
+ if (err < 0) {
dev_warn(led_data->led_cdev.dev, "Failed to get current brightness, error: %d\n",
- ret);
+ err);
/* Assume the LED is OFF */
return LED_OFF;
}
@@ -125,11 +126,9 @@ mlxreg_led_get_hw(struct mlxreg_led_data *led_data)
data->bit) : ror32(regval, data->bit + 4);
if (regval >= led_data->base_color &&
regval <= (led_data->base_color + MLXREG_LED_OFFSET_BLINK_6HZ))
- ret = LED_FULL;
- else
- ret = LED_OFF;
+ return LED_FULL;
- return ret;
+ return LED_OFF;
}
static int
@@ -208,6 +207,12 @@ static int mlxreg_led_config(struct mlxreg_led_priv_data *priv)
}
if (!(regval & data->bit))
continue;
+ /*
+ * Field "bit" can contain one capability bit in 0 byte
+ * and offset bit in 1-3 bytes. Clear capability bit and
+ * keep only offset bit.
+ */
+ data->bit &= MLXREG_LED_CAPABILITY_CLEAR;
}
led_cdev = &led_data->led_cdev;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
index f1ada4cdbd6b..6956bbebe2f1 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
@@ -208,7 +208,7 @@ static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev,
1);
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtbr), mtbr_pl);
if (err) {
- dev_err(dev, "Failed to query module temprature sensor\n");
+ dev_err(dev, "Failed to query module temperature sensor\n");
return err;
}
@@ -251,7 +251,7 @@ static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
1);
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtbr), mtbr_pl);
if (err) {
- dev_err(dev, "Failed to query module temprature sensor\n");
+ dev_err(dev, "Failed to query module temperature sensor\n");
return err;
}
@@ -291,7 +291,7 @@ mlxsw_hwmon_module_temp_critical_show(struct device *dev,
err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
SFP_TEMP_HIGH_WARN, &temp);
if (err) {
- dev_err(dev, "Failed to query module temprature thresholds\n");
+ dev_err(dev, "Failed to query module temperature thresholds\n");
return err;
}
@@ -314,7 +314,7 @@ mlxsw_hwmon_module_temp_emergency_show(struct device *dev,
err = mlxsw_env_module_temp_thresholds_get(mlxsw_hwmon->core, module,
SFP_TEMP_HIGH_ALARM, &temp);
if (err) {
- dev_err(dev, "Failed to query module temprature thresholds\n");
+ 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 0a2e7a2f1569..002654918ee9 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -23,7 +23,6 @@
#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 0xffffffff
#define MLXSW_THERMAL_MAX_STATE 10
#define MLXSW_THERMAL_MAX_DUTY 255
/* Minimum and maximum fan allowed speed in percent: from 20% to 100%. Values
@@ -113,8 +112,6 @@ struct mlxsw_thermal {
enum thermal_device_mode mode;
struct mlxsw_thermal_module *tz_module_arr;
unsigned int tz_module_num;
- int tz_highest;
- struct mutex tz_update_lock;
};
static inline u8 mlxsw_state_to_duty(int state)
@@ -179,7 +176,7 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
/* According to the system thermal requirements, the thermal zones are
* defined with four trip points. The critical and emergency
* temperature thresholds, provided by QSFP module are set as "active"
- * and "hot" trip points, "normal" and "critical" trip points ar
+ * and "hot" trip points, "normal" and "critical" trip points are
* derived from "active" and "hot" by subtracting or adding double
* hysteresis value.
*/
@@ -199,140 +196,6 @@ mlxsw_thermal_module_trips_update(struct device *dev, struct mlxsw_core *core,
return 0;
}
-static void mlxsw_thermal_tz_score_get(struct mlxsw_thermal_trip *trips,
- int temp, int *score)
-{
- struct mlxsw_thermal_trip *trip = trips;
- int delta, i, shift = 1;
-
- /* Calculate thermal zone score, if temperature is above the critical
- * threshold score is set to MLXSW_THERMAL_TEMP_SCORE_MAX.
- */
- *score = MLXSW_THERMAL_TEMP_SCORE_MAX;
- for (i = MLXSW_THERMAL_TEMP_TRIP_NORM; i < MLXSW_THERMAL_NUM_TRIPS;
- i++, trip++) {
- if (temp < trip->temp) {
- delta = DIV_ROUND_CLOSEST(temp, trip->temp - temp);
- *score = delta * shift;
- break;
- }
- shift *= 256;
- }
-}
-
-static int
-mlxsw_thermal_highest_tz_get(struct device *dev, struct mlxsw_thermal *thermal,
- int module_count, unsigned int seed_temp,
- int *max_tz, int *max_score)
-{
- char mtbr_pl[MLXSW_REG_MTBR_LEN];
- struct mlxsw_thermal_module *tz;
- int i, j, index, off, score;
- u16 temp;
- int err;
-
- mlxsw_thermal_tz_score_get(thermal->trips, seed_temp, max_score);
- /* Read modules temperature. */
- index = 0;
- while (index < module_count) {
- off = min_t(u8, MLXSW_REG_MTBR_REC_MAX_COUNT,
- module_count - index);
- mlxsw_reg_mtbr_pack(mtbr_pl, MLXSW_REG_MTBR_BASE_MODULE_INDEX +
- index, off);
- err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtbr), mtbr_pl);
- if (err) {
- dev_err(dev, "Failed to get temp from index %d\n",
- off);
- return err;
- }
-
- for (i = 0, j = index; i < off; i++, j++) {
- mlxsw_reg_mtbr_temp_unpack(mtbr_pl, i, &temp, NULL);
- /* Update status and temperature cache. */
- switch (temp) {
- case MLXSW_REG_MTBR_NO_CONN: /* fall-through */
- case MLXSW_REG_MTBR_NO_TEMP_SENS: /* fall-through */
- case MLXSW_REG_MTBR_INDEX_NA: /* fall-through */
- case MLXSW_REG_MTBR_BAD_SENS_INFO:
- temp = 0;
- break;
- default:
- tz = &thermal->tz_module_arr[j];
- if (!tz)
- break;
- /* Reset all trip point. */
- mlxsw_thermal_module_trips_reset(tz);
- temp = MLXSW_REG_MTMP_TEMP_TO_MC(temp);
- /* Do not consider zero temperature. */
- if (!temp)
- break;
-
- err = mlxsw_thermal_module_trips_update(dev,
- thermal->core,
- tz);
- if (err) {
- dev_err(dev, "Failed to update trips for %s\n",
- tz->tzdev->type);
- return err;
- }
-
- score = 0;
- mlxsw_thermal_tz_score_get(tz->trips, temp,
- &score);
- if (score > *max_score) {
- *max_score = score;
- *max_tz = j + 1;
- }
- break;
- }
- }
- index += off;
- }
-
- return 0;
-}
-
-static int
-mlxsw_thermal_highest_tz_notify(struct device *dev,
- struct thermal_zone_device *tzdev,
- struct mlxsw_thermal *thermal,
- int module_count, unsigned int temp)
-{
- char env_record[24];
- char *envp[2] = { env_record, NULL };
- struct mlxsw_thermal_module *tz_module;
- struct thermal_zone_device *tz;
- int max_tz = 0, max_score = 0;
- int err;
-
- err = mlxsw_thermal_highest_tz_get(dev, thermal,
- thermal->tz_module_num, temp,
- &max_tz, &max_score);
- if (err) {
- dev_err(dev, "Failed to query module temp sensor\n");
- return err;
- }
-
- if (thermal->tz_highest != max_tz) {
- sprintf(env_record, "TZ_HIGHEST==%u", max_score);
- if (max_tz && (&thermal->tz_module_arr[max_tz - 1])) {
- tz_module = &thermal->tz_module_arr[max_tz - 1];
- tz = tz_module->tzdev;
- err = kobject_uevent_env(&tz->device.kobj, KOBJ_CHANGE,
- envp);
- } else {
- err = kobject_uevent_env(&tzdev->device.kobj,
- KOBJ_CHANGE, envp);
- }
- if (err)
- dev_err(dev, "Error sending uevent %s\n", envp[0]);
- else
- thermal->tz_highest = max_tz;
- }
-
- return 0;
-}
-
static int mlxsw_thermal_bind(struct thermal_zone_device *tzdev,
struct thermal_cooling_device *cdev)
{
@@ -398,20 +261,15 @@ static int mlxsw_thermal_set_mode(struct thermal_zone_device *tzdev,
mutex_lock(&tzdev->lock);
- if (mode == THERMAL_DEVICE_ENABLED) {
- thermal->tz_highest = 0;
+ if (mode == THERMAL_DEVICE_ENABLED)
tzdev->polling_delay = thermal->polling_delay;
- } else {
+ else
tzdev->polling_delay = 0;
- }
mutex_unlock(&tzdev->lock);
thermal->mode = mode;
-
- mutex_lock(&thermal->tz_update_lock);
thermal_zone_device_update(tzdev, THERMAL_EVENT_UNSPECIFIED);
- mutex_unlock(&thermal->tz_update_lock);
return 0;
}
@@ -433,15 +291,7 @@ static int mlxsw_thermal_get_temp(struct thermal_zone_device *tzdev,
return err;
}
mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
-#if 0
- if (thermal->tz_module_arr) {
- err = mlxsw_thermal_highest_tz_notify(dev, tzdev, thermal,
- thermal->tz_module_num,
- temp);
- if (err)
- dev_err(dev, "Failed to query module temp sensor\n");
- }
-#endif
+
*p_temp = (int) temp;
return 0;
}
@@ -589,10 +439,7 @@ static int mlxsw_thermal_module_mode_set(struct thermal_zone_device *tzdev,
mutex_unlock(&tzdev->lock);
tz->mode = mode;
-
- mutex_lock(&thermal->tz_update_lock);
thermal_zone_device_update(tzdev, THERMAL_EVENT_UNSPECIFIED);
- mutex_unlock(&thermal->tz_update_lock);
return 0;
}
@@ -993,7 +840,6 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
thermal->core = core;
thermal->bus_info = bus_info;
- mutex_init(&thermal->tz_update_lock);
memcpy(thermal->trips, default_thermal_trips, sizeof(thermal->trips));
err = mlxsw_reg_query(thermal->core, MLXSW_REG(mfcr), mfcr_pl);
@@ -1028,8 +874,8 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
struct thermal_cooling_device *cdev;
cdev = thermal_cooling_device_register("mlxsw_fan",
- thermal,
- &mlxsw_cooling_ops);
+ thermal,
+ &mlxsw_cooling_ops);
if (IS_ERR(cdev)) {
err = PTR_ERR(cdev);
dev_err(dev, "Failed to register cooling device\n");
@@ -1069,6 +915,8 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
*p_thermal = thermal;
return 0;
+err_unreg_modules_tzdev:
+ mlxsw_thermal_modules_fini(thermal);
err_unreg_tzdev:
if (thermal->tzdev) {
thermal_zone_device_unregister(thermal->tzdev);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
index b1471c2b6af2..307fd5fcd302 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
@@ -399,7 +399,10 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
if (reg_size % MLXSW_I2C_BLK_MAX)
num++;
- mutex_lock(&mlxsw_i2c->cmd.lock);
+ if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
+ dev_err(&client->dev, "Could not acquire lock");
+ return -EINVAL;
+ }
err = mlxsw_i2c_write(dev, reg_size, in_mbox, num, status);
if (err)
@@ -415,7 +418,10 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
reg_size = MLXSW_I2C_MAX_DATA_SIZE;
num = reg_size / MLXSW_I2C_BLK_MAX;
- mutex_lock(&mlxsw_i2c->cmd.lock);
+ if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
+ dev_err(&client->dev, "Could not acquire lock");
+ return -EINVAL;
+ }
err = mlxsw_i2c_write_init_cmd(client, mlxsw_i2c, opcode,
in_mod);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
index 9312f42c8f9b..740b3753de44 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
-/* Copyright (c) 2016-2018 Mellanox Technologies. All rights reserved */
+/* Copyright (c) 2016-2019 Mellanox Technologies. All rights reserved */
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -50,11 +50,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;
- int err;
-
- err = mlxsw_env_get_module_info(core, mlxsw_m_port->module, modinfo);
- return err;
+ return mlxsw_env_get_module_info(core, mlxsw_m_port->module, modinfo);
}
static int
@@ -63,12 +60,9 @@ 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;
- int err;
-
- err = mlxsw_env_get_module_eeprom(netdev, core,
- mlxsw_m_port->module, ee, data);
- return err;
+ return mlxsw_env_get_module_eeprom(netdev, core, mlxsw_m_port->module,
+ ee, data);
}
static const struct ethtool_ops mlxsw_m_port_ethtool_ops = {
@@ -199,7 +193,7 @@ static int mlxsw_m_port_module_map(struct mlxsw_m *mlxsw_m, u8 local_port,
u8 module, width;
int err;
- /* Fill out to local port mapping array */
+ /* Fill out to local port mapping array */
err = mlxsw_m_port_module_info_get(mlxsw_m, local_port, &module,
&width);
if (err)
@@ -216,57 +210,39 @@ static int mlxsw_m_port_module_map(struct mlxsw_m *mlxsw_m, u8 local_port,
return 0;
}
-static int mlxsw_m_port_module_unmap(struct mlxsw_m *mlxsw_m, u8 module)
+static void mlxsw_m_port_module_unmap(struct mlxsw_m *mlxsw_m, u8 module)
{
mlxsw_m->module_to_port[module] = -1;
-
- return 0;
-}
-
-static void mlxsw_m_ports_remove(struct mlxsw_m *mlxsw_m)
-{
- int i;
-
- for (i = 0; i < mlxsw_m->max_ports; i++) {
- if (mlxsw_m->module_to_port[i] > 0) {
- mlxsw_m_port_remove(mlxsw_m,
- mlxsw_m->module_to_port[i]);
- mlxsw_m_port_module_unmap(mlxsw_m, i);
- }
- }
-
- kfree(mlxsw_m->module_to_port);
- kfree(mlxsw_m->ports);
}
static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)
{
- unsigned int max_port = mlxsw_core_max_ports(mlxsw_m->core);
- u8 last_module = max_port;
+ unsigned int max_ports = mlxsw_core_max_ports(mlxsw_m->core);
+ u8 last_module = max_ports;
int i;
int err;
- mlxsw_m->ports = kcalloc(max_port, sizeof(*mlxsw_m->ports),
+ mlxsw_m->ports = kcalloc(max_ports, sizeof(*mlxsw_m->ports),
GFP_KERNEL);
if (!mlxsw_m->ports)
return -ENOMEM;
- mlxsw_m->module_to_port = kmalloc_array(max_port, sizeof(int),
+ mlxsw_m->module_to_port = kmalloc_array(max_ports, sizeof(int),
GFP_KERNEL);
if (!mlxsw_m->module_to_port) {
err = -ENOMEM;
- goto err_port_create;
+ goto err_module_to_port_alloc;
}
/* Invalidate the entries of module to local port mapping array */
- for (i = 0; i < max_port; i++)
+ for (i = 0; i < max_ports; i++)
mlxsw_m->module_to_port[i] = -1;
/* Fill out module to local port mapping array */
- for (i = 1; i < max_port; i++) {
+ for (i = 1; i < max_ports; i++) {
err = mlxsw_m_port_module_map(mlxsw_m, i, &last_module);
if (err)
- goto err_port_create;
+ goto err_module_to_port_map;
}
/* Create port objects for each valid entry */
@@ -276,17 +252,44 @@ static int mlxsw_m_ports_create(struct mlxsw_m *mlxsw_m)
mlxsw_m->module_to_port[i],
i);
if (err)
- goto err_port_create;
+ goto err_module_to_port_create;
}
}
return 0;
-err_port_create:
- mlxsw_m_ports_remove(mlxsw_m);
+err_module_to_port_create:
+ for (i--; i >= 0; i--) {
+ if (mlxsw_m->module_to_port[i] > 0)
+ mlxsw_m_port_remove(mlxsw_m,
+ mlxsw_m->module_to_port[i]);
+ }
+ i = max_ports;
+err_module_to_port_map:
+ for (i--; i > 0; i--)
+ mlxsw_m_port_module_unmap(mlxsw_m, i);
+ kfree(mlxsw_m->module_to_port);
+err_module_to_port_alloc:
+ kfree(mlxsw_m->ports);
return err;
}
+static void mlxsw_m_ports_remove(struct mlxsw_m *mlxsw_m)
+{
+ int i;
+
+ for (i = 0; i < mlxsw_m->max_ports; i++) {
+ if (mlxsw_m->module_to_port[i] > 0) {
+ mlxsw_m_port_remove(mlxsw_m,
+ mlxsw_m->module_to_port[i]);
+ mlxsw_m_port_module_unmap(mlxsw_m, i);
+ }
+ }
+
+ kfree(mlxsw_m->module_to_port);
+ kfree(mlxsw_m->ports);
+}
+
static int mlxsw_m_init(struct mlxsw_core *mlxsw_core,
const struct mlxsw_bus_info *mlxsw_bus_info)
{
--
2.11.0

View File

@@ -0,0 +1,87 @@
From d0e273393dd610f552ffbe9a9d1cf3448c8c028e Mon Sep 17 00:00:00 2001
From: Vadim Pasternak <vadimp@mellanox.com>
Date: Sun, 3 Mar 2019 08:50:49 +0000
Subject: [PATCH backport 5.1] mlxsw: core: Add check for split port during
thermal zone initialization
Skip thermal zone creation in case of split port.
Overwrite the first byte in base MAC address in
minimal driver.
Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 15 ++++++++++++---
drivers/net/ethernet/mellanox/mlxsw/minimal.c | 2 +-
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
index 002654918ee9..1f7ef90b2270 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -752,6 +752,9 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
module_tz = &thermal->tz_module_arr[module];
+ /* Skip if parent is already set - could in in case of port split. */
+ if (module_tz->parent)
+ return 0;
module_tz->module = module;
module_tz->parent = thermal;
memcpy(module_tz->trips, default_thermal_trips,
@@ -773,6 +776,7 @@ static void mlxsw_thermal_module_fini(struct mlxsw_thermal_module *module_tz)
if (module_tz && module_tz->tzdev) {
mlxsw_thermal_module_tz_fini(module_tz->tzdev);
module_tz->tzdev = NULL;
+ module_tz->parent = 0;
}
}
@@ -781,6 +785,7 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
struct mlxsw_thermal *thermal)
{
unsigned int module_count = mlxsw_core_max_ports(core);
+ struct mlxsw_thermal_module *module_tz;
int i, err;
thermal->tz_module_arr = kcalloc(module_count,
@@ -795,8 +800,12 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
goto err_unreg_tz_module_arr;
}
- for (i = 0; i < thermal->tz_module_num; i++) {
- err = mlxsw_thermal_module_tz_init(&thermal->tz_module_arr[i]);
+ module_count -= 1;
+ for (i = 0; i < module_count; i++) {
+ module_tz = &thermal->tz_module_arr[i];
+ if (!module_tz->parent)
+ continue;
+ err = mlxsw_thermal_module_tz_init(module_tz);
if (err)
goto err_unreg_tz_module_arr;
}
@@ -804,7 +813,7 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
return 0;
err_unreg_tz_module_arr:
- for (i = module_count - 1; i >= 0; i--)
+ for (i = module_count; i >= 0; i--)
mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
kfree(thermal->tz_module_arr);
return err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
index 740b3753de44..cac36c231864 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
@@ -104,7 +104,7 @@ 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;
return 0;
}
--
2.11.0

View File

@@ -0,0 +1,665 @@
diff -Nur a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
--- a/drivers/platform/x86/mlx-platform.c 2019-02-21 13:41:06.654605472 +0000
+++ b/drivers/platform/x86/mlx-platform.c 2019-02-21 13:48:22.670032634 +0000
@@ -61,9 +61,11 @@
#define MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET 0xc9
#define MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET 0xcb
#define MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET 0xcd
+#define MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET 0xce
#define MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET 0xcf
#define MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET 0xd1
-#define MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET 0xd2
+#define MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET 0xd2
+#define MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET 0xd3
#define MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET 0xe3
#define MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET 0xe4
#define MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET 0xe5
@@ -1369,7 +1371,9 @@
.counter = ARRAY_SIZE(mlxplat_mlxcpld_default_fan_data),
};
-/* Type1 watchdog implementation on MSN2700, MSN2100 and MSN2140 systems */
+/* Watchdog type1: hardware implementation version1
+ * (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140 systems).
+ */
static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type1[] = {
{
.label = "action",
@@ -1422,17 +1426,19 @@
{
.data = mlxplat_mlxcpld_wd_main_regs_type1,
.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type1),
+ .version = MLX_WDT_TYPE1,
.identity = "mlx-wdt-main",
},
{
.data = mlxplat_mlxcpld_wd_aux_regs_type1,
.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type1),
+ .version = MLX_WDT_TYPE1,
.identity = "mlx-wdt-aux",
},
};
-/* Type2 watchdog implementation on MSB8700 and up systems
- * To differentiate: ping reg == action reg
+/* Watchdog type2: hardware implementation version 2
+ * (all systems except (MSN2700, MSN2410, MSN2740, MSN2100 and MSN2140).
*/
static struct mlxreg_core_data mlxplat_mlxcpld_wd_main_regs_type2[] = {
{
@@ -1448,6 +1454,11 @@
.health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
},
{
+ .label = "timeleft",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
+ },
+ {
.label = "ping",
.reg = MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET,
.mask = MLXPLAT_CPLD_WD_RESET_ACT_MASK,
@@ -1475,6 +1486,11 @@
.health_cntr = MLXPLAT_CPLD_WD_DFLT_TIMEOUT,
},
{
+ .label = "timeleft",
+ .reg = MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET,
+ .mask = MLXPLAT_CPLD_WD_TYPE2_TO_MASK,
+ },
+ {
.label = "ping",
.reg = MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET,
.mask = MLXPLAT_CPLD_WD_FAN_ACT_MASK,
@@ -1486,11 +1502,13 @@
{
.data = mlxplat_mlxcpld_wd_main_regs_type2,
.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_main_regs_type2),
+ .version = MLX_WDT_TYPE2,
.identity = "mlx-wdt-main",
},
{
.data = mlxplat_mlxcpld_wd_aux_regs_type2,
.counter = ARRAY_SIZE(mlxplat_mlxcpld_wd_aux_regs_type2),
+ .version = MLX_WDT_TYPE2,
.identity = "mlx-wdt-aux",
},
};
@@ -1573,8 +1591,10 @@
case MLXPLAT_CPLD_LPC_REG_WD1_TMR_OFFSET:
case MLXPLAT_CPLD_LPC_REG_WD1_ACT_OFFSET:
case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
case MLXPLAT_CPLD_LPC_REG_WD2_ACT_OFFSET:
case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET:
case MLXPLAT_CPLD_LPC_REG_WD3_ACT_OFFSET:
case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
@@ -1634,7 +1654,9 @@
case MLXPLAT_CPLD_LPC_REG_FAN_EVENT_OFFSET:
case MLXPLAT_CPLD_LPC_REG_FAN_MASK_OFFSET:
case MLXPLAT_CPLD_LPC_REG_WD2_TMR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD2_TLEFT_OFFSET:
case MLXPLAT_CPLD_LPC_REG_WD3_TMR_OFFSET:
+ case MLXPLAT_CPLD_LPC_REG_WD3_TLEFT_OFFSET:
case MLXPLAT_CPLD_LPC_REG_PWM1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_TACHO1_OFFSET:
case MLXPLAT_CPLD_LPC_REG_TACHO2_OFFSET:
@@ -2094,8 +2116,8 @@
for (j = 0; j < MLXPLAT_CPLD_WD_MAX_DEVS; j++) {
if (mlxplat_wd_data[j]) {
mlxplat_wd_data[j]->regmap = mlxplat_hotplug->regmap;
- priv->pdev_wd[j] = platform_device_register_resndata(
- &mlxplat_dev->dev,
+ priv->pdev_wd[j] = platform_device_register_resndata
+ (&mlxplat_dev->dev,
"mlx-wdt", j, NULL, 0,
mlxplat_wd_data[j],
sizeof(*mlxplat_wd_data[j]));
@@ -2115,8 +2137,10 @@
return 0;
fail_platform_wd_register:
- while (--j >= 0)
- platform_device_unregister(priv->pdev_wd[j]);
+ while (--j >= 0) {
+ if (priv->pdev_wd[j])
+ platform_device_unregister(priv->pdev_wd[j]);
+ }
if (mlxplat_fan)
platform_device_unregister(priv->pdev_fan);
fail_platform_io_regs_register:
@@ -2142,16 +2166,16 @@
struct mlxplat_priv *priv = platform_get_drvdata(mlxplat_dev);
int i;
+ for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--) {
+ if (mlxplat_wd_data[i])
+ platform_device_unregister(priv->pdev_wd[i]);
+ }
if (priv->pdev_fan)
platform_device_unregister(priv->pdev_fan);
if (priv->pdev_io_regs)
platform_device_unregister(priv->pdev_io_regs);
platform_device_unregister(priv->pdev_led);
platform_device_unregister(priv->pdev_hotplug);
- for (i = MLXPLAT_CPLD_WD_MAX_DEVS - 1; i >= 0 ; i--) {
- if (mlxplat_wd_data[i])
- platform_device_unregister(priv->pdev_wd[i]);
- }
for (i = ARRAY_SIZE(mlxplat_mux_data) - 1; i >= 0 ; i--)
platform_device_unregister(priv->pdev_mux[i]);
diff -Nur a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
--- a/drivers/watchdog/Kconfig 2019-02-21 13:41:44.518903255 +0000
+++ b/drivers/watchdog/Kconfig 2019-02-21 13:54:11.964775375 +0000
@@ -141,21 +141,6 @@
This driver can also be built as a module. If so the module
will be called menf21bmc_wdt.
-config MLX_WDT
- tristate "Mellanox Watchdog"
- select WATCHDOG_CORE
- select REGMAP
- ---help---
- This is the driver for the hardware watchdog on Mellanox systems.
- If you are going to use it, say Y here, otherwise N.
- This driver can be used together with the watchdog daemon.
- It can also watch your kernel to make sure it doesn't freeze,
- and if it does, it reboots your system after a certain amount of
- time.
-
- To compile this driver as a module, choose M here: the
- module will be called mlx-wdt.
-
config TANGOX_WATCHDOG
tristate "Sigma Designs SMP86xx/SMP87xx watchdog"
select WATCHDOG_CORE
@@ -218,6 +203,22 @@
To compile this driver as a module, choose M here: the
module will be called ziirave_wdt.
+config MLX_WDT
+ tristate "Mellanox Watchdog"
+ depends on MELLANOX_PLATFORM
+ select WATCHDOG_CORE
+ select REGMAP
+ help
+ This is the driver for the hardware watchdog on Mellanox systems.
+ If you are going to use it, say Y here, otherwise N.
+ This driver can be used together with the watchdog daemon.
+ It can also watch your kernel to make sure it doesn't freeze,
+ and if it does, it reboots your system after a certain amount of
+ time.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mlx-wdt.
+
# ALPHA Architecture
# ARM Architecture
diff -Nur a/drivers/watchdog/mlx_wdt.c b/drivers/watchdog/mlx_wdt.c
--- a/drivers/watchdog/mlx_wdt.c 2019-02-21 13:42:09.119096705 +0000
+++ b/drivers/watchdog/mlx_wdt.c 2019-02-21 15:36:44.116225080 +0000
@@ -2,8 +2,8 @@
/*
* Mellanox watchdog driver
*
- * Copyright (C) 2018 Mellanox Technologies
- * Copyright (C) 2018 Michael Shych <mshych@mellanox.com>
+ * Copyright (C) 2019 Mellanox Technologies
+ * Copyright (C) 2019 Michael Shych <mshych@mellanox.com>
*/
#include <linux/bitops.h>
@@ -21,20 +21,9 @@
#define MLXREG_WDT_CLOCK_SCALE 1000
#define MLXREG_WDT_MAX_TIMEOUT_TYPE1 32
#define MLXREG_WDT_MAX_TIMEOUT_TYPE2 255
-#define MLXREG_WDT_MIN_TIMEOUT 1
-#define MLXREG_WDT_HW_TIMEOUT_CONVERT(hw_timeout) ((1 << (hw_timeout)) \
- / MLXREG_WDT_CLOCK_SCALE)
-
-/**
- * enum mlxreg_wdt_type - type of HW watchdog
- *
- * TYPE1 can be differentiated by different register/mask
- * for WD action set and ping.
- */
-enum mlxreg_wdt_type {
- MLX_WDT_TYPE1,
- MLX_WDT_TYPE2,
-};
+#define MLXREG_WDT_MIN_TIMEOUT 1
+#define MLXREG_WDT_OPTIONS_BASE (WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE | \
+ WDIOF_SETTIMEOUT)
/**
* struct mlxreg_wdt - wd private data:
@@ -44,16 +33,12 @@
* @pdata: data received from platform driver;
* @regmap: register map of parent device;
* @timeout: defined timeout in sec.;
- * @hw_timeout: real timeout set in hw;
- * It will be roundup base of 2 in WD type 1,
- * in WD type 2 it will be same number of sec as timeout;
* @action_idx: index for direct access to action register;
* @timeout_idx:index for direct access to TO register;
+ * @tleft_idx: index for direct access to time left register;
* @ping_idx: index for direct access to ping register;
* @reset_idx: index for direct access to reset cause register;
* @wd_type: watchdog HW type;
- * @hw_timeout: actual HW timeout;
- * @io_lock: spinlock for io access;
*/
struct mlxreg_wdt {
struct watchdog_device wdd;
@@ -61,138 +46,61 @@
void *regmap;
int action_idx;
int timeout_idx;
+ int tleft_idx;
int ping_idx;
int reset_idx;
enum mlxreg_wdt_type wdt_type;
- u8 hw_timeout;
- spinlock_t io_lock; /* the lock for io operations */
};
-static int mlxreg_wdt_roundup_to_base_2(struct mlxreg_wdt *wdt, int timeout)
-{
- timeout *= MLXREG_WDT_CLOCK_SCALE;
-
- wdt->hw_timeout = order_base_2(timeout);
- dev_info(wdt->wdd.parent,
- "watchdog %s timeout %d was rounded up to %lu (msec)\n",
- wdt->wdd.info->identity, timeout, roundup_pow_of_two(timeout));
-
- return 0;
-}
-
-static enum mlxreg_wdt_type
-mlxreg_wdt_check_watchdog_type(struct mlxreg_wdt *wdt,
- struct mlxreg_core_platform_data *pdata)
-{
- if ((pdata->data[wdt->action_idx].reg ==
- pdata->data[wdt->ping_idx].reg) &&
- (pdata->data[wdt->action_idx].mask ==
- pdata->data[wdt->ping_idx].mask))
- return MLX_WDT_TYPE2;
- else
- return MLX_WDT_TYPE1;
-}
-
-static int mlxreg_wdt_check_card_reset(struct mlxreg_wdt *wdt)
+static void mlxreg_wdt_check_card_reset(struct mlxreg_wdt *wdt)
{
struct mlxreg_core_data *reg_data;
u32 regval;
int rc;
if (wdt->reset_idx == -EINVAL)
- return -EINVAL;
+ return;
if (!(wdt->wdd.info->options & WDIOF_CARDRESET))
- return 0;
+ return;
- spin_lock(&wdt->io_lock);
reg_data = &wdt->pdata->data[wdt->reset_idx];
rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
- spin_unlock(&wdt->io_lock);
- if (rc)
- goto read_error;
-
- if (regval & ~reg_data->mask) {
- wdt->wdd.bootstatus = WDIOF_CARDRESET;
- dev_info(wdt->wdd.parent,
- "watchdog previously reset the CPU\n");
+ if (!rc) {
+ if (regval & ~reg_data->mask) {
+ wdt->wdd.bootstatus = WDIOF_CARDRESET;
+ dev_info(wdt->wdd.parent,
+ "watchdog previously reset the CPU\n");
+ }
}
-
-read_error:
- return rc;
}
static int mlxreg_wdt_start(struct watchdog_device *wdd)
{
struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->action_idx];
- u32 regval;
- int rc;
-
- spin_lock(&wdt->io_lock);
- rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
- if (rc) {
- spin_unlock(&wdt->io_lock);
- goto read_error;
- }
-
- regval = (regval & reg_data->mask) | BIT(reg_data->bit);
- rc = regmap_write(wdt->regmap, reg_data->reg, regval);
- spin_unlock(&wdt->io_lock);
- if (!rc) {
- set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
- dev_info(wdt->wdd.parent, "watchdog %s started\n",
- wdd->info->identity);
- }
-read_error:
- return rc;
+ return regmap_update_bits(wdt->regmap, reg_data->reg, ~reg_data->mask,
+ BIT(reg_data->bit));
}
static int mlxreg_wdt_stop(struct watchdog_device *wdd)
{
struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->action_idx];
- u32 regval;
- int rc;
-
- spin_lock(&wdt->io_lock);
- rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
- if (rc) {
- spin_unlock(&wdt->io_lock);
- goto read_error;
- }
- regval = (regval & reg_data->mask) & ~BIT(reg_data->bit);
- rc = regmap_write(wdt->regmap, reg_data->reg, regval);
- spin_unlock(&wdt->io_lock);
- if (!rc)
- dev_info(wdt->wdd.parent, "watchdog %s stopped\n",
- wdd->info->identity);
-
-read_error:
- return rc;
+ return regmap_update_bits(wdt->regmap, reg_data->reg, ~reg_data->mask,
+ ~BIT(reg_data->bit));
}
static int mlxreg_wdt_ping(struct watchdog_device *wdd)
{
struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->ping_idx];
- u32 regval;
- int rc;
- spin_lock(&wdt->io_lock);
- rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
- if (rc)
- goto read_error;
-
- regval = (regval & reg_data->mask) | BIT(reg_data->bit);
- rc = regmap_write(wdt->regmap, reg_data->reg, regval);
-
-read_error:
- spin_unlock(&wdt->io_lock);
-
- return rc;
+ return regmap_update_bits_base(wdt->regmap, reg_data->reg,
+ ~reg_data->mask, BIT(reg_data->bit),
+ NULL, false, true);
}
static int mlxreg_wdt_set_timeout(struct watchdog_device *wdd,
@@ -200,25 +108,37 @@
{
struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->timeout_idx];
- u32 regval;
+ u32 regval, set_time, hw_timeout;
int rc;
- spin_lock(&wdt->io_lock);
-
if (wdt->wdt_type == MLX_WDT_TYPE1) {
rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
if (rc)
- goto read_error;
- regval = (regval & reg_data->mask) | wdt->hw_timeout;
+ return rc;
+
+ hw_timeout = order_base_2(timeout * MLXREG_WDT_CLOCK_SCALE);
+ regval = (regval & reg_data->mask) | hw_timeout;
+ /* Rowndown to actual closest number of sec. */
+ set_time = BIT(hw_timeout) / MLXREG_WDT_CLOCK_SCALE;
} else {
- wdt->hw_timeout = timeout;
+ set_time = timeout;
regval = timeout;
}
+ wdd->timeout = set_time;
rc = regmap_write(wdt->regmap, reg_data->reg, regval);
-read_error:
- spin_unlock(&wdt->io_lock);
+ if (!rc) {
+ /*
+ * Restart watchdog with new timeout period
+ * if watchdog is already started.
+ */
+ if (watchdog_active(wdd)) {
+ rc = mlxreg_wdt_stop(wdd);
+ if (!rc)
+ rc = mlxreg_wdt_start(wdd);
+ }
+ }
return rc;
}
@@ -226,23 +146,13 @@
static unsigned int mlxreg_wdt_get_timeleft(struct watchdog_device *wdd)
{
struct mlxreg_wdt *wdt = watchdog_get_drvdata(wdd);
- struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->timeout_idx];
+ struct mlxreg_core_data *reg_data = &wdt->pdata->data[wdt->tleft_idx];
u32 regval;
int rc;
- if (wdt->wdt_type == MLX_WDT_TYPE1)
- return 0;
-
- spin_lock(&wdt->io_lock);
rc = regmap_read(wdt->regmap, reg_data->reg, &regval);
- if (rc)
- rc = 0;
- else
- rc = regval;
-
- spin_unlock(&wdt->io_lock);
-
- return rc;
+ /* Return 0 timeleft in case of failure register read. */
+ return rc == 0 ? regval : 0;
}
static const struct watchdog_ops mlxreg_wdt_ops_type1 = {
@@ -263,26 +173,22 @@
};
static const struct watchdog_info mlxreg_wdt_main_info = {
- .options = WDIOF_KEEPALIVEPING
- | WDIOF_MAGICCLOSE
- | WDIOF_SETTIMEOUT
+ .options = MLXREG_WDT_OPTIONS_BASE
| WDIOF_CARDRESET,
.identity = "mlx-wdt-main",
};
static const struct watchdog_info mlxreg_wdt_aux_info = {
- .options = WDIOF_KEEPALIVEPING
- | WDIOF_MAGICCLOSE
- | WDIOF_SETTIMEOUT
+ .options = MLXREG_WDT_OPTIONS_BASE
| WDIOF_ALARMONLY,
.identity = "mlx-wdt-aux",
};
-static int mlxreg_wdt_config(struct mlxreg_wdt *wdt,
- struct mlxreg_core_platform_data *pdata)
+static void mlxreg_wdt_config(struct mlxreg_wdt *wdt,
+ struct mlxreg_core_platform_data *pdata)
{
struct mlxreg_core_data *data = pdata->data;
- int i, timeout;
+ int i;
wdt->reset_idx = -EINVAL;
for (i = 0; i < pdata->counter; i++, data++) {
@@ -290,6 +196,8 @@
wdt->action_idx = i;
else if (strnstr(data->label, "timeout", sizeof(data->label)))
wdt->timeout_idx = i;
+ else if (strnstr(data->label, "timeleft", sizeof(data->label)))
+ wdt->tleft_idx = i;
else if (strnstr(data->label, "ping", sizeof(data->label)))
wdt->ping_idx = i;
else if (strnstr(data->label, "reset", sizeof(data->label)))
@@ -303,24 +211,24 @@
else
wdt->wdd.info = &mlxreg_wdt_aux_info;
- timeout = pdata->data[wdt->timeout_idx].health_cntr;
- wdt->wdt_type = mlxreg_wdt_check_watchdog_type(wdt, pdata);
+ wdt->wdt_type = pdata->version;
if (wdt->wdt_type == MLX_WDT_TYPE2) {
- wdt->hw_timeout = timeout;
wdt->wdd.ops = &mlxreg_wdt_ops_type2;
- wdt->wdd.timeout = wdt->hw_timeout;
wdt->wdd.max_timeout = MLXREG_WDT_MAX_TIMEOUT_TYPE2;
} else {
- mlxreg_wdt_roundup_to_base_2(wdt, timeout);
wdt->wdd.ops = &mlxreg_wdt_ops_type1;
- /* Rowndown to actual closest number of sec. */
- wdt->wdd.timeout =
- MLXREG_WDT_HW_TIMEOUT_CONVERT(wdt->hw_timeout);
wdt->wdd.max_timeout = MLXREG_WDT_MAX_TIMEOUT_TYPE1;
}
wdt->wdd.min_timeout = MLXREG_WDT_MIN_TIMEOUT;
+}
- return -EINVAL;
+static int mlxreg_wdt_init_timeout(struct mlxreg_wdt *wdt,
+ struct mlxreg_core_platform_data *pdata)
+{
+ u32 timeout;
+
+ timeout = pdata->data[wdt->timeout_idx].health_cntr;
+ return mlxreg_wdt_set_timeout(&wdt->wdd, timeout);
}
static int mlxreg_wdt_probe(struct platform_device *pdev)
@@ -338,48 +246,38 @@
if (!wdt)
return -ENOMEM;
- spin_lock_init(&wdt->io_lock);
-
wdt->wdd.parent = &pdev->dev;
wdt->regmap = pdata->regmap;
mlxreg_wdt_config(wdt, pdata);
- if ((pdata->features & MLXREG_CORE_WD_FEATURE_NOSTOP_AFTER_START))
+ if ((pdata->features & MLXREG_CORE_WD_FEATURE_NOWAYOUT))
watchdog_set_nowayout(&wdt->wdd, WATCHDOG_NOWAYOUT);
watchdog_stop_on_reboot(&wdt->wdd);
- watchdog_init_timeout(&wdt->wdd, 0, &pdev->dev);
watchdog_set_drvdata(&wdt->wdd, wdt);
+ rc = mlxreg_wdt_init_timeout(wdt, pdata);
+ if (rc)
+ goto register_error;
+ if ((pdata->features & MLXREG_CORE_WD_FEATURE_START_AT_BOOT)) {
+ rc = mlxreg_wdt_start(&wdt->wdd);
+ if (rc)
+ goto register_error;
+ set_bit(WDOG_HW_RUNNING, &wdt->wdd.status);
+ }
mlxreg_wdt_check_card_reset(wdt);
rc = devm_watchdog_register_device(&pdev->dev, &wdt->wdd);
- if (rc) {
+
+register_error:
+ if (rc)
dev_err(&pdev->dev,
"Cannot register watchdog device (err=%d)\n", rc);
- return rc;
- }
-
- mlxreg_wdt_set_timeout(&wdt->wdd, wdt->wdd.timeout);
- if ((pdata->features & MLXREG_CORE_WD_FEATURE_START_AT_BOOT))
- mlxreg_wdt_start(&wdt->wdd);
-
return rc;
}
-static int mlxreg_wdt_remove(struct platform_device *pdev)
-{
- struct mlxreg_wdt *wdt = dev_get_platdata(&pdev->dev);
-
- mlxreg_wdt_stop(&wdt->wdd);
- watchdog_unregister_device(&wdt->wdd);
-
- return 0;
-}
-
static struct platform_driver mlxreg_wdt_driver = {
.probe = mlxreg_wdt_probe,
- .remove = mlxreg_wdt_remove,
.driver = {
- .name = "mlx-wdt",
+ .name = "mlx-wdt",
},
};
diff -Nur a/include/linux/platform_data/mlxreg.h b/include/linux/platform_data/mlxreg.h
--- a/include/linux/platform_data/mlxreg.h 2019-02-21 13:58:39.410873888 +0000
+++ b/include/linux/platform_data/mlxreg.h 2019-02-21 13:59:41.015345425 +0000
@@ -35,8 +35,19 @@
#define __LINUX_PLATFORM_DATA_MLXREG_H
#define MLXREG_CORE_LABEL_MAX_SIZE 32
-#define MLXREG_CORE_WD_FEATURE_NOSTOP_AFTER_START BIT(0)
-#define MLXREG_CORE_WD_FEATURE_START_AT_BOOT BIT(1)
+#define MLXREG_CORE_WD_FEATURE_NOWAYOUT BIT(0)
+#define MLXREG_CORE_WD_FEATURE_START_AT_BOOT BIT(1)
+
+/**
+ * enum mlxreg_wdt_type - type of HW watchdog
+ *
+ * TYPE1 HW watchdog implementation exist in old systems.
+ * All new systems have TYPE2 HW watchdog.
+ */
+enum mlxreg_wdt_type {
+ MLX_WDT_TYPE1,
+ MLX_WDT_TYPE2,
+};
/**
* struct mlxreg_hotplug_device - I2C device data:
@@ -115,6 +126,7 @@
* @regmap: register map of parent device;
* @counter: number of instances;
* @features: supported features of device;
+ * @version: implementation version;
* @identity: device identity name;
*/
struct mlxreg_core_platform_data {
@@ -122,6 +134,7 @@
void *regmap;
int counter;
u32 features;
+ u32 version;
char identity[MLXREG_CORE_LABEL_MAX_SIZE];
};

View File

@@ -0,0 +1,74 @@
From 7f31d9b833b0c31f5c8d75416758a9f30add6190 Mon Sep 17 00:00:00 2001
From: Vadim Pasternak <vadimp@mellanox.com>
Date: Wed, 15 May 2019 15:22:44 +0000
Subject: [PATCH backport v5.2] mlxsw: core: Prevent reading unsupported slave
address from SFP EEPROM
Prevent reading unsupported slave address from SFP EEPROM by testing
Diagnostic Monitoring Type byte in EEPROM. Read only page zero of
EEPROM, in case this byte is zero.
If some SFP transceiver don't support Digital Optical Monitoring (DOM),
thus reading SFP EEPROM slave address 0x51 could return error.
Availability of DOM support is verified by reading from zero page
Diagnostic Monitoring Type byte describing how diagnostic monitoring is
implemented by transceiver. If bit 6 of this byte is set, it indicates
that digital diagnostic monitoring has been implemented. Otherwise it is
not and transceiver could fail to reply to transaction for slave address
0x51 [1010001X (A2h)], which is used to access measurements page.
Such issue has been observed when reading cable MCP2M00-xxxx,
MCP7F00-xxxx, and few others.
Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/core_env.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
index 7a15e932ed2f..edcf1b656cbf 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
@@ -3,6 +3,7 @@
#include <linux/kernel.h>
#include <linux/err.h>
+#include <linux/sfp.h>
#include "core.h"
#include "core_env.h"
@@ -162,7 +163,7 @@ int mlxsw_env_get_module_info(struct mlxsw_core *mlxsw_core, int module,
{
u8 module_info[MLXSW_REG_MCIA_EEPROM_MODULE_INFO_SIZE];
u16 offset = MLXSW_REG_MCIA_EEPROM_MODULE_INFO_SIZE;
- u8 module_rev_id, module_id;
+ u8 module_rev_id, module_id, diag_mon;
unsigned int read_size;
int err;
@@ -195,8 +196,21 @@ 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 digital diagnostic monitoring page */
+ err = mlxsw_env_query_module_eeprom(mlxsw_core, module,
+ SFP_DIAGMON, 1, &diag_mon,
+ &read_size);
+ if (err)
+ return err;
+
+ if (read_size < 1)
+ return -EIO;
+
modinfo->type = ETH_MODULE_SFF_8472;
- modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
+ if (diag_mon)
+ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN;
+ else
+ modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN / 2;
break;
default:
return -EINVAL;
--
2.11.0

View File

@@ -0,0 +1,650 @@
From 83d2cf92f7fef5df0de2cf19f4235dc6c50f92a5 Mon Sep 17 00:00:00 2001
From: Vadim Pasternak <vadimp@mellanox.com>
Date: Mon, 4 Mar 2019 14:50:48 +0000
Subject: [PATCH backport 5.1] mlxsw: core: add support for Gear Box
temperatures in hwmon
Add hwmon interface for inter-connects temperature reading.
This information is a critical for the system equipped with such hardware.
These new attributes are necessary for the system monitoring.
Such inter-connect devices are equipped on new Mellanox MSN3800
Ethernet 2U systems with 64xQSFP28 100GbE full bidirectional bandwidth
ports.
The connectivity map is depicted below.
+------+D01
| |+-->+--------+
| | | Die0+--->P01
| | |Gear +--->P02
| | |Box |
| S | |01 +--->P03
| P | | Die1+--->P04
| E |+-->+--------+
| C |D02
| T |...
| R |D15
| U |+-->+---------+
| M | | Die0+--->P29
| 2 | |Gear +--->P30
| | |Box |
| C | |08 +--->P31
| H | | Die1+--->P32
| I |+-->+---------+
| P |D16
| |...
| |D31
| |+-->+---------+
| | | Die0+--->P61
| | |Gear +--->P62
| | |Box |
| | |16 +--->P63
| | | Die1+--->P64
| |+-->+---------+
+------+D32
Spectrum-2 chip provides 64 100GbE ports toward the front panel, in 64
QSFP ports.
Each D(i) above is a pair of 2x50GBe lanes utilizing PAM4 (Pulse
Amplitude Modulation) technology lanes.
Each P(k) above is 4x25GBe lanes utilizing NRZ (Non-Return to Zero)
technology.
Each Gearbox(j) above is a low power 400GbE device supporting data
streams in re-timer mode with PAM-4 modulation or 26.5625Gbps down to
1.25Gbps streams with NRZ modulation.
Each such device is equipped with two dies and each die is equipped
with the temperature sensor for junction temperature measurement. The
operating junction temperature is between 0C and 110C.
These sensors are the subject of this patchset.
Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 85 ++++++++++-
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 165 ++++++++++++++++-----
drivers/net/ethernet/mellanox/mlxsw/qsfp_sysfs.c | 7 +
drivers/net/ethernet/mellanox/mlxsw/reg.h | 56 ++++++-
drivers/platform/mellanox/mlxreg-hotplug.c | 5 +-
drivers/platform/x86/mlx-platform.c | 6 +-
6 files changed, 276 insertions(+), 48 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
index 6956bbebe2f1..976f81a2bbba 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
@@ -15,6 +15,9 @@
#define MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT 127
#define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT * 4 + \
MLXSW_MFCR_TACHOS_MAX + MLXSW_MFCR_PWMS_MAX)
+#define MLXSW_HWMON_GET_ATTR_INDEX(ind, count) \
+ (((ind) >= (count)) ? (ind) % (count) + \
+ MLXSW_REG_MTMP_GBOX_INDEX_MIN : (ind))
struct mlxsw_hwmon_attr {
struct device_attribute dev_attr;
@@ -33,6 +36,7 @@ struct mlxsw_hwmon {
struct mlxsw_hwmon_attr hwmon_attrs[MLXSW_HWMON_ATTR_COUNT];
unsigned int attrs_count;
u8 sensor_count;
+ u8 module_sensor_count;
};
static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
@@ -44,10 +48,12 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
char mtmp_pl[MLXSW_REG_MTMP_LEN];
unsigned int temp;
+ int index;
int err;
- mlxsw_reg_mtmp_pack(mtmp_pl, mlwsw_hwmon_attr->type_index,
- false, false);
+ index = MLXSW_HWMON_GET_ATTR_INDEX(mlwsw_hwmon_attr->type_index,
+ mlxsw_hwmon->module_sensor_count);
+ mlxsw_reg_mtmp_pack(mtmp_pl, 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");
@@ -66,10 +72,12 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
char mtmp_pl[MLXSW_REG_MTMP_LEN];
unsigned int temp_max;
+ int index;
int err;
- mlxsw_reg_mtmp_pack(mtmp_pl, mlwsw_hwmon_attr->type_index,
- false, false);
+ index = MLXSW_HWMON_GET_ATTR_INDEX(mlwsw_hwmon_attr->type_index,
+ mlxsw_hwmon->module_sensor_count);
+ mlxsw_reg_mtmp_pack(mtmp_pl, 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");
@@ -88,6 +96,7 @@ static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
char mtmp_pl[MLXSW_REG_MTMP_LEN];
unsigned long val;
+ int index;
int err;
err = kstrtoul(buf, 10, &val);
@@ -96,7 +105,9 @@ static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
if (val != 1)
return -EINVAL;
- mlxsw_reg_mtmp_pack(mtmp_pl, mlwsw_hwmon_attr->type_index, true, true);
+ index = MLXSW_HWMON_GET_ATTR_INDEX(mlwsw_hwmon_attr->type_index,
+ mlxsw_hwmon->module_sensor_count);
+ mlxsw_reg_mtmp_pack(mtmp_pl, index, true, true);
err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
if (err) {
dev_err(mlxsw_hwmon->bus_info->dev, "Failed to reset temp sensor history\n");
@@ -333,6 +344,20 @@ mlxsw_hwmon_module_temp_label_show(struct device *dev,
mlwsw_hwmon_attr->type_index);
}
+static ssize_t
+mlxsw_hwmon_gbox_temp_label_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
+ container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
+ struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
+ int index = mlwsw_hwmon_attr->type_index -
+ mlxsw_hwmon->module_sensor_count + 1;
+
+ return sprintf(buf, "gearbox %03u\n", index);
+}
+
enum mlxsw_hwmon_attr_type {
MLXSW_HWMON_ATTR_TYPE_TEMP,
MLXSW_HWMON_ATTR_TYPE_TEMP_MAX,
@@ -345,6 +370,7 @@ enum mlxsw_hwmon_attr_type {
MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_CRIT,
MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_EMERG,
MLXSW_HWMON_ATTR_TYPE_TEMP_MODULE_LABEL,
+ MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL,
};
static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
@@ -428,6 +454,13 @@ static void mlxsw_hwmon_attr_add(struct mlxsw_hwmon *mlxsw_hwmon,
snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
"temp%u_label", num + 1);
break;
+ case MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL:
+ mlxsw_hwmon_attr->dev_attr.show =
+ mlxsw_hwmon_gbox_temp_label_show;
+ mlxsw_hwmon_attr->dev_attr.attr.mode = 0444;
+ snprintf(mlxsw_hwmon_attr->name, sizeof(mlxsw_hwmon_attr->name),
+ "temp%u_label", num + 1);
+ break;
default:
WARN_ON(1);
}
@@ -553,6 +586,43 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
index, index);
index++;
}
+ mlxsw_hwmon->module_sensor_count = index;
+
+ return 0;
+}
+
+static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
+{
+ char mgpir_pl[MLXSW_REG_MGPIR_LEN];
+ int index, max_index;
+ u8 gbox_num;
+ int err;
+
+ mlxsw_reg_mgpir_pack(mgpir_pl);
+ err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mgpir), mgpir_pl);
+ if (err)
+ return 0;
+
+ mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, NULL, NULL);
+ if (!gbox_num)
+ return 0;
+
+ index = mlxsw_hwmon->module_sensor_count;
+ max_index = mlxsw_hwmon->module_sensor_count + gbox_num;
+ while (index < max_index) {
+ mlxsw_hwmon_attr_add(mlxsw_hwmon, MLXSW_HWMON_ATTR_TYPE_TEMP,
+ index, index);
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
+ MLXSW_HWMON_ATTR_TYPE_TEMP_MAX, index,
+ index);
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
+ MLXSW_HWMON_ATTR_TYPE_TEMP_RST, index,
+ index);
+ mlxsw_hwmon_attr_add(mlxsw_hwmon,
+ MLXSW_HWMON_ATTR_TYPE_TEMP_GBOX_LABEL,
+ index, index);
+ index++;
+ }
return 0;
}
@@ -583,6 +653,10 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
if (err)
goto err_temp_module_init;
+ err = mlxsw_hwmon_gearbox_init(mlxsw_hwmon);
+ if (err)
+ goto err_temp_gearbox_init;
+
mlxsw_hwmon->groups[0] = &mlxsw_hwmon->group;
mlxsw_hwmon->group.attrs = mlxsw_hwmon->attrs;
@@ -599,6 +673,7 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core,
return 0;
err_hwmon_register:
+err_temp_gearbox_init:
err_temp_module_init:
err_fans_init:
err_temp_init:
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
index 1f7ef90b2270..5f970798ab6a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -112,6 +112,8 @@ struct mlxsw_thermal {
enum thermal_device_mode mode;
struct mlxsw_thermal_module *tz_module_arr;
unsigned int tz_module_num;
+ struct mlxsw_thermal_module *tz_gearbox_arr;
+ u8 tz_gearbox_num;
};
static inline u8 mlxsw_state_to_duty(int state)
@@ -546,62 +548,61 @@ mlxsw_thermal_module_trip_hyst_set(struct thermal_zone_device *tzdev, int trip,
return 0;
}
-static int mlxsw_thermal_module_trend_get(struct thermal_zone_device *tzdev,
- int trip, enum thermal_trend *trend)
+static struct thermal_zone_params mlxsw_thermal_module_params = {
+ .governor_name = "user_space",
+};
+
+static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
+ .bind = mlxsw_thermal_module_bind,
+ .unbind = mlxsw_thermal_module_unbind,
+ .get_mode = mlxsw_thermal_module_mode_get,
+ .set_mode = mlxsw_thermal_module_mode_set,
+ .get_temp = mlxsw_thermal_module_temp_get,
+ .get_trip_type = mlxsw_thermal_module_trip_type_get,
+ .get_trip_temp = mlxsw_thermal_module_trip_temp_get,
+ .set_trip_temp = mlxsw_thermal_module_trip_temp_set,
+ .get_trip_hyst = mlxsw_thermal_module_trip_hyst_get,
+ .set_trip_hyst = mlxsw_thermal_module_trip_hyst_set,
+};
+
+static int mlxsw_thermal_gearbox_temp_get(struct thermal_zone_device *tzdev,
+ int *p_temp)
{
struct mlxsw_thermal_module *tz = tzdev->devdata;
struct mlxsw_thermal *thermal = tz->parent;
- struct device *dev = thermal->bus_info->dev;
- char *envp[2] = { "TZ_DOWN=1", NULL };
- int delta, window;
+ char mtmp_pl[MLXSW_REG_MTMP_LEN];
+ unsigned int temp;
+ u16 index;
int err;
- if (trip < 0 || trip >= MLXSW_THERMAL_NUM_TRIPS)
- return -EINVAL;
+ index = MLXSW_REG_MTMP_GBOX_INDEX_MIN + tz->module;
+ mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
- delta = tzdev->last_temperature - tzdev->temperature;
- window = tz->trips[MLXSW_THERMAL_TEMP_TRIP_HIGH].temp -
- tz->trips[MLXSW_THERMAL_TEMP_TRIP_NORM].temp;
- if (delta > window && !window && !tzdev->last_temperature) {
- /* Notify user about fast temperature decreasing by sending
- * hwmon uevent. Fast decreasing could happen when some hot
- * module is removed. In this situation temperature trend could
- * go down once, and then stay in a stable state.
- * Notification will allow user to handle such case, if user
- * supposes to optimize PWM state.
- */
- err = kobject_uevent_env(&tzdev->device.kobj, KOBJ_CHANGE,
- envp);
- if (err)
- dev_err(dev, "Error sending uevent %s\n", envp[0]);
- }
+ err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
+ if (err)
+ return err;
- if (tzdev->temperature > tzdev->last_temperature)
- *trend = THERMAL_TREND_RAISING;
- else if (tzdev->temperature < tzdev->last_temperature)
- *trend = THERMAL_TREND_DROPPING;
- else
- *trend = THERMAL_TREND_STABLE;
+ mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
+ *p_temp = (int) temp;
return 0;
}
-static struct thermal_zone_params mlxsw_thermal_module_params = {
- .governor_name = "user_space",
-};
-
-static struct thermal_zone_device_ops mlxsw_thermal_module_ops = {
+static struct thermal_zone_device_ops mlxsw_thermal_gearbox_ops = {
.bind = mlxsw_thermal_module_bind,
.unbind = mlxsw_thermal_module_unbind,
.get_mode = mlxsw_thermal_module_mode_get,
.set_mode = mlxsw_thermal_module_mode_set,
- .get_temp = mlxsw_thermal_module_temp_get,
+ .get_temp = mlxsw_thermal_gearbox_temp_get,
.get_trip_type = mlxsw_thermal_module_trip_type_get,
.get_trip_temp = mlxsw_thermal_module_trip_temp_get,
.set_trip_temp = mlxsw_thermal_module_trip_temp_set,
.get_trip_hyst = mlxsw_thermal_module_trip_hyst_get,
.set_trip_hyst = mlxsw_thermal_module_trip_hyst_set,
- .get_trend = mlxsw_thermal_module_trend_get,
+};
+
+static struct thermal_zone_params mlxsw_thermal_gearbox_params = {
+ .governor_name = "user_space",
};
static int mlxsw_thermal_get_max_state(struct thermal_cooling_device *cdev,
@@ -752,7 +753,7 @@ mlxsw_thermal_module_init(struct device *dev, struct mlxsw_core *core,
module = mlxsw_reg_pmlp_module_get(pmlp_pl, 0);
module_tz = &thermal->tz_module_arr[module];
- /* Skip if parent is already set - could in in case of port split. */
+ /* Skip if parent is already set (case of port split). */
if (module_tz->parent)
return 0;
module_tz->module = module;
@@ -776,7 +777,7 @@ static void mlxsw_thermal_module_fini(struct mlxsw_thermal_module *module_tz)
if (module_tz && module_tz->tzdev) {
mlxsw_thermal_module_tz_fini(module_tz->tzdev);
module_tz->tzdev = NULL;
- module_tz->parent = 0;
+ module_tz->parent = NULL;
}
}
@@ -830,6 +831,89 @@ mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal)
kfree(thermal->tz_module_arr);
}
+static int
+mlxsw_thermal_gearbox_tz_init(struct mlxsw_thermal_module *gearbox_tz)
+{
+ char tz_name[MLXSW_THERMAL_ZONE_MAX_NAME];
+ int err;
+
+ 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,
+ gearbox_tz,
+ &mlxsw_thermal_gearbox_ops,
+ &mlxsw_thermal_gearbox_params,
+ 0, 0);
+ if (IS_ERR(gearbox_tz->tzdev)) {
+ err = PTR_ERR(gearbox_tz->tzdev);
+ return err;
+ }
+
+ return 0;
+}
+
+static void
+mlxsw_thermal_gearbox_tz_fini(struct mlxsw_thermal_module *gearbox_tz)
+{
+ thermal_zone_device_unregister(gearbox_tz->tzdev);
+}
+
+static int
+mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
+ struct mlxsw_thermal *thermal)
+{
+ struct mlxsw_thermal_module *gearbox_tz;
+ char mgpir_pl[MLXSW_REG_MGPIR_LEN];
+ int i;
+ int err;
+
+ mlxsw_reg_mgpir_pack(mgpir_pl);
+ err = mlxsw_reg_query(core, MLXSW_REG(mgpir), mgpir_pl);
+ if (err)
+ return 0;
+
+ mlxsw_reg_mgpir_unpack(mgpir_pl, &thermal->tz_gearbox_num, NULL, NULL);
+ if (!thermal->tz_gearbox_num)
+ return 0;
+
+ thermal->tz_gearbox_arr = kcalloc(thermal->tz_gearbox_num,
+ sizeof(*thermal->tz_gearbox_arr),
+ GFP_KERNEL);
+ if (!thermal->tz_gearbox_arr)
+ return -ENOMEM;
+
+ for (i = 0; i < thermal->tz_gearbox_num; i++) {
+ gearbox_tz = &thermal->tz_gearbox_arr[i];
+ memcpy(gearbox_tz->trips, default_thermal_trips,
+ sizeof(thermal->trips));
+ gearbox_tz->module = i;
+ gearbox_tz->parent = thermal;
+ err = mlxsw_thermal_gearbox_tz_init(gearbox_tz);
+ if (err)
+ goto err_unreg_tz_gearbox;
+ }
+
+ return 0;
+
+err_unreg_tz_gearbox:
+ for (i--; i >= 0; i--)
+ mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
+ kfree(thermal->tz_gearbox_arr);
+ return err;
+}
+
+static void
+mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal)
+{
+ 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);
+}
+
int mlxsw_thermal_init(struct mlxsw_core *core,
const struct mlxsw_bus_info *bus_info,
struct mlxsw_thermal **p_thermal)
@@ -920,6 +1004,10 @@ int mlxsw_thermal_init(struct mlxsw_core *core,
if (err)
goto err_unreg_tzdev;
+ mlxsw_thermal_gearboxes_init(dev, core, thermal);
+ if (err)
+ goto err_unreg_modules_tzdev;
+
thermal->mode = THERMAL_DEVICE_ENABLED;
*p_thermal = thermal;
return 0;
@@ -944,6 +1032,7 @@ void mlxsw_thermal_fini(struct mlxsw_thermal *thermal)
{
int i;
+ mlxsw_thermal_gearboxes_fini(thermal);
mlxsw_thermal_modules_fini(thermal);
if (thermal->tzdev) {
thermal_zone_device_unregister(thermal->tzdev);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/qsfp_sysfs.c b/drivers/net/ethernet/mellanox/mlxsw/qsfp_sysfs.c
index bee2a08d372b..347f9823e375 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/qsfp_sysfs.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/qsfp_sysfs.c
@@ -268,6 +268,13 @@ static const struct dmi_system_id mlxsw_qsfp_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "MSN37"),
},
},
+ {
+ .callback = mlxsw_qsfp_dmi_set_qsfp_num,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "Mellanox Technologies"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MSN38"),
+ },
+ },
{ }
};
MODULE_DEVICE_TABLE(dmi, mlxsw_qsfp_dmi_table);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index 94407dcfacdb..f16d27e115d2 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -7589,6 +7589,7 @@ MLXSW_ITEM32(reg, mtcap, sensor_count, 0x00, 0, 7);
*/
#define MLXSW_REG_MTMP_ID 0x900A
#define MLXSW_REG_MTMP_LEN 0x20
+#define MLXSW_REG_MTMP_GBOX_INDEX_MIN 256
MLXSW_REG_DEFINE(mtmp, MLXSW_REG_MTMP_ID, MLXSW_REG_MTMP_LEN);
@@ -7598,7 +7599,7 @@ MLXSW_REG_DEFINE(mtmp, MLXSW_REG_MTMP_ID, MLXSW_REG_MTMP_LEN);
* (module 0 is mapped to sensor_index 64).
* Access: Index
*/
-MLXSW_ITEM32(reg, mtmp, sensor_index, 0x00, 0, 7);
+MLXSW_ITEM32(reg, mtmp, sensor_index, 0x00, 0, 11);
/* Convert to milli degrees Celsius */
#define MLXSW_REG_MTMP_TEMP_TO_MC(val) (val * 125)
@@ -7660,7 +7661,7 @@ 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, u8 sensor_index,
+static inline void mlxsw_reg_mtmp_pack(char *payload, u16 sensor_index,
bool max_temp_enable,
bool max_temp_reset)
{
@@ -8579,6 +8580,56 @@ static inline void mlxsw_reg_mprs_pack(char *payload, u16 parsing_depth,
mlxsw_reg_mprs_vxlan_udp_dport_set(payload, vxlan_udp_dport);
}
+/* MGPIR - Management General Peripheral Information Register
+ * ----------------------------------------------------------
+ * MGPIR register allows software to query the hardware and
+ * firmware general information of peripheral entities.
+ */
+#define MLXSW_REG_MGPIR_ID 0x9100
+#define MLXSW_REG_MGPIR_LEN 0xA0
+
+MLXSW_REG_DEFINE(mgpir, MLXSW_REG_MGPIR_ID, MLXSW_REG_MGPIR_LEN);
+
+/* device_type
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mgpir, device_type, 0x00, 24, 4);
+
+/* 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
+ * Number of devices of device_type.
+ * Access: RO
+ */
+MLXSW_ITEM32(reg, mgpir, num_of_devices, 0x00, 0, 8);
+
+enum mlxsw_reg_mgpir_device_type {
+ MLXSW_REG_MGPIR_TYPE_NONE,
+ MLXSW_REG_MGPIR_TYPE_GEARBOX_DIE,
+};
+
+static inline void mlxsw_reg_mgpir_pack(char *payload)
+{
+ MLXSW_REG_ZERO(mgpir, payload);
+}
+
+static inline void mlxsw_reg_mgpir_unpack(char *payload, u8 *num_of_devices,
+ u8 *device_type,
+ u8 *devices_per_flash)
+{
+ if (num_of_devices)
+ *num_of_devices = mlxsw_reg_mgpir_num_of_devices_get(payload);
+ if (device_type)
+ *device_type = mlxsw_reg_mgpir_device_type_get(payload);
+ if (devices_per_flash)
+ *devices_per_flash =
+ mlxsw_reg_mgpir_devices_per_flash_get(payload);
+}
+
/* TNGCR - Tunneling NVE General Configuration Register
* ----------------------------------------------------
* The TNGCR register is used for setting up the NVE Tunneling configuration.
@@ -9591,6 +9642,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
MLXSW_REG(mcda),
MLXSW_REG(mgpc),
MLXSW_REG(mprs),
+ MLXSW_REG(mgpir),
MLXSW_REG(tngcr),
MLXSW_REG(tnumt),
MLXSW_REG(tnqcr),
diff --git a/drivers/platform/mellanox/mlxreg-hotplug.c b/drivers/platform/mellanox/mlxreg-hotplug.c
index 52314a1ffaaf..687ce6817d0d 100644
--- a/drivers/platform/mellanox/mlxreg-hotplug.c
+++ b/drivers/platform/mellanox/mlxreg-hotplug.c
@@ -248,7 +248,8 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv,
struct mlxreg_core_item *item)
{
struct mlxreg_core_data *data;
- u32 asserted, regval, bit;
+ unsigned long asserted;
+ u32 regval, bit;
int ret;
/*
@@ -281,7 +282,7 @@ mlxreg_hotplug_work_helper(struct mlxreg_hotplug_priv_data *priv,
asserted = item->cache ^ regval;
item->cache = regval;
- for_each_set_bit(bit, (unsigned long *)&asserted, 8) {
+ for_each_set_bit(bit, &asserted, 8) {
data = item->data + bit;
if (regval & BIT(bit)) {
if (item->inversed)
diff --git a/drivers/platform/x86/mlx-platform.c b/drivers/platform/x86/mlx-platform.c
index af033fb2e5d9..d5d2448dc7e4 100644
--- a/drivers/platform/x86/mlx-platform.c
+++ b/drivers/platform/x86/mlx-platform.c
@@ -938,6 +938,11 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_ng_led_data[] = {
.capability = MLXPLAT_CPLD_LPC_REG_FAN_DRW_CAP_OFFSET,
.bit = BIT(5),
},
+ {
+ .label = "uid:blue",
+ .reg = MLXPLAT_CPLD_LPC_REG_LED5_OFFSET,
+ .mask = MLXPLAT_CPLD_LED_LO_NIBBLE_MASK,
+ },
};
static struct mlxreg_core_platform_data mlxplat_default_ng_led_data = {
@@ -1361,7 +1366,6 @@ static struct mlxreg_core_data mlxplat_mlxcpld_default_fan_data[] = {
},
{
.label = "conf",
- .reg = MLXPLAT_CPLD_LPC_REG_TACHO12_OFFSET,
.capability = MLXPLAT_CPLD_LPC_REG_TACHO_SPEED_OFFSET,
},
};
--
2.11.0

View File

@@ -0,0 +1,668 @@
From 8c964a3e17bb41eef69c81d45864d72cbc1185f4 Mon Sep 17 00:00:00 2001
From: Vadim Pasternak <vadimp@mellanox.com>
Date: Fri, 17 May 2019 09:22:21 +0000
Subject: [PATCH backport 5.2] mlxsw: minimal: Provide optimization for I2C bus
access
Use register MTMP instead of MTBR.
Use maximum buffer size allowed by I2C adapter.
Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
---
drivers/i2c/busses/i2c-mlxcpld.c | 2 +-
drivers/net/ethernet/mellanox/mlxsw/core.c | 6 ++
drivers/net/ethernet/mellanox/mlxsw/core.h | 2 +
drivers/net/ethernet/mellanox/mlxsw/core_env.c | 29 ++-----
drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 98 +++++++++-------------
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c | 60 +++++++------
drivers/net/ethernet/mellanox/mlxsw/i2c.c | 56 +++++++++----
drivers/net/ethernet/mellanox/mlxsw/minimal.c | 18 ++++
drivers/net/ethernet/mellanox/mlxsw/reg.h | 7 +-
9 files changed, 144 insertions(+), 134 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mlxcpld.c b/drivers/i2c/busses/i2c-mlxcpld.c
index 745ed43a22d6..2fd717d8dd30 100644
--- a/drivers/i2c/busses/i2c-mlxcpld.c
+++ b/drivers/i2c/busses/i2c-mlxcpld.c
@@ -503,6 +503,7 @@ static int mlxcpld_i2c_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
priv->dev = &pdev->dev;
+ priv->base_addr = MLXPLAT_CPLD_LPC_I2C_BASE_ADDR;
/* Register with i2c layer */
mlxcpld_i2c_adapter.timeout = usecs_to_jiffies(MLXCPLD_I2C_XFER_TO);
@@ -518,7 +519,6 @@ static int mlxcpld_i2c_probe(struct platform_device *pdev)
mlxcpld_i2c_adapter.nr = pdev->id;
priv->adap = mlxcpld_i2c_adapter;
priv->adap.dev.parent = &pdev->dev;
- priv->base_addr = MLXPLAT_CPLD_LPC_I2C_BASE_ADDR;
i2c_set_adapdata(&priv->adap, priv);
err = i2c_add_numbered_adapter(&priv->adap);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index e420451942e2..9a74ae8beb43 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -122,6 +122,12 @@ 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);
+
struct mlxsw_rx_listener_item {
struct list_head list;
struct mlxsw_rx_listener rxl;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index 76e8fd76ef36..1e1bcfd8d032 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -28,6 +28,8 @@ 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);
+
int mlxsw_core_driver_register(struct mlxsw_driver *mlxsw_driver);
void mlxsw_core_driver_unregister(struct mlxsw_driver *mlxsw_driver);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
index edcf1b656cbf..d2c7ce67c300 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c
@@ -92,33 +92,20 @@ int mlxsw_env_module_temp_thresholds_get(struct mlxsw_core *core, int module,
u16 temp;
} temp_thresh;
char mcia_pl[MLXSW_REG_MCIA_LEN] = {0};
- char mtbr_pl[MLXSW_REG_MTBR_LEN] = {0};
- u16 module_temp;
+ char mtmp_pl[MLXSW_REG_MTMP_LEN];
+ unsigned int module_temp;
bool qsfp;
int err;
- mlxsw_reg_mtbr_pack(mtbr_pl, MLXSW_REG_MTBR_BASE_MODULE_INDEX + module,
- 1);
- err = mlxsw_reg_query(core, MLXSW_REG(mtbr), mtbr_pl);
+ mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN + module,
+ false, false);
+ err = mlxsw_reg_query(core, MLXSW_REG(mtmp), mtmp_pl);
if (err)
return err;
-
- /* Don't read temperature thresholds for module with no valid info. */
- mlxsw_reg_mtbr_temp_unpack(mtbr_pl, 0, &module_temp, NULL);
- switch (module_temp) {
- case MLXSW_REG_MTBR_BAD_SENS_INFO: /* fall-through */
- case MLXSW_REG_MTBR_NO_CONN: /* fall-through */
- case MLXSW_REG_MTBR_NO_TEMP_SENS: /* fall-through */
- case MLXSW_REG_MTBR_INDEX_NA:
+ mlxsw_reg_mtmp_unpack(mtmp_pl, &module_temp, NULL, NULL);
+ if (!module_temp) {
*temp = 0;
return 0;
- default:
- /* Do not consider thresholds for zero temperature. */
- if (!MLXSW_REG_MTMP_TEMP_TO_MC(module_temp)) {
- *temp = 0;
- return 0;
- }
- break;
}
/* Read Free Side Device Temperature Thresholds from page 03h
@@ -196,7 +183,7 @@ 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 digital diagnostic monitoring page */
+ /* Verify if transceiver provides diagnostic monitoring page */
err = mlxsw_env_query_module_eeprom(mlxsw_core, module,
SFP_DIAGMON, 1, &diag_mon,
&read_size);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
index 976f81a2bbba..a414a09efb5d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
@@ -15,9 +15,6 @@
#define MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT 127
#define MLXSW_HWMON_ATTR_COUNT (MLXSW_HWMON_TEMP_SENSOR_MAX_COUNT * 4 + \
MLXSW_MFCR_TACHOS_MAX + MLXSW_MFCR_PWMS_MAX)
-#define MLXSW_HWMON_GET_ATTR_INDEX(ind, count) \
- (((ind) >= (count)) ? (ind) % (count) + \
- MLXSW_REG_MTMP_GBOX_INDEX_MIN : (ind))
struct mlxsw_hwmon_attr {
struct device_attribute dev_attr;
@@ -26,6 +23,14 @@ struct mlxsw_hwmon_attr {
char name[32];
};
+static int mlxsw_hwmon_get_attr_index(int index, int count)
+{
+ if (index >= count)
+ return index % count + MLXSW_REG_MTMP_GBOX_INDEX_MIN;
+
+ return index;
+}
+
struct mlxsw_hwmon {
struct mlxsw_core *core;
const struct mlxsw_bus_info *bus_info;
@@ -51,7 +56,7 @@ static ssize_t mlxsw_hwmon_temp_show(struct device *dev,
int index;
int err;
- index = MLXSW_HWMON_GET_ATTR_INDEX(mlwsw_hwmon_attr->type_index,
+ index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
mlxsw_hwmon->module_sensor_count);
mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
@@ -75,7 +80,7 @@ static ssize_t mlxsw_hwmon_temp_max_show(struct device *dev,
int index;
int err;
- index = MLXSW_HWMON_GET_ATTR_INDEX(mlwsw_hwmon_attr->type_index,
+ index = mlxsw_hwmon_get_attr_index(mlwsw_hwmon_attr->type_index,
mlxsw_hwmon->module_sensor_count);
mlxsw_reg_mtmp_pack(mtmp_pl, index, false, false);
err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
@@ -105,7 +110,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(mlwsw_hwmon_attr->type_index,
mlxsw_hwmon->module_sensor_count);
mlxsw_reg_mtmp_pack(mtmp_pl, index, true, true);
err = mlxsw_reg_write(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
@@ -209,38 +214,18 @@ static ssize_t mlxsw_hwmon_module_temp_show(struct device *dev,
struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
- char mtbr_pl[MLXSW_REG_MTBR_LEN] = {0};
- u16 temp;
+ char mtmp_pl[MLXSW_REG_MTMP_LEN];
+ unsigned int temp;
u8 module;
int err;
module = mlwsw_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);
- if (err) {
- dev_err(dev, "Failed to query module temperature sensor\n");
+ 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);
+ if (err)
return err;
- }
-
- mlxsw_reg_mtbr_temp_unpack(mtbr_pl, 0, &temp, NULL);
- /* Update status and temperature cache. */
- switch (temp) {
- case MLXSW_REG_MTBR_NO_CONN: /* fall-through */
- case MLXSW_REG_MTBR_NO_TEMP_SENS: /* fall-through */
- case MLXSW_REG_MTBR_INDEX_NA:
- temp = 0;
- break;
- case MLXSW_REG_MTBR_BAD_SENS_INFO:
- /* Untrusted cable is connected. Reading temperature from its
- * sensor is faulty.
- */
- temp = 0;
- break;
- default:
- temp = MLXSW_REG_MTMP_TEMP_TO_MC(temp);
- break;
- }
+ mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
return sprintf(buf, "%u\n", temp);
}
@@ -252,37 +237,18 @@ static ssize_t mlxsw_hwmon_module_temp_fault_show(struct device *dev,
struct mlxsw_hwmon_attr *mlwsw_hwmon_attr =
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
struct mlxsw_hwmon *mlxsw_hwmon = mlwsw_hwmon_attr->hwmon;
- char mtbr_pl[MLXSW_REG_MTBR_LEN] = {0};
+ char mtmp_pl[MLXSW_REG_MTMP_LEN];
u8 module, fault;
- u16 temp;
int err;
module = mlwsw_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);
- if (err) {
- dev_err(dev, "Failed to query module temperature sensor\n");
- return err;
- }
-
- mlxsw_reg_mtbr_temp_unpack(mtbr_pl, 0, &temp, NULL);
-
- /* Update status and temperature cache. */
- switch (temp) {
- case MLXSW_REG_MTBR_BAD_SENS_INFO:
- /* Untrusted cable is connected. Reading temperature from its
- * sensor is faulty.
- */
+ mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTBR_BASE_MODULE_INDEX + module,
+ false, false);
+ err = mlxsw_reg_query(mlxsw_hwmon->core, MLXSW_REG(mtmp), mtmp_pl);
+ if (err)
fault = 1;
- break;
- case MLXSW_REG_MTBR_NO_CONN: /* fall-through */
- case MLXSW_REG_MTBR_NO_TEMP_SENS: /* fall-through */
- case MLXSW_REG_MTBR_INDEX_NA:
- default:
+ else
fault = 0;
- break;
- }
return sprintf(buf, "%u\n", fault);
}
@@ -551,6 +517,9 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
u8 width;
int err;
+ if (!mlxsw_core_res_query_enabled(mlxsw_hwmon->core))
+ return 0;
+
/* Add extra attributes for module temperature. Sensor index is
* assigned to sensor_count value, while all indexed before
* sensor_count are already utilized by the sensors connected through
@@ -593,8 +562,9 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
{
+ int index, max_index, sensor_index;
char mgpir_pl[MLXSW_REG_MGPIR_LEN];
- int index, max_index;
+ char mtmp_pl[MLXSW_REG_MTMP_LEN];
u8 gbox_num;
int err;
@@ -610,6 +580,16 @@ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
index = mlxsw_hwmon->module_sensor_count;
max_index = mlxsw_hwmon->module_sensor_count + gbox_num;
while (index < max_index) {
+ sensor_index = index % mlxsw_hwmon->module_sensor_count +
+ MLXSW_REG_MTMP_GBOX_INDEX_MIN;
+ mlxsw_reg_mtmp_pack(mtmp_pl, sensor_index, true, true);
+ err = mlxsw_reg_write(mlxsw_hwmon->core,
+ MLXSW_REG(mtmp), mtmp_pl);
+ if (err) {
+ dev_err(mlxsw_hwmon->bus_info->dev, "Failed to setup temp sensor number %d\n",
+ sensor_index);
+ return err;
+ }
mlxsw_hwmon_attr_add(mlxsw_hwmon, MLXSW_HWMON_ATTR_TYPE_TEMP,
index, index);
mlxsw_hwmon_attr_add(mlxsw_hwmon,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
index 5f970798ab6a..e9451e447bf0 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
@@ -452,36 +452,27 @@ static int mlxsw_thermal_module_temp_get(struct thermal_zone_device *tzdev,
struct mlxsw_thermal_module *tz = tzdev->devdata;
struct mlxsw_thermal *thermal = tz->parent;
struct device *dev = thermal->bus_info->dev;
- char mtbr_pl[MLXSW_REG_MTBR_LEN];
- u16 temp;
+ char mtmp_pl[MLXSW_REG_MTMP_LEN];
+ unsigned int temp;
int err;
/* Read module temperature. */
- mlxsw_reg_mtbr_pack(mtbr_pl, MLXSW_REG_MTBR_BASE_MODULE_INDEX +
- tz->module, 1);
- err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtbr), mtbr_pl);
- if (err)
- return err;
-
- mlxsw_reg_mtbr_temp_unpack(mtbr_pl, 0, &temp, NULL);
- /* Update temperature. */
- switch (temp) {
- case MLXSW_REG_MTBR_NO_CONN: /* fall-through */
- case MLXSW_REG_MTBR_NO_TEMP_SENS: /* fall-through */
- case MLXSW_REG_MTBR_INDEX_NA: /* fall-through */
- case MLXSW_REG_MTBR_BAD_SENS_INFO:
+ mlxsw_reg_mtmp_pack(mtmp_pl, MLXSW_REG_MTMP_MODULE_INDEX_MIN +
+ tz->module, false, false);
+ err = mlxsw_reg_query(thermal->core, MLXSW_REG(mtmp), mtmp_pl);
+ if (err) {
+ dev_err(dev, "Failed to query temp sensor\n");
temp = 0;
- break;
- default:
- temp = MLXSW_REG_MTMP_TEMP_TO_MC(temp);
- /* Reset all trip point. */
- mlxsw_thermal_module_trips_reset(tz);
- /* Update trip points. */
+ *p_temp = (int) temp;
+ return 0;
+ }
+ mlxsw_reg_mtmp_unpack(mtmp_pl, &temp, NULL, NULL);
+
+ if (temp) {
err = mlxsw_thermal_module_trips_update(dev, thermal->core,
tz);
if (err)
return err;
- break;
}
*p_temp = (int) temp;
@@ -714,12 +705,12 @@ mlxsw_thermal_module_tz_init(struct mlxsw_thermal_module *module_tz)
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,
- module_tz,
- &mlxsw_thermal_module_ops,
- &mlxsw_thermal_module_params,
- 0, 0);
+ MLXSW_THERMAL_NUM_TRIPS,
+ MLXSW_THERMAL_TRIP_MASK,
+ module_tz,
+ &mlxsw_thermal_module_ops,
+ &mlxsw_thermal_module_params,
+ 0, 0);
if (IS_ERR(module_tz->tzdev)) {
err = PTR_ERR(module_tz->tzdev);
return err;
@@ -789,6 +780,9 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
struct mlxsw_thermal_module *module_tz;
int i, err;
+ if (!mlxsw_core_res_query_enabled(core))
+ return 0;
+
thermal->tz_module_arr = kcalloc(module_count,
sizeof(*thermal->tz_module_arr),
GFP_KERNEL);
@@ -801,8 +795,7 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
goto err_unreg_tz_module_arr;
}
- module_count -= 1;
- for (i = 0; i < module_count; i++) {
+ for (i = 0; i < module_count - 1; i++) {
module_tz = &thermal->tz_module_arr[i];
if (!module_tz->parent)
continue;
@@ -814,7 +807,7 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core,
return 0;
err_unreg_tz_module_arr:
- for (i = module_count; i >= 0; i--)
+ for (i = module_count - 1; i >= 0; i--)
mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
kfree(thermal->tz_module_arr);
return err;
@@ -826,6 +819,9 @@ mlxsw_thermal_modules_fini(struct mlxsw_thermal *thermal)
unsigned int module_count = mlxsw_core_max_ports(thermal->core);
int i;
+ if (!mlxsw_core_res_query_enabled(thermal->core))
+ return;
+
for (i = module_count - 1; i >= 0; i--)
mlxsw_thermal_module_fini(&thermal->tz_module_arr[i]);
kfree(thermal->tz_module_arr);
@@ -910,7 +906,7 @@ mlxsw_thermal_gearboxes_fini(struct mlxsw_thermal *thermal)
int i;
for (i = thermal->tz_gearbox_num - 1; i >= 0; i--)
- mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]);
+ mlxsw_thermal_gearbox_tz_fini(&thermal->tz_gearbox_arr[i]); /*Remove*/
kfree(thermal->tz_gearbox_arr);
}
diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
index 307fd5fcd302..08c774875d1e 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
@@ -43,11 +43,10 @@
#define MLXSW_I2C_PREP_SIZE (MLXSW_I2C_ADDR_WIDTH + 28)
#define MLXSW_I2C_MBOX_SIZE 20
#define MLXSW_I2C_MBOX_OUT_PARAM_OFF 12
-#define MLXSW_I2C_MAX_BUFF_SIZE 32
#define MLXSW_I2C_MBOX_OFFSET_BITS 20
#define MLXSW_I2C_MBOX_SIZE_BITS 12
#define MLXSW_I2C_ADDR_BUF_SIZE 4
-#define MLXSW_I2C_BLK_MAX 32
+#define MLXSW_I2C_BLK_DEF 32
#define MLXSW_I2C_RETRY 5
#define MLXSW_I2C_TIMEOUT_MSECS 5000
#define MLXSW_I2C_MAX_DATA_SIZE 256
@@ -62,6 +61,7 @@
* @dev: I2C device;
* @core: switch core pointer;
* @bus_info: bus info block;
+ * @block_size: maximum block size allowed to pass to under layer;
*/
struct mlxsw_i2c {
struct {
@@ -74,6 +74,7 @@ struct mlxsw_i2c {
struct device *dev;
struct mlxsw_core *core;
struct mlxsw_bus_info bus_info;
+ u16 block_size;
};
#define MLXSW_I2C_READ_MSG(_client, _addr_buf, _buf, _len) { \
@@ -315,20 +316,26 @@ mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
struct i2c_client *client = to_i2c_client(dev);
struct mlxsw_i2c *mlxsw_i2c = i2c_get_clientdata(client);
unsigned long timeout = msecs_to_jiffies(MLXSW_I2C_TIMEOUT_MSECS);
- u8 tran_buf[MLXSW_I2C_MAX_BUFF_SIZE + MLXSW_I2C_ADDR_BUF_SIZE];
int off = mlxsw_i2c->cmd.mb_off_in, chunk_size, i, j;
unsigned long end;
+ u8 *tran_buf;
struct i2c_msg write_tran =
- MLXSW_I2C_WRITE_MSG(client, tran_buf, MLXSW_I2C_PUSH_CMD_SIZE);
+ MLXSW_I2C_WRITE_MSG(client, NULL, MLXSW_I2C_PUSH_CMD_SIZE);
int err;
+ tran_buf = kmalloc(mlxsw_i2c->block_size + MLXSW_I2C_ADDR_BUF_SIZE,
+ GFP_KERNEL);
+ if (!tran_buf)
+ return -ENOMEM;
+
+ write_tran.buf = tran_buf;
for (i = 0; i < num; i++) {
- chunk_size = (in_mbox_size > MLXSW_I2C_BLK_MAX) ?
- MLXSW_I2C_BLK_MAX : in_mbox_size;
+ chunk_size = (in_mbox_size > mlxsw_i2c->block_size) ?
+ mlxsw_i2c->block_size : in_mbox_size;
write_tran.len = MLXSW_I2C_ADDR_WIDTH + chunk_size;
mlxsw_i2c_set_slave_addr(tran_buf, off);
memcpy(&tran_buf[MLXSW_I2C_ADDR_BUF_SIZE], in_mbox +
- MLXSW_I2C_BLK_MAX * i, chunk_size);
+ mlxsw_i2c->block_size * i, chunk_size);
j = 0;
end = jiffies + timeout;
@@ -342,9 +349,10 @@ mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
(j++ < MLXSW_I2C_RETRY));
if (err != 1) {
- if (!err)
+ if (!err) {
err = -EIO;
- return err;
+ goto mlxsw_i2c_write_exit;
+ }
}
off += chunk_size;
@@ -355,24 +363,28 @@ mlxsw_i2c_write(struct device *dev, size_t in_mbox_size, u8 *in_mbox, int num,
err = mlxsw_i2c_write_cmd(client, mlxsw_i2c, 0);
if (err) {
dev_err(&client->dev, "Could not start transaction");
- return -EIO;
+ err = -EIO;
+ goto mlxsw_i2c_write_exit;
}
/* Wait until go bit is cleared. */
err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, p_status);
if (err) {
dev_err(&client->dev, "HW semaphore is not released");
- return err;
+ goto mlxsw_i2c_write_exit;
}
/* Validate transaction completion status. */
if (*p_status) {
dev_err(&client->dev, "Bad transaction completion status %x\n",
*p_status);
- return -EIO;
+ err = -EIO;
}
- return 0;
+mlxsw_i2c_write_exit:
+ kfree(tran_buf);
+
+ return err;
}
/* Routine executes I2C command. */
@@ -395,8 +407,8 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
if (in_mbox) {
reg_size = mlxsw_i2c_get_reg_size(in_mbox);
- num = reg_size / MLXSW_I2C_BLK_MAX;
- if (reg_size % MLXSW_I2C_BLK_MAX)
+ num = reg_size / mlxsw_i2c->block_size;
+ if (reg_size % mlxsw_i2c->block_size)
num++;
if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
@@ -416,7 +428,7 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
} else {
/* No input mailbox is case of initialization query command. */
reg_size = MLXSW_I2C_MAX_DATA_SIZE;
- num = reg_size / MLXSW_I2C_BLK_MAX;
+ num = reg_size / mlxsw_i2c->block_size;
if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) {
dev_err(&client->dev, "Could not acquire lock");
@@ -432,8 +444,8 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
/* Send read transaction to get output mailbox content. */
read_tran[1].buf = out_mbox;
for (i = 0; i < num; i++) {
- chunk_size = (reg_size > MLXSW_I2C_BLK_MAX) ?
- MLXSW_I2C_BLK_MAX : reg_size;
+ chunk_size = (reg_size > mlxsw_i2c->block_size) ?
+ mlxsw_i2c->block_size : reg_size;
read_tran[1].len = chunk_size;
mlxsw_i2c_set_slave_addr(tran_buf, off);
@@ -546,6 +558,7 @@ static const struct mlxsw_bus mlxsw_i2c_bus = {
static int mlxsw_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ const struct i2c_adapter_quirks *quirks = client->adapter->quirks;
struct mlxsw_i2c *mlxsw_i2c;
u8 status;
int err;
@@ -554,6 +567,13 @@ static int mlxsw_i2c_probe(struct i2c_client *client,
if (!mlxsw_i2c)
return -ENOMEM;
+ if (quirks)
+ mlxsw_i2c->block_size = max_t(u16, MLXSW_I2C_BLK_DEF,
+ min_t(u16, quirks->max_read_len,
+ quirks->max_write_len));
+ else
+ mlxsw_i2c->block_size = MLXSW_I2C_BLK_DEF;
+
i2c_set_clientdata(client, mlxsw_i2c);
mutex_init(&mlxsw_i2c->cmd.lock);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
index cac36c231864..5290993ff93f 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c
@@ -45,6 +45,23 @@ static const struct net_device_ops mlxsw_m_port_netdev_ops = {
.ndo_stop = mlxsw_m_port_dummy_open_stop,
};
+static void mlxsw_m_module_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ struct mlxsw_m_port *mlxsw_m_port = netdev_priv(dev);
+ struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m;
+
+ strlcpy(drvinfo->driver, mlxsw_m->bus_info->device_kind,
+ sizeof(drvinfo->driver));
+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
+ "%d.%d.%d",
+ mlxsw_m->bus_info->fw_rev.major,
+ mlxsw_m->bus_info->fw_rev.minor,
+ mlxsw_m->bus_info->fw_rev.subminor);
+ strlcpy(drvinfo->bus_info, mlxsw_m->bus_info->device_name,
+ sizeof(drvinfo->bus_info));
+}
+
static int mlxsw_m_get_module_info(struct net_device *netdev,
struct ethtool_modinfo *modinfo)
{
@@ -66,6 +83,7 @@ mlxsw_m_get_module_eeprom(struct net_device *netdev, struct ethtool_eeprom *ee,
}
static const struct ethtool_ops mlxsw_m_port_ethtool_ops = {
+ .get_drvinfo = mlxsw_m_module_get_drvinfo,
.get_module_info = mlxsw_m_get_module_info,
.get_module_eeprom = mlxsw_m_get_module_eeprom,
};
diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h
index f16d27e115d2..eb58940d2e9c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/reg.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h
@@ -7589,17 +7589,18 @@ MLXSW_ITEM32(reg, mtcap, sensor_count, 0x00, 0, 7);
*/
#define MLXSW_REG_MTMP_ID 0x900A
#define MLXSW_REG_MTMP_LEN 0x20
-#define MLXSW_REG_MTMP_GBOX_INDEX_MIN 256
MLXSW_REG_DEFINE(mtmp, MLXSW_REG_MTMP_ID, MLXSW_REG_MTMP_LEN);
+#define MLXSW_REG_MTMP_MODULE_INDEX_MIN 64
+#define MLXSW_REG_MTMP_GBOX_INDEX_MIN 256
/* reg_mtmp_sensor_index
* Sensors index to access.
* 64-127 of sensor_index are mapped to the SFP+/QSFP modules sequentially
* (module 0 is mapped to sensor_index 64).
* Access: Index
*/
-MLXSW_ITEM32(reg, mtmp, sensor_index, 0x00, 0, 11);
+MLXSW_ITEM32(reg, mtmp, sensor_index, 0x00, 0, 12);
/* Convert to milli degrees Celsius */
#define MLXSW_REG_MTMP_TEMP_TO_MC(val) (val * 125)
@@ -7710,7 +7711,7 @@ MLXSW_REG_DEFINE(mtbr, MLXSW_REG_MTBR_ID, MLXSW_REG_MTBR_LEN);
* 64-127 are mapped to the SFP+/QSFP modules sequentially).
* Access: Index
*/
-MLXSW_ITEM32(reg, mtbr, base_sensor_index, 0x00, 0, 7);
+MLXSW_ITEM32(reg, mtbr, base_sensor_index, 0x00, 0, 12);
/* reg_mtbr_num_rec
* Request: Number of records to read
--
2.11.0

View File

@@ -19,5 +19,15 @@ driver-add-the-support-max6620.patch
0016-qsfp_sysfs-Fix-dmidecode-call.patch
0017-mlxsw-qsfp_sysfs-Support-extended-port-numbers-for-S.patch
0018-mlxsw-thermal-monitoring-amendments.patch
0019-watchdog-mlx-wdt-introduce-watchdog-driver-for-Mella.patch
0020-mlxsw-qsfp_sysfs-Support-port-numbers-initialization.patch
0021-mlxsw-Align-code-with-kernel-v-5.0.patch
0023-hwmon-pmbus-Fix-driver-info-initialization-in-probe-.patch
0024-mlxsw-thermal-disable-highest-zone-calculation.patch
0025-platform-x86-mlx-platform-Add-CPLD4-register.patch
0026-mlxsw-Align-code-with-kernel-v-5.1.patch
0027-mlxsw-core-Add-check-for-split-port-during-thermal-z.patch
0028-watchdog-mlx-wdt-kernel-upstream-and-wd-type2-change.patch
0029-mlxsw-core-Prevent-reading-unsupported-slave-address.patch
0029-mlxsw-core-add-support-for-Gear-Box-temperatures-in-.patch
0030-mlxsw-minimal-Provide-optimization-for-I2C-bus-acces.patch

View File

@@ -9,7 +9,7 @@
#include <mlnx_common/mlnx_common_config.h>
#include <mlnx_common/mlnx_common.h>
#define MAX_NUM_OF_CPLD 3
#define MAX_NUM_OF_CPLD 4
#define PREFIX_PATH_ON_CPLD_DEV HW_MANAGEMENT_PATH"/system"
mlnx_platform_info_t* get_platform_info(void);

View File

@@ -71,7 +71,9 @@ led_light_mode_map_t led_map[] = {
{LED_SYSTEM, LED_MODE_OFF, ONLP_LED_MODE_OFF},
{LED_SYSTEM, LED_MODE_GREEN, ONLP_LED_MODE_GREEN},
{LED_SYSTEM, LED_MODE_RED, ONLP_LED_MODE_RED},
{LED_SYSTEM, LED_MODE_ORANGE, ONLP_LED_MODE_ORANGE},
{LED_SYSTEM, LED_MODE_RED_BLINK, ONLP_LED_MODE_RED_BLINKING},
{LED_SYSTEM, LED_MODE_ORANGE_BLINK, ONLP_LED_MODE_ORANGE_BLINKING},
{LED_SYSTEM, LED_MODE_GREEN_BLINK, ONLP_LED_MODE_GREEN_BLINKING},
{LED_SYSTEM, LED_MODE_AUTO, ONLP_LED_MODE_AUTO},
@@ -305,7 +307,7 @@ onlp_ledi_info_get(onlp_oid_t id, onlp_led_info_t* info)
mlnx_platform_info_t* mlnx_platform_info = get_platform_info();
/* Set the onlp_oid_hdr_t and capabilities */
*info = mlnx_platform_info->linfo[ONLP_OID_ID_GET(id)];
*info = mlnx_platform_info->linfo[local_id];
/* Get LED mode */
if (mc_get_kernel_ver() >= KERNEL_VERSION(4,9,30)) {

View File

@@ -42,7 +42,8 @@ static char arr_cplddev_name[MAX_NUM_OF_CPLD][30] =
{
"cpld_brd_version",
"cpld_mgmt_version",
"cpld_port_version"
"cpld_port_version",
"cpld_gearbox_version",
};
mlnx_platform_info_t* get_platform_info()
@@ -82,6 +83,9 @@ onlp_sysi_platform_info_get(onlp_platform_info_t* pi)
case 3:
pi->cpld_versions = aim_fstrdup("brd=%d, mgmt=%d, port=%d", v[0], v[1], v[2]);
break;
case 4:
pi->cpld_versions = aim_fstrdup("brd=%d, mgmt=%d, port=%d", v[0], v[1], v[2]);
break;
case 0:
default:
AIM_LOG_ERROR("Incorrect CPLD Number %d\n", platform_info->cpld_num);
@@ -382,15 +386,12 @@ onlp_sysi_platform_manage_leds_type2(void)
int
onlp_sysi_platform_manage_leds_type3(void)
{
int fan_number, psu_number;
int fan_number, fan_sub, fan_idx, psu_number;
onlp_led_mode_t mode, system_mode;
int min_fan_speed;
int fan_led_id[6] = { LED_FAN1, LED_FAN2, LED_FAN3, LED_FAN4, LED_FAN5, LED_FAN6 };
int fan_problem = 0;
int psu_problem = 0;
/*
* FAN Indicators
*
@@ -399,59 +400,37 @@ onlp_sysi_platform_manage_leds_type3(void)
* Off - No power
*
*/
for (fan_number = 1; fan_number <= mlnx_platform_info.fan_num; fan_number += 2)
fan_idx=0;
for (fan_number = 1; fan_number <= mlnx_platform_info.fan_num; fan_idx++)
{
/* each 2 fans had same led_fan */
onlp_fan_info_t fi;
/* check fans */
mode = ONLP_LED_MODE_GREEN;
if (onlp_fani_info_get(ONLP_FAN_ID_CREATE(fan_number), &fi) < 0)
{
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
} else if ((fi.status & ONLP_FAN_STATUS_PRESENT) == 0) {
if (mlnx_platform_info.fan_fixed == false)
{
/* Not present */
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
}
} else if (fi.status & ONLP_FAN_STATUS_FAILED) {
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
} else {
min_fan_speed = onlp_fani_get_min_rpm(fan_number);
if (fi.rpm < min_fan_speed)
{
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
}
}
/* check fan i+1 */
if (onlp_fani_info_get(ONLP_FAN_ID_CREATE(fan_number + 1), &fi) < 0)
{
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
} else if ((fi.status & 0x1) == 0) {
if (mlnx_platform_info.fan_fixed == false)
{
/* Not present */
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
}
} else if (fi.status & ONLP_FAN_STATUS_FAILED)
{
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
} else {
min_fan_speed = onlp_fani_get_min_rpm(fan_number + 1);
if (fi.rpm < min_fan_speed)
{
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
}
}
onlp_ledi_mode_set( ONLP_OID_TYPE_CREATE(ONLP_OID_TYPE_LED, fan_led_id[fan_number / 2]), mode);
for (fan_sub = 0; fan_sub < mlnx_platform_info.fan_per_module; fan_sub++, fan_number++) {
/* check fans */
if (onlp_fani_info_get(ONLP_FAN_ID_CREATE(fan_number), &fi) < 0)
{
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
} else if ((fi.status & ONLP_FAN_STATUS_PRESENT) == 0) {
if (mlnx_platform_info.fan_fixed == false)
{
/* Not present */
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
}
} else if (fi.status & ONLP_FAN_STATUS_FAILED) {
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
} else {
min_fan_speed = onlp_fani_get_min_rpm(fan_number);
if (fi.rpm < min_fan_speed)
{
mode = ONLP_LED_MODE_ORANGE;
fan_problem = 1;
}
}
}
onlp_ledi_mode_set( ONLP_OID_TYPE_CREATE(ONLP_OID_TYPE_LED, fan_led_id[fan_idx]), mode);
}
for (psu_number = 1; psu_number <= mlnx_platform_info.psu_num; psu_number++)

View File

@@ -12,6 +12,5 @@ class OnlPlatform_x86_64_mlnx_mqm8700_r0(OnlPlatformMellanox,
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
os.system("/etc/mlnx/mlnx-hw-management start")
self.syseeprom_export();
return True

View File

@@ -12,6 +12,5 @@ class OnlPlatform_x86_64_mlnx_msn2010_r0(OnlPlatformMellanox,
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
os.system("/etc/mlnx/mlnx-hw-management start")
self.syseeprom_export();
return True

View File

@@ -12,6 +12,5 @@ class OnlPlatform_x86_64_mlnx_msn2100_r0(OnlPlatformMellanox,
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
os.system("/etc/mlnx/mlnx-hw-management start")
self.syseeprom_export();
return True

View File

@@ -12,6 +12,5 @@ class OnlPlatform_x86_64_mlnx_msn2100b_r0(OnlPlatformMellanox,
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
os.system("/etc/mlnx/mlnx-hw-management start")
self.syseeprom_export();
return True

View File

@@ -1,6 +1,5 @@
from onl.platform.base import *
from onl.platform.mellanox import *
import os
class OnlPlatform_x86_64_mlnx_msn2410_r0(OnlPlatformMellanox,
OnlPlatformPortConfig_32x100):
@@ -8,18 +7,10 @@ class OnlPlatform_x86_64_mlnx_msn2410_r0(OnlPlatformMellanox,
MODEL="SN2410"
SYS_OBJECT_ID=".2410.1"
def hw_management_start(self):
for tool in [ '/etc/mlnx/mlnx-hw-management', '/usr/bin/hw-management.sh' ]:
if os.path.exists(tool):
print "Starting Mellanox HW Management..."
os.system("%s start" % tool)
return True
return False
def baseconfig(self):
if not self.hw_management_start():
print "Mellanox HW Management Package Missing."
# load modules
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
self.syseeprom_export();
return True

View File

@@ -12,6 +12,5 @@ class OnlPlatform_x86_64_mlnx_msn2410b_r0(OnlPlatformMellanox,
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
os.system("/etc/mlnx/mlnx-hw-management start")
self.syseeprom_export();
return True

View File

@@ -1,25 +1,16 @@
from onl.platform.base import *
from onl.platform.mellanox import *
import os
class OnlPlatform_x86_64_mlnx_msn2700_r0(OnlPlatformMellanox,
OnlPlatformPortConfig_48x25_8x100):
OnlPlatformPortConfig_32x100):
PLATFORM='x86-64-mlnx-msn2700-r0'
MODEL="SN2700"
SYS_OBJECT_ID=".2700.1"
def hw_management_start(self):
for tool in [ '/etc/mlnx/mlnx-hw-management', '/usr/bin/hw-management.sh' ]:
if os.path.exists(tool):
print "Starting Mellanox HW Management..."
os.system("%s start" % tool)
return True
return False
def baseconfig(self):
if not self.hw_management_start():
print "Mellanox HW Management Package Missing."
# load modules
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
self.syseeprom_export();
return True

View File

@@ -12,6 +12,5 @@ class OnlPlatform_x86_64_mlnx_msn2700b_r0(OnlPlatformMellanox,
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
os.system("/etc/mlnx/mlnx-hw-management start")
self.syseeprom_export();
return True

View File

@@ -12,6 +12,5 @@ class OnlPlatform_x86_64_mlnx_msn2740_r0(OnlPlatformMellanox,
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
os.system("/etc/mlnx/mlnx-hw-management start")
self.syseeprom_export();
return True

View File

@@ -12,6 +12,5 @@ class OnlPlatform_x86_64_mlnx_msn2740b_r0(OnlPlatformMellanox,
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
os.system("/etc/mlnx/mlnx-hw-management start")
self.syseeprom_export();
return True

View File

@@ -12,6 +12,5 @@ class OnlPlatform_x86_64_mlnx_msn3700_r0(OnlPlatformMellanox,
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
os.system("/etc/mlnx/mlnx-hw-management start")
self.syseeprom_export();
return True

View File

@@ -12,6 +12,5 @@ class OnlPlatform_x86_64_mlnx_msn3700c_r0(OnlPlatformMellanox,
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
os.system("/etc/mlnx/mlnx-hw-management start")
self.syseeprom_export();
return True

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/no-platform-modules.yml ARCH=amd64 VENDOR=mellanox BASENAME=x86-64-mlnx-msn3800

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/onlp-platform-any.yml PLATFORM=x86-64-mlnx-msn3800 ARCH=amd64 TOOLCHAIN=x86_64-linux-gnu

View File

@@ -0,0 +1,2 @@
FILTER=src
include $(ONL)/make/subdirs.mk

View File

@@ -0,0 +1,46 @@
############################################################
# <bsn.cl fy=2014 v=onl>
#
# Copyright 2014 BigSwitch Networks, Inc.
#
# Licensed under the Eclipse Public License, Version 1.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.eclipse.org/legal/epl-v10.html
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific
# language governing permissions and limitations under the
# License.
#
# </bsn.cl>
############################################################
#
#
############################################################
include $(ONL)/make/config.amd64.mk
MODULE := libonlp-x86-64-mlnx-msn3800
include $(BUILDER)/standardinit.mk
DEPENDMODULES := AIM IOF mlnx_common x86_64_mlnx_msn3800 onlplib
DEPENDMODULE_HEADERS := sff
include $(BUILDER)/dependmodules.mk
SHAREDLIB := libonlp-x86-64-mlnx-msn3800.so
$(SHAREDLIB)_TARGETS := $(ALL_TARGETS)
include $(BUILDER)/so.mk
.DEFAULT_GOAL := $(SHAREDLIB)
GLOBAL_CFLAGS += -I$(onlp_BASEDIR)/module/inc
GLOBAL_CFLAGS += -I$(mlnx_common_BASEDIR)/module/inc
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1
GLOBAL_CFLAGS += -fPIC
GLOBAL_LINK_LIBS += -lpthread
include $(BUILDER)/targets.mk

View File

@@ -0,0 +1,10 @@
###############################################################################
#
# Inclusive Makefile for the libonlp-x86-64-mlnx-msn3800-r0 module.
#
# Autogenerated 2015-12-23 23:45:22.249911
#
###############################################################################
libonlp-x86-64-mlnx-msn3800-r0_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

View File

@@ -0,0 +1,10 @@
###############################################################################
#
# Inclusive Makefile for the libonlp-x86-64-mlnx-msn3800 module.
#
# Autogenerated 2016-10-13 22:58:39.095824
#
###############################################################################
libonlp-x86-64-mlnx-msn3800_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

View File

@@ -0,0 +1,10 @@
###############################################################################
#
# Inclusive Makefile for the x86_64_mlnx_msn3800 module.
#
# Autogenerated 2015-12-23 23:45:22.262891
#
###############################################################################
x86_64_mlnx_msn3800_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

View File

@@ -0,0 +1,46 @@
############################################################
# <bsn.cl fy=2014 v=onl>
#
# Copyright 2014 BigSwitch Networks, Inc.
#
# Licensed under the Eclipse Public License, Version 1.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.eclipse.org/legal/epl-v10.html
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
# either express or implied. See the License for the specific
# language governing permissions and limitations under the
# License.
#
# </bsn.cl>
############################################################
#
#
#
############################################################
include $(ONL)/make/config.amd64.mk
.DEFAULT_GOAL := onlpdump
MODULE := onlpdump
include $(BUILDER)/standardinit.mk
DEPENDMODULES := AIM IOF onlp mlnx_common x86_64_mlnx_msn3800 onlplib onlp_platform_defaults sff cjson cjson_util timer_wheel OS
include $(BUILDER)/dependmodules.mk
BINARY := onlpdump
$(BINARY)_LIBRARIES := $(LIBRARY_TARGETS)
include $(BUILDER)/bin.mk
GLOBAL_CFLAGS += -DAIM_CONFIG_AIM_MAIN_FUNCTION=onlpdump_main
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MODULES_INIT=1
GLOBAL_CFLAGS += -DAIM_CONFIG_INCLUDE_MAIN=1
GLOBAL_LINK_LIBS += -lpthread -lm
include $(BUILDER)/targets.mk

View File

@@ -0,0 +1,10 @@
###############################################################################
#
# Inclusive Makefile for the onlpdump module.
#
# Autogenerated 2016-10-13 22:58:37.393320
#
###############################################################################
onlpdump_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))

View File

@@ -0,0 +1 @@
name: x86_64_mlnx_msn3800

View File

@@ -0,0 +1,9 @@
###############################################################################
#
#
#
###############################################################################
include ../../init.mk
MODULE := x86_64_mlnx_msn3800
AUTOMODULE := x86_64_mlnx_msn3800
include $(BUILDER)/definemodule.mk

View File

@@ -0,0 +1,6 @@
###############################################################################
#
# x86_64_mlnx_msn3800 README
#
###############################################################################

View File

@@ -0,0 +1,9 @@
###############################################################################
#
# x86_64_mlnx_msn3800 Autogeneration
#
###############################################################################
x86_64_mlnx_msn3800_AUTO_DEFS := module/auto/x86_64_mlnx_msn3800.yml
x86_64_mlnx_msn3800_AUTO_DIRS := module/inc/x86_64_mlnx_msn3800 module/src
include $(BUILDER)/auto.mk

View File

@@ -0,0 +1,50 @@
###############################################################################
#
# x86_64_mlnx_msn3800 Autogeneration Definitions.
#
###############################################################################
cdefs: &cdefs
- X86_64_MLNX_MSN3800_CONFIG_INCLUDE_LOGGING:
doc: "Include or exclude logging."
default: 1
- X86_64_MLNX_MSN3800_CONFIG_LOG_OPTIONS_DEFAULT:
doc: "Default enabled log options."
default: AIM_LOG_OPTIONS_DEFAULT
- X86_64_MLNX_MSN3800_CONFIG_LOG_BITS_DEFAULT:
doc: "Default enabled log bits."
default: AIM_LOG_BITS_DEFAULT
- X86_64_MLNX_MSN3800_CONFIG_LOG_CUSTOM_BITS_DEFAULT:
doc: "Default enabled custom log bits."
default: 0
- X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB:
doc: "Default all porting macros to use the C standard libraries."
default: 1
- X86_64_MLNX_MSN3800_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS:
doc: "Include standard library headers for stdlib porting macros."
default: x86_64_mlnx_msn3800_CONFIG_PORTING_STDLIB
- X86_64_MLNX_MSN3800_CONFIG_INCLUDE_UCLI:
doc: "Include generic uCli support."
default: 0
- X86_64_MLNX_MSN3800_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION:
doc: "Assume chassis fan direction is the same as the PSU fan direction."
default: 0
definitions:
cdefs:
X86_64_MLNX_MSN3800_CONFIG_HEADER:
defs: *cdefs
basename: x86_64_mlnx_msn3800_config
portingmacro:
x86_64_mlnx_msn3800:
macros:
- malloc
- free
- memset
- memcpy
- strncpy
- vsnprintf
- snprintf
- strlen

View File

@@ -0,0 +1,14 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_mlnx_msn3800/x86_64_mlnx_msn3800_config.h>
/* <--auto.start.xmacro(ALL).define> */
/* <auto.end.xmacro(ALL).define> */
/* <--auto.start.xenum(ALL).define> */
/* <auto.end.xenum(ALL).define> */

View File

@@ -0,0 +1,137 @@
/**************************************************************************//**
*
* @file
* @brief x86_64_mlnx_msn3800 Configuration Header
*
* @addtogroup x86_64_mlnx_msn3800-config
* @{
*
*****************************************************************************/
#ifndef __X86_64_MLNX_MSN3800_CONFIG_H__
#define __X86_64_MLNX_MSN3800_CONFIG_H__
#ifdef GLOBAL_INCLUDE_CUSTOM_CONFIG
#include <global_custom_config.h>
#endif
#ifdef X86_64_MLNX_MSN3800_INCLUDE_CUSTOM_CONFIG
#include <x86_64_mlnx_msn3800_custom_config.h>
#endif
/* <auto.start.cdefs(X86_64_MLNX_MSN3800_CONFIG_HEADER).header> */
#include <AIM/aim.h>
/**
* X86_64_MLNX_MSN3800_CONFIG_INCLUDE_LOGGING
*
* Include or exclude logging. */
#ifndef X86_64_MLNX_MSN3800_CONFIG_INCLUDE_LOGGING
#define X86_64_MLNX_MSN3800_CONFIG_INCLUDE_LOGGING 1
#endif
/**
* X86_64_MLNX_MSN3800_CONFIG_LOG_OPTIONS_DEFAULT
*
* Default enabled log options. */
#ifndef X86_64_MLNX_MSN3800_CONFIG_LOG_OPTIONS_DEFAULT
#define X86_64_MLNX_MSN3800_CONFIG_LOG_OPTIONS_DEFAULT AIM_LOG_OPTIONS_DEFAULT
#endif
/**
* X86_64_MLNX_MSN3800_CONFIG_LOG_BITS_DEFAULT
*
* Default enabled log bits. */
#ifndef X86_64_MLNX_MSN3800_CONFIG_LOG_BITS_DEFAULT
#define X86_64_MLNX_MSN3800_CONFIG_LOG_BITS_DEFAULT AIM_LOG_BITS_DEFAULT
#endif
/**
* X86_64_MLNX_MSN3800_CONFIG_LOG_CUSTOM_BITS_DEFAULT
*
* Default enabled custom log bits. */
#ifndef X86_64_MLNX_MSN3800_CONFIG_LOG_CUSTOM_BITS_DEFAULT
#define X86_64_MLNX_MSN3800_CONFIG_LOG_CUSTOM_BITS_DEFAULT 0
#endif
/**
* X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB
*
* Default all porting macros to use the C standard libraries. */
#ifndef X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB
#define X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB 1
#endif
/**
* X86_64_MLNX_MSN3800_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS
*
* Include standard library headers for stdlib porting macros. */
#ifndef X86_64_MLNX_MSN3800_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS
#define X86_64_MLNX_MSN3800_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB
#endif
/**
* X86_64_MLNX_MSN3800_CONFIG_INCLUDE_UCLI
*
* Include generic uCli support. */
#ifndef X86_64_MLNX_MSN3800_CONFIG_INCLUDE_UCLI
#define X86_64_MLNX_MSN3800_CONFIG_INCLUDE_UCLI 0
#endif
/**
* X86_64_MLNX_MSN3800_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION
*
* Assume chassis fan direction is the same as the PSU fan direction. */
#ifndef X86_64_MLNX_MSN3800_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION
#define X86_64_MLNX_MSN3800_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION 0
#endif
/**
* All compile time options can be queried or displayed
*/
/** Configuration settings structure. */
typedef struct x86_64_mlnx_msn3800_config_settings_s {
/** name */
const char* name;
/** value */
const char* value;
} x86_64_mlnx_msn3800_config_settings_t;
/** Configuration settings table. */
/** x86_64_mlnx_msn3800_config_settings table. */
extern x86_64_mlnx_msn3800_config_settings_t x86_64_mlnx_msn3800_config_settings[];
/**
* @brief Lookup a configuration setting.
* @param setting The name of the configuration option to lookup.
*/
const char* x86_64_mlnx_msn3800_config_lookup(const char* setting);
/**
* @brief Show the compile-time configuration.
* @param pvs The output stream.
*/
int x86_64_mlnx_msn3800_config_show(struct aim_pvs_s* pvs);
/* <auto.end.cdefs(X86_64_MLNX_MSN3800_CONFIG_HEADER).header> */
#include "x86_64_mlnx_msn3800_porting.h"
#endif /* __X86_64_MLNX_MSN3800_CONFIG_H__ */
/* @} */

View File

@@ -0,0 +1,26 @@
/**************************************************************************//**
*
* x86_64_mlnx_msn3800 Doxygen Header
*
*****************************************************************************/
#ifndef __X86_64_MLNX_MSN3800_DOX_H__
#define __X86_64_MLNX_MSN3800_DOX_H__
/**
* @defgroup x86_64_mlnx_msn3800 x86_64_mlnx_msn3800 - x86_64_mlnx_msn3800 Description
*
The documentation overview for this module should go here.
*
* @{
*
* @defgroup x86_64_mlnx_msn3800-x86_64_mlnx_msn3800 Public Interface
* @defgroup x86_64_mlnx_msn3800-config Compile Time Configuration
* @defgroup x86_64_mlnx_msn3800-porting Porting Macros
*
* @}
*
*/
#endif /* __X86_64_MLNX_MSN3800_DOX_H__ */

View File

@@ -0,0 +1,107 @@
/**************************************************************************//**
*
* @file
* @brief x86_64_mlnx_msn3800 Porting Macros.
*
* @addtogroup x86_64_mlnx_msn3800-porting
* @{
*
*****************************************************************************/
#ifndef __X86_64_MLNX_MSN3800_PORTING_H__
#define __X86_64_MLNX_MSN3800_PORTING_H__
/* <auto.start.portingmacro(ALL).define> */
#if X86_64_MLNX_MSN3800_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS == 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <memory.h>
#endif
#ifndef X86_64_MLNX_MSN3800_MALLOC
#if defined(GLOBAL_MALLOC)
#define X86_64_MLNX_MSN3800_MALLOC GLOBAL_MALLOC
#elif X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB == 1
#define X86_64_MLNX_MSN3800_MALLOC malloc
#else
#error The macro X86_64_MLNX_MSN3800_MALLOC is required but cannot be defined.
#endif
#endif
#ifndef X86_64_MLNX_MSN3800_FREE
#if defined(GLOBAL_FREE)
#define X86_64_MLNX_MSN3800_FREE GLOBAL_FREE
#elif X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB == 1
#define X86_64_MLNX_MSN3800_FREE free
#else
#error The macro X86_64_MLNX_MSN3800_FREE is required but cannot be defined.
#endif
#endif
#ifndef X86_64_MLNX_MSN3800_MEMSET
#if defined(GLOBAL_MEMSET)
#define X86_64_MLNX_MSN3800_MEMSET GLOBAL_MEMSET
#elif X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB == 1
#define X86_64_MLNX_MSN3800_MEMSET memset
#else
#error The macro X86_64_MLNX_MSN3800_MEMSET is required but cannot be defined.
#endif
#endif
#ifndef X86_64_MLNX_MSN3800_MEMCPY
#if defined(GLOBAL_MEMCPY)
#define X86_64_MLNX_MSN3800_MEMCPY GLOBAL_MEMCPY
#elif X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB == 1
#define X86_64_MLNX_MSN3800_MEMCPY memcpy
#else
#error The macro X86_64_MLNX_MSN3800_MEMCPY is required but cannot be defined.
#endif
#endif
#ifndef X86_64_MLNX_MSN3800_STRNCPY
#if defined(GLOBAL_STRNCPY)
#define X86_64_MLNX_MSN3800_STRNCPY GLOBAL_STRNCPY
#elif X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB == 1
#define X86_64_MLNX_MSN3800_STRNCPY strncpy
#else
#error The macro X86_64_MLNX_MSN3800_STRNCPY is required but cannot be defined.
#endif
#endif
#ifndef X86_64_MLNX_MSN3800_VSNPRINTF
#if defined(GLOBAL_VSNPRINTF)
#define X86_64_MLNX_MSN3800_VSNPRINTF GLOBAL_VSNPRINTF
#elif X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB == 1
#define X86_64_MLNX_MSN3800_VSNPRINTF vsnprintf
#else
#error The macro X86_64_MLNX_MSN3800_VSNPRINTF is required but cannot be defined.
#endif
#endif
#ifndef X86_64_MLNX_MSN3800_SNPRINTF
#if defined(GLOBAL_SNPRINTF)
#define X86_64_MLNX_MSN3800_SNPRINTF GLOBAL_SNPRINTF
#elif X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB == 1
#define X86_64_MLNX_MSN3800_SNPRINTF snprintf
#else
#error The macro X86_64_MLNX_MSN3800_SNPRINTF is required but cannot be defined.
#endif
#endif
#ifndef X86_64_MLNX_MSN3800_STRLEN
#if defined(GLOBAL_STRLEN)
#define X86_64_MLNX_MSN3800_STRLEN GLOBAL_STRLEN
#elif X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB == 1
#define X86_64_MLNX_MSN3800_STRLEN strlen
#else
#error The macro X86_64_MLNX_MSN3800_STRLEN is required but cannot be defined.
#endif
#endif
/* <auto.end.portingmacro(ALL).define> */
#endif /* __X86_64_MLNX_MSN3800_PORTING_H__ */
/* @} */

View File

@@ -0,0 +1,10 @@
###############################################################################
#
#
#
###############################################################################
THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
x86_64_mlnx_msn3800_INCLUDES := -I $(THIS_DIR)inc
x86_64_mlnx_msn3800_INTERNAL_INCLUDES := -I $(THIS_DIR)src
x86_64_mlnx_msn3800_DEPENDMODULE_ENTRIES := init:x86_64_mlnx_msn3800 ucli:x86_64_mlnx_msn3800

View File

@@ -0,0 +1,9 @@
###############################################################################
#
# Local source generation targets.
#
###############################################################################
ucli:
@../../../../tools/uclihandlers.py x86_64_mlnx_msn3800_ucli.c

View File

@@ -0,0 +1,80 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
* Fan Platform Implementation Defaults.
*
***********************************************************/
#include <fcntl.h>
#include <onlplib/file.h>
#include <onlplib/mmap.h>
#include <onlp/platformi/fani.h>
#include "platform_lib.h"
#include "mlnx_common/mlnx_common.h"
#define FAN_RESERVED 0
#define FAN_1_ON_MAIN_BOARD 1
#define FAN_2_ON_MAIN_BOARD 2
#define FAN_3_ON_MAIN_BOARD 3
#define FAN_1_ON_PSU1 4
#define FAN_1_ON_PSU2 5
#define FIRST_PSU_FAN_ID 4
static int min_fan_speed[CHASSIS_FAN_COUNT+1] = {0};
static int max_fan_speed[CHASSIS_FAN_COUNT+1] = {0};
static fan_path_T fan_path[] = /* must map with onlp_fan_id */
{
MAKE_FAN_PATH_ON_MAIN_BOARD(PROJECT_NAME, FAN_RESERVED),
MAKE_FAN_PATH_ON_MAIN_BOARD(PROJECT_NAME, FAN_1_ON_MAIN_BOARD),
MAKE_FAN_PATH_ON_MAIN_BOARD(PROJECT_NAME, FAN_2_ON_MAIN_BOARD),
MAKE_FAN_PATH_ON_MAIN_BOARD(PROJECT_NAME, FAN_3_ON_MAIN_BOARD),
MAKE_FAN_PATH_ON_PSU(1 ,1),
MAKE_FAN_PATH_ON_PSU(2, 1)
};
/* Static fan information */
onlp_fan_info_t finfo[] = {
{ }, /* Not used */
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(1),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(2),
MAKE_FAN_INFO_NODE_ON_MAIN_BOARD(3),
MAKE_FAN_INFO_NODE_ON_PSU(1,1),
MAKE_FAN_INFO_NODE_ON_PSU(2,1)
};
/*
* This function will be called prior to all of onlp_fani_* functions.
*/
int
onlp_fani_init(void)
{
mlnx_platform_info_t* mlnx_platform_info = get_platform_info();
mlnx_platform_info->min_fan_speed = min_fan_speed;
mlnx_platform_info->max_fan_speed = max_fan_speed;
mlnx_platform_info->finfo = finfo;
mlnx_platform_info->fan_fnames = fan_path;
mlnx_platform_info->fan_type = FAN_TYPE_NO_EEPROM;
mlnx_platform_info->fan_per_module = 1;
mlnx_platform_info->first_psu_fan_id = FIRST_PSU_FAN_ID;
return ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,97 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <onlplib/mmap.h>
#include <onlplib/file.h>
#include <onlp/platformi/ledi.h>
#include "platform_lib.h"
#include <mlnx_common/mlnx_common.h>
static char* file_names[] = /* must map with onlp_led_id */
{
"reserved",
"status",
"fan1",
"fan2",
"fan3",
"psu",
"psu",
};
/*
* Get the information for the given LED OID.
*/
static onlp_led_info_t linfo[] =
{
{ }, /* Not used */
{
{ ONLP_LED_ID_CREATE(LED_SYSTEM), "Chassis LED 1 (SYSTEM LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_GREEN_BLINKING |
ONLP_LED_CAPS_ORANGE | ONLP_LED_CAPS_ORANGE_BLINKING | ONLP_LED_CAPS_AUTO,
},
{
{ ONLP_LED_ID_CREATE(LED_FAN1), "Chassis LED 2 (FAN1)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_GREEN_BLINKING |
ONLP_LED_CAPS_ORANGE | ONLP_LED_CAPS_ORANGE_BLINKING | ONLP_LED_CAPS_AUTO,
},
{
{ ONLP_LED_ID_CREATE(LED_FAN2), "Chassis LED 3 (FAN2)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_GREEN_BLINKING |
ONLP_LED_CAPS_ORANGE | ONLP_LED_CAPS_ORANGE_BLINKING | ONLP_LED_CAPS_AUTO,
},
{
{ ONLP_LED_ID_CREATE(LED_FAN3), "Chassis LED 4 (FAN3)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_GREEN_BLINKING |
ONLP_LED_CAPS_ORANGE | ONLP_LED_CAPS_ORANGE_BLINKING | ONLP_LED_CAPS_AUTO,
},
{
{ ONLP_LED_ID_CREATE(LED_PSU_T3), "Chassis LED 5 (PSU LED)", 0 },
ONLP_LED_STATUS_PRESENT,
ONLP_LED_CAPS_ON_OFF | ONLP_LED_CAPS_GREEN | ONLP_LED_CAPS_GREEN_BLINKING |
ONLP_LED_CAPS_ORANGE | ONLP_LED_CAPS_ORANGE_BLINKING | ONLP_LED_CAPS_AUTO,
},
};
/*
* This function will be called prior to any other onlp_ledi_* functions.
*/
int
onlp_ledi_init(void)
{
/*
* ONLPD calls it too early before all BSP insfrastructure is set
*/
mlnx_platform_info_t* mlnx_platform_info = get_platform_info();
mlnx_platform_info->linfo = linfo;
mlnx_platform_info->led_fnames = file_names;
return ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,9 @@
###############################################################################
#
#
#
###############################################################################
LIBRARY := x86_64_mlnx_msn3800
$(LIBRARY)_SUBDIR := $(dir $(lastword $(MAKEFILE_LIST)))
include $(BUILDER)/lib.mk

View File

@@ -0,0 +1,39 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#ifndef __PLATFORM_LIB_H__
#define __PLATFORM_LIB_H__
#include "x86_64_mlnx_msn3800_log.h"
#define CHASSIS_PSU_COUNT 2
#define CHASSIS_TOTAL_FAN_COUNT 5
#define CHASSIS_TOTAL_THERMAL_COUNT 10
#define CHASSIS_FAN_COUNT (CHASSIS_TOTAL_FAN_COUNT - CHASSIS_PSU_COUNT)
#define CHASSIS_THERMAL_COUNT (CHASSIS_TOTAL_THERMAL_COUNT - CHASSIS_PSU_COUNT)
#define CPLD_COUNT 4
#define SFP_PORT_COUNT 32
#define CHASSIS_LED_COUNT 5
#endif /* __PLATFORM_LIB_H__ */

View File

@@ -0,0 +1,64 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
*
*
***********************************************************/
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <onlplib/file.h>
#include <onlp/platformi/fani.h>
#include <onlp/platformi/ledi.h>
#include <onlp/platformi/psui.h>
#include <onlp/platformi/sysi.h>
#include <onlp/platformi/thermali.h>
#include "platform_lib.h"
#include <mlnx_common/mlnx_common.h>
#include "x86_64_mlnx_msn3800_int.h"
#include "x86_64_mlnx_msn3800_log.h"
#define ONL_PLATFORM_NAME "x86-64-mlnx-msn3800-r0"
int mc_get_platform_info(mlnx_platform_info_t* mlnx_platform)
{
strncpy(mlnx_platform->onl_platform_name, ONL_PLATFORM_NAME, PLATFORM_NAME_MAX_LEN);
mlnx_platform->sfp_num = SFP_PORT_COUNT;
mlnx_platform->led_num = CHASSIS_LED_COUNT;
mlnx_platform->psu_num = CHASSIS_PSU_COUNT;
mlnx_platform->fan_num = CHASSIS_FAN_COUNT;
mlnx_platform->thermal_num = CHASSIS_THERMAL_COUNT;
mlnx_platform->cpld_num = CPLD_COUNT;
mlnx_platform->psu_fixed = false;
mlnx_platform->fan_fixed = false;
mlnx_platform->psu_type = PSU_TYPE_3;
mlnx_platform->led_type = LED_TYPE_3;
return ONLP_STATUS_OK;
}
int
onlp_sysi_init(void)
{
return ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,119 @@
/************************************************************
* <bsn.cl fy=2014 v=onl>
*
* Copyright 2014 Big Switch Networks, Inc.
*
* Licensed under the Eclipse Public License, Version 1.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*
* </bsn.cl>
************************************************************
*
* Thermal Sensor Platform Implementation.
*
***********************************************************/
#include <fcntl.h>
#include <unistd.h>
#include <AIM/aim_log.h>
#include <onlplib/file.h>
#include <onlplib/mmap.h>
#include <onlp/platformi/thermali.h>
#include "platform_lib.h"
#include "mlnx_common/mlnx_common.h"
enum onlp_thermal_id
{
THERMAL_RESERVED = 0,
THERMAL_CPU_CORE_0,
THERMAL_CPU_CORE_1,
THERMAL_CPU_CORE_2,
THERMAL_CPU_CORE_3,
THERMAL_CPU_PACK,
THERMAL_ASIC,
THERMAL_BOARD_AMB,
THERMAL_PORT,
THERMAL_ON_PSU1,
THERMAL_ON_PSU2,
};
static char* thermal_fnames[] = /* must map with onlp_thermal_id */
{
"reserved",
"cpu_core0",
"cpu_core1",
"cpu_core2",
"cpu_core3",
"cpu_pack",
"asic",
"fan_amb",
"port_amb",
"psu1",
"psu2"
};
/* Static values */
static onlp_thermal_info_t tinfo[] = {
{ }, /* Not used */
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_0), "CPU Core 0", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, CPU_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_1), "CPU Core 1", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, CPU_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_2), "CPU Core 2", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, CPU_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_CORE_3), "CPU Core 3", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, CPU_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_CPU_PACK), "CPU pack", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, CPU_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_ASIC), "Asic Thermal Sensor", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_ALL, 0, ASIC_THERMAL_THRESHOLD_INIT_DEFAULTS
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_BOARD_AMB), "Board AMB Thermal Sensor", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_GET_TEMPERATURE, 0, {0,0,0}
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_PORT), "Port AMB Thermal Sensor", 0},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_GET_TEMPERATURE, 0, {0,0,0}
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_ON_PSU1), "PSU-1 Thermal Sensor 1", ONLP_PSU_ID_CREATE(PSU1_ID)},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_GET_TEMPERATURE, 0, {0,0,0}
},
{ { ONLP_THERMAL_ID_CREATE(THERMAL_ON_PSU2), "PSU-2 Thermal Sensor 1", ONLP_PSU_ID_CREATE(PSU2_ID)},
ONLP_THERMAL_STATUS_PRESENT,
ONLP_THERMAL_CAPS_GET_TEMPERATURE, 0, {0,0,0}
}
};
/*
* This will be called to intiialize the thermali subsystem.
*/
int
onlp_thermali_init(void)
{
mlnx_platform_info_t* mlnx_platform_info = get_platform_info();
mlnx_platform_info->tinfo=tinfo;
mlnx_platform_info->thermal_fnames=thermal_fnames;
return ONLP_STATUS_OK;
}

View File

@@ -0,0 +1,81 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_mlnx_msn3800/x86_64_mlnx_msn3800_config.h>
/* <auto.start.cdefs(X86_64_MLNX_MSN3800_CONFIG_HEADER).source> */
#define __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME(_x) #_x
#define __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_VALUE(_x) __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME(_x)
x86_64_mlnx_msn3800_config_settings_t x86_64_mlnx_msn3800_config_settings[] =
{
#ifdef X86_64_MLNX_MSN3800_CONFIG_INCLUDE_LOGGING
{ __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME(X86_64_MLNX_MSN3800_CONFIG_INCLUDE_LOGGING), __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_VALUE(X86_64_MLNX_MSN3800_CONFIG_INCLUDE_LOGGING) },
#else
{ X86_64_MLNX_MSN3800_CONFIG_INCLUDE_LOGGING(__X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_MLNX_MSN3800_CONFIG_LOG_OPTIONS_DEFAULT
{ __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME(X86_64_MLNX_MSN3800_CONFIG_LOG_OPTIONS_DEFAULT), __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_VALUE(X86_64_MLNX_MSN3800_CONFIG_LOG_OPTIONS_DEFAULT) },
#else
{ X86_64_MLNX_MSN3800_CONFIG_LOG_OPTIONS_DEFAULT(__X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_MLNX_MSN3800_CONFIG_LOG_BITS_DEFAULT
{ __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME(X86_64_MLNX_MSN3800_CONFIG_LOG_BITS_DEFAULT), __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_VALUE(X86_64_MLNX_MSN3800_CONFIG_LOG_BITS_DEFAULT) },
#else
{ X86_64_MLNX_MSN3800_CONFIG_LOG_BITS_DEFAULT(__X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_MLNX_MSN3800_CONFIG_LOG_CUSTOM_BITS_DEFAULT
{ __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME(X86_64_MLNX_MSN3800_CONFIG_LOG_CUSTOM_BITS_DEFAULT), __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_VALUE(X86_64_MLNX_MSN3800_CONFIG_LOG_CUSTOM_BITS_DEFAULT) },
#else
{ X86_64_MLNX_MSN3800_CONFIG_LOG_CUSTOM_BITS_DEFAULT(__X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB
{ __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME(X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB), __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_VALUE(X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB) },
#else
{ X86_64_MLNX_MSN3800_CONFIG_PORTING_STDLIB(__X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_MLNX_MSN3800_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS
{ __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME(X86_64_MLNX_MSN3800_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS), __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_VALUE(X86_64_MLNX_MSN3800_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS) },
#else
{ X86_64_MLNX_MSN3800_CONFIG_PORTING_INCLUDE_STDLIB_HEADERS(__X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_MLNX_MSN3800_CONFIG_INCLUDE_UCLI
{ __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME(X86_64_MLNX_MSN3800_CONFIG_INCLUDE_UCLI), __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_VALUE(X86_64_MLNX_MSN3800_CONFIG_INCLUDE_UCLI) },
#else
{ X86_64_MLNX_MSN3800_CONFIG_INCLUDE_UCLI(__X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME), "__undefined__" },
#endif
#ifdef X86_64_MLNX_MSN3800_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION
{ __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME(X86_64_MLNX_MSN3800_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION), __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_VALUE(X86_64_MLNX_MSN3800_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION) },
#else
{ X86_64_MLNX_MSN3800_CONFIG_INCLUDE_DEFAULT_FAN_DIRECTION(__X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME), "__undefined__" },
#endif
{ NULL, NULL }
};
#undef __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_VALUE
#undef __X86_64_MLNX_MSN3800_CONFIG_STRINGIFY_NAME
const char*
x86_64_mlnx_msn3800_config_lookup(const char* setting)
{
int i;
for(i = 0; x86_64_mlnx_msn3800_config_settings[i].name; i++) {
if(strcmp(x86_64_mlnx_msn3800_config_settings[i].name, setting)) {
return x86_64_mlnx_msn3800_config_settings[i].value;
}
}
return NULL;
}
int
x86_64_mlnx_msn3800_config_show(struct aim_pvs_s* pvs)
{
int i;
for(i = 0; x86_64_mlnx_msn3800_config_settings[i].name; i++) {
aim_printf(pvs, "%s = %s\n", x86_64_mlnx_msn3800_config_settings[i].name, x86_64_mlnx_msn3800_config_settings[i].value);
}
return i;
}
/* <auto.end.cdefs(x86_64_mlnx_msn3800_CONFIG_HEADER).source> */

View File

@@ -0,0 +1,10 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_mlnx_msn3800/x86_64_mlnx_msn3800_config.h>
/* <--auto.start.enum(ALL).source> */
/* <auto.end.enum(ALL).source> */

View File

@@ -0,0 +1,12 @@
/**************************************************************************//**
*
* x86_64_mlnx_msn3800 Internal Header
*
*****************************************************************************/
#ifndef __X86_64_MLNX_MSN3800_INT_H__
#define __X86_64_MLNX_MSN3800_INT_H__
#include <x86_64_mlnx_msn3800/x86_64_mlnx_msn3800_config.h>
#endif /* __X86_64_MLNX_MSN3800_INT_H__ */

View File

@@ -0,0 +1,18 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_mlnx_msn3800/x86_64_mlnx_msn3800_config.h>
#include "x86_64_mlnx_msn3800_log.h"
/*
* x86_64_mlnx_msn3800 log struct.
*/
AIM_LOG_STRUCT_DEFINE(
X86_64_MLNX_MSN3800_CONFIG_LOG_OPTIONS_DEFAULT,
X86_64_MLNX_MSN3800_CONFIG_LOG_BITS_DEFAULT,
NULL, /* Custom log map */
X86_64_MLNX_MSN3800_CONFIG_LOG_CUSTOM_BITS_DEFAULT
);

View File

@@ -0,0 +1,12 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#ifndef __X86_64_MLNX_MSN3800_LOG_H__
#define __X86_64_MLNX_MSN3800_LOG_H__
#define AIM_LOG_MODULE_NAME x86_64_mlnx_msn3800
#include <AIM/aim_log.h>
#endif /* __X86_64_MLNX_MSN3800_LOG_H__ */

View File

@@ -0,0 +1,24 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_mlnx_msn3800/x86_64_mlnx_msn3800_config.h>
#include "x86_64_mlnx_msn3800_log.h"
static int
datatypes_init__(void)
{
#define x86_64_mlnx_msn3800_ENUMERATION_ENTRY(_enum_name, _desc) AIM_DATATYPE_MAP_REGISTER(_enum_name, _enum_name##_map, _desc, AIM_LOG_INTERNAL);
#include <x86_64_mlnx_msn3800/x86_64_mlnx_msn3800.x>
return 0;
}
void __x86_64_mlnx_msn3800_module_init__(void)
{
AIM_LOG_STRUCT_REGISTER();
datatypes_init__();
}
int __onlp_platform_version__ = 1;

View File

@@ -0,0 +1,50 @@
/**************************************************************************//**
*
*
*
*****************************************************************************/
#include <x86_64_mlnx_msn3800/x86_64_mlnx_msn3800_config.h>
#if x86_64_mlnx_msn3800_CONFIG_INCLUDE_UCLI == 1
#include <uCli/ucli.h>
#include <uCli/ucli_argparse.h>
#include <uCli/ucli_handler_macros.h>
static ucli_status_t
x86_64_mlnx_msn3800_ucli_ucli__config__(ucli_context_t* uc)
{
UCLI_HANDLER_MACRO_MODULE_CONFIG(x86_64_mlnx_msn3800)
}
/* <auto.ucli.handlers.start> */
/* <auto.ucli.handlers.end> */
static ucli_module_t
x86_64_mlnx_msn3800_ucli_module__ =
{
"x86_64_mlnx_msn3800_ucli",
NULL,
x86_64_mlnx_msn3800_ucli_ucli_handlers__,
NULL,
NULL,
};
ucli_node_t*
x86_64_mlnx_msn3800_ucli_node_create(void)
{
ucli_node_t* n;
ucli_module_init(&x86_64_mlnx_msn3800_ucli_module__);
n = ucli_node_create("x86_64_mlnx_msn3800", NULL, &x86_64_mlnx_msn3800_ucli_module__);
ucli_node_subnode_add(n, ucli_module_log_node_create("x86_64_mlnx_msn3800"));
return n;
}
#else
void*
x86_64_mlnx_msn3800_ucli_node_create(void)
{
return NULL;
}
#endif

View File

@@ -0,0 +1,13 @@
###############################################################################
#
# Inclusive Makefile for the x86_64_mlnx_msn3800 module.
#
# Autogenerated 2015-12-23 23:45:56.754200
#
###############################################################################
x86_64_mlnx_msn3800_BASEDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
include $(x86_64_mlnx_msn3800_BASEDIR)/module/make.mk
include $(x86_64_mlnx_msn3800_BASEDIR)/module/auto/make.mk
include $(x86_64_mlnx_msn3800_BASEDIR)/module/src/make.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
include $(ONL)/make/pkg.mk

View File

@@ -0,0 +1 @@
!include $ONL_TEMPLATES/platform-config-platform.yml ARCH=amd64 VENDOR=mellanox BASENAME=x86-64-mlnx-msn3800 REVISION=r0

View File

@@ -0,0 +1,33 @@
---
######################################################################
#
# platform-config for Mellanox msn3800
#
######################################################################
x86-64-mlnx-msn3800-r0:
grub:
serial: >-
--unit=0
--speed=115200
--word=8
--parity=0
--stop=1
kernel:
<<: *kernel-4-9
args: >-
nopat
console=ttyS0,115200n8
rd_NO_MD
rd_NO_LUKS
##network
## interfaces:
## ma1:
## name: ~
## syspath: pci0000:00/0000:00:14.0

View File

@@ -0,0 +1,16 @@
from onl.platform.base import *
from onl.platform.mellanox import *
class OnlPlatform_x86_64_mlnx_msn3800_r0(OnlPlatformMellanox,
OnlPlatformPortConfig_32x100):
PLATFORM='x86-64-mlnx-msn3800-r0'
MODEL="MSN3800"
SYS_OBJECT_ID=".3800.1"
def baseconfig(self):
# load modules
import os
# necessary if there are issues with the install
# os.system("/usr/bin/apt-get install")
self.syseeprom_export();
return True