Skip to content

Commit 50e2bff

Browse files
[patch] mlxsw: i2c: Prevent transaction execution for special chip (sonic-net#279)
* [patch] mlxsw: i2c: Prevent transaction execution for special chip states Do not run transaction in cases chip is in reset or in-filed update states. This patch fixes an issue encountered during SONiC warm-reboot: during ISSU start the kernel reports that CPU stall is detected: ``` INFO: rcu_sched detected stalls on CPUs/tasks ``` This patch won't be upstreamed due to the upstream driver not supporting ISSU. Signed-off-by: Stepan Blyschak <[email protected]> * remove TMP tag Signed-off-by: Stepan Blyschak <[email protected]>
1 parent fa9411d commit 50e2bff

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
From d3e0bf403d527f717a62ea328781256f999d4f95 Mon Sep 17 00:00:00 2001
2+
From: Stepan Blyschak <[email protected]>
3+
Date: Mon, 20 Jun 2022 19:28:04 +0300
4+
Subject: [PATCH] mlxsw: i2c: Prevent transaction execution for special
5+
chip states
6+
7+
Do not run transaction in cases chip is in reset or in-service update
8+
states. In such case firmware is not accessible and will reject transaction
9+
with the relevant status "RUNNING_RESET" or "FW_ISSU_ONGOING".
10+
In case transaction is failed do to one of these reasons, stop sending
11+
transactions. In such case driver is about to be removed since it
12+
cannot continue running after reset or in-service update. And
13+
re-probed again after reset or in-service update is completed.
14+
15+
Signed-off-by: Vadim Pasternak <[email protected]>
16+
Signed-off-by: Stepan Blyschak <[email protected]>
17+
---
18+
drivers/net/ethernet/mellanox/mlxsw/cmd.h | 4 ++++
19+
drivers/net/ethernet/mellanox/mlxsw/i2c.c | 29 ++++++++++++++++++++---
20+
2 files changed, 30 insertions(+), 3 deletions(-)
21+
22+
diff --git a/drivers/net/ethernet/mellanox/mlxsw/cmd.h b/drivers/net/ethernet/mellanox/mlxsw/cmd.h
23+
index 91f68fb0b..d8ecb8c8a 100644
24+
--- a/drivers/net/ethernet/mellanox/mlxsw/cmd.h
25+
+++ b/drivers/net/ethernet/mellanox/mlxsw/cmd.h
26+
@@ -149,6 +149,8 @@ enum mlxsw_cmd_status {
27+
MLXSW_CMD_STATUS_BAD_NVMEM = 0x0B,
28+
/* Device is currently running reset */
29+
MLXSW_CMD_STATUS_RUNNING_RESET = 0x26,
30+
+ /* FW ISSU ongoing. */
31+
+ MLXSW_CMD_STATUS_FW_ISSU = 0x27,
32+
/* Bad management packet (silently discarded). */
33+
MLXSW_CMD_STATUS_BAD_PKT = 0x30,
34+
};
35+
@@ -180,6 +182,8 @@ static inline const char *mlxsw_cmd_status_str(u8 status)
36+
return "BAD_NVMEM";
37+
case MLXSW_CMD_STATUS_RUNNING_RESET:
38+
return "RUNNING_RESET";
39+
+ case MLXSW_CMD_STATUS_FW_ISSU:
40+
+ return "FW_ISSU_ONGOING";
41+
case MLXSW_CMD_STATUS_BAD_PKT:
42+
return "BAD_PKT";
43+
default:
44+
diff --git a/drivers/net/ethernet/mellanox/mlxsw/i2c.c b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
45+
index 939b692ff..3c9d2c7a0 100644
46+
--- a/drivers/net/ethernet/mellanox/mlxsw/i2c.c
47+
+++ b/drivers/net/ethernet/mellanox/mlxsw/i2c.c
48+
@@ -63,6 +63,7 @@
49+
* @core: switch core pointer;
50+
* @bus_info: bus info block;
51+
* @block_size: maximum block size allowed to pass to under layer;
52+
+ * @status: status to indicate chip reset or in-service update;
53+
*/
54+
struct mlxsw_i2c {
55+
struct {
56+
@@ -76,6 +77,7 @@ struct mlxsw_i2c {
57+
struct mlxsw_core *core;
58+
struct mlxsw_bus_info bus_info;
59+
u16 block_size;
60+
+ u8 status;
61+
};
62+
63+
#define MLXSW_I2C_READ_MSG(_client, _addr_buf, _buf, _len) { \
64+
@@ -222,6 +224,19 @@ static int mlxsw_i2c_write_cmd(struct i2c_client *client,
65+
return 0;
66+
}
67+
68+
+static bool
69+
+mlxsw_i2c_cmd_status_verify(struct device *dev, struct mlxsw_i2c *mlxsw_i2c,
70+
+ u8 status)
71+
+{
72+
+ if (status == MLXSW_CMD_STATUS_FW_ISSU ||
73+
+ status == MLXSW_CMD_STATUS_RUNNING_RESET) {
74+
+ mlxsw_i2c->status = status;
75+
+ dev_info(dev, "FW status=%x(%s)): Access to device is not allowed in this state\n", status, mlxsw_cmd_status_str(status));
76+
+ return true;
77+
+ }
78+
+ return false;
79+
+}
80+
+
81+
/* Routine posts initialization command to ASIC through mail box. */
82+
static int
83+
mlxsw_i2c_write_init_cmd(struct i2c_client *client,
84+
@@ -405,6 +420,10 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
85+
86+
WARN_ON(in_mbox_size % sizeof(u32) || out_mbox_size % sizeof(u32));
87+
88+
+ /* Do not run transaction if chip is in reset or in-service update state. */
89+
+ if (mlxsw_i2c->status)
90+
+ return 0;
91+
+
92+
if (in_mbox) {
93+
reg_size = mlxsw_i2c_get_reg_size(in_mbox);
94+
num = reg_size / mlxsw_i2c->block_size;
95+
@@ -479,6 +498,8 @@ mlxsw_i2c_cmd(struct device *dev, u16 opcode, u32 in_mod, size_t in_mbox_size,
96+
97+
cmd_fail:
98+
mutex_unlock(&mlxsw_i2c->cmd.lock);
99+
+ if (mlxsw_i2c_cmd_status_verify(&client->dev, mlxsw_i2c, *status))
100+
+ err = 0;
101+
return err;
102+
}
103+
104+
@@ -608,14 +629,16 @@ static int mlxsw_i2c_probe(struct i2c_client *client,
105+
/* Wait until go bit is cleared. */
106+
err = mlxsw_i2c_wait_go_bit(client, mlxsw_i2c, &status);
107+
if (err) {
108+
- dev_err(&client->dev, "HW semaphore is not released");
109+
+ if (!mlxsw_i2c_cmd_status_verify(&client->dev, mlxsw_i2c, status))
110+
+ dev_err(&client->dev, "HW semaphore is not released");
111+
goto errout;
112+
}
113+
114+
/* Validate transaction completion status. */
115+
if (status) {
116+
- dev_err(&client->dev, "Bad transaction completion status %x\n",
117+
- status);
118+
+ if (!mlxsw_i2c_cmd_status_verify(&client->dev, mlxsw_i2c, status))
119+
+ dev_err(&client->dev, "Bad transaction completion status %x\n",
120+
+ status);
121+
err = -EIO;
122+
goto errout;
123+
}
124+
--
125+
2.17.1
126+

patch/series

+1
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ kernel-compat-always-include-linux-compat.h-from-net-compat.patch
128128
0096-hwmon-mlxreg-fan-Modify-PWM-connectivity-valida.patch
129129
0097-hwmon-mlxreg-fan-Support-distinctive-names-per-.patch
130130
0999-Revert-mlxsw-thermal-Fix-out-of-bounds-memory-a.patch
131+
0098-mlxsw-i2c-Prevent-transaction-execution-for.patch
131132

132133

133134
# Cisco patches for 5.10 kernel

0 commit comments

Comments
 (0)